getThingsPaginated.ts•2.6 kB
import ThingiversePuppeteer from '@/class/thingiverser.class';
import { mcpServer } from '@/index';
import { Thing } from '@/types/things';
import z from 'zod';
mcpServer.tool(
'search-things-paginated',
'Search for things with pagination support',
{
term: z.string().describe("Term to search within thingiverse's database"),
categoryId: z.string().optional().describe('Category ID to search in if known'),
page: z.number().optional().default(1).describe('Page number to retrieve'),
sortBy: z
.enum(['relevant', 'popular', 'newest', 'makes', 'likes'])
.optional()
.default('relevant')
.describe('How to sort the results'),
},
async ({ term, categoryId, page, sortBy }) => {
const thingiverser = new ThingiversePuppeteer(process.env.APP_TOKEN as string);
const perPage = 100;
await thingiverser.init();
try {
// Add the improved search method to ThingiversePuppeteer class
const searchResponse = await thingiverser.searchThingsPaginated(
term,
page,
perPage,
sortBy,
categoryId,
);
if (searchResponse.total === 0) {
await thingiverser.close();
return {
content: [
{
type: 'text',
text: JSON.stringify(
{
total: 0,
page,
perPage,
totalPages: 0,
items: [],
},
null,
2,
),
},
],
};
}
await thingiverser.close();
const totalPages = Math.ceil(searchResponse.total / perPage);
const response = {
total: searchResponse.total,
page,
perPage,
totalPages,
items: searchResponse.hits.map((thing: Thing) => ({
id: thing.id,
name: thing.name,
url: thing.public_url,
thumbnail: thing.thumbnail,
likeCount: thing.like_count,
description: thing.description,
creator: {
id: thing.creator.id,
name: thing.creator.name,
},
added: thing.added,
downloadCount: thing.download_count,
tags: thing.tags,
})),
};
return {
content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],
};
} catch (error) {
await thingiverser.close();
return {
isError: true,
content: [{ type: 'text', text: `Error searching things: ${error}` }],
};
}
},
);