UNPKG

libdocs-mcp

Version:

Multi-agent MCP server providing smart documentation lookup, repository analysis, and web research with relevance-focused filtering

429 lines (420 loc) 13.2 kB
#!/usr/bin/env node import "./schema-DtMlVbqf.js"; import "./library-cache-repository-CAhg8ODn.js"; import "./library-cache-injector-DcAO1tyB.js"; import "./provider-D3FVNira.js"; import "./model-DeOogyds.js"; import "./library-cache-tools-765pOTtk.js"; import "./mcp-tool-jwyv-m9T.js"; import "./date-C9YPN4Jt.js"; import "./context-D5sOV8BM.js"; import "./processor-BYTvlU9x.js"; import "./utils-Cz9gLIX8.js"; import "./context7-agent-CpGLWMVD.js"; import "./github-search-tool-2T6pAxmM.js"; import "./deepwiki-agent-DjQtb062.js"; import "./web-fetch-tool-6TquyWh0.js"; import "./web-search-tool-DH_aeLOP.js"; import "./web-research-agent-Dlp_6_j-.js"; import { mastra } from "./mastra-B_qjVo9U.js"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { z } from "zod-v3"; //#region package.json var name = "libdocs-mcp"; var version = "0.0.2"; var description = "Multi-agent MCP server providing smart documentation lookup, repository analysis, and web research with relevance-focused filtering"; var keywords = [ "mcp", "mcp-server", "model-context-protocol", "documentation", "ai-agent", "mastra", "context7", "deepwiki", "tavily", "web-research", "repository-analysis", "llm-tools" ]; var license = "MIT"; var author = "Hudrazine <39614590+hudrazine@users.noreply.github.com>"; var type = "module"; var main = "dist/index.js"; var bin = { "libdocs-mcp": "dist/index.js" }; var files = [ "dist/**/*", "README.md", "LICENSE" ]; var engines = { "node": ">=22.0.0" }; var packageManager = "pnpm@10.16.0"; var repository = { "type": "git", "url": "git+https://github.com/hudrazine/libdocs-mcp.git" }; var homepage = "https://github.com/hudrazine/libdocs-mcp#readme"; var bugs = { "url": "https://github.com/hudrazine/libdocs-mcp/issues" }; var scripts = { "dev": "mastra dev", "build": "tsdown", "start": "mastra start", "inspector": "pnpm run build && dotenvx run -- pnpm dlx @modelcontextprotocol/inspector node dist/index.js", "typecheck": "tsc --noEmit", "lint": "pnpm exec biome lint --write", "format": "pnpm exec biome format --write", "prepack": "pnpm build" }; var publishConfig = { "access": "public" }; var dependencies = { "@mastra/core": "^0.18.0", "@mastra/libsql": "^0.14.3", "@mastra/loggers": "^0.10.13", "@mastra/mcp": "^0.13.1", "@mastra/memory": "^0.15.3", "@modelcontextprotocol/sdk": "^1.18.2", "@openrouter/ai-sdk-provider": "^1.2.0", "@tavily/core": "^0.5.12", "octokit": "^5.0.3", "pino": "^9.11.0", "pino-pretty": "^13.1.1", "zod": "^4.1.11", "zod-v3": "npm:zod@3.25.76" }; var devDependencies = { "@biomejs/biome": "2.2.4", "@dotenvx/dotenvx": "^1.51.0", "@types/node": "^24.5.2", "lefthook": "^1.13.4", "mastra": "^0.13.2", "tsdown": "^0.15.4", "typescript": "^5.9.2", "vitest": "^3.2.4" }; var package_default = { name, version, description, keywords, license, author, type, main, bin, files, engines, packageManager, repository, homepage, bugs, scripts, publishConfig, dependencies, devDependencies }; //#endregion //#region src/index.ts const server = new McpServer({ name: package_default.name, version: package_default.version }); const logger = mastra.getLogger(); const { Context7Agent, DeepWikiAgent, WebResearchAgent } = mastra.getAgents(); server.registerTool("library_docs_lookup", { title: "Library Documentation Lookup", description: `A specialized tool for retrieving official documentation for libraries and frameworks. It efficiently extracts accurate and reliable information from Context7's curated database. Optimal use cases: - Retrieving API references, SDK guides, or version-specific documentation for libraries and frameworks. - Assists developers in quickly accessing precise information from official sources. Input prompt examples: - "Explain React hooks, especially useState usage and internal behavior from official documentation" - "Provide details and examples of Express v4 middleware API" - "I want to know about Pandas DataFrame methods, particularly for filtering and grouping"`, inputSchema: { prompt: z.string().describe("Library name, version, and specific documentation query. Examples: 'React hooks documentation', 'express v4 middleware API', 'pandas DataFrame methods', 'tensorflow 2.x model.fit parameters'") } }, async ({ prompt }, { requestId, signal }) => { try { if (signal.aborted) { logger.debug("library_docs_lookup_aborted_pre", { requestId, stage: "pre-exec", reason: signal.reason }); return { content: [{ type: "text", text: "Request was cancelled before execution" }], isError: true }; } const response = await Context7Agent.generateVNext(prompt, { maxSteps: 20, memory: { resource: "library-docs-resource", thread: requestId.toString() }, abortSignal: signal }); if (response.error) { const errorMessage = typeof response.error === "string" ? response.error : response.error.message || "Unknown error occurred"; logger.error("library_docs_lookup_error", { requestId, error: errorMessage }); return { content: [{ type: "text", text: `Library docs agent error: ${errorMessage}` }], isError: true }; } if (response.finishReason !== "stop") { logger.error("library_docs_lookup_unexpected_finish", { requestId, finishReason: response.finishReason, expected: "stop", steps: response.steps?.length, hasText: Boolean(response.text) }); return { content: [{ type: "text", text: `Library docs agent error: finishReason="${response.finishReason}" (expected "stop"). No final answer produced. Retry with a more specific query; if it persists report this with requestId=${requestId}.` }], isError: true }; } return { content: [{ type: "text", text: response.text }] }; } catch (err) { const error = err; if (signal.aborted) { logger.warn("library_docs_lookup_aborted_during", { requestId, stage: "execute", reason: signal.reason }); return { content: [{ type: "text", text: "Library docs agent error: request cancelled during execution" }], isError: true }; } logger.error("library_docs_lookup_failure", { requestId, cause: error }); return { content: [{ type: "text", text: `Library docs agent error: ${error.message || "Unknown error occurred"}` }], isError: true }; } }); server.registerTool("github_repo_analyzer", { title: "GitHub Repository Analyzer", description: `A tool providing technical insights into GitHub repositories. It analyzes repository structure and code patterns, supporting deep understanding for specific questions. Optimal use cases: - Exploring repository architecture, implementation details, and design decisions; ideal for codebase-specific queries. - Helps developers grasp specific mechanisms within a repository for efficient learning and troubleshooting. Input prompt examples: - "Analyze in detail how component lifecycle is implemented in the facebook/react repository" - "Provide an overview of the middleware architecture and key patterns in the Express repository" - "Explain the reactivity system in the Vue.js repository, including specific code examples"`, inputSchema: { prompt: z.string().describe("Repository name (owner/repo format) or search query, and technical question. Examples: 'facebook/react component lifecycle implementation', 'express repository architecture overview', 'how does vue handle reactivity system'") } }, async ({ prompt }, { requestId, signal }) => { try { if (signal.aborted) { logger.debug("github_repo_analyzer_aborted_pre", { requestId, stage: "pre-exec", reason: signal.reason }); return { content: [{ type: "text", text: "Request was cancelled before execution" }], isError: true }; } const response = await DeepWikiAgent.generateVNext(prompt, { maxSteps: 25, memory: { resource: "github-repo-resource", thread: requestId.toString() }, abortSignal: signal }); if (response.error) { const errorMessage = typeof response.error === "string" ? response.error : response.error.message || "Unknown error occurred"; logger.error("github_repo_analyzer_error", { requestId, error: errorMessage }); return { content: [{ type: "text", text: `GitHub repository analysis error: ${errorMessage}` }], isError: true }; } if (response.finishReason !== "stop") { logger.error("github_repo_analyzer_unexpected_finish", { requestId, finishReason: response.finishReason, expected: "stop", steps: response.steps?.length, hasText: Boolean(response.text) }); return { content: [{ type: "text", text: `GitHub repository analysis error: finishReason="${response.finishReason}" (expected "stop"). No final answer produced. Retry with a more specific query; if it persists report this with requestId=${requestId}.` }], isError: true }; } return { content: [{ type: "text", text: response.text }] }; } catch (err) { const error = err; if (signal.aborted) { logger.warn("github_repo_analyzer_aborted_during", { requestId, stage: "execute", reason: signal.reason }); return { content: [{ type: "text", text: "GitHub repository analysis error: request cancelled during execution" }], isError: true }; } logger.error("github_repo_analyzer_failure", { requestId, cause: error }); return { content: [{ type: "text", text: `GitHub repository analysis error: ${error.message || "Unknown error occurred"}` }], isError: true }; } }); server.registerTool("web_research_assistant", { title: "Web Research Assistant", description: `A tool for gathering and synthesizing information from broad web sources. It verifies multiple online resources to provide comprehensive insights. Optimal use cases: - Investigating technology news, market trend analysis, historical facts, travel guides, business strategies, and various other topics. - Suitable for diverse information sources outside official documentation or specialized repositories, offering practical knowledge from cross-source perspectives. Input prompt examples: - "Tell me about the 2025 performance comparison between React and Vue, including the latest benchmarks and trends" - "Summarize the latest scientific consensus on climate change and its impacts from reliable sources" - "Explain best practices for error handling in Node.js production environments, with case studies"`, inputSchema: { prompt: z.string().describe("Research topic requiring broad web coverage. Best for: technology news, library comparisons, tutorials, troubleshooting guides, community discussions. Example: 'compare React vs Vue performance in 2025', 'latest Next.js 15 features and breaking changes'") } }, async ({ prompt }, { requestId, signal }) => { try { if (signal.aborted) { logger.debug("web_research_assistant_aborted_pre", { requestId, stage: "pre-exec", reason: signal.reason }); return { content: [{ type: "text", text: "Request was cancelled before execution" }], isError: true }; } const response = await WebResearchAgent.generateVNext(prompt, { maxSteps: 30, abortSignal: signal }); if (response.error) { const errorMessage = typeof response.error === "string" ? response.error : response.error.message || "Unknown error occurred"; logger.error("web_research_assistant_error", { requestId, error: errorMessage }); return { content: [{ type: "text", text: `Web research error: ${errorMessage}` }], isError: true }; } if (response.finishReason !== "stop") { logger.error("web_research_assistant_unexpected_finish", { requestId, finishReason: response.finishReason, expected: "stop", steps: response.steps?.length, hasText: Boolean(response.text) }); return { content: [{ type: "text", text: `Web research error: finishReason="${response.finishReason}" (expected "stop"). No final answer produced. Retry with a more specific query; if it persists report this with requestId=${requestId}.` }], isError: true }; } return { content: [{ type: "text", text: response.text }] }; } catch (err) { const error = err; if (signal.aborted) { logger.warn("web_research_assistant_aborted_during", { requestId, stage: "execute", reason: signal.reason }); return { content: [{ type: "text", text: "Web research error: request cancelled during execution" }], isError: true }; } logger.error("web_research_assistant_failure", { requestId, cause: error }); return { content: [{ type: "text", text: `Web research error: ${error.message || "Unknown error occurred"}` }], isError: true }; } }); const transport = new StdioServerTransport(); await server.connect(transport).catch((error) => { console.error("Error running MCP server:", error); process.exit(1); }); //#endregion export { };