api_endpoints
List API endpoints from an imported API specification, filtered by tag, method, or path. Auto-selects the only imported spec if name is not given.
Instructions
Lista los endpoints de un API importada. Filtra por tag, método o path. Si no se especifica nombre y solo hay un spec importado, lo usa automáticamente.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente | |
| tag | No | Filtrar por tag (ej: "blog", "auth", "users") | |
| method | No | Filtrar por método HTTP | |
| path | No | Filtrar por path (búsqueda parcial, ej: "/blog" muestra todos los que contienen /blog) |
Implementation Reference
- src/tools/api-spec.ts:220-321 (handler)The 'api_endpoints' tool handler. Registered as an MCP tool that lists endpoints of an imported OpenAPI spec. Accepts optional filters: name (spec name), tag, method, path. Resolves the spec name, fetches endpoints from storage, applies filters, and returns formatted output.
server.tool( 'api_endpoints', 'Lista los endpoints de un API importada. Filtra por tag, método o path. Si no se especifica nombre y solo hay un spec importado, lo usa automáticamente.', { name: z .string() .optional() .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'), tag: z .string() .optional() .describe('Filtrar por tag (ej: "blog", "auth", "users")'), method: z .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']) .optional() .describe('Filtrar por método HTTP'), path: z .string() .optional() .describe('Filtrar por path (búsqueda parcial, ej: "/blog" muestra todos los que contienen /blog)'), }, async (params) => { try { const resolved = await resolveSpecName(params.name, storage) if (resolved.error) { return { content: [{ type: 'text' as const, text: resolved.error }], isError: true, } } const resolvedName = resolved.name as string const spec = await storage.getSpec(resolvedName) if (!spec) { return { content: [ { type: 'text' as const, text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`, }, ], isError: true, } } let endpoints = spec.endpoints // Apply filters if (params.tag) { endpoints = endpoints.filter((ep) => (ep.tags ?? []).some((t) => t.toLowerCase() === params.tag!.toLowerCase()), ) } if (params.method) { endpoints = endpoints.filter((ep) => ep.method === params.method) } if (params.path) { const search = params.path.toLowerCase() endpoints = endpoints.filter((ep) => ep.path.toLowerCase().includes(search)) } if (endpoints.length === 0) { return { content: [ { type: 'text' as const, text: 'No se encontraron endpoints con los filtros aplicados.', }, ], } } // Format output const lines = endpoints.map((ep) => { const tags = ep.tags?.length ? ` [${ep.tags.join(', ')}]` : '' const summary = ep.summary ? ` — ${ep.summary}` : '' return `${ep.method.padEnd(7)} ${ep.path}${summary}${tags}` }) return { content: [ { type: 'text' as const, text: [ `API: ${spec.name} (${endpoints.length} endpoints)`, '', ...lines, '', 'Usa api_endpoint_detail para ver parámetros, body y respuestas de un endpoint.', ].join('\n'), }, ], } } catch (error) { const message = error instanceof Error ? error.message : String(error) return { content: [{ type: 'text' as const, text: `Error: ${message}` }], isError: true, } } }, ) - src/tools/api-spec.ts:223-240 (schema)Zod schema definitions for the api_endpoints tool inputs: optional name (string), optional tag (string), optional method (enum of HTTP methods), optional path (string).
{ name: z .string() .optional() .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'), tag: z .string() .optional() .describe('Filtrar por tag (ej: "blog", "auth", "users")'), method: z .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']) .optional() .describe('Filtrar por método HTTP'), path: z .string() .optional() .describe('Filtrar por path (búsqueda parcial, ej: "/blog" muestra todos los que contienen /blog)'), }, - src/tools/api-spec.ts:220-321 (registration)The api_endpoints tool is registered inside registerApiSpecTools() by calling server.tool('api_endpoints', ...). The registration function is exported and invoked at src/server.ts:65.
server.tool( 'api_endpoints', 'Lista los endpoints de un API importada. Filtra por tag, método o path. Si no se especifica nombre y solo hay un spec importado, lo usa automáticamente.', { name: z .string() .optional() .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'), tag: z .string() .optional() .describe('Filtrar por tag (ej: "blog", "auth", "users")'), method: z .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']) .optional() .describe('Filtrar por método HTTP'), path: z .string() .optional() .describe('Filtrar por path (búsqueda parcial, ej: "/blog" muestra todos los que contienen /blog)'), }, async (params) => { try { const resolved = await resolveSpecName(params.name, storage) if (resolved.error) { return { content: [{ type: 'text' as const, text: resolved.error }], isError: true, } } const resolvedName = resolved.name as string const spec = await storage.getSpec(resolvedName) if (!spec) { return { content: [ { type: 'text' as const, text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`, }, ], isError: true, } } let endpoints = spec.endpoints // Apply filters if (params.tag) { endpoints = endpoints.filter((ep) => (ep.tags ?? []).some((t) => t.toLowerCase() === params.tag!.toLowerCase()), ) } if (params.method) { endpoints = endpoints.filter((ep) => ep.method === params.method) } if (params.path) { const search = params.path.toLowerCase() endpoints = endpoints.filter((ep) => ep.path.toLowerCase().includes(search)) } if (endpoints.length === 0) { return { content: [ { type: 'text' as const, text: 'No se encontraron endpoints con los filtros aplicados.', }, ], } } // Format output const lines = endpoints.map((ep) => { const tags = ep.tags?.length ? ` [${ep.tags.join(', ')}]` : '' const summary = ep.summary ? ` — ${ep.summary}` : '' return `${ep.method.padEnd(7)} ${ep.path}${summary}${tags}` }) return { content: [ { type: 'text' as const, text: [ `API: ${spec.name} (${endpoints.length} endpoints)`, '', ...lines, '', 'Usa api_endpoint_detail para ver parámetros, body y respuestas de un endpoint.', ].join('\n'), }, ], } } catch (error) { const message = error instanceof Error ? error.message : String(error) return { content: [{ type: 'text' as const, text: `Error: ${message}` }], isError: true, } } }, ) - src/server.ts:65-65 (registration)Wire-up call: registerApiSpecTools(server, storage) registers all API spec tools including api_endpoints on the MCP server.
registerApiSpecTools(server, storage) - src/tools/api-spec.ts:27-48 (helper)The resolveSpecName helper function used by api_endpoints to determine which imported spec to query. Supports explicit name, active environment spec, or automatic single-spec fallback.
async function resolveSpecName( name: string | undefined, storage: Storage, ): Promise<{ name: string; error?: never } | { name?: never; error: string }> { if (name) return { name } // Try active environment spec const activeSpec = await storage.getActiveSpec() if (activeSpec) return { name: activeSpec } // Fallback to single spec const specs = await storage.listSpecs() if (specs.length === 0) { return { error: 'No hay specs importados. Usa api_import para importar uno.' } } if (specs.length === 1) { return { name: specs[0].name } } return { error: `Hay ${specs.length} specs importados. Especifica cuál usar: ${specs.map((s) => s.name).join(', ')}`, } }