fetch-peacock-docs
Retrieve answers about the Peacock VS Code extension by querying its official documentation from GitHub.
Instructions
Fetches the Peacock for VS Code extension docs from its GitHub repository and answers questions based on the documentation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | The question to answer based on the Peacock documentation |
Implementation Reference
- src/index.ts:25-46 (registration)Registers the "fetch-peacock-docs" MCP tool, including its description, input schema (query: string), and handler function that calls handleDocumentationQuery from peacock-docs.ts and formats the response.server.tool( "fetch-peacock-docs", "Fetches the Peacock for VS Code extension docs from its GitHub repository and answers questions based on the documentation ", { query: z.string().describe("The question to answer based on the Peacock documentation") }, async ({ query }) => { try { const { text } = await handleDocumentationQuery(query); return { content: [{ type: "text", text }], }; } catch (error) { return { content: [ { type: "text", text: `Error searching Peacock documentation: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } );
- src/utils/peacock-docs.ts:221-251 (handler)Core handler function for the tool logic: initializes documentation and code caches from Peacock GitHub repo if needed, searches relevant files for the query, and returns formatted text response with sources.export async function handleDocumentationQuery(query: string): Promise<{ text: string }> { // Initialize cache if needed if (!isDocsCacheInitialized) { isDocsCacheInitialized = await initializeDocsCache(); if (!isDocsCacheInitialized) { return { text: "Failed to initialize documentation cache. Please try again later." }; } } // Check if cache is empty if (Object.keys(docsCache).length === 0 && Object.keys(codeCache).length === 0) { return { text: "No files were found in the Peacock repository." }; } // Handle listing available files if (query.toLowerCase().includes("available") && query.toLowerCase().includes("files")) { return { text: `Available documentation files:\n${docFilesList.join("\n")}\n\nAvailable code files:\n${codeFilesList.join( "\n" )}`, }; } // Search documentation and code const { results, sources } = searchAll(query); if (!results) { return { text: `No information related to "${query}" was found in the Peacock documentation or code.` }; } return { text: `Information related to "${query}":\n\n${results}\n\nSources: ${sources.join(", ")}` }; }
- src/utils/peacock-docs.ts:91-113 (helper)Initializes the caches by recursively fetching and caching documentation (.md) and code files (.ts/.js etc.) from the Peacock GitHub repository.export async function initializeDocsCache(): Promise<boolean> { try { // Process root README await processDocumentationFile("README.md"); // Process docs directory const docsItems = await fetchDirectoryContents("docs"); await processDirectoryItems(docsItems); // Process src directory const srcItems = await fetchDirectoryContents("src"); await processDirectoryItems(srcItems); const totalFiles = docFilesList.length + codeFilesList.length; console.error( `Indexed ${docFilesList.length} documentation files and ${codeFilesList.length} code files from Peacock repository` ); return totalFiles > 0; } catch (error) { console.error(`Error initializing cache: ${error instanceof Error ? error.message : String(error)}`); return false; } }
- src/utils/peacock-docs.ts:175-218 (helper)Searches through cached documentation and code files for matches to the query, extracts relevant sections with context, and compiles results with sources.export function searchAll(query: string): { results: string; sources: string[] } { const queryLower = query.toLowerCase(); const relevantContent: string[] = []; const sources: string[] = []; // Search documentation files for (const [filePath, content] of Object.entries(docsCache)) { if (!content.toLowerCase().includes(queryLower)) continue; const lines = content.split("\n"); for (let i = 0; i < lines.length; i++) { if (lines[i].toLowerCase().includes(queryLower)) { const { content: sectionContent, endIndex } = processMatchingMarkdownSection(lines, i, queryLower); if (sectionContent) { relevantContent.push(sectionContent); sources.push(filePath); } i = endIndex; } } } // Search code files for (const [filePath, content] of Object.entries(codeCache)) { if (!content.toLowerCase().includes(queryLower)) continue; const lines = content.split("\n"); for (let i = 0; i < lines.length; i++) { if (lines[i].toLowerCase().includes(queryLower)) { const { content: sectionContent, endIndex } = processMatchingCodeSection(lines, i, queryLower, filePath); if (sectionContent) { relevantContent.push(sectionContent); sources.push(filePath); } i = endIndex; } } } return { results: relevantContent.join("\n\n---\n\n"), sources: [...new Set(sources)], }; }