fetch_components
Retrieve Storyblok components using server-side filtering, sorting, and group inclusion options. Supports pagination and summary fields.
Instructions
Fetches components with server-side filters, sorting, and option to include groups.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| component_summary | No | If true, return only id, name, and display_name for each component | |
| include_schema_details | No | If false, exclude schema from component response | |
| filter_by_name | No | Search query for filtering components by name | |
| is_root | No | Filter for root components only | |
| in_group | No | Filter by component group ID | |
| sort_by | No | Field to sort by | |
| per_page | No | Number of results per page |
Implementation Reference
- src/tools/components.ts:72-124 (handler)Handler function for the fetch_components tool. It builds query params from inputs, calls apiGet('/components', params) to fetch components, optionally summarizes or excludes schema, also fetches component_groups, and returns a JSON response.
async ({ component_summary, include_schema_details, filter_by_name, is_root, in_group, sort_by, per_page }) => { try { const params: Record<string, string> = {}; if (filter_by_name) { params.search = filter_by_name; } if (is_root !== undefined) { params.is_root = is_root ? '1' : '0'; } if (in_group !== undefined) { params.in_group = String(in_group); } if (sort_by) { params.sort_by = sort_by; } if (per_page) { params.per_page = String(per_page); } const data = await apiGet<{ components: Array<Record<string, unknown>> }>('/components', params); let components = data.components || []; // Summaries or remove schema if requested if (component_summary) { components = components.map((c) => ({ id: c.id, name: c.name, display_name: c.display_name, })); } else if (!include_schema_details) { components = components.map((c) => { const { schema, ...rest } = c; return rest; }); } // Also fetch component groups (folders) const groupsData = await apiGet<{ component_groups: Array<Record<string, unknown>> }>('/component_groups'); const groups = groupsData.component_groups || []; return createJsonResponse({ components_count: components.length, components, component_groups: groups, }); } catch (error) { if (error instanceof APIError) { return createErrorResponse(error); } throw error; } } ); - src/tools/components.ts:55-71 (schema)Zod schema definitions for fetch_components inputs: component_summary, include_schema_details, filter_by_name, is_root, in_group, sort_by, per_page.
{ component_summary: z .boolean() .optional() .default(false) .describe('If true, return only id, name, and display_name for each component'), include_schema_details: z .boolean() .optional() .default(true) .describe('If false, exclude schema from component response'), filter_by_name: z.string().optional().describe('Search query for filtering components by name'), is_root: z.boolean().optional().describe('Filter for root components only'), in_group: z.number().optional().describe('Filter by component group ID'), sort_by: z.string().optional().describe('Field to sort by'), per_page: z.number().optional().describe('Number of results per page'), }, - src/tools/components.ts:50-124 (registration)Registration of the fetch_components tool via server.tool('fetch_components', ...) inside the registerComponents function.
export function registerComponents(server: McpServer): void { // Tool: fetch_components server.tool( 'fetch_components', 'Fetches components with server-side filters, sorting, and option to include groups.', { component_summary: z .boolean() .optional() .default(false) .describe('If true, return only id, name, and display_name for each component'), include_schema_details: z .boolean() .optional() .default(true) .describe('If false, exclude schema from component response'), filter_by_name: z.string().optional().describe('Search query for filtering components by name'), is_root: z.boolean().optional().describe('Filter for root components only'), in_group: z.number().optional().describe('Filter by component group ID'), sort_by: z.string().optional().describe('Field to sort by'), per_page: z.number().optional().describe('Number of results per page'), }, async ({ component_summary, include_schema_details, filter_by_name, is_root, in_group, sort_by, per_page }) => { try { const params: Record<string, string> = {}; if (filter_by_name) { params.search = filter_by_name; } if (is_root !== undefined) { params.is_root = is_root ? '1' : '0'; } if (in_group !== undefined) { params.in_group = String(in_group); } if (sort_by) { params.sort_by = sort_by; } if (per_page) { params.per_page = String(per_page); } const data = await apiGet<{ components: Array<Record<string, unknown>> }>('/components', params); let components = data.components || []; // Summaries or remove schema if requested if (component_summary) { components = components.map((c) => ({ id: c.id, name: c.name, display_name: c.display_name, })); } else if (!include_schema_details) { components = components.map((c) => { const { schema, ...rest } = c; return rest; }); } // Also fetch component groups (folders) const groupsData = await apiGet<{ component_groups: Array<Record<string, unknown>> }>('/component_groups'); const groups = groupsData.component_groups || []; return createJsonResponse({ components_count: components.length, components, component_groups: groups, }); } catch (error) { if (error instanceof APIError) { return createErrorResponse(error); } throw error; } } ); - src/tools/index.ts:88-89 (registration)Top-level registration call: registerComponents(server) which registers fetch_components among other component tools.
registerComponents(server); registerComponentsFolder(server); - src/utils/api.ts:180-190 (helper)The apiGet helper used by fetch_components to make GET requests to the Storyblok Management API.
export async function apiGet<T = unknown>( path: string, params: Record<string, string> = {} ): Promise<T> { const url = buildUrlWithParams(buildManagementUrl(path), params); const response = await fetch(url, { method: 'GET', headers: getManagementHeaders(), }); return handleResponse<T>(response, url); }