get_catalog_products
Retrieve catalog products with filtering by category, search, and product type. Supports pagination and sorting to manage large result sets.
Instructions
Get all catalog products
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cursor | No | Cursor for fetching the next page of results | |
| per_page | No | Number of results per page (default: 25) | |
| published | No | Show only published products | |
| category_id | No | Filter results on category_id | |
| productable_type | No | Filter results on productable_type | |
| search | No | Filter results on search | |
| sort | No | Sort the results. Can change order by using `<sort_by>:<direction>` where `<direction>` is either `asc` or `desc` |
Implementation Reference
- src/tools/catalog_products.ts:31-55 (handler)The async handler function for the 'get_catalog_products' tool. Calls apiList('/catalog/products', ...), logs the response, formats the result using formatList, and appends a next-cursor hint if paginated.
async ({ cursor, per_page, published, category_id, productable_type, search, sort }) => { try { const result = await apiList<EduframeRecord>("/catalog/products", { cursor, per_page, published, category_id, productable_type, search, sort, }); void logResponse( "get_catalog_products", { cursor, per_page, published, category_id, productable_type, search, sort }, result, ); const toolResult = formatList(result.records, "catalog products"); if (result.nextCursor) { toolResult.content.push({ type: "text", text: `\nNext page cursor: ${result.nextCursor}` }); } return toolResult; } catch (error) { return formatError(error); } }, - src/tools/catalog_products.ts:10-29 (schema)Input schema for 'get_catalog_products' with filter parameters: cursor, per_page, published, category_id, productable_type, search, and sort.
{ description: "Get all catalog products", annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }, inputSchema: { cursor: z.string().optional().describe("Cursor for fetching the next page of results"), per_page: z.number().int().positive().optional().describe("Number of results per page (default: 25)"), published: z.enum(["published"]).optional().describe("Show only published products"), category_id: z.number().int().optional().describe("Filter results on category_id"), productable_type: z .enum(["Course", "Program::Program"]) .optional() .describe("Filter results on productable_type"), search: z.string().optional().describe("Filter results on search"), sort: z .array(z.enum(["id:asc", "id:desc", "position:asc", "position:desc"])) .optional() .describe( "Sort the results. Can change order by using `<sort_by>:<direction>` where `<direction>` is either `asc` or `desc`", ), }, - src/tools/catalog_products.ts:8-56 (registration)Registration of the 'get_catalog_products' tool via server.registerTool() with its schema, annotations, and handler.
server.registerTool( "get_catalog_products", { description: "Get all catalog products", annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }, inputSchema: { cursor: z.string().optional().describe("Cursor for fetching the next page of results"), per_page: z.number().int().positive().optional().describe("Number of results per page (default: 25)"), published: z.enum(["published"]).optional().describe("Show only published products"), category_id: z.number().int().optional().describe("Filter results on category_id"), productable_type: z .enum(["Course", "Program::Program"]) .optional() .describe("Filter results on productable_type"), search: z.string().optional().describe("Filter results on search"), sort: z .array(z.enum(["id:asc", "id:desc", "position:asc", "position:desc"])) .optional() .describe( "Sort the results. Can change order by using `<sort_by>:<direction>` where `<direction>` is either `asc` or `desc`", ), }, }, async ({ cursor, per_page, published, category_id, productable_type, search, sort }) => { try { const result = await apiList<EduframeRecord>("/catalog/products", { cursor, per_page, published, category_id, productable_type, search, sort, }); void logResponse( "get_catalog_products", { cursor, per_page, published, category_id, productable_type, search, sort }, result, ); const toolResult = formatList(result.records, "catalog products"); if (result.nextCursor) { toolResult.content.push({ type: "text", text: `\nNext page cursor: ${result.nextCursor}` }); } return toolResult; } catch (error) { return formatError(error); } }, ); - src/tools/index.ts:69-69 (registration)The registerCatalogProductTools function is called from the central tools index to register all catalog product tools (including get_catalog_products).
registerCatalogProductTools, - src/api.ts:122-137 (helper)The apiList helper function that performs the actual GET request to the paginated list endpoint (used by the handler).
export async function apiList<T>(path: string, query?: Record<string, QueryValue>): Promise<ListResult<T>> { const { token } = getConfig(); const url = buildUrl(path, query); const response = await fetch(url.toString(), { method: "GET", headers: buildHeaders(token), }); await checkResponse(response); const records = (await response.json()) as T[]; const nextCursor = parseNextCursor(response.headers.get("Link")); return { records, nextCursor }; }