docusaurus-plugin-mcp-server 0.10.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/search/flexsearch-core.ts","../src/providers/search/flexsearch-provider.ts","../src/providers/loader.ts","../src/mcp/tools/docs-search.ts","../src/mcp/tools/docs-fetch.ts","../src/mcp/server.ts","../src/adapters/cors.ts","../src/adapters/vercel.ts","../src/adapters/netlify.ts","../src/adapters/cloudflare.ts","../src/adapters/generator.ts","../src/adapters/node.ts"],"names":["FlexSearch","results","fs","z","McpServer","StreamableHTTPServerTransport","WebStandardStreamableHTTPServerTransport","createServer"],"mappings":"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","file":"adapters-entry.js","sourcesContent":["import FlexSearch from 'flexsearch';\nimport type { ProcessedDoc, SearchResult } from '../types/index.js';\nimport type { IndexableDocument } from './types.js';\n\nexport type FlexSearchDocument = FlexSearch.Document<IndexableDocument, string[]>;\n\n/**\n * Field weights for search ranking\n * Higher values = more importance\n */\nconst FIELD_WEIGHTS = {\n title: 3.0,\n headings: 2.0,\n description: 1.5,\n content: 1.0,\n} as const;\n\n/**\n * Simple English stemmer\n * Handles common suffixes for better matching\n */\nfunction englishStemmer(word: string): string {\n // Only process words longer than 3 characters\n if (word.length <= 3) return word;\n\n return (\n word\n // -ing endings\n .replace(/ing$/, '')\n // -tion, -sion endings -> t, s\n .replace(/tion$/, 't')\n .replace(/sion$/, 's')\n // -ed endings (careful with short words)\n .replace(/([^aeiou])ed$/, '$1')\n // -es endings\n .replace(/([^aeiou])es$/, '$1')\n // -ly endings\n .replace(/ly$/, '')\n // -ment endings\n .replace(/ment$/, '')\n // -ness endings\n .replace(/ness$/, '')\n // -ies -> y\n .replace(/ies$/, 'y')\n // -s endings (simple plural)\n .replace(/([^s])s$/, '$1')\n );\n}\n\n/**\n * Create a FlexSearch document index with enhanced configuration\n *\n * Features:\n * - Full substring matching (finds \"auth\" in \"authentication\")\n * - English stemming (finds \"authenticate\" when searching \"authentication\")\n * - Context-aware scoring for phrase matching\n * - Optimized resolution for relevance ranking\n */\nexport function createSearchIndex(): FlexSearchDocument {\n return new FlexSearch.Document<IndexableDocument, string[]>({\n // Use 'full' tokenization for substring matching\n // This allows \"auth\" to match \"authentication\"\n tokenize: 'full',\n\n // Enable caching for faster repeated queries\n cache: 100,\n\n // Higher resolution = more granular ranking (1-9)\n resolution: 9,\n\n // Enable context for phrase/proximity matching\n context: {\n resolution: 2,\n depth: 2,\n bidirectional: true,\n },\n\n // Apply stemming to normalize word forms\n encode: (str: string) => {\n // Normalize to lowercase and split into words\n const words = str.toLowerCase().split(/[\\s\\-_.,;:!?'\"()[\\]{}]+/);\n // Apply stemmer to each word\n return words.filter(Boolean).map(englishStemmer);\n },\n\n // Document schema\n document: {\n id: 'id',\n // Index these fields for searching\n index: ['title', 'content', 'headings', 'description'],\n // Store these fields in results (for enriched queries)\n store: ['title', 'description'],\n },\n });\n}\n\n/**\n * Add a document to the search index\n *\n * @param index - The FlexSearch index\n * @param doc - The document to add\n * @param baseUrl - Optional base URL to construct full URL as document ID\n */\nexport function addDocumentToIndex(\n index: FlexSearchDocument,\n doc: ProcessedDoc,\n baseUrl?: string\n): void {\n // Use full URL as ID if baseUrl is provided, otherwise use route\n const id = baseUrl ? `${baseUrl.replace(/\\/$/, '')}${doc.route}` : doc.route;\n\n const indexable: IndexableDocument = {\n id,\n title: doc.title,\n content: doc.markdown,\n headings: doc.headings.map((h) => h.text).join(' '),\n description: doc.description,\n };\n\n index.add(indexable);\n}\n\n/**\n * Build the search index from processed documents\n *\n * @param docs - Documents to index\n * @param baseUrl - Optional base URL to construct full URLs as document IDs\n */\nexport function buildSearchIndex(docs: ProcessedDoc[], baseUrl?: string): FlexSearchDocument {\n const index = createSearchIndex();\n\n for (const doc of docs) {\n addDocumentToIndex(index, doc, baseUrl);\n }\n\n return index;\n}\n\n/**\n * Search the index and return results with weighted ranking\n *\n * Ranking combines:\n * - Field importance (title > headings > description > content)\n * - Position in results (earlier = more relevant)\n */\nexport function searchIndex(\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>,\n query: string,\n options: { limit?: number } = {}\n): SearchResult[] {\n const { limit = 5 } = options;\n\n // Search across all fields\n const rawResults = index.search(query, {\n limit: limit * 3, // Get extra results for better ranking after weighting\n enrich: true,\n });\n\n // Aggregate scores across fields with weighting\n const docScores = new Map<string, number>();\n\n for (const fieldResult of rawResults) {\n // Determine which field this result is from\n const field = fieldResult.field as keyof typeof FIELD_WEIGHTS;\n const fieldWeight = FIELD_WEIGHTS[field] ?? 1.0;\n\n // With enrich: true, results are objects with id property\n const results = fieldResult.result as unknown as Array<{ id: string } | string>;\n\n for (let i = 0; i < results.length; i++) {\n const item = results[i];\n if (!item) continue;\n\n const docId = typeof item === 'string' ? item : item.id;\n\n // Position-based score (earlier = higher)\n const positionScore = (results.length - i) / results.length;\n\n // Apply field weight to position score\n const weightedScore = positionScore * fieldWeight;\n\n // Combine with existing score (additive for multi-field matches)\n const existingScore = docScores.get(docId) ?? 0;\n docScores.set(docId, existingScore + weightedScore);\n }\n }\n\n // Build results array\n const results: SearchResult[] = [];\n\n for (const [docId, score] of docScores) {\n const doc = docs[docId];\n if (!doc) continue;\n\n results.push({\n url: docId, // docId is the full URL when indexed with baseUrl\n route: doc.route,\n title: doc.title,\n score,\n snippet: generateSnippet(doc.markdown, query),\n matchingHeadings: findMatchingHeadings(doc, query),\n });\n }\n\n // Sort by score (highest first) and limit\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n/**\n * Generate a snippet from the markdown content around the query terms\n */\nexport function generateSnippet(markdown: string, query: string): string {\n const maxLength = 200;\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n if (queryTerms.length === 0) {\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const lowerMarkdown = markdown.toLowerCase();\n let bestIndex = -1;\n let bestTerm = '';\n\n // Also try stemmed versions of query terms\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n\n for (const term of allTerms) {\n const index = lowerMarkdown.indexOf(term);\n if (index !== -1 && (bestIndex === -1 || index < bestIndex)) {\n bestIndex = index;\n bestTerm = term;\n }\n }\n\n if (bestIndex === -1) {\n // No term found, return beginning of document\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const snippetStart = Math.max(0, bestIndex - 50);\n const snippetEnd = Math.min(markdown.length, bestIndex + bestTerm.length + 150);\n\n let snippet = markdown.slice(snippetStart, snippetEnd);\n\n snippet = snippet\n // Remove markdown headings\n .replace(/^#{1,6}\\s+/gm, '')\n // Remove markdown links but keep text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n // Remove markdown images\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Remove code block markers\n .replace(/```[a-z]*\\n?/g, '')\n // Remove inline code backticks\n .replace(/`([^`]+)`/g, '$1')\n // Clean up whitespace\n .replace(/\\s+/g, ' ')\n .trim();\n\n const prefix = snippetStart > 0 ? '...' : '';\n const suffix = snippetEnd < markdown.length ? '...' : '';\n\n return prefix + snippet + suffix;\n}\n\n/**\n * Find headings that match the query (including stemmed forms)\n */\nfunction findMatchingHeadings(doc: ProcessedDoc, query: string): string[] {\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n // Include stemmed versions for better matching\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n const matching: string[] = [];\n\n for (const heading of doc.headings) {\n const headingLower = heading.text.toLowerCase();\n const headingStemmed = headingLower.split(/\\s+/).map(englishStemmer).join(' ');\n\n // Check if any query term matches the heading or its stemmed form\n if (\n allTerms.some(\n (term) => headingLower.includes(term) || headingStemmed.includes(englishStemmer(term))\n )\n ) {\n matching.push(heading.text);\n }\n }\n\n return matching.slice(0, 3); // Limit to 3 matching headings\n}\n\n/**\n * Export the search index to a serializable format\n */\nexport async function exportSearchIndex(index: FlexSearchDocument): Promise<unknown> {\n const exportData: Record<string, unknown> = {};\n\n await index.export((key, data) => {\n exportData[key as string] = data;\n });\n\n return exportData;\n}\n\n/**\n * Import a search index from serialized data\n */\nexport async function importSearchIndex(\n data: Record<string, unknown>\n): Promise<FlexSearchDocument> {\n const index = createSearchIndex();\n\n for (const [key, value] of Object.entries(data)) {\n // FlexSearch's import expects the data in a specific format\n await (index as unknown as { import: (key: string, data: unknown) => Promise<void> }).import(\n key,\n value\n );\n }\n\n return index;\n}\n","import fs from 'fs-extra';\nimport type { ProcessedDoc, SearchResult } from '../../types/index.js';\nimport type {\n SearchProvider,\n ProviderContext,\n SearchProviderInitData,\n SearchOptions,\n} from '../types.js';\nimport {\n importSearchIndex,\n searchIndex,\n type FlexSearchDocument,\n} from '../../search/flexsearch-core.js';\n\n/**\n * Built-in FlexSearch search provider.\n *\n * This provider uses the local FlexSearch index for search queries.\n * Supports both file-based loading (Node.js) and pre-loaded data (Workers).\n */\nexport class FlexSearchProvider implements SearchProvider {\n readonly name = 'flexsearch';\n\n private docs: Record<string, ProcessedDoc> | null = null;\n private searchIndex: FlexSearchDocument | null = null;\n private ready = false;\n\n async initialize(_context: ProviderContext, initData?: SearchProviderInitData): Promise<void> {\n if (!initData) {\n throw new Error('[FlexSearch] SearchProviderInitData required for FlexSearch provider');\n }\n\n // Pre-loaded data mode (Cloudflare Workers, etc.)\n if (initData.docs && initData.indexData) {\n this.docs = initData.docs;\n this.searchIndex = await importSearchIndex(initData.indexData as Record<string, unknown>);\n this.ready = true;\n return;\n }\n\n // File-based mode (Node.js)\n if (initData.docsPath && initData.indexPath) {\n if (await fs.pathExists(initData.docsPath)) {\n this.docs = await fs.readJson(initData.docsPath);\n } else {\n throw new Error(`[FlexSearch] Docs file not found: ${initData.docsPath}`);\n }\n\n if (await fs.pathExists(initData.indexPath)) {\n const indexData = await fs.readJson(initData.indexPath);\n this.searchIndex = await importSearchIndex(indexData);\n } else {\n throw new Error(`[FlexSearch] Search index not found: ${initData.indexPath}`);\n }\n\n this.ready = true;\n return;\n }\n\n throw new Error(\n '[FlexSearch] Invalid init data: must provide either file paths (docsPath, indexPath) or pre-loaded data (docs, indexData)'\n );\n }\n\n isReady(): boolean {\n return this.ready && this.docs !== null && this.searchIndex !== null;\n }\n\n async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {\n if (!this.isReady() || !this.docs || !this.searchIndex) {\n throw new Error('[FlexSearch] Provider not initialized');\n }\n\n const limit = options?.limit ?? 5;\n return searchIndex(this.searchIndex, this.docs, query, { limit });\n }\n\n async getDocument(url: string): Promise<ProcessedDoc | null> {\n if (!this.docs) {\n throw new Error('[FlexSearch] Provider not initialized');\n }\n\n // Direct lookup by URL\n return this.docs[url] ?? null;\n }\n\n async healthCheck(): Promise<{ healthy: boolean; message?: string }> {\n if (!this.isReady()) {\n return { healthy: false, message: 'FlexSearch provider not initialized' };\n }\n\n const docCount = this.docs ? Object.keys(this.docs).length : 0;\n return {\n healthy: true,\n message: `FlexSearch provider ready with ${docCount} documents`,\n };\n }\n\n /**\n * Get all loaded documents (for compatibility with existing server code)\n */\n getDocs(): Record<string, ProcessedDoc> | null {\n return this.docs;\n }\n\n /**\n * Get the FlexSearch index (for compatibility with existing server code)\n */\n getSearchIndex(): FlexSearchDocument | null {\n return this.searchIndex;\n }\n}\n","import type { ContentIndexer, SearchProvider } from './types.js';\nimport { FlexSearchIndexer } from './indexers/flexsearch-indexer.js';\nimport { FlexSearchProvider } from './search/flexsearch-provider.js';\n\n/**\n * Load an indexer by name or module path.\n *\n * @param specifier - Either 'flexsearch' for the built-in indexer, or a module path\n * (relative path like './my-indexer.js' or npm package like '@myorg/indexer')\n * @returns Instantiated ContentIndexer\n *\n * @example\n * ```typescript\n * // Built-in\n * const indexer = await loadIndexer('flexsearch');\n *\n * // Custom relative path\n * const indexer = await loadIndexer('./src/providers/algolia-indexer.js');\n *\n * // Custom npm package\n * const indexer = await loadIndexer('@myorg/custom-indexer');\n * ```\n */\nexport async function loadIndexer(specifier: string): Promise<ContentIndexer> {\n // Built-in FlexSearch indexer\n if (specifier === 'flexsearch') {\n return new FlexSearchIndexer();\n }\n\n try {\n const module = await import(specifier);\n const IndexerClass = module.default;\n\n if (typeof IndexerClass === 'function') {\n // It's a class constructor\n const instance = new IndexerClass();\n\n if (!isContentIndexer(instance)) {\n throw new Error(\n `Invalid indexer module \"${specifier}\": does not implement ContentIndexer interface`\n );\n }\n\n return instance;\n }\n\n if (isContentIndexer(IndexerClass)) {\n return IndexerClass;\n }\n\n throw new Error(\n `Invalid indexer module \"${specifier}\": must export a default class or ContentIndexer instance`\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes('Cannot find module')) {\n throw new Error(`Indexer module not found: \"${specifier}\". Check the path or package name.`);\n }\n throw error;\n }\n}\n\n/**\n * Load a search provider by name or module path.\n *\n * @param specifier - Either 'flexsearch' for the built-in provider, or a module path\n * (relative path like './my-search.js' or npm package like '@myorg/search')\n * @returns Instantiated SearchProvider\n *\n * @example\n * ```typescript\n * // Built-in\n * const provider = await loadSearchProvider('flexsearch');\n *\n * // Custom relative path\n * const provider = await loadSearchProvider('./src/providers/glean-search.js');\n *\n * // Custom npm package\n * const provider = await loadSearchProvider('@myorg/glean-search');\n * ```\n */\nexport async function loadSearchProvider(specifier: string): Promise<SearchProvider> {\n if (specifier === 'flexsearch') {\n return new FlexSearchProvider();\n }\n\n try {\n const module = await import(specifier);\n const ProviderClass = module.default;\n\n if (typeof ProviderClass === 'function') {\n const instance = new ProviderClass();\n\n if (!isSearchProvider(instance)) {\n throw new Error(\n `Invalid search provider module \"${specifier}\": does not implement SearchProvider interface`\n );\n }\n\n return instance;\n }\n\n if (isSearchProvider(ProviderClass)) {\n return ProviderClass;\n }\n\n throw new Error(\n `Invalid search provider module \"${specifier}\": must export a default class or SearchProvider instance`\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes('Cannot find module')) {\n throw new Error(\n `Search provider module not found: \"${specifier}\". Check the path or package name.`\n );\n }\n throw error;\n }\n}\n\n/**\n * Type guard to check if an object implements ContentIndexer\n */\nfunction isContentIndexer(obj: unknown): obj is ContentIndexer {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n const indexer = obj as ContentIndexer;\n return (\n typeof indexer.name === 'string' &&\n typeof indexer.initialize === 'function' &&\n typeof indexer.indexDocuments === 'function' &&\n typeof indexer.finalize === 'function'\n );\n}\n\n/**\n * Type guard to check if an object implements SearchProvider\n */\nfunction isSearchProvider(obj: unknown): obj is SearchProvider {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n const provider = obj as SearchProvider;\n return (\n typeof provider.name === 'string' &&\n typeof provider.initialize === 'function' &&\n typeof provider.isReady === 'function' &&\n typeof provider.search === 'function'\n );\n}\n","import { z } from 'zod';\nimport type { ProcessedDoc, SearchResult, DocsSearchParams } from '../../types/index.js';\nimport { searchIndex, type FlexSearchDocument } from '../../search/flexsearch-core.js';\n\n/**\n * Zod schema for docs_search input parameters\n */\nexport const docsSearchInputSchema = {\n query: z.string().min(1).describe('The search query string'),\n limit: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .default(5)\n .describe('Maximum number of results to return (1-20, default: 5)'),\n};\n\n/**\n * Tool definition for docs_search\n */\nexport const docsSearchTool = {\n name: 'docs_search',\n description:\n 'Search the documentation for relevant pages. Returns matching documents with URLs, snippets, and relevance scores. Use this to find information across all documentation.',\n inputSchema: docsSearchInputSchema,\n};\n\n/**\n * Execute the docs_search tool\n */\nexport function executeDocsSearch(\n params: DocsSearchParams,\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>\n): SearchResult[] {\n const { query, limit = 5 } = params;\n\n // Validate parameters\n if (!query || typeof query !== 'string' || query.trim().length === 0) {\n throw new Error('Query parameter is required and must be a non-empty string');\n }\n\n const effectiveLimit = Math.min(Math.max(1, limit), 20);\n\n // Search the index\n const results = searchIndex(index, docs, query.trim(), {\n limit: effectiveLimit,\n });\n\n return results;\n}\n\n/**\n * Format search results for MCP response\n */\nexport function formatSearchResults(results: SearchResult[]): string {\n if (results.length === 0) {\n return 'No matching documents found.';\n }\n\n const lines: string[] = [`Found ${results.length} result(s):\\n`];\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (!result) continue;\n\n lines.push(`${i + 1}. **${result.title}**`);\n lines.push(` URL: ${result.url}`);\n\n if (result.matchingHeadings && result.matchingHeadings.length > 0) {\n lines.push(` Matching sections: ${result.matchingHeadings.join(', ')}`);\n }\n\n lines.push(` ${result.snippet}`);\n lines.push('');\n }\n\n lines.push('Use docs_fetch with the URL to retrieve the full page content.');\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { ProcessedDoc } from '../../types/index.js';\n\n/**\n * Zod schema for docs_fetch input parameters\n */\nexport const docsFetchInputSchema = {\n url: z\n .string()\n .url()\n .describe(\n 'The full URL of the page to fetch (e.g., \"https://docs.example.com/docs/getting-started\")'\n ),\n};\n\n/**\n * Tool definition for docs_fetch\n */\nexport const docsFetchTool = {\n name: 'docs_fetch',\n description:\n 'Fetch the complete content of a documentation page. Use this after searching to get the full markdown content of a specific page.',\n inputSchema: docsFetchInputSchema,\n};\n\n/**\n * Format page content for MCP response\n */\nexport function formatPageContent(doc: ProcessedDoc | null): string {\n if (!doc) {\n return 'Page not found. Please check the URL and try again.';\n }\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${doc.title}`);\n lines.push('');\n\n // Metadata\n if (doc.description) {\n lines.push(`> ${doc.description}`);\n lines.push('');\n }\n\n // Table of contents (if there are headings)\n if (doc.headings.length > 0) {\n lines.push('## Contents');\n lines.push('');\n for (const heading of doc.headings) {\n if (heading.level <= 3) {\n const indent = ' '.repeat(heading.level - 1);\n lines.push(`${indent}- [${heading.text}](#${heading.id})`);\n }\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Main content\n lines.push(doc.markdown);\n\n return lines.join('\\n');\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type {\n ProcessedDoc,\n McpServerConfig,\n McpServerFileConfig,\n McpServerDataConfig,\n} from '../types/index.js';\nimport { loadSearchProvider } from '../providers/loader.js';\nimport { FlexSearchProvider } from '../providers/search/flexsearch-provider.js';\nimport type {\n SearchProvider,\n ProviderContext,\n SearchProviderInitData,\n} from '../providers/types.js';\nimport { docsSearchTool, formatSearchResults } from './tools/docs-search.js';\nimport { docsFetchTool, formatPageContent } from './tools/docs-fetch.js';\n\n/**\n * Type guard to check if config uses file-based loading\n */\nfunction isFileConfig(config: McpServerConfig): config is McpServerFileConfig {\n return 'docsPath' in config && 'indexPath' in config;\n}\n\n/**\n * Type guard to check if config uses pre-loaded data\n */\nfunction isDataConfig(config: McpServerConfig): config is McpServerDataConfig {\n return 'docs' in config && 'searchIndexData' in config;\n}\n\n/**\n * MCP Server for documentation\n *\n * This class provides the MCP server implementation that can be used\n * with any HTTP framework (Express, Vercel, Cloudflare Workers, etc.)\n *\n * Supports two modes:\n * - File-based: Load docs and search index from filesystem (Node.js)\n * - Pre-loaded: Accept docs and search index data directly (Workers)\n *\n * Uses the official MCP SDK for proper protocol handling.\n */\nexport class McpDocsServer {\n private config: McpServerConfig;\n private searchProvider: SearchProvider | null = null;\n private mcpServer: McpServer;\n private initialized = false;\n\n constructor(config: McpServerConfig) {\n this.config = config;\n\n this.mcpServer = new McpServer(\n {\n name: config.name,\n version: config.version ?? '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n this.registerTools();\n }\n\n /**\n * Register all MCP tools using definitions from tool files\n */\n private registerTools(): void {\n // Register docs_search tool\n this.mcpServer.registerTool(\n docsSearchTool.name,\n {\n description: docsSearchTool.description,\n inputSchema: docsSearchTool.inputSchema,\n },\n async ({ query, limit }) => {\n await this.initialize();\n\n if (!this.searchProvider || !this.searchProvider.isReady()) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n try {\n const results = await this.searchProvider.search(query, { limit });\n return {\n content: [{ type: 'text' as const, text: formatSearchResults(results) }],\n };\n } catch (error) {\n console.error('[MCP] Search error:', error);\n return {\n content: [{ type: 'text' as const, text: `Search error: ${String(error)}` }],\n isError: true,\n };\n }\n }\n );\n\n // Register docs_fetch tool\n this.mcpServer.registerTool(\n docsFetchTool.name,\n {\n description: docsFetchTool.description,\n inputSchema: docsFetchTool.inputSchema,\n },\n async ({ url }) => {\n await this.initialize();\n\n if (!this.searchProvider || !this.searchProvider.isReady()) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n try {\n const doc = await this.getDocument(url);\n return {\n content: [{ type: 'text' as const, text: formatPageContent(doc) }],\n };\n } catch (error) {\n console.error('[MCP] Fetch error:', error);\n return {\n content: [{ type: 'text' as const, text: `Error fetching page: ${String(error)}` }],\n isError: true,\n };\n }\n }\n );\n }\n\n /**\n * Get a document by URL using the search provider\n */\n private async getDocument(url: string): Promise<ProcessedDoc | null> {\n if (!this.searchProvider) {\n return null;\n }\n\n if (this.searchProvider.getDocument) {\n return this.searchProvider.getDocument(url);\n }\n\n return null;\n }\n\n /**\n * Load docs and search index using the configured search provider\n *\n * For file-based config: reads from disk\n * For data config: uses pre-loaded data directly\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n try {\n // Load the search provider\n const searchSpecifier = this.config.search ?? 'flexsearch';\n this.searchProvider = await loadSearchProvider(searchSpecifier);\n\n // Build provider context\n const providerContext: ProviderContext = {\n baseUrl: this.config.baseUrl ?? '',\n serverName: this.config.name,\n serverVersion: this.config.version ?? '1.0.0',\n outputDir: '', // Not relevant for runtime\n };\n\n // Build init data based on config type\n const initData: SearchProviderInitData = {};\n\n if (isDataConfig(this.config)) {\n // Pre-loaded data mode (Cloudflare Workers, etc.)\n initData.docs = this.config.docs;\n initData.indexData = this.config.searchIndexData;\n } else if (isFileConfig(this.config)) {\n // File-based mode (Node.js)\n initData.docsPath = this.config.docsPath;\n initData.indexPath = this.config.indexPath;\n } else {\n throw new Error('Invalid server config: must provide either file paths or pre-loaded data');\n }\n\n // Initialize the search provider\n await this.searchProvider.initialize(providerContext, initData);\n\n this.initialized = true;\n } catch (error) {\n console.error('[MCP] Failed to initialize:', error);\n throw error;\n }\n }\n\n /**\n * Handle an HTTP request using the MCP SDK's transport\n *\n * This method is designed for serverless environments (Vercel, Netlify).\n * It creates a stateless transport instance and processes the request.\n *\n * @param req - Node.js IncomingMessage or compatible request object\n * @param res - Node.js ServerResponse or compatible response object\n * @param parsedBody - Optional pre-parsed request body\n */\n async handleHttpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n parsedBody?: unknown\n ): Promise<void> {\n await this.initialize();\n\n // Create a stateless transport for this request\n // enableJsonResponse: true means we get simple JSON responses instead of SSE\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode - no session tracking\n enableJsonResponse: true, // Return JSON instead of SSE streams\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request\n await transport.handleRequest(req, res, parsedBody);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Handle a Web Standard Request (Cloudflare Workers, Deno, Bun)\n *\n * This method is designed for Web Standard environments that use\n * the Fetch API Request/Response pattern.\n *\n * @param request - Web Standard Request object\n * @returns Web Standard Response object\n */\n async handleWebRequest(request: Request): Promise<Response> {\n await this.initialize();\n\n // Create a stateless transport for Web Standards\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode\n enableJsonResponse: true,\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request and return the response\n return await transport.handleRequest(request);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Get server status information\n *\n * Useful for health checks and debugging\n */\n async getStatus(): Promise<{\n name: string;\n version: string;\n initialized: boolean;\n docCount: number;\n baseUrl?: string;\n searchProvider?: string;\n }> {\n let docCount = 0;\n\n // Get doc count from FlexSearchProvider if available\n if (this.searchProvider instanceof FlexSearchProvider) {\n const docs = this.searchProvider.getDocs();\n docCount = docs ? Object.keys(docs).length : 0;\n }\n\n return {\n name: this.config.name,\n version: this.config.version ?? '1.0.0',\n initialized: this.initialized,\n docCount,\n baseUrl: this.config.baseUrl,\n searchProvider: this.searchProvider?.name,\n };\n }\n\n /**\n * Get the underlying McpServer instance\n *\n * Useful for advanced use cases like custom transports\n */\n getMcpServer(): McpServer {\n return this.mcpServer;\n }\n}\n","/**\n * Standard CORS headers for MCP server responses\n *\n * These headers enable cross-origin requests from browser-based MCP clients.\n */\nexport const CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n} as const;\n\n/**\n * Get CORS headers as a plain object (for JSON responses)\n */\nexport function getCorsHeaders(): Record<string, string> {\n return { ...CORS_HEADERS };\n}\n","/**\n * Vercel adapter for MCP server\n *\n * Creates a Vercel serverless function handler for the MCP server.\n *\n * @example\n * // api/mcp.js\n * const { createVercelHandler } = require('docusaurus-plugin-mcp-server/adapters');\n * const path = require('path');\n *\n * module.exports = createVercelHandler({\n * docsPath: path.join(__dirname, '../build/mcp/docs.json'),\n * indexPath: path.join(__dirname, '../build/mcp/search-index.json'),\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * });\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Vercel request object (extends Node.js IncomingMessage)\n */\nexport interface VercelRequest extends IncomingMessage {\n body?: unknown;\n}\n\n/**\n * Vercel response object (extends Node.js ServerResponse)\n */\nexport interface VercelResponse extends ServerResponse {\n status(code: number): VercelResponse;\n json(data: unknown): void;\n}\n\n/**\n * Create a Vercel serverless function handler for the MCP server\n *\n * Uses the MCP SDK's StreamableHTTPServerTransport for proper protocol handling.\n */\nexport function createVercelHandler(config: McpServerConfig) {\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n return async function handler(req: VercelRequest, res: VercelResponse) {\n const corsHeaders = getCorsHeaders();\n\n // Handle CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204, corsHeaders);\n res.end();\n return;\n }\n\n // Handle GET requests for health check\n if (req.method === 'GET') {\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return res.status(200).json(status);\n }\n\n // Only allow POST requests for MCP\n if (req.method !== 'POST') {\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n return res.status(405).json({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n });\n }\n\n try {\n // Set CORS headers before handling\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n const mcpServer = getServer();\n // Use the SDK transport to handle the request\n await mcpServer.handleHttpRequest(req, res, req.body);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return res.status(500).json({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n });\n }\n };\n}\n","/**\n * Netlify adapter for MCP server\n *\n * Creates a Netlify serverless function handler for the MCP server.\n * Converts Netlify's AWS Lambda-style events to Web Standard Request\n * and uses the MCP SDK's transport for proper protocol handling.\n *\n * @example\n * // netlify/functions/mcp.js\n * const { createNetlifyHandler } = require('docusaurus-plugin-mcp-server/adapters');\n * const path = require('path');\n *\n * exports.handler = createNetlifyHandler({\n * docsPath: path.join(__dirname, '../../build/mcp/docs.json'),\n * indexPath: path.join(__dirname, '../../build/mcp/search-index.json'),\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * });\n */\n\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Netlify event object (simplified interface)\n */\nexport interface NetlifyEvent {\n httpMethod: string;\n headers: Record<string, string | undefined>;\n body: string | null;\n isBase64Encoded?: boolean;\n path?: string;\n rawUrl?: string;\n}\n\n/**\n * Netlify context object (simplified interface)\n */\nexport interface NetlifyContext {\n functionName: string;\n functionVersion?: string;\n invokedFunctionArn?: string;\n memoryLimitInMB?: string;\n awsRequestId?: string;\n logGroupName?: string;\n logStreamName?: string;\n getRemainingTimeInMillis?: () => number;\n}\n\n/**\n * Netlify function response\n */\ninterface NetlifyResponse {\n statusCode: number;\n headers?: Record<string, string>;\n body?: string;\n}\n\n/**\n * Convert a Netlify event to a Web Standard Request\n */\nfunction eventToRequest(event: NetlifyEvent): Request {\n const url = event.rawUrl || `https://localhost${event.path || '/'}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(event.headers)) {\n if (value) {\n headers.set(key, value);\n }\n }\n\n // Decode body if base64 encoded\n let body: string | null = event.body;\n if (body && event.isBase64Encoded) {\n body = Buffer.from(body, 'base64').toString('utf-8');\n }\n\n return new Request(url, {\n method: event.httpMethod,\n headers,\n body: event.httpMethod !== 'GET' && event.httpMethod !== 'HEAD' ? body : undefined,\n });\n}\n\n/**\n * Convert a Web Standard Response to a Netlify response\n */\nasync function responseToNetlify(\n response: Response,\n additionalHeaders: Record<string, string>\n): Promise<NetlifyResponse> {\n const headers: Record<string, string> = { ...additionalHeaders };\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n const body = await response.text();\n\n return {\n statusCode: response.status,\n headers,\n body: body || undefined,\n };\n}\n\n/**\n * Create a Netlify serverless function handler for the MCP server\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for\n * proper protocol handling.\n */\nexport function createNetlifyHandler(config: McpServerConfig) {\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n return async function handler(\n event: NetlifyEvent,\n _context: NetlifyContext\n ): Promise<NetlifyResponse> {\n const corsHeaders = getCorsHeaders();\n const headers = {\n 'Content-Type': 'application/json',\n ...corsHeaders,\n };\n\n // Handle CORS preflight\n if (event.httpMethod === 'OPTIONS') {\n return {\n statusCode: 204,\n headers: corsHeaders,\n };\n }\n\n // Handle GET requests for health check\n if (event.httpMethod === 'GET') {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify(status),\n };\n }\n\n // Only allow POST requests for MCP\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n }),\n };\n }\n\n try {\n const mcpServer = getServer();\n\n // Convert Netlify event to Web Standard Request\n const request = eventToRequest(event);\n\n // Use the SDK's Web Standard transport to handle the request\n const response = await mcpServer.handleWebRequest(request);\n\n // Convert back to Netlify response format with CORS headers\n return await responseToNetlify(response, corsHeaders);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n }),\n };\n }\n };\n}\n","/**\n * Cloudflare Workers adapter for MCP server\n *\n * Creates a Cloudflare Workers fetch handler for the MCP server.\n * Since Workers can't access the filesystem, this adapter requires\n * pre-loaded docs and search index data.\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for proper\n * protocol handling with Web Standard Request/Response.\n *\n * @example\n * // src/worker.js\n * import { createCloudflareHandler } from 'docusaurus-plugin-mcp-server/adapters';\n * import docs from '../build/mcp/docs.json';\n * import searchIndex from '../build/mcp/search-index.json';\n *\n * export default {\n * fetch: createCloudflareHandler({\n * docs,\n * searchIndexData: searchIndex,\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * }),\n * };\n */\n\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { ProcessedDoc, McpServerDataConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Config for Cloudflare Workers adapter\n */\nexport interface CloudflareAdapterConfig {\n /** Pre-loaded docs data (imported from docs.json) */\n docs: Record<string, ProcessedDoc>;\n /** Pre-loaded search index data (imported from search-index.json) */\n searchIndexData: Record<string, unknown>;\n /** Server name */\n name: string;\n /** Server version */\n version?: string;\n /** Base URL for constructing full page URLs */\n baseUrl?: string;\n}\n\n/**\n * Create a Cloudflare Workers fetch handler for the MCP server\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for\n * proper protocol handling.\n */\nexport function createCloudflareHandler(config: CloudflareAdapterConfig) {\n let server: McpDocsServer | null = null;\n\n const serverConfig: McpServerDataConfig = {\n docs: config.docs,\n searchIndexData: config.searchIndexData,\n name: config.name,\n version: config.version,\n baseUrl: config.baseUrl,\n };\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(serverConfig);\n }\n return server;\n }\n\n return async function fetch(request: Request): Promise<Response> {\n const corsHeaders = getCorsHeaders();\n\n // Handle CORS preflight\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 204, headers: corsHeaders });\n }\n\n // Handle GET requests for health check\n if (request.method === 'GET') {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return new Response(JSON.stringify(status), {\n status: 200,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n });\n }\n\n // Only allow POST requests for MCP\n if (request.method !== 'POST') {\n return new Response(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n }),\n {\n status: 405,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n }\n );\n }\n\n try {\n const mcpServer = getServer();\n // Use the SDK's Web Standard transport to handle the request\n const response = await mcpServer.handleWebRequest(request);\n\n // Add CORS headers to the response\n const newHeaders = new Headers(response.headers);\n Object.entries(corsHeaders).forEach(([key, value]) => {\n newHeaders.set(key, value);\n });\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return new Response(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n }),\n {\n status: 500,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n }\n );\n }\n };\n}\n","/**\n * Adapter file generator\n *\n * Generates platform-specific adapter files for deploying the MCP server.\n */\n\nexport type Platform = 'vercel' | 'netlify' | 'cloudflare';\n\nexport interface GeneratorOptions {\n /** Target platform */\n platform: Platform;\n /** Server name */\n name: string;\n /** Base URL for the documentation site */\n baseUrl: string;\n /** Output path for the generated files (defaults to current directory) */\n outputPath?: string;\n}\n\nexport interface GeneratedFile {\n /** Relative path for the file */\n path: string;\n /** File contents */\n content: string;\n /** Description of the file */\n description: string;\n}\n\n/**\n * Generate adapter files for a specific platform\n */\nexport function generateAdapterFiles(options: GeneratorOptions): GeneratedFile[] {\n const { platform, name, baseUrl } = options;\n\n switch (platform) {\n case 'vercel':\n return generateVercelFiles(name, baseUrl);\n case 'netlify':\n return generateNetlifyFiles(name, baseUrl);\n case 'cloudflare':\n return generateCloudflareFiles(name, baseUrl);\n default:\n throw new Error(`Unknown platform: ${platform}`);\n }\n}\n\nfunction generateVercelFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'api/mcp.js',\n description: 'Vercel serverless function for MCP server',\n content: `/**\n * Vercel API route for MCP server\n * Deploy to Vercel and this will be available at /api/mcp\n */\n\nconst { createVercelHandler } = require('docusaurus-plugin-mcp-server/adapters');\nconst path = require('path');\n\nconst projectRoot = path.join(__dirname, '..');\n\nmodule.exports = createVercelHandler({\n docsPath: path.join(projectRoot, 'build/mcp/docs.json'),\n indexPath: path.join(projectRoot, 'build/mcp/search-index.json'),\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n});\n`,\n },\n {\n path: 'vercel.json',\n description: 'Vercel configuration (merge with existing if present)',\n content: `{\n \"functions\": {\n \"api/mcp.js\": {\n \"includeFiles\": \"build/mcp/**\"\n }\n },\n \"rewrites\": [\n {\n \"source\": \"/mcp\",\n \"destination\": \"/api/mcp\"\n }\n ]\n}\n`,\n },\n ];\n}\n\nfunction generateNetlifyFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'netlify/functions/mcp.js',\n description: 'Netlify serverless function for MCP server',\n content: `/**\n * Netlify function for MCP server\n * Deploy to Netlify and this will be available at /.netlify/functions/mcp\n */\n\nconst { createNetlifyHandler } = require('docusaurus-plugin-mcp-server/adapters');\nconst path = require('path');\n\nconst projectRoot = path.join(__dirname, '../..');\n\nexports.handler = createNetlifyHandler({\n docsPath: path.join(projectRoot, 'build/mcp/docs.json'),\n indexPath: path.join(projectRoot, 'build/mcp/search-index.json'),\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n});\n`,\n },\n {\n path: 'netlify.toml',\n description: 'Netlify configuration (merge with existing if present)',\n content: `[build]\n publish = \"build\"\n command = \"npm run build\"\n\n[functions]\n directory = \"netlify/functions\"\n included_files = [\"build/mcp/**\"]\n\n[[redirects]]\n from = \"/mcp\"\n to = \"/.netlify/functions/mcp\"\n status = 200\n`,\n },\n ];\n}\n\nfunction generateCloudflareFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'workers/mcp.js',\n description: 'Cloudflare Worker for MCP server',\n content: `/**\n * Cloudflare Worker for MCP server\n *\n * Note: This requires bundling docs.json and search-index.json with the worker,\n * or using Cloudflare KV/R2 for storage.\n *\n * For bundling, use wrangler with custom build configuration.\n */\n\nimport { createCloudflareHandler } from 'docusaurus-plugin-mcp-server/adapters';\n\n// Option 1: Import bundled data (requires bundler configuration)\n// import docs from '../build/mcp/docs.json';\n// import searchIndex from '../build/mcp/search-index.json';\n\n// Option 2: Use KV bindings (requires KV namespace configuration)\n// const docs = await env.MCP_KV.get('docs', { type: 'json' });\n// const searchIndex = await env.MCP_KV.get('search-index', { type: 'json' });\n\nexport default {\n fetch: createCloudflareHandler({\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n // docsPath and indexPath are used for file-based loading\n // For Workers, you'll need to configure data loading differently\n docsPath: './mcp/docs.json',\n indexPath: './mcp/search-index.json',\n }),\n};\n`,\n },\n {\n path: 'wrangler.toml',\n description: 'Cloudflare Wrangler configuration',\n content: `name = \"${name}-mcp\"\nmain = \"workers/mcp.js\"\ncompatibility_date = \"2024-01-01\"\n\n# Uncomment to use KV for storing docs\n# [[kv_namespaces]]\n# binding = \"MCP_KV\"\n# id = \"your-kv-namespace-id\"\n\n# Static assets (the Docusaurus build)\n# [site]\n# bucket = \"./build\"\n`,\n },\n ];\n}\n","/**\n * Node.js adapter for MCP server\n *\n * Creates a standalone HTTP server for local development and testing.\n *\n * @example\n * ```typescript\n * import { createNodeServer } from 'docusaurus-plugin-mcp-server/adapters';\n *\n * const server = createNodeServer({\n * docsPath: './build/mcp/docs.json',\n * indexPath: './build/mcp/search-index.json',\n * name: 'my-docs',\n * });\n *\n * server.listen(3456, () => {\n * console.log('MCP server running at http://localhost:3456');\n * });\n * ```\n */\n\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerFileConfig } from '../types/index.js';\n\n/**\n * Options for the Node.js MCP server\n */\nexport interface NodeServerOptions extends McpServerFileConfig {\n /**\n * CORS origin to allow. Defaults to '*' (all origins).\n * Set to a specific origin or false to disable CORS headers.\n */\n corsOrigin?: string | false;\n}\n\n/**\n * Create a Node.js request handler for the MCP server.\n *\n * This returns a handler function compatible with `http.createServer()`.\n * For a complete server, use `createNodeServer()` instead.\n */\nexport function createNodeHandler(options: NodeServerOptions) {\n const { corsOrigin = '*', ...config } = options;\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n function setCorsHeaders(res: ServerResponse): void {\n if (corsOrigin !== false) {\n res.setHeader('Access-Control-Allow-Origin', corsOrigin);\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n }\n }\n\n return async function handler(req: IncomingMessage, res: ServerResponse): Promise<void> {\n setCorsHeaders(res);\n\n // Handle CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // Handle GET requests for health check\n if (req.method === 'GET') {\n try {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status, null, 2));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: message }));\n }\n return;\n }\n\n // Only allow POST requests for MCP\n if (req.method !== 'POST') {\n res.writeHead(405, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n })\n );\n return;\n }\n\n // Parse request body\n try {\n const body = await parseRequestBody(req);\n const mcpServer = getServer();\n await mcpServer.handleHttpRequest(req, res, body);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error('[MCP] Request error:', error);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${message}`,\n },\n })\n );\n }\n };\n}\n\n/**\n * Create a complete Node.js HTTP server for the MCP server.\n *\n * This is the simplest way to run an MCP server locally for development.\n */\nexport function createNodeServer(options: NodeServerOptions): Server {\n const handler = createNodeHandler(options);\n return createServer(handler);\n}\n\n/**\n * Parse the request body as JSON\n */\nasync function parseRequestBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : undefined);\n } catch {\n reject(new Error('Invalid JSON in request body'));\n }\n });\n req.on('error', reject);\n });\n}\n"]}
1
+ {"version":3,"sources":["../src/search/flexsearch-core.ts","../src/providers/search/flexsearch-provider.ts","../src/providers/loader.ts","../src/mcp/tools/docs-search.ts","../src/mcp/tools/docs-fetch.ts","../src/mcp/server.ts","../src/adapters/cors.ts","../src/adapters/vercel.ts","../src/adapters/netlify.ts","../src/adapters/cloudflare.ts","../src/adapters/generator.ts","../src/adapters/node.ts"],"names":["results","z"],"mappings":"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","file":"adapters-entry.js","sourcesContent":["import FlexSearch from 'flexsearch';\nimport type { ProcessedDoc, SearchResult } from '../types/index.js';\nimport type { IndexableDocument } from './types.js';\n\nexport type FlexSearchDocument = FlexSearch.Document<IndexableDocument, string[]>;\n\n/**\n * Field weights for search ranking\n * Higher values = more importance\n */\nconst FIELD_WEIGHTS = {\n title: 3.0,\n headings: 2.0,\n description: 1.5,\n content: 1.0,\n} as const;\n\n/**\n * Simple English stemmer\n * Handles common suffixes for better matching\n */\nfunction englishStemmer(word: string): string {\n // Only process words longer than 3 characters\n if (word.length <= 3) return word;\n\n return (\n word\n // -ing endings\n .replace(/ing$/, '')\n // -tion, -sion endings -> t, s\n .replace(/tion$/, 't')\n .replace(/sion$/, 's')\n // -ed endings (careful with short words)\n .replace(/([^aeiou])ed$/, '$1')\n // -es endings\n .replace(/([^aeiou])es$/, '$1')\n // -ly endings\n .replace(/ly$/, '')\n // -ment endings\n .replace(/ment$/, '')\n // -ness endings\n .replace(/ness$/, '')\n // -ies -> y\n .replace(/ies$/, 'y')\n // -s endings (simple plural)\n .replace(/([^s])s$/, '$1')\n );\n}\n\n/**\n * Create a FlexSearch document index with enhanced configuration\n *\n * Features:\n * - Full substring matching (finds \"auth\" in \"authentication\")\n * - English stemming (finds \"authenticate\" when searching \"authentication\")\n * - Context-aware scoring for phrase matching\n * - Optimized resolution for relevance ranking\n */\nexport function createSearchIndex(): FlexSearchDocument {\n return new FlexSearch.Document<IndexableDocument, string[]>({\n // Use 'full' tokenization for substring matching\n // This allows \"auth\" to match \"authentication\"\n tokenize: 'full',\n\n // Enable caching for faster repeated queries\n cache: 100,\n\n // Higher resolution = more granular ranking (1-9)\n resolution: 9,\n\n // Enable context for phrase/proximity matching\n context: {\n resolution: 2,\n depth: 2,\n bidirectional: true,\n },\n\n // Apply stemming to normalize word forms\n encode: (str: string) => {\n // Normalize to lowercase and split into words\n const words = str.toLowerCase().split(/[\\s\\-_.,;:!?'\"()[\\]{}]+/);\n // Apply stemmer to each word\n return words.filter(Boolean).map(englishStemmer);\n },\n\n // Document schema\n document: {\n id: 'id',\n // Index these fields for searching\n index: ['title', 'content', 'headings', 'description'],\n // Store these fields in results (for enriched queries)\n store: ['title', 'description'],\n },\n });\n}\n\n/**\n * Add a document to the search index\n *\n * @param index - The FlexSearch index\n * @param doc - The document to add\n * @param baseUrl - Optional base URL to construct full URL as document ID\n */\nexport function addDocumentToIndex(\n index: FlexSearchDocument,\n doc: ProcessedDoc,\n baseUrl?: string\n): void {\n // Use full URL as ID if baseUrl is provided, otherwise use route\n const id = baseUrl ? `${baseUrl.replace(/\\/$/, '')}${doc.route}` : doc.route;\n\n const indexable: IndexableDocument = {\n id,\n title: doc.title,\n content: doc.markdown,\n headings: doc.headings.map((h) => h.text).join(' '),\n description: doc.description,\n };\n\n index.add(indexable);\n}\n\n/**\n * Build the search index from processed documents\n *\n * @param docs - Documents to index\n * @param baseUrl - Optional base URL to construct full URLs as document IDs\n */\nexport function buildSearchIndex(docs: ProcessedDoc[], baseUrl?: string): FlexSearchDocument {\n const index = createSearchIndex();\n\n for (const doc of docs) {\n addDocumentToIndex(index, doc, baseUrl);\n }\n\n return index;\n}\n\n/**\n * Search the index and return results with weighted ranking\n *\n * Ranking combines:\n * - Field importance (title > headings > description > content)\n * - Position in results (earlier = more relevant)\n */\nexport function searchIndex(\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>,\n query: string,\n options: { limit?: number } = {}\n): SearchResult[] {\n const { limit = 5 } = options;\n\n // Search across all fields\n const rawResults = index.search(query, {\n limit: limit * 3, // Get extra results for better ranking after weighting\n enrich: true,\n });\n\n // Aggregate scores across fields with weighting\n const docScores = new Map<string, number>();\n\n for (const fieldResult of rawResults) {\n // Determine which field this result is from\n const field = fieldResult.field as keyof typeof FIELD_WEIGHTS;\n const fieldWeight = FIELD_WEIGHTS[field] ?? 1.0;\n\n // With enrich: true, results are objects with id property\n const results = fieldResult.result as unknown as Array<{ id: string } | string>;\n\n for (let i = 0; i < results.length; i++) {\n const item = results[i];\n if (!item) continue;\n\n const docId = typeof item === 'string' ? item : item.id;\n\n // Position-based score (earlier = higher)\n const positionScore = (results.length - i) / results.length;\n\n // Apply field weight to position score\n const weightedScore = positionScore * fieldWeight;\n\n // Combine with existing score (additive for multi-field matches)\n const existingScore = docScores.get(docId) ?? 0;\n docScores.set(docId, existingScore + weightedScore);\n }\n }\n\n // Build results array\n const results: SearchResult[] = [];\n\n for (const [docId, score] of docScores) {\n const doc = docs[docId];\n if (!doc) continue;\n\n results.push({\n url: docId, // docId is the full URL when indexed with baseUrl\n route: doc.route,\n title: doc.title,\n score,\n snippet: generateSnippet(doc.markdown, query),\n matchingHeadings: findMatchingHeadings(doc, query),\n });\n }\n\n // Sort by score (highest first) and limit\n results.sort((a, b) => b.score - a.score);\n return results.slice(0, limit);\n}\n\n/**\n * Generate a snippet from the markdown content around the query terms\n */\nexport function generateSnippet(markdown: string, query: string): string {\n const maxLength = 200;\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\n if (queryTerms.length === 0) {\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const lowerMarkdown = markdown.toLowerCase();\n let bestIndex = -1;\n let bestTerm = '';\n\n // Also try stemmed versions of query terms\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n\n for (const term of allTerms) {\n const index = lowerMarkdown.indexOf(term);\n if (index !== -1 && (bestIndex === -1 || index < bestIndex)) {\n bestIndex = index;\n bestTerm = term;\n }\n }\n\n if (bestIndex === -1) {\n // No term found, return beginning of document\n return markdown.slice(0, maxLength) + (markdown.length > maxLength ? '...' : '');\n }\n\n const snippetStart = Math.max(0, bestIndex - 50);\n const snippetEnd = Math.min(markdown.length, bestIndex + bestTerm.length + 150);\n\n let snippet = markdown.slice(snippetStart, snippetEnd);\n\n snippet = snippet\n // Remove markdown headings\n .replace(/^#{1,6}\\s+/gm, '')\n // Remove markdown links but keep text\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n // Remove markdown images\n .replace(/!\\[([^\\]]*)\\]\\([^)]+\\)/g, '')\n // Remove code block markers\n .replace(/```[a-z]*\\n?/g, '')\n // Remove inline code backticks\n .replace(/`([^`]+)`/g, '$1')\n // Clean up whitespace\n .replace(/\\s+/g, ' ')\n .trim();\n\n const prefix = snippetStart > 0 ? '...' : '';\n const suffix = snippetEnd < markdown.length ? '...' : '';\n\n return prefix + snippet + suffix;\n}\n\n/**\n * Find headings that match the query (including stemmed forms)\n */\nfunction findMatchingHeadings(doc: ProcessedDoc, query: string): string[] {\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n // Include stemmed versions for better matching\n const allTerms = [...queryTerms, ...queryTerms.map(englishStemmer)];\n const matching: string[] = [];\n\n for (const heading of doc.headings) {\n const headingLower = heading.text.toLowerCase();\n const headingStemmed = headingLower.split(/\\s+/).map(englishStemmer).join(' ');\n\n // Check if any query term matches the heading or its stemmed form\n if (\n allTerms.some(\n (term) => headingLower.includes(term) || headingStemmed.includes(englishStemmer(term))\n )\n ) {\n matching.push(heading.text);\n }\n }\n\n return matching.slice(0, 3); // Limit to 3 matching headings\n}\n\n/**\n * Export the search index to a serializable format\n */\nexport async function exportSearchIndex(index: FlexSearchDocument): Promise<unknown> {\n const exportData: Record<string, unknown> = {};\n\n await index.export((key, data) => {\n exportData[key as string] = data;\n });\n\n return exportData;\n}\n\n/**\n * Import a search index from serialized data\n */\nexport async function importSearchIndex(\n data: Record<string, unknown>\n): Promise<FlexSearchDocument> {\n const index = createSearchIndex();\n\n for (const [key, value] of Object.entries(data)) {\n // FlexSearch's import expects the data in a specific format\n await (index as unknown as { import: (key: string, data: unknown) => Promise<void> }).import(\n key,\n value\n );\n }\n\n return index;\n}\n","import fs from 'fs-extra';\nimport type { ProcessedDoc, SearchResult } from '../../types/index.js';\nimport type {\n SearchProvider,\n ProviderContext,\n SearchProviderInitData,\n SearchOptions,\n} from '../types.js';\nimport {\n importSearchIndex,\n searchIndex,\n type FlexSearchDocument,\n} from '../../search/flexsearch-core.js';\n\n/**\n * Built-in FlexSearch search provider.\n *\n * This provider uses the local FlexSearch index for search queries.\n * Supports both file-based loading (Node.js) and pre-loaded data (Workers).\n */\nexport class FlexSearchProvider implements SearchProvider {\n readonly name = 'flexsearch';\n\n private docs: Record<string, ProcessedDoc> | null = null;\n private searchIndex: FlexSearchDocument | null = null;\n private ready = false;\n\n async initialize(_context: ProviderContext, initData?: SearchProviderInitData): Promise<void> {\n if (!initData) {\n throw new Error('[FlexSearch] SearchProviderInitData required for FlexSearch provider');\n }\n\n // Pre-loaded data mode (Cloudflare Workers, etc.)\n if (initData.docs && initData.indexData) {\n this.docs = initData.docs;\n this.searchIndex = await importSearchIndex(initData.indexData as Record<string, unknown>);\n this.ready = true;\n return;\n }\n\n // File-based mode (Node.js)\n if (initData.docsPath && initData.indexPath) {\n if (await fs.pathExists(initData.docsPath)) {\n this.docs = await fs.readJson(initData.docsPath);\n } else {\n throw new Error(`[FlexSearch] Docs file not found: ${initData.docsPath}`);\n }\n\n if (await fs.pathExists(initData.indexPath)) {\n const indexData = await fs.readJson(initData.indexPath);\n this.searchIndex = await importSearchIndex(indexData);\n } else {\n throw new Error(`[FlexSearch] Search index not found: ${initData.indexPath}`);\n }\n\n this.ready = true;\n return;\n }\n\n throw new Error(\n '[FlexSearch] Invalid init data: must provide either file paths (docsPath, indexPath) or pre-loaded data (docs, indexData)'\n );\n }\n\n isReady(): boolean {\n return this.ready && this.docs !== null && this.searchIndex !== null;\n }\n\n async search(query: string, options?: SearchOptions): Promise<SearchResult[]> {\n if (!this.isReady() || !this.docs || !this.searchIndex) {\n throw new Error('[FlexSearch] Provider not initialized');\n }\n\n const limit = options?.limit ?? 5;\n return searchIndex(this.searchIndex, this.docs, query, { limit });\n }\n\n async getDocument(url: string): Promise<ProcessedDoc | null> {\n if (!this.docs) {\n throw new Error('[FlexSearch] Provider not initialized');\n }\n\n // Direct lookup by URL\n return this.docs[url] ?? null;\n }\n\n async healthCheck(): Promise<{ healthy: boolean; message?: string }> {\n if (!this.isReady()) {\n return { healthy: false, message: 'FlexSearch provider not initialized' };\n }\n\n const docCount = this.docs ? Object.keys(this.docs).length : 0;\n return {\n healthy: true,\n message: `FlexSearch provider ready with ${docCount} documents`,\n };\n }\n\n /**\n * Get all loaded documents (for compatibility with existing server code)\n */\n getDocs(): Record<string, ProcessedDoc> | null {\n return this.docs;\n }\n\n /**\n * Get the FlexSearch index (for compatibility with existing server code)\n */\n getSearchIndex(): FlexSearchDocument | null {\n return this.searchIndex;\n }\n}\n","import type { ContentIndexer, SearchProvider } from './types.js';\nimport { FlexSearchIndexer } from './indexers/flexsearch-indexer.js';\nimport { FlexSearchProvider } from './search/flexsearch-provider.js';\n\n/**\n * Load an indexer by name or module path.\n *\n * @param specifier - Either 'flexsearch' for the built-in indexer, or a module path\n * (relative path like './my-indexer.js' or npm package like '@myorg/indexer')\n * @returns Instantiated ContentIndexer\n *\n * @example\n * ```typescript\n * // Built-in\n * const indexer = await loadIndexer('flexsearch');\n *\n * // Custom relative path\n * const indexer = await loadIndexer('./src/providers/algolia-indexer.js');\n *\n * // Custom npm package\n * const indexer = await loadIndexer('@myorg/custom-indexer');\n * ```\n */\nexport async function loadIndexer(specifier: string): Promise<ContentIndexer> {\n // Built-in FlexSearch indexer\n if (specifier === 'flexsearch') {\n return new FlexSearchIndexer();\n }\n\n try {\n const module = await import(specifier);\n const IndexerClass = module.default;\n\n if (typeof IndexerClass === 'function') {\n // It's a class constructor\n const instance = new IndexerClass();\n\n if (!isContentIndexer(instance)) {\n throw new Error(\n `Invalid indexer module \"${specifier}\": does not implement ContentIndexer interface`\n );\n }\n\n return instance;\n }\n\n if (isContentIndexer(IndexerClass)) {\n return IndexerClass;\n }\n\n throw new Error(\n `Invalid indexer module \"${specifier}\": must export a default class or ContentIndexer instance`\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes('Cannot find module')) {\n throw new Error(`Indexer module not found: \"${specifier}\". Check the path or package name.`);\n }\n throw error;\n }\n}\n\n/**\n * Load a search provider by name or module path.\n *\n * @param specifier - Either 'flexsearch' for the built-in provider, or a module path\n * (relative path like './my-search.js' or npm package like '@myorg/search')\n * @returns Instantiated SearchProvider\n *\n * @example\n * ```typescript\n * // Built-in\n * const provider = await loadSearchProvider('flexsearch');\n *\n * // Custom relative path\n * const provider = await loadSearchProvider('./src/providers/glean-search.js');\n *\n * // Custom npm package\n * const provider = await loadSearchProvider('@myorg/glean-search');\n * ```\n */\nexport async function loadSearchProvider(specifier: string): Promise<SearchProvider> {\n if (specifier === 'flexsearch') {\n return new FlexSearchProvider();\n }\n\n try {\n const module = await import(specifier);\n const ProviderClass = module.default;\n\n if (typeof ProviderClass === 'function') {\n const instance = new ProviderClass();\n\n if (!isSearchProvider(instance)) {\n throw new Error(\n `Invalid search provider module \"${specifier}\": does not implement SearchProvider interface`\n );\n }\n\n return instance;\n }\n\n if (isSearchProvider(ProviderClass)) {\n return ProviderClass;\n }\n\n throw new Error(\n `Invalid search provider module \"${specifier}\": must export a default class or SearchProvider instance`\n );\n } catch (error) {\n if (error instanceof Error && error.message.includes('Cannot find module')) {\n throw new Error(\n `Search provider module not found: \"${specifier}\". Check the path or package name.`\n );\n }\n throw error;\n }\n}\n\n/**\n * Type guard to check if an object implements ContentIndexer\n */\nfunction isContentIndexer(obj: unknown): obj is ContentIndexer {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n const indexer = obj as ContentIndexer;\n return (\n typeof indexer.name === 'string' &&\n typeof indexer.initialize === 'function' &&\n typeof indexer.indexDocuments === 'function' &&\n typeof indexer.finalize === 'function'\n );\n}\n\n/**\n * Type guard to check if an object implements SearchProvider\n */\nfunction isSearchProvider(obj: unknown): obj is SearchProvider {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n const provider = obj as SearchProvider;\n return (\n typeof provider.name === 'string' &&\n typeof provider.initialize === 'function' &&\n typeof provider.isReady === 'function' &&\n typeof provider.search === 'function'\n );\n}\n","import { z } from 'zod';\nimport type { ProcessedDoc, SearchResult, DocsSearchParams } from '../../types/index.js';\nimport { searchIndex, type FlexSearchDocument } from '../../search/flexsearch-core.js';\n\n/**\n * Zod schema for docs_search input parameters\n */\nexport const docsSearchInputSchema = {\n query: z.string().min(1).describe('The search query string'),\n limit: z\n .number()\n .int()\n .min(1)\n .max(20)\n .optional()\n .default(5)\n .describe('Maximum number of results to return (1-20, default: 5)'),\n};\n\n/**\n * Tool definition for docs_search\n */\nexport const docsSearchTool = {\n name: 'docs_search',\n description:\n 'Search the documentation for relevant pages. Returns matching documents with URLs, snippets, and relevance scores. Use this to find information across all documentation.',\n inputSchema: docsSearchInputSchema,\n};\n\n/**\n * Execute the docs_search tool\n */\nexport function executeDocsSearch(\n params: DocsSearchParams,\n index: FlexSearchDocument,\n docs: Record<string, ProcessedDoc>\n): SearchResult[] {\n const { query, limit = 5 } = params;\n\n // Validate parameters\n if (!query || typeof query !== 'string' || query.trim().length === 0) {\n throw new Error('Query parameter is required and must be a non-empty string');\n }\n\n const effectiveLimit = Math.min(Math.max(1, limit), 20);\n\n // Search the index\n const results = searchIndex(index, docs, query.trim(), {\n limit: effectiveLimit,\n });\n\n return results;\n}\n\n/**\n * Format search results for MCP response\n */\nexport function formatSearchResults(results: SearchResult[]): string {\n if (results.length === 0) {\n return 'No matching documents found.';\n }\n\n const lines: string[] = [`Found ${results.length} result(s):\\n`];\n\n for (let i = 0; i < results.length; i++) {\n const result = results[i];\n if (!result) continue;\n\n lines.push(`${i + 1}. **${result.title}**`);\n lines.push(` URL: ${result.url}`);\n\n if (result.matchingHeadings && result.matchingHeadings.length > 0) {\n lines.push(` Matching sections: ${result.matchingHeadings.join(', ')}`);\n }\n\n lines.push(` ${result.snippet}`);\n lines.push('');\n }\n\n lines.push('Use docs_fetch with the URL to retrieve the full page content.');\n\n return lines.join('\\n');\n}\n","import { z } from 'zod';\nimport type { ProcessedDoc } from '../../types/index.js';\n\n/**\n * Zod schema for docs_fetch input parameters\n */\nexport const docsFetchInputSchema = {\n url: z\n .string()\n .url()\n .describe(\n 'The full URL of the page to fetch (e.g., \"https://docs.example.com/docs/getting-started\")'\n ),\n};\n\n/**\n * Tool definition for docs_fetch\n */\nexport const docsFetchTool = {\n name: 'docs_fetch',\n description:\n 'Fetch the complete content of a documentation page. Use this after searching to get the full markdown content of a specific page.',\n inputSchema: docsFetchInputSchema,\n};\n\n/**\n * Format page content for MCP response\n */\nexport function formatPageContent(doc: ProcessedDoc | null): string {\n if (!doc) {\n return 'Page not found. Please check the URL and try again.';\n }\n\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${doc.title}`);\n lines.push('');\n\n // Metadata\n if (doc.description) {\n lines.push(`> ${doc.description}`);\n lines.push('');\n }\n\n // Table of contents (if there are headings)\n if (doc.headings.length > 0) {\n lines.push('## Contents');\n lines.push('');\n for (const heading of doc.headings) {\n if (heading.level <= 3) {\n const indent = ' '.repeat(heading.level - 1);\n lines.push(`${indent}- [${heading.text}](#${heading.id})`);\n }\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Main content\n lines.push(doc.markdown);\n\n return lines.join('\\n');\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type {\n ProcessedDoc,\n McpServerConfig,\n McpServerFileConfig,\n McpServerDataConfig,\n} from '../types/index.js';\nimport { loadSearchProvider } from '../providers/loader.js';\nimport { FlexSearchProvider } from '../providers/search/flexsearch-provider.js';\nimport type {\n SearchProvider,\n ProviderContext,\n SearchProviderInitData,\n} from '../providers/types.js';\nimport { docsSearchTool, formatSearchResults } from './tools/docs-search.js';\nimport { docsFetchTool, formatPageContent } from './tools/docs-fetch.js';\n\n/**\n * Type guard to check if config uses file-based loading\n */\nfunction isFileConfig(config: McpServerConfig): config is McpServerFileConfig {\n return 'docsPath' in config && 'indexPath' in config;\n}\n\n/**\n * Type guard to check if config uses pre-loaded data\n */\nfunction isDataConfig(config: McpServerConfig): config is McpServerDataConfig {\n return 'docs' in config && 'searchIndexData' in config;\n}\n\n/**\n * MCP Server for documentation\n *\n * This class provides the MCP server implementation that can be used\n * with any HTTP framework (Express, Vercel, Cloudflare Workers, etc.)\n *\n * Supports two modes:\n * - File-based: Load docs and search index from filesystem (Node.js)\n * - Pre-loaded: Accept docs and search index data directly (Workers)\n *\n * Uses the official MCP SDK for proper protocol handling.\n */\nexport class McpDocsServer {\n private config: McpServerConfig;\n private searchProvider: SearchProvider | null = null;\n private mcpServer: McpServer;\n private initialized = false;\n\n constructor(config: McpServerConfig) {\n this.config = config;\n\n this.mcpServer = new McpServer(\n {\n name: config.name,\n version: config.version ?? '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n this.registerTools();\n }\n\n /**\n * Register all MCP tools using definitions from tool files\n */\n private registerTools(): void {\n // Register docs_search tool\n this.mcpServer.registerTool(\n docsSearchTool.name,\n {\n description: docsSearchTool.description,\n inputSchema: docsSearchTool.inputSchema,\n },\n async ({ query, limit }) => {\n await this.initialize();\n\n if (!this.searchProvider || !this.searchProvider.isReady()) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n try {\n const results = await this.searchProvider.search(query, { limit });\n return {\n content: [{ type: 'text' as const, text: formatSearchResults(results) }],\n };\n } catch (error) {\n console.error('[MCP] Search error:', error);\n return {\n content: [{ type: 'text' as const, text: `Search error: ${String(error)}` }],\n isError: true,\n };\n }\n }\n );\n\n // Register docs_fetch tool\n this.mcpServer.registerTool(\n docsFetchTool.name,\n {\n description: docsFetchTool.description,\n inputSchema: docsFetchTool.inputSchema,\n },\n async ({ url }) => {\n await this.initialize();\n\n if (!this.searchProvider || !this.searchProvider.isReady()) {\n return {\n content: [{ type: 'text' as const, text: 'Server not initialized. Please try again.' }],\n isError: true,\n };\n }\n\n try {\n const doc = await this.getDocument(url);\n return {\n content: [{ type: 'text' as const, text: formatPageContent(doc) }],\n };\n } catch (error) {\n console.error('[MCP] Fetch error:', error);\n return {\n content: [{ type: 'text' as const, text: `Error fetching page: ${String(error)}` }],\n isError: true,\n };\n }\n }\n );\n }\n\n /**\n * Get a document by URL using the search provider\n */\n private async getDocument(url: string): Promise<ProcessedDoc | null> {\n if (!this.searchProvider) {\n return null;\n }\n\n if (this.searchProvider.getDocument) {\n return this.searchProvider.getDocument(url);\n }\n\n return null;\n }\n\n /**\n * Load docs and search index using the configured search provider\n *\n * For file-based config: reads from disk\n * For data config: uses pre-loaded data directly\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n try {\n // Load the search provider\n const searchSpecifier = this.config.search ?? 'flexsearch';\n this.searchProvider = await loadSearchProvider(searchSpecifier);\n\n // Build provider context\n const providerContext: ProviderContext = {\n baseUrl: this.config.baseUrl ?? '',\n serverName: this.config.name,\n serverVersion: this.config.version ?? '1.0.0',\n outputDir: '', // Not relevant for runtime\n };\n\n // Build init data based on config type\n const initData: SearchProviderInitData = {};\n\n if (isDataConfig(this.config)) {\n // Pre-loaded data mode (Cloudflare Workers, etc.)\n initData.docs = this.config.docs;\n initData.indexData = this.config.searchIndexData;\n } else if (isFileConfig(this.config)) {\n // File-based mode (Node.js)\n initData.docsPath = this.config.docsPath;\n initData.indexPath = this.config.indexPath;\n } else {\n throw new Error('Invalid server config: must provide either file paths or pre-loaded data');\n }\n\n // Initialize the search provider\n await this.searchProvider.initialize(providerContext, initData);\n\n this.initialized = true;\n } catch (error) {\n console.error('[MCP] Failed to initialize:', error);\n throw error;\n }\n }\n\n /**\n * Handle an HTTP request using the MCP SDK's transport\n *\n * This method is designed for serverless environments (Vercel, Netlify).\n * It creates a stateless transport instance and processes the request.\n *\n * @param req - Node.js IncomingMessage or compatible request object\n * @param res - Node.js ServerResponse or compatible response object\n * @param parsedBody - Optional pre-parsed request body\n */\n async handleHttpRequest(\n req: IncomingMessage,\n res: ServerResponse,\n parsedBody?: unknown\n ): Promise<void> {\n await this.initialize();\n\n // Create a stateless transport for this request\n // enableJsonResponse: true means we get simple JSON responses instead of SSE\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode - no session tracking\n enableJsonResponse: true, // Return JSON instead of SSE streams\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request\n await transport.handleRequest(req, res, parsedBody);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Handle a Web Standard Request (Cloudflare Workers, Deno, Bun)\n *\n * This method is designed for Web Standard environments that use\n * the Fetch API Request/Response pattern.\n *\n * @param request - Web Standard Request object\n * @returns Web Standard Response object\n */\n async handleWebRequest(request: Request): Promise<Response> {\n await this.initialize();\n\n // Create a stateless transport for Web Standards\n const transport = new WebStandardStreamableHTTPServerTransport({\n sessionIdGenerator: undefined, // Stateless mode\n enableJsonResponse: true,\n });\n\n // Connect the server to this transport\n await this.mcpServer.connect(transport);\n\n try {\n // Let the transport handle the request and return the response\n return await transport.handleRequest(request);\n } finally {\n // Clean up the transport after request\n await transport.close();\n }\n }\n\n /**\n * Get server status information\n *\n * Useful for health checks and debugging\n */\n async getStatus(): Promise<{\n name: string;\n version: string;\n initialized: boolean;\n docCount: number;\n baseUrl?: string;\n searchProvider?: string;\n }> {\n let docCount = 0;\n\n // Get doc count from FlexSearchProvider if available\n if (this.searchProvider instanceof FlexSearchProvider) {\n const docs = this.searchProvider.getDocs();\n docCount = docs ? Object.keys(docs).length : 0;\n }\n\n return {\n name: this.config.name,\n version: this.config.version ?? '1.0.0',\n initialized: this.initialized,\n docCount,\n baseUrl: this.config.baseUrl,\n searchProvider: this.searchProvider?.name,\n };\n }\n\n /**\n * Get the underlying McpServer instance\n *\n * Useful for advanced use cases like custom transports\n */\n getMcpServer(): McpServer {\n return this.mcpServer;\n }\n}\n","/**\n * Standard CORS headers for MCP server responses\n *\n * These headers enable cross-origin requests from browser-based MCP clients.\n */\nexport const CORS_HEADERS = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type',\n} as const;\n\n/**\n * Get CORS headers as a plain object (for JSON responses)\n */\nexport function getCorsHeaders(): Record<string, string> {\n return { ...CORS_HEADERS };\n}\n","/**\n * Vercel adapter for MCP server\n *\n * Creates a Vercel serverless function handler for the MCP server.\n *\n * @example\n * // api/mcp.js\n * import { createVercelHandler } from 'docusaurus-plugin-mcp-server/adapters';\n * import path from 'path';\n * import { fileURLToPath } from 'url';\n *\n * const __dirname = path.dirname(fileURLToPath(import.meta.url));\n *\n * export default createVercelHandler({\n * docsPath: path.join(__dirname, '../build/mcp/docs.json'),\n * indexPath: path.join(__dirname, '../build/mcp/search-index.json'),\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * });\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Vercel request object (extends Node.js IncomingMessage)\n */\nexport interface VercelRequest extends IncomingMessage {\n body?: unknown;\n}\n\n/**\n * Vercel response object (extends Node.js ServerResponse)\n */\nexport interface VercelResponse extends ServerResponse {\n status(code: number): VercelResponse;\n json(data: unknown): void;\n}\n\n/**\n * Create a Vercel serverless function handler for the MCP server\n *\n * Uses the MCP SDK's StreamableHTTPServerTransport for proper protocol handling.\n */\nexport function createVercelHandler(config: McpServerConfig) {\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n return async function handler(req: VercelRequest, res: VercelResponse) {\n const corsHeaders = getCorsHeaders();\n\n // Handle CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204, corsHeaders);\n res.end();\n return;\n }\n\n // Handle GET requests for health check\n if (req.method === 'GET') {\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return res.status(200).json(status);\n }\n\n // Only allow POST requests for MCP\n if (req.method !== 'POST') {\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n return res.status(405).json({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n });\n }\n\n try {\n // Set CORS headers before handling\n Object.entries(corsHeaders).forEach(([key, value]) => {\n res.setHeader(key, value);\n });\n\n const mcpServer = getServer();\n // Use the SDK transport to handle the request\n await mcpServer.handleHttpRequest(req, res, req.body);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return res.status(500).json({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n });\n }\n };\n}\n","/**\n * Netlify adapter for MCP server\n *\n * Creates a Netlify serverless function handler for the MCP server.\n * Converts Netlify's AWS Lambda-style events to Web Standard Request\n * and uses the MCP SDK's transport for proper protocol handling.\n *\n * @example\n * // netlify/functions/mcp.js\n * import { createNetlifyHandler } from 'docusaurus-plugin-mcp-server/adapters';\n * import path from 'path';\n * import { fileURLToPath } from 'url';\n *\n * const __dirname = path.dirname(fileURLToPath(import.meta.url));\n *\n * export const handler = createNetlifyHandler({\n * docsPath: path.join(__dirname, '../../build/mcp/docs.json'),\n * indexPath: path.join(__dirname, '../../build/mcp/search-index.json'),\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * });\n */\n\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Netlify event object (simplified interface)\n */\nexport interface NetlifyEvent {\n httpMethod: string;\n headers: Record<string, string | undefined>;\n body: string | null;\n isBase64Encoded?: boolean;\n path?: string;\n rawUrl?: string;\n}\n\n/**\n * Netlify context object (simplified interface)\n */\nexport interface NetlifyContext {\n functionName: string;\n functionVersion?: string;\n invokedFunctionArn?: string;\n memoryLimitInMB?: string;\n awsRequestId?: string;\n logGroupName?: string;\n logStreamName?: string;\n getRemainingTimeInMillis?: () => number;\n}\n\n/**\n * Netlify function response\n */\ninterface NetlifyResponse {\n statusCode: number;\n headers?: Record<string, string>;\n body?: string;\n}\n\n/**\n * Convert a Netlify event to a Web Standard Request\n */\nfunction eventToRequest(event: NetlifyEvent): Request {\n const url = event.rawUrl || `https://localhost${event.path || '/'}`;\n\n const headers = new Headers();\n for (const [key, value] of Object.entries(event.headers)) {\n if (value) {\n headers.set(key, value);\n }\n }\n\n // Decode body if base64 encoded\n let body: string | null = event.body;\n if (body && event.isBase64Encoded) {\n body = Buffer.from(body, 'base64').toString('utf-8');\n }\n\n return new Request(url, {\n method: event.httpMethod,\n headers,\n body: event.httpMethod !== 'GET' && event.httpMethod !== 'HEAD' ? body : undefined,\n });\n}\n\n/**\n * Convert a Web Standard Response to a Netlify response\n */\nasync function responseToNetlify(\n response: Response,\n additionalHeaders: Record<string, string>\n): Promise<NetlifyResponse> {\n const headers: Record<string, string> = { ...additionalHeaders };\n response.headers.forEach((value, key) => {\n headers[key] = value;\n });\n\n const body = await response.text();\n\n return {\n statusCode: response.status,\n headers,\n body: body || undefined,\n };\n}\n\n/**\n * Create a Netlify serverless function handler for the MCP server\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for\n * proper protocol handling.\n */\nexport function createNetlifyHandler(config: McpServerConfig) {\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n return async function handler(\n event: NetlifyEvent,\n _context: NetlifyContext\n ): Promise<NetlifyResponse> {\n const corsHeaders = getCorsHeaders();\n const headers = {\n 'Content-Type': 'application/json',\n ...corsHeaders,\n };\n\n // Handle CORS preflight\n if (event.httpMethod === 'OPTIONS') {\n return {\n statusCode: 204,\n headers: corsHeaders,\n };\n }\n\n // Handle GET requests for health check\n if (event.httpMethod === 'GET') {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return {\n statusCode: 200,\n headers,\n body: JSON.stringify(status),\n };\n }\n\n // Only allow POST requests for MCP\n if (event.httpMethod !== 'POST') {\n return {\n statusCode: 405,\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n }),\n };\n }\n\n try {\n const mcpServer = getServer();\n\n // Convert Netlify event to Web Standard Request\n const request = eventToRequest(event);\n\n // Use the SDK's Web Standard transport to handle the request\n const response = await mcpServer.handleWebRequest(request);\n\n // Convert back to Netlify response format with CORS headers\n return await responseToNetlify(response, corsHeaders);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return {\n statusCode: 500,\n headers,\n body: JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n }),\n };\n }\n };\n}\n","/**\n * Cloudflare Workers adapter for MCP server\n *\n * Creates a Cloudflare Workers fetch handler for the MCP server.\n * Since Workers can't access the filesystem, this adapter requires\n * pre-loaded docs and search index data.\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for proper\n * protocol handling with Web Standard Request/Response.\n *\n * @example\n * // src/worker.js\n * import { createCloudflareHandler } from 'docusaurus-plugin-mcp-server/adapters';\n * import docs from '../build/mcp/docs.json';\n * import searchIndex from '../build/mcp/search-index.json';\n *\n * export default {\n * fetch: createCloudflareHandler({\n * docs,\n * searchIndexData: searchIndex,\n * name: 'my-docs',\n * baseUrl: 'https://docs.example.com',\n * }),\n * };\n */\n\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { ProcessedDoc, McpServerDataConfig } from '../types/index.js';\nimport { getCorsHeaders } from './cors.js';\n\n/**\n * Config for Cloudflare Workers adapter\n */\nexport interface CloudflareAdapterConfig {\n /** Pre-loaded docs data (imported from docs.json) */\n docs: Record<string, ProcessedDoc>;\n /** Pre-loaded search index data (imported from search-index.json) */\n searchIndexData: Record<string, unknown>;\n /** Server name */\n name: string;\n /** Server version */\n version?: string;\n /** Base URL for constructing full page URLs */\n baseUrl?: string;\n}\n\n/**\n * Create a Cloudflare Workers fetch handler for the MCP server\n *\n * Uses the MCP SDK's WebStandardStreamableHTTPServerTransport for\n * proper protocol handling.\n */\nexport function createCloudflareHandler(config: CloudflareAdapterConfig) {\n let server: McpDocsServer | null = null;\n\n const serverConfig: McpServerDataConfig = {\n docs: config.docs,\n searchIndexData: config.searchIndexData,\n name: config.name,\n version: config.version,\n baseUrl: config.baseUrl,\n };\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(serverConfig);\n }\n return server;\n }\n\n return async function fetch(request: Request): Promise<Response> {\n const corsHeaders = getCorsHeaders();\n\n // Handle CORS preflight\n if (request.method === 'OPTIONS') {\n return new Response(null, { status: 204, headers: corsHeaders });\n }\n\n // Handle GET requests for health check\n if (request.method === 'GET') {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n return new Response(JSON.stringify(status), {\n status: 200,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n });\n }\n\n // Only allow POST requests for MCP\n if (request.method !== 'POST') {\n return new Response(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n }),\n {\n status: 405,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n }\n );\n }\n\n try {\n const mcpServer = getServer();\n // Use the SDK's Web Standard transport to handle the request\n const response = await mcpServer.handleWebRequest(request);\n\n // Add CORS headers to the response\n const newHeaders = new Headers(response.headers);\n Object.entries(corsHeaders).forEach(([key, value]) => {\n newHeaders.set(key, value);\n });\n\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers: newHeaders,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error('MCP Server Error:', error);\n return new Response(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${errorMessage}`,\n },\n }),\n {\n status: 500,\n headers: { ...corsHeaders, 'Content-Type': 'application/json' },\n }\n );\n }\n };\n}\n","/**\n * Adapter file generator\n *\n * Generates platform-specific adapter files for deploying the MCP server.\n */\n\nexport type Platform = 'vercel' | 'netlify' | 'cloudflare';\n\nexport interface GeneratorOptions {\n /** Target platform */\n platform: Platform;\n /** Server name */\n name: string;\n /** Base URL for the documentation site */\n baseUrl: string;\n /** Output path for the generated files (defaults to current directory) */\n outputPath?: string;\n}\n\nexport interface GeneratedFile {\n /** Relative path for the file */\n path: string;\n /** File contents */\n content: string;\n /** Description of the file */\n description: string;\n}\n\n/**\n * Generate adapter files for a specific platform\n */\nexport function generateAdapterFiles(options: GeneratorOptions): GeneratedFile[] {\n const { platform, name, baseUrl } = options;\n\n switch (platform) {\n case 'vercel':\n return generateVercelFiles(name, baseUrl);\n case 'netlify':\n return generateNetlifyFiles(name, baseUrl);\n case 'cloudflare':\n return generateCloudflareFiles(name, baseUrl);\n default:\n throw new Error(`Unknown platform: ${platform}`);\n }\n}\n\nfunction generateVercelFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'api/mcp.js',\n description: 'Vercel serverless function for MCP server',\n content: `/**\n * Vercel API route for MCP server\n * Deploy to Vercel and this will be available at /api/mcp\n */\n\nimport { createVercelHandler } from 'docusaurus-plugin-mcp-server/adapters';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst projectRoot = path.join(__dirname, '..');\n\nexport default createVercelHandler({\n docsPath: path.join(projectRoot, 'build/mcp/docs.json'),\n indexPath: path.join(projectRoot, 'build/mcp/search-index.json'),\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n});\n`,\n },\n {\n path: 'vercel.json',\n description: 'Vercel configuration (merge with existing if present)',\n content: `{\n \"functions\": {\n \"api/mcp.js\": {\n \"includeFiles\": \"build/mcp/**\"\n }\n },\n \"rewrites\": [\n {\n \"source\": \"/mcp\",\n \"destination\": \"/api/mcp\"\n }\n ]\n}\n`,\n },\n ];\n}\n\nfunction generateNetlifyFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'netlify/functions/mcp.js',\n description: 'Netlify serverless function for MCP server',\n content: `/**\n * Netlify function for MCP server\n * Deploy to Netlify and this will be available at /.netlify/functions/mcp\n */\n\nimport { createNetlifyHandler } from 'docusaurus-plugin-mcp-server/adapters';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst projectRoot = path.join(__dirname, '../..');\n\nexport const handler = createNetlifyHandler({\n docsPath: path.join(projectRoot, 'build/mcp/docs.json'),\n indexPath: path.join(projectRoot, 'build/mcp/search-index.json'),\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n});\n`,\n },\n {\n path: 'netlify.toml',\n description: 'Netlify configuration (merge with existing if present)',\n content: `[build]\n publish = \"build\"\n command = \"npm run build\"\n\n[functions]\n directory = \"netlify/functions\"\n included_files = [\"build/mcp/**\"]\n\n[[redirects]]\n from = \"/mcp\"\n to = \"/.netlify/functions/mcp\"\n status = 200\n`,\n },\n ];\n}\n\nfunction generateCloudflareFiles(name: string, baseUrl: string): GeneratedFile[] {\n return [\n {\n path: 'workers/mcp.js',\n description: 'Cloudflare Worker for MCP server',\n content: `/**\n * Cloudflare Worker for MCP server\n *\n * Note: This requires bundling docs.json and search-index.json with the worker,\n * or using Cloudflare KV/R2 for storage.\n *\n * For bundling, use wrangler with custom build configuration.\n */\n\nimport { createCloudflareHandler } from 'docusaurus-plugin-mcp-server/adapters';\n\n// Option 1: Import bundled data (requires bundler configuration)\n// import docs from '../build/mcp/docs.json';\n// import searchIndex from '../build/mcp/search-index.json';\n\n// Option 2: Use KV bindings (requires KV namespace configuration)\n// const docs = await env.MCP_KV.get('docs', { type: 'json' });\n// const searchIndex = await env.MCP_KV.get('search-index', { type: 'json' });\n\nexport default {\n fetch: createCloudflareHandler({\n name: '${name}',\n version: '1.0.0',\n baseUrl: '${baseUrl}',\n // docsPath and indexPath are used for file-based loading\n // For Workers, you'll need to configure data loading differently\n docsPath: './mcp/docs.json',\n indexPath: './mcp/search-index.json',\n }),\n};\n`,\n },\n {\n path: 'wrangler.toml',\n description: 'Cloudflare Wrangler configuration',\n content: `name = \"${name}-mcp\"\nmain = \"workers/mcp.js\"\ncompatibility_date = \"2024-01-01\"\n\n# Uncomment to use KV for storing docs\n# [[kv_namespaces]]\n# binding = \"MCP_KV\"\n# id = \"your-kv-namespace-id\"\n\n# Static assets (the Docusaurus build)\n# [site]\n# bucket = \"./build\"\n`,\n },\n ];\n}\n","/**\n * Node.js adapter for MCP server\n *\n * Creates a standalone HTTP server for local development and testing.\n *\n * @example\n * ```typescript\n * import { createNodeServer } from 'docusaurus-plugin-mcp-server/adapters';\n *\n * const server = createNodeServer({\n * docsPath: './build/mcp/docs.json',\n * indexPath: './build/mcp/search-index.json',\n * name: 'my-docs',\n * });\n *\n * server.listen(3456, () => {\n * console.log('MCP server running at http://localhost:3456');\n * });\n * ```\n */\n\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { McpDocsServer } from '../mcp/server.js';\nimport type { McpServerFileConfig } from '../types/index.js';\n\n/**\n * Options for the Node.js MCP server\n */\nexport interface NodeServerOptions extends McpServerFileConfig {\n /**\n * CORS origin to allow. Defaults to '*' (all origins).\n * Set to a specific origin or false to disable CORS headers.\n */\n corsOrigin?: string | false;\n}\n\n/**\n * Create a Node.js request handler for the MCP server.\n *\n * This returns a handler function compatible with `http.createServer()`.\n * For a complete server, use `createNodeServer()` instead.\n */\nexport function createNodeHandler(options: NodeServerOptions) {\n const { corsOrigin = '*', ...config } = options;\n let server: McpDocsServer | null = null;\n\n function getServer(): McpDocsServer {\n if (!server) {\n server = new McpDocsServer(config);\n }\n return server;\n }\n\n function setCorsHeaders(res: ServerResponse): void {\n if (corsOrigin !== false) {\n res.setHeader('Access-Control-Allow-Origin', corsOrigin);\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');\n }\n }\n\n return async function handler(req: IncomingMessage, res: ServerResponse): Promise<void> {\n setCorsHeaders(res);\n\n // Handle CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n // Handle GET requests for health check\n if (req.method === 'GET') {\n try {\n const mcpServer = getServer();\n const status = await mcpServer.getStatus();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(status, null, 2));\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: message }));\n }\n return;\n }\n\n // Only allow POST requests for MCP\n if (req.method !== 'POST') {\n res.writeHead(405, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32600,\n message: 'Method not allowed. Use POST for MCP requests, GET for status.',\n },\n })\n );\n return;\n }\n\n // Parse request body\n try {\n const body = await parseRequestBody(req);\n const mcpServer = getServer();\n await mcpServer.handleHttpRequest(req, res, body);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error('[MCP] Request error:', error);\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n id: null,\n error: {\n code: -32603,\n message: `Internal server error: ${message}`,\n },\n })\n );\n }\n };\n}\n\n/**\n * Create a complete Node.js HTTP server for the MCP server.\n *\n * This is the simplest way to run an MCP server locally for development.\n */\nexport function createNodeServer(options: NodeServerOptions): Server {\n const handler = createNodeHandler(options);\n return createServer(handler);\n}\n\n/**\n * Parse the request body as JSON\n */\nasync function parseRequestBody(req: IncomingMessage): Promise<unknown> {\n return new Promise((resolve, reject) => {\n let body = '';\n req.on('data', (chunk) => {\n body += chunk;\n });\n req.on('end', () => {\n try {\n resolve(body ? JSON.parse(body) : undefined);\n } catch {\n reject(new Error('Invalid JSON in request body'));\n }\n });\n req.on('error', reject);\n });\n}\n"]}
@@ -1,19 +1,11 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';
3
-
4
- var fs2 = require('fs-extra');
5
- var path = require('path');
6
- var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
7
- var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
8
- var webStandardStreamableHttp_js = require('@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js');
9
- var FlexSearch = require('flexsearch');
10
- var zod = require('zod');
11
-
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
-
14
- var fs2__default = /*#__PURE__*/_interopDefault(fs2);
15
- var path__default = /*#__PURE__*/_interopDefault(path);
16
- var FlexSearch__default = /*#__PURE__*/_interopDefault(FlexSearch);
2
+ import fs2 from 'fs-extra';
3
+ import path from 'path';
4
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
6
+ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
7
+ import FlexSearch from 'flexsearch';
8
+ import { z } from 'zod';
17
9
 
18
10
  var FIELD_WEIGHTS = {
19
11
  title: 3,
@@ -26,7 +18,7 @@ function englishStemmer(word) {
26
18
  return word.replace(/ing$/, "").replace(/tion$/, "t").replace(/sion$/, "s").replace(/([^aeiou])ed$/, "$1").replace(/([^aeiou])es$/, "$1").replace(/ly$/, "").replace(/ment$/, "").replace(/ness$/, "").replace(/ies$/, "y").replace(/([^s])s$/, "$1");
27
19
  }
28
20
  function createSearchIndex() {
29
- return new FlexSearch__default.default.Document({
21
+ return new FlexSearch.Document({
30
22
  // Use 'full' tokenization for substring matching
31
23
  // This allows "auth" to match "authentication"
32
24
  tokenize: "full",
@@ -163,13 +155,13 @@ var FlexSearchProvider = class {
163
155
  return;
164
156
  }
165
157
  if (initData.docsPath && initData.indexPath) {
166
- if (await fs2__default.default.pathExists(initData.docsPath)) {
167
- this.docs = await fs2__default.default.readJson(initData.docsPath);
158
+ if (await fs2.pathExists(initData.docsPath)) {
159
+ this.docs = await fs2.readJson(initData.docsPath);
168
160
  } else {
169
161
  throw new Error(`[FlexSearch] Docs file not found: ${initData.docsPath}`);
170
162
  }
171
- if (await fs2__default.default.pathExists(initData.indexPath)) {
172
- const indexData = await fs2__default.default.readJson(initData.indexPath);
163
+ if (await fs2.pathExists(initData.indexPath)) {
164
+ const indexData = await fs2.readJson(initData.indexPath);
173
165
  this.searchIndex = await importSearchIndex(indexData);
174
166
  } else {
175
167
  throw new Error(`[FlexSearch] Search index not found: ${initData.indexPath}`);
@@ -261,8 +253,8 @@ function isSearchProvider(obj) {
261
253
  return typeof provider.name === "string" && typeof provider.initialize === "function" && typeof provider.isReady === "function" && typeof provider.search === "function";
262
254
  }
263
255
  var docsSearchInputSchema = {
264
- query: zod.z.string().min(1).describe("The search query string"),
265
- limit: zod.z.number().int().min(1).max(20).optional().default(5).describe("Maximum number of results to return (1-20, default: 5)")
256
+ query: z.string().min(1).describe("The search query string"),
257
+ limit: z.number().int().min(1).max(20).optional().default(5).describe("Maximum number of results to return (1-20, default: 5)")
266
258
  };
267
259
  var docsSearchTool = {
268
260
  name: "docs_search",
@@ -290,7 +282,7 @@ function formatSearchResults(results) {
290
282
  return lines.join("\n");
291
283
  }
292
284
  var docsFetchInputSchema = {
293
- url: zod.z.string().url().describe(
285
+ url: z.string().url().describe(
294
286
  'The full URL of the page to fetch (e.g., "https://docs.example.com/docs/getting-started")'
295
287
  )
296
288
  };
@@ -341,7 +333,7 @@ var McpDocsServer = class {
341
333
  initialized = false;
342
334
  constructor(config) {
343
335
  this.config = config;
344
- this.mcpServer = new mcp_js.McpServer(
336
+ this.mcpServer = new McpServer(
345
337
  {
346
338
  name: config.name,
347
339
  version: config.version ?? "1.0.0"
@@ -476,7 +468,7 @@ var McpDocsServer = class {
476
468
  */
477
469
  async handleHttpRequest(req, res, parsedBody) {
478
470
  await this.initialize();
479
- const transport = new streamableHttp_js.StreamableHTTPServerTransport({
471
+ const transport = new StreamableHTTPServerTransport({
480
472
  sessionIdGenerator: void 0,
481
473
  // Stateless mode - no session tracking
482
474
  enableJsonResponse: true
@@ -500,7 +492,7 @@ var McpDocsServer = class {
500
492
  */
501
493
  async handleWebRequest(request) {
502
494
  await this.initialize();
503
- const transport = new webStandardStreamableHttp_js.WebStandardStreamableHTTPServerTransport({
495
+ const transport = new WebStandardStreamableHTTPServerTransport({
504
496
  sessionIdGenerator: void 0,
505
497
  // Stateless mode
506
498
  enableJsonResponse: true
@@ -550,8 +542,8 @@ async function verifyBuild(buildDir) {
550
542
  errors: [],
551
543
  warnings: []
552
544
  };
553
- const mcpDir = path__default.default.join(buildDir, "mcp");
554
- if (!await fs2__default.default.pathExists(mcpDir)) {
545
+ const mcpDir = path.join(buildDir, "mcp");
546
+ if (!await fs2.pathExists(mcpDir)) {
555
547
  result.errors.push(`MCP directory not found: ${mcpDir}`);
556
548
  result.errors.push('Did you run "npm run build" with the MCP plugin configured?');
557
549
  result.success = false;
@@ -559,8 +551,8 @@ async function verifyBuild(buildDir) {
559
551
  }
560
552
  const requiredFiles = ["docs.json", "search-index.json", "manifest.json"];
561
553
  for (const file of requiredFiles) {
562
- const filePath = path__default.default.join(mcpDir, file);
563
- if (!await fs2__default.default.pathExists(filePath)) {
554
+ const filePath = path.join(mcpDir, file);
555
+ if (!await fs2.pathExists(filePath)) {
564
556
  result.errors.push(`Required file missing: ${filePath}`);
565
557
  result.success = false;
566
558
  }
@@ -569,8 +561,8 @@ async function verifyBuild(buildDir) {
569
561
  return result;
570
562
  }
571
563
  try {
572
- const docsPath = path__default.default.join(mcpDir, "docs.json");
573
- const docs = await fs2__default.default.readJson(docsPath);
564
+ const docsPath = path.join(mcpDir, "docs.json");
565
+ const docs = await fs2.readJson(docsPath);
574
566
  if (typeof docs !== "object" || docs === null) {
575
567
  result.errors.push("docs.json is not a valid object");
576
568
  result.success = false;
@@ -594,8 +586,8 @@ async function verifyBuild(buildDir) {
594
586
  result.success = false;
595
587
  }
596
588
  try {
597
- const indexPath = path__default.default.join(mcpDir, "search-index.json");
598
- const indexData = await fs2__default.default.readJson(indexPath);
589
+ const indexPath = path.join(mcpDir, "search-index.json");
590
+ const indexData = await fs2.readJson(indexPath);
599
591
  if (typeof indexData !== "object" || indexData === null) {
600
592
  result.errors.push("search-index.json is not a valid object");
601
593
  result.success = false;
@@ -605,8 +597,8 @@ async function verifyBuild(buildDir) {
605
597
  result.success = false;
606
598
  }
607
599
  try {
608
- const manifestPath = path__default.default.join(mcpDir, "manifest.json");
609
- const manifest = await fs2__default.default.readJson(manifestPath);
600
+ const manifestPath = path.join(mcpDir, "manifest.json");
601
+ const manifest = await fs2.readJson(manifestPath);
610
602
  if (!manifest.name || typeof manifest.name !== "string") {
611
603
  result.warnings.push("manifest.json is missing server name");
612
604
  }
@@ -620,14 +612,14 @@ async function verifyBuild(buildDir) {
620
612
  return result;
621
613
  }
622
614
  async function testServer(buildDir) {
623
- const mcpDir = path__default.default.join(buildDir, "mcp");
624
- const docsPath = path__default.default.join(mcpDir, "docs.json");
625
- const indexPath = path__default.default.join(mcpDir, "search-index.json");
626
- const manifestPath = path__default.default.join(mcpDir, "manifest.json");
615
+ const mcpDir = path.join(buildDir, "mcp");
616
+ const docsPath = path.join(mcpDir, "docs.json");
617
+ const indexPath = path.join(mcpDir, "search-index.json");
618
+ const manifestPath = path.join(mcpDir, "manifest.json");
627
619
  try {
628
- const manifest = await fs2__default.default.readJson(manifestPath);
629
- const docs = await fs2__default.default.readJson(docsPath);
630
- const searchIndexData = await fs2__default.default.readJson(indexPath);
620
+ const manifest = await fs2.readJson(manifestPath);
621
+ const docs = await fs2.readJson(docsPath);
622
+ const searchIndexData = await fs2.readJson(indexPath);
631
623
  const server = new McpDocsServer({
632
624
  name: manifest.name || "test-docs",
633
625
  version: manifest.version || "1.0.0",
@@ -659,7 +651,7 @@ async function main() {
659
651
  console.log("");
660
652
  console.log("\u{1F50D} MCP Build Verification");
661
653
  console.log("=".repeat(50));
662
- console.log(`Build directory: ${path__default.default.resolve(buildDir)}`);
654
+ console.log(`Build directory: ${path.resolve(buildDir)}`);
663
655
  console.log("");
664
656
  console.log("\u{1F4C1} Checking build output...");
665
657
  const verifyResult = await verifyBuild(buildDir);