getThingsDetailed.ts•2.3 kB
import ThingiversePuppeteer from '@/class/thingiverser.class';
import { mcpServer } from '@/index';
import z from 'zod';
mcpServer.tool(
'get-thing-details',
'Get detailed information about a specific 3D model',
{
thingId: z.number().describe('The ID of the thing/model to retrieve'),
includeFiles: z.boolean().optional().default(true).describe('Include file information'),
},
async ({ thingId, includeFiles }) => {
const thingiverser = new ThingiversePuppeteer(process.env.APP_TOKEN as string);
await thingiverser.init();
try {
// Get the thing details
const thing = await thingiverser.getThingById(thingId);
// Get files if requested
let files;
if (includeFiles) {
files = await thingiverser.getFilesFromThing(thingId);
}
await thingiverser.close();
// Format the response
const response = {
id: thing.id,
name: thing.name,
creator: {
id: thing.creator.id,
name: thing.creator.name,
public_url: thing.creator.public_url,
},
description: thing.description,
instructions: thing.instructions,
license: thing.license,
public_url: thing.public_url,
added: thing.added,
modified: thing.modified,
like_count: thing.like_count,
collect_count: thing.collect_count,
download_count: thing.download_count,
view_count: thing.view_count,
make_count: thing.make_count,
remix_count: thing.remix_count,
tags: thing.tags,
files:
includeFiles && files
? files.map(file => ({
id: file.id,
name: file.name,
size: file.size,
formatted_size: file.formatted_size,
download_url: file.download_url,
thumbnail: file.thumbnail,
download_count: file.download_count,
}))
: undefined,
};
return {
content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],
};
} catch (error) {
await thingiverser.close();
return {
isError: true,
content: [{ type: 'text', text: `Error fetching thing details: ${error}` }],
};
}
},
);