mcpjam_search_mcp_spec
Retrieve content from specific sections of the MCP specification, such as Tools, Resources, and Authorization, by selecting a section from a predefined list.
Instructions
Search the MCP specification document for relevant content
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Select a specific section of the MCP specification to retrieve. |
Implementation Reference
- src/index.ts:96-170 (registration)Registers the 'mcpjam_search_mcp_spec' tool with the FastMCP server, defining its name, description, parameters (zod enum schema), and execute handler.
server.addTool({ name: "mcpjam_search_mcp_spec", description: "Search the MCP specification document for relevant content", parameters: z.object({ query: z .enum([ "Introduction", "Core components", "Connection lifecycle", "Elicitation", "Prompts", "Resources", "Roots", "Sampling", "Tools", "Transports", "Debugging", "Follow logs in real-time", "For Client Developers", "For Server Developers", "Architecture", "Authorization", "Lifecycle", "Security Best Practices", "Transports", "Cancellation", "Ping", "Progress", "Elicitation", "Roots", "Sampling", "Specification", "Overview", "Prompts", "Resources", "Tools", "Completion", "Logging", "Pagination", "Versioning", ]) .describe( "Select a specific section of the MCP specification to retrieve." ), }), execute: async (args) => { const fuse = loadAndIndexDocument(); try { if (!fuse) { throw new UserError("Search index not initialized. Please try again."); } // Find exact section match const matchingChunk = documentChunks.find( (chunk) => chunk.section === args.query ); if (!matchingChunk) { return `No section found with the name "${args.query}".`; } return JSON.stringify( { content: matchingChunk.content, }, null, 2 ); } catch (error) { return `Search error: ${ error instanceof Error ? error.message : "Unknown error" }`; } }, }); - src/index.ts:99-138 (schema)Zod schema for the tool's input: a single 'query' parameter that must be one of the predefined MCP spec section names like 'Introduction', 'Core components', 'Tools', etc.
parameters: z.object({ query: z .enum([ "Introduction", "Core components", "Connection lifecycle", "Elicitation", "Prompts", "Resources", "Roots", "Sampling", "Tools", "Transports", "Debugging", "Follow logs in real-time", "For Client Developers", "For Server Developers", "Architecture", "Authorization", "Lifecycle", "Security Best Practices", "Transports", "Cancellation", "Ping", "Progress", "Elicitation", "Roots", "Sampling", "Specification", "Overview", "Prompts", "Resources", "Tools", "Completion", "Logging", "Pagination", "Versioning", ]) .describe( "Select a specific section of the MCP specification to retrieve." - src/index.ts:141-169 (handler)The execute handler: loads and indexes the MCP spec document using Fuse.js, then finds the document chunk matching the requested section name, and returns its JSON-stringified content.
execute: async (args) => { const fuse = loadAndIndexDocument(); try { if (!fuse) { throw new UserError("Search index not initialized. Please try again."); } // Find exact section match const matchingChunk = documentChunks.find( (chunk) => chunk.section === args.query ); if (!matchingChunk) { return `No section found with the name "${args.query}".`; } return JSON.stringify( { content: matchingChunk.content, }, null, 2 ); } catch (error) { return `Search error: ${ error instanceof Error ? error.message : "Unknown error" }`; } }, - src/index.ts:27-94 (helper)Helper function that loads the MCP specification markdown file (llms-full.md), splits it into chunks by section headers (~500 lines each), and builds a Fuse.js search index over the chunks.
function loadAndIndexDocument(): Fuse<(typeof documentChunks)[0]> | undefined { try { const docPath = join(__dirname, "../src/lib/llms-full.md"); const content = readFileSync(docPath, "utf-8"); const lines = content.split("\n"); let currentSection = "Overview"; let chunkId = 0; let chunkContent = ""; let chunkStartLine = 1; for (let i = 0; i < lines.length; i++) { const line = lines[i]; if (line.match(/^# /)) { if (chunkContent.trim()) { documentChunks.push({ id: chunkId, content: chunkContent.trim(), section: currentSection, line: chunkStartLine, }); chunkId++; } currentSection = line.replace(/^#+\s*/, ""); chunkContent = line + "\n"; chunkStartLine = i + 1; } else { chunkContent += line + "\n"; // Create chunks of reasonable size (~500 lines) if (chunkContent.split("\n").length > 500) { documentChunks.push({ id: chunkId, content: chunkContent.trim(), section: currentSection, line: chunkStartLine, }); chunkId++; chunkContent = ""; chunkStartLine = i + 1; } } } // Add final chunk if (chunkContent.trim()) { documentChunks.push({ id: chunkId, content: chunkContent.trim(), section: currentSection, line: chunkStartLine, }); } // Initialize Fuse.js search fuse = new Fuse(documentChunks, { keys: ["content", "section"], threshold: 0.3, includeScore: true, }); return fuse; } catch (error) { console.error("Failed to load document:", error); } }