docusaurus-plugin-mcp-server 0.9.0 → 0.10.1

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/cli/verify.ts"],"names":["FlexSearch","results","fs","z","McpServer","StreamableHTTPServerTransport","WebStandardStreamableHTTPServerTransport","path"],"mappings":"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","file":"verify.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","#!/usr/bin/env node\n/**\n * MCP Verification CLI\n *\n * Verifies that the MCP build output is valid and the server works correctly.\n *\n * Usage:\n * npx docusaurus-mcp-verify [buildDir]\n *\n * Options:\n * buildDir Path to Docusaurus build output (default: ./build)\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { McpDocsServer } from '../mcp/server.js';\n\ninterface VerifyResult {\n success: boolean;\n docsFound: number;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Verify the MCP build output\n */\nasync function verifyBuild(buildDir: string): Promise<VerifyResult> {\n const result: VerifyResult = {\n success: true,\n docsFound: 0,\n errors: [],\n warnings: [],\n };\n\n const mcpDir = path.join(buildDir, 'mcp');\n\n // Check if MCP directory exists\n if (!(await fs.pathExists(mcpDir))) {\n result.errors.push(`MCP directory not found: ${mcpDir}`);\n result.errors.push('Did you run \"npm run build\" with the MCP plugin configured?');\n result.success = false;\n return result;\n }\n\n // Check required files\n const requiredFiles = ['docs.json', 'search-index.json', 'manifest.json'];\n\n for (const file of requiredFiles) {\n const filePath = path.join(mcpDir, file);\n if (!(await fs.pathExists(filePath))) {\n result.errors.push(`Required file missing: ${filePath}`);\n result.success = false;\n }\n }\n\n if (!result.success) {\n return result;\n }\n\n // Validate docs.json\n try {\n const docsPath = path.join(mcpDir, 'docs.json');\n const docs = await fs.readJson(docsPath);\n\n if (typeof docs !== 'object' || docs === null) {\n result.errors.push('docs.json is not a valid object');\n result.success = false;\n } else {\n result.docsFound = Object.keys(docs).length;\n\n if (result.docsFound === 0) {\n result.warnings.push('docs.json contains no documents');\n }\n\n // Validate document structure\n for (const [route, doc] of Object.entries(docs)) {\n const d = doc as Record<string, unknown>;\n if (!d.title || typeof d.title !== 'string') {\n result.warnings.push(`Document ${route} is missing a title`);\n }\n if (!d.markdown || typeof d.markdown !== 'string') {\n result.warnings.push(`Document ${route} is missing markdown content`);\n }\n }\n }\n } catch (error) {\n result.errors.push(`Failed to parse docs.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n // Validate search-index.json\n try {\n const indexPath = path.join(mcpDir, 'search-index.json');\n const indexData = await fs.readJson(indexPath);\n\n if (typeof indexData !== 'object' || indexData === null) {\n result.errors.push('search-index.json is not a valid object');\n result.success = false;\n }\n } catch (error) {\n result.errors.push(`Failed to parse search-index.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n // Validate manifest.json\n try {\n const manifestPath = path.join(mcpDir, 'manifest.json');\n const manifest = await fs.readJson(manifestPath);\n\n if (!manifest.name || typeof manifest.name !== 'string') {\n result.warnings.push('manifest.json is missing server name');\n }\n if (!manifest.version || typeof manifest.version !== 'string') {\n result.warnings.push('manifest.json is missing server version');\n }\n } catch (error) {\n result.errors.push(`Failed to parse manifest.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n return result;\n}\n\n/**\n * Test the MCP server with the build output\n */\nasync function testServer(buildDir: string): Promise<{ success: boolean; message: string }> {\n const mcpDir = path.join(buildDir, 'mcp');\n const docsPath = path.join(mcpDir, 'docs.json');\n const indexPath = path.join(mcpDir, 'search-index.json');\n const manifestPath = path.join(mcpDir, 'manifest.json');\n\n try {\n const manifest = await fs.readJson(manifestPath);\n const docs = await fs.readJson(docsPath);\n const searchIndexData = await fs.readJson(indexPath);\n\n const server = new McpDocsServer({\n name: manifest.name || 'test-docs',\n version: manifest.version || '1.0.0',\n docs,\n searchIndexData,\n });\n\n await server.initialize();\n const status = await server.getStatus();\n\n if (!status.initialized) {\n return { success: false, message: 'Server failed to initialize' };\n }\n\n if (status.docCount === 0) {\n return { success: false, message: 'Server has no documents loaded' };\n }\n\n return {\n success: true,\n message: `Server initialized with ${status.docCount} documents`,\n };\n } catch (error) {\n return {\n success: false,\n message: `Server test failed: ${(error as Error).message}`,\n };\n }\n}\n\n/**\n * Main CLI entry point\n */\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const buildDir = args[0] || './build';\n\n console.log('');\n console.log('🔍 MCP Build Verification');\n console.log('='.repeat(50));\n console.log(`Build directory: ${path.resolve(buildDir)}`);\n console.log('');\n\n // Verify build output\n console.log('📁 Checking build output...');\n const verifyResult = await verifyBuild(buildDir);\n\n if (verifyResult.errors.length > 0) {\n console.log('');\n console.log('❌ Errors:');\n for (const error of verifyResult.errors) {\n console.log(` • ${error}`);\n }\n }\n\n if (verifyResult.warnings.length > 0) {\n console.log('');\n console.log('⚠️ Warnings:');\n for (const warning of verifyResult.warnings) {\n console.log(` • ${warning}`);\n }\n }\n\n if (!verifyResult.success) {\n console.log('');\n console.log('❌ Build verification failed');\n process.exit(1);\n }\n\n console.log(` ✓ Found ${verifyResult.docsFound} documents`);\n console.log(' ✓ All required files present');\n console.log(' ✓ File structure valid');\n\n // Test server\n console.log('');\n console.log('🚀 Testing MCP server...');\n const serverResult = await testServer(buildDir);\n\n if (!serverResult.success) {\n console.log(` ❌ ${serverResult.message}`);\n console.log('');\n console.log('❌ Server test failed');\n process.exit(1);\n }\n\n console.log(` ✓ ${serverResult.message}`);\n\n console.log('');\n console.log('✅ All checks passed!');\n console.log('');\n console.log('Next steps:');\n console.log(' 1. Deploy your site to a hosting provider');\n console.log(' 2. Configure MCP endpoint (see README for platform guides)');\n console.log(' 3. Connect your AI tools to the MCP server');\n console.log('');\n\n process.exit(0);\n}\n\nmain().catch((error) => {\n console.error('Unexpected error:', error);\n process.exit(1);\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/cli/verify.ts"],"names":["results","fs","z"],"mappings":"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","file":"verify.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","#!/usr/bin/env node\n/**\n * MCP Verification CLI\n *\n * Verifies that the MCP build output is valid and the server works correctly.\n *\n * Usage:\n * npx docusaurus-mcp-verify [buildDir]\n *\n * Options:\n * buildDir Path to Docusaurus build output (default: ./build)\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { McpDocsServer } from '../mcp/server.js';\n\ninterface VerifyResult {\n success: boolean;\n docsFound: number;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Verify the MCP build output\n */\nasync function verifyBuild(buildDir: string): Promise<VerifyResult> {\n const result: VerifyResult = {\n success: true,\n docsFound: 0,\n errors: [],\n warnings: [],\n };\n\n const mcpDir = path.join(buildDir, 'mcp');\n\n // Check if MCP directory exists\n if (!(await fs.pathExists(mcpDir))) {\n result.errors.push(`MCP directory not found: ${mcpDir}`);\n result.errors.push('Did you run \"npm run build\" with the MCP plugin configured?');\n result.success = false;\n return result;\n }\n\n // Check required files\n const requiredFiles = ['docs.json', 'search-index.json', 'manifest.json'];\n\n for (const file of requiredFiles) {\n const filePath = path.join(mcpDir, file);\n if (!(await fs.pathExists(filePath))) {\n result.errors.push(`Required file missing: ${filePath}`);\n result.success = false;\n }\n }\n\n if (!result.success) {\n return result;\n }\n\n // Validate docs.json\n try {\n const docsPath = path.join(mcpDir, 'docs.json');\n const docs = await fs.readJson(docsPath);\n\n if (typeof docs !== 'object' || docs === null) {\n result.errors.push('docs.json is not a valid object');\n result.success = false;\n } else {\n result.docsFound = Object.keys(docs).length;\n\n if (result.docsFound === 0) {\n result.warnings.push('docs.json contains no documents');\n }\n\n // Validate document structure\n for (const [route, doc] of Object.entries(docs)) {\n const d = doc as Record<string, unknown>;\n if (!d.title || typeof d.title !== 'string') {\n result.warnings.push(`Document ${route} is missing a title`);\n }\n if (!d.markdown || typeof d.markdown !== 'string') {\n result.warnings.push(`Document ${route} is missing markdown content`);\n }\n }\n }\n } catch (error) {\n result.errors.push(`Failed to parse docs.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n // Validate search-index.json\n try {\n const indexPath = path.join(mcpDir, 'search-index.json');\n const indexData = await fs.readJson(indexPath);\n\n if (typeof indexData !== 'object' || indexData === null) {\n result.errors.push('search-index.json is not a valid object');\n result.success = false;\n }\n } catch (error) {\n result.errors.push(`Failed to parse search-index.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n // Validate manifest.json\n try {\n const manifestPath = path.join(mcpDir, 'manifest.json');\n const manifest = await fs.readJson(manifestPath);\n\n if (!manifest.name || typeof manifest.name !== 'string') {\n result.warnings.push('manifest.json is missing server name');\n }\n if (!manifest.version || typeof manifest.version !== 'string') {\n result.warnings.push('manifest.json is missing server version');\n }\n } catch (error) {\n result.errors.push(`Failed to parse manifest.json: ${(error as Error).message}`);\n result.success = false;\n }\n\n return result;\n}\n\n/**\n * Test the MCP server with the build output\n */\nasync function testServer(buildDir: string): Promise<{ success: boolean; message: string }> {\n const mcpDir = path.join(buildDir, 'mcp');\n const docsPath = path.join(mcpDir, 'docs.json');\n const indexPath = path.join(mcpDir, 'search-index.json');\n const manifestPath = path.join(mcpDir, 'manifest.json');\n\n try {\n const manifest = await fs.readJson(manifestPath);\n const docs = await fs.readJson(docsPath);\n const searchIndexData = await fs.readJson(indexPath);\n\n const server = new McpDocsServer({\n name: manifest.name || 'test-docs',\n version: manifest.version || '1.0.0',\n docs,\n searchIndexData,\n });\n\n await server.initialize();\n const status = await server.getStatus();\n\n if (!status.initialized) {\n return { success: false, message: 'Server failed to initialize' };\n }\n\n if (status.docCount === 0) {\n return { success: false, message: 'Server has no documents loaded' };\n }\n\n return {\n success: true,\n message: `Server initialized with ${status.docCount} documents`,\n };\n } catch (error) {\n return {\n success: false,\n message: `Server test failed: ${(error as Error).message}`,\n };\n }\n}\n\n/**\n * Main CLI entry point\n */\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const buildDir = args[0] || './build';\n\n console.log('');\n console.log('🔍 MCP Build Verification');\n console.log('='.repeat(50));\n console.log(`Build directory: ${path.resolve(buildDir)}`);\n console.log('');\n\n // Verify build output\n console.log('📁 Checking build output...');\n const verifyResult = await verifyBuild(buildDir);\n\n if (verifyResult.errors.length > 0) {\n console.log('');\n console.log('❌ Errors:');\n for (const error of verifyResult.errors) {\n console.log(` • ${error}`);\n }\n }\n\n if (verifyResult.warnings.length > 0) {\n console.log('');\n console.log('⚠️ Warnings:');\n for (const warning of verifyResult.warnings) {\n console.log(` • ${warning}`);\n }\n }\n\n if (!verifyResult.success) {\n console.log('');\n console.log('❌ Build verification failed');\n process.exit(1);\n }\n\n console.log(` ✓ Found ${verifyResult.docsFound} documents`);\n console.log(' ✓ All required files present');\n console.log(' ✓ File structure valid');\n\n // Test server\n console.log('');\n console.log('🚀 Testing MCP server...');\n const serverResult = await testServer(buildDir);\n\n if (!serverResult.success) {\n console.log(` ❌ ${serverResult.message}`);\n console.log('');\n console.log('❌ Server test failed');\n process.exit(1);\n }\n\n console.log(` ✓ ${serverResult.message}`);\n\n console.log('');\n console.log('✅ All checks passed!');\n console.log('');\n console.log('Next steps:');\n console.log(' 1. Deploy your site to a hosting provider');\n console.log(' 2. Configure MCP endpoint (see README for platform guides)');\n console.log(' 3. Connect your AI tools to the MCP server');\n console.log('');\n\n process.exit(0);\n}\n\nmain().catch((error) => {\n console.error('Unexpected error:', error);\n process.exit(1);\n});\n"]}
package/dist/index.d.ts CHANGED
@@ -476,4 +476,4 @@ declare function discoverHtmlFiles(outDir: string): Promise<FlattenedRoute[]>;
476
476
  */
477
477
  declare function collectRoutes(outDir: string, excludePatterns: string[]): Promise<FlattenedRoute[]>;
478
478
 
479
- export { type ContentIndexer, type ContentIndexerModule, DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, FlexSearchIndexer, FlexSearchProvider, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, type ProviderContext, type SearchOptions, type SearchProvider, type SearchProviderInitData, type SearchProviderModule, SearchResult, buildSearchIndex, collectRoutes, discoverHtmlFiles, docsFetchTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, loadIndexer, loadSearchProvider, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
479
+ export { type ContentIndexer, type ContentIndexerModule, DocHeading, ExtractedContent, FlattenedRoute, type FlexSearchDocument, FlexSearchIndexer, FlexSearchProvider, McpDocsServer, McpServerConfig, McpServerPluginOptions, ProcessedDoc, type ProviderContext, type SearchOptions, type SearchProvider, type SearchProviderInitData, type SearchProviderModule, SearchResult, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsFetchTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, loadIndexer, loadSearchProvider, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
package/dist/index.js CHANGED
@@ -1,32 +1,19 @@
1
- 'use strict';
2
-
3
- var path = require('path');
4
- var fs3 = require('fs-extra');
5
- var pMap = require('p-map');
6
- var unified = require('unified');
7
- var rehypeParse = require('rehype-parse');
8
- var hastUtilSelect = require('hast-util-select');
9
- var hastUtilToString = require('hast-util-to-string');
10
- var hastUtilToHtml = require('hast-util-to-html');
11
- var rehypeRemark = require('rehype-remark');
12
- var remarkStringify = require('remark-stringify');
13
- var remarkGfm = require('remark-gfm');
14
- var FlexSearch = require('flexsearch');
15
- var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
16
- var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
17
- var webStandardStreamableHttp_js = require('@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js');
18
- var zod = require('zod');
19
-
20
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
21
-
22
- var path__default = /*#__PURE__*/_interopDefault(path);
23
- var fs3__default = /*#__PURE__*/_interopDefault(fs3);
24
- var pMap__default = /*#__PURE__*/_interopDefault(pMap);
25
- var rehypeParse__default = /*#__PURE__*/_interopDefault(rehypeParse);
26
- var rehypeRemark__default = /*#__PURE__*/_interopDefault(rehypeRemark);
27
- var remarkStringify__default = /*#__PURE__*/_interopDefault(remarkStringify);
28
- var remarkGfm__default = /*#__PURE__*/_interopDefault(remarkGfm);
29
- var FlexSearch__default = /*#__PURE__*/_interopDefault(FlexSearch);
1
+ import path from 'path';
2
+ import fs3 from 'fs-extra';
3
+ import pMap from 'p-map';
4
+ import { unified } from 'unified';
5
+ import rehypeParse from 'rehype-parse';
6
+ import { select } from 'hast-util-select';
7
+ import { toString } from 'hast-util-to-string';
8
+ import { toHtml } from 'hast-util-to-html';
9
+ import rehypeRemark from 'rehype-remark';
10
+ import remarkStringify from 'remark-stringify';
11
+ import remarkGfm from 'remark-gfm';
12
+ import FlexSearch from 'flexsearch';
13
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
14
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
15
+ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js';
16
+ import { z } from 'zod';
30
17
 
31
18
  // src/plugin/docusaurus-plugin.ts
32
19
 
@@ -65,17 +52,17 @@ function filterRoutes(routes, excludePatterns) {
65
52
  async function discoverHtmlFiles(outDir) {
66
53
  const routes = [];
67
54
  async function scanDirectory(dir) {
68
- const entries = await fs3__default.default.readdir(dir, { withFileTypes: true });
55
+ const entries = await fs3.readdir(dir, { withFileTypes: true });
69
56
  for (const entry of entries) {
70
- const fullPath = path__default.default.join(dir, entry.name);
57
+ const fullPath = path.join(dir, entry.name);
71
58
  if (entry.isDirectory()) {
72
59
  if (["assets", "img", "static"].includes(entry.name)) {
73
60
  continue;
74
61
  }
75
62
  await scanDirectory(fullPath);
76
63
  } else if (entry.name === "index.html") {
77
- const relativePath = path__default.default.relative(outDir, fullPath);
78
- let routePath = "/" + path__default.default.dirname(relativePath).replace(/\\/g, "/");
64
+ const relativePath = path.relative(outDir, fullPath);
65
+ let routePath = "/" + path.dirname(relativePath).replace(/\\/g, "/");
79
66
  if (routePath === "/.") {
80
67
  routePath = "/";
81
68
  }
@@ -101,30 +88,30 @@ async function collectRoutes(outDir, excludePatterns) {
101
88
  return Array.from(uniqueRoutes.values());
102
89
  }
103
90
  function parseHtml(html) {
104
- const processor = unified.unified().use(rehypeParse__default.default);
91
+ const processor = unified().use(rehypeParse);
105
92
  return processor.parse(html);
106
93
  }
107
94
  async function parseHtmlFile(filePath) {
108
- const html = await fs3__default.default.readFile(filePath, "utf-8");
95
+ const html = await fs3.readFile(filePath, "utf-8");
109
96
  return parseHtml(html);
110
97
  }
111
98
  function extractTitle(tree) {
112
- const h1Element = hastUtilSelect.select("h1", tree);
99
+ const h1Element = select("h1", tree);
113
100
  if (h1Element) {
114
- return hastUtilToString.toString(h1Element).trim();
101
+ return toString(h1Element).trim();
115
102
  }
116
- const titleElement = hastUtilSelect.select("title", tree);
103
+ const titleElement = select("title", tree);
117
104
  if (titleElement) {
118
- return hastUtilToString.toString(titleElement).trim();
105
+ return toString(titleElement).trim();
119
106
  }
120
107
  return "Untitled";
121
108
  }
122
109
  function extractDescription(tree) {
123
- const metaDescription = hastUtilSelect.select('meta[name="description"]', tree);
110
+ const metaDescription = select('meta[name="description"]', tree);
124
111
  if (metaDescription && metaDescription.properties?.content) {
125
112
  return String(metaDescription.properties.content);
126
113
  }
127
- const ogDescription = hastUtilSelect.select('meta[property="og:description"]', tree);
114
+ const ogDescription = select('meta[property="og:description"]', tree);
128
115
  if (ogDescription && ogDescription.properties?.content) {
129
116
  return String(ogDescription.properties.content);
130
117
  }
@@ -132,9 +119,9 @@ function extractDescription(tree) {
132
119
  }
133
120
  function findContentElement(tree, selectors) {
134
121
  for (const selector of selectors) {
135
- const element = hastUtilSelect.select(selector, tree);
122
+ const element = select(selector, tree);
136
123
  if (element) {
137
- const text = hastUtilToString.toString(element).trim();
124
+ const text = toString(element).trim();
138
125
  if (text.length > 50) {
139
126
  return element;
140
127
  }
@@ -188,7 +175,7 @@ async function extractContent(filePath, options) {
188
175
  const description = extractDescription(tree);
189
176
  let contentElement = findContentElement(tree, options.contentSelectors);
190
177
  if (!contentElement) {
191
- const body = hastUtilSelect.select("body", tree);
178
+ const body = select("body", tree);
192
179
  if (body) {
193
180
  contentElement = body;
194
181
  }
@@ -196,7 +183,7 @@ async function extractContent(filePath, options) {
196
183
  let contentHtml = "";
197
184
  if (contentElement) {
198
185
  const cleanedElement = cleanContentElement(contentElement, options.excludeSelectors);
199
- contentHtml = hastUtilToHtml.toHtml(cleanedElement);
186
+ contentHtml = toHtml(cleanedElement);
200
187
  }
201
188
  return {
202
189
  title,
@@ -209,7 +196,7 @@ async function htmlToMarkdown(html) {
209
196
  return "";
210
197
  }
211
198
  try {
212
- const processor = unified.unified().use(rehypeParse__default.default, { fragment: true }).use(rehypeRemark__default.default).use(remarkGfm__default.default).use(remarkStringify__default.default, {
199
+ const processor = unified().use(rehypeParse, { fragment: true }).use(rehypeRemark).use(remarkGfm).use(remarkStringify, {
213
200
  bullet: "-",
214
201
  fences: true
215
202
  });
@@ -311,7 +298,7 @@ function englishStemmer(word) {
311
298
  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");
312
299
  }
313
300
  function createSearchIndex() {
314
- return new FlexSearch__default.default.Document({
301
+ return new FlexSearch.Document({
315
302
  // Use 'full' tokenization for substring matching
316
303
  // This allows "auth" to match "authentication"
317
304
  tokenize: "full",
@@ -517,13 +504,13 @@ var FlexSearchProvider = class {
517
504
  return;
518
505
  }
519
506
  if (initData.docsPath && initData.indexPath) {
520
- if (await fs3__default.default.pathExists(initData.docsPath)) {
521
- this.docs = await fs3__default.default.readJson(initData.docsPath);
507
+ if (await fs3.pathExists(initData.docsPath)) {
508
+ this.docs = await fs3.readJson(initData.docsPath);
522
509
  } else {
523
510
  throw new Error(`[FlexSearch] Docs file not found: ${initData.docsPath}`);
524
511
  }
525
- if (await fs3__default.default.pathExists(initData.indexPath)) {
526
- const indexData = await fs3__default.default.readJson(initData.indexPath);
512
+ if (await fs3.pathExists(initData.indexPath)) {
513
+ const indexData = await fs3.readJson(initData.indexPath);
527
514
  this.searchIndex = await importSearchIndex(indexData);
528
515
  } else {
529
516
  throw new Error(`[FlexSearch] Search index not found: ${initData.indexPath}`);
@@ -722,7 +709,7 @@ function mcpServerPlugin(context, options) {
722
709
  excludeSelectors: resolvedOptions.excludeSelectors,
723
710
  minContentLength: resolvedOptions.minContentLength
724
711
  };
725
- const processedDocs = await pMap__default.default(
712
+ const processedDocs = await pMap(
726
713
  routes,
727
714
  async (route) => {
728
715
  return processHtmlFile(route.htmlPath, route.path, processOptions);
@@ -735,7 +722,7 @@ function mcpServerPlugin(context, options) {
735
722
  console.warn("[MCP] No valid documents to index");
736
723
  return;
737
724
  }
738
- const mcpOutputDir = path__default.default.join(outDir, resolvedOptions.outputDir);
725
+ const mcpOutputDir = path.join(outDir, resolvedOptions.outputDir);
739
726
  const providerContext = {
740
727
  baseUrl: context.siteConfig.url,
741
728
  serverName: resolvedOptions.server.name,
@@ -743,7 +730,7 @@ function mcpServerPlugin(context, options) {
743
730
  outputDir: mcpOutputDir
744
731
  };
745
732
  const indexerSpecs = resolvedOptions.indexers ?? ["flexsearch"];
746
- await fs3__default.default.ensureDir(mcpOutputDir);
733
+ await fs3.ensureDir(mcpOutputDir);
747
734
  const indexerNames = [];
748
735
  for (const indexerSpec of indexerSpecs) {
749
736
  try {
@@ -757,7 +744,7 @@ function mcpServerPlugin(context, options) {
757
744
  await indexer.indexDocuments(validDocs);
758
745
  const artifacts = await indexer.finalize();
759
746
  for (const [filename, content] of artifacts) {
760
- await fs3__default.default.writeJson(path__default.default.join(mcpOutputDir, filename), content, { spaces: 0 });
747
+ await fs3.writeJson(path.join(mcpOutputDir, filename), content, { spaces: 0 });
761
748
  }
762
749
  indexerNames.push(indexer.name);
763
750
  } catch (error) {
@@ -774,7 +761,7 @@ function mcpServerPlugin(context, options) {
774
761
  baseUrl: context.siteConfig.url,
775
762
  indexers: indexerNames
776
763
  };
777
- await fs3__default.default.writeJson(path__default.default.join(mcpOutputDir, "manifest.json"), manifest, { spaces: 2 });
764
+ await fs3.writeJson(path.join(mcpOutputDir, "manifest.json"), manifest, { spaces: 2 });
778
765
  }
779
766
  const elapsed = Date.now() - startTime;
780
767
  console.log(`[MCP] Artifacts written to ${mcpOutputDir}`);
@@ -783,8 +770,8 @@ function mcpServerPlugin(context, options) {
783
770
  };
784
771
  }
785
772
  var docsSearchInputSchema = {
786
- query: zod.z.string().min(1).describe("The search query string"),
787
- limit: zod.z.number().int().min(1).max(20).optional().default(5).describe("Maximum number of results to return (1-20, default: 5)")
773
+ query: z.string().min(1).describe("The search query string"),
774
+ limit: z.number().int().min(1).max(20).optional().default(5).describe("Maximum number of results to return (1-20, default: 5)")
788
775
  };
789
776
  var docsSearchTool = {
790
777
  name: "docs_search",
@@ -812,7 +799,7 @@ function formatSearchResults(results) {
812
799
  return lines.join("\n");
813
800
  }
814
801
  var docsFetchInputSchema = {
815
- url: zod.z.string().url().describe(
802
+ url: z.string().url().describe(
816
803
  'The full URL of the page to fetch (e.g., "https://docs.example.com/docs/getting-started")'
817
804
  )
818
805
  };
@@ -863,7 +850,7 @@ var McpDocsServer = class {
863
850
  initialized = false;
864
851
  constructor(config) {
865
852
  this.config = config;
866
- this.mcpServer = new mcp_js.McpServer(
853
+ this.mcpServer = new McpServer(
867
854
  {
868
855
  name: config.name,
869
856
  version: config.version ?? "1.0.0"
@@ -998,7 +985,7 @@ var McpDocsServer = class {
998
985
  */
999
986
  async handleHttpRequest(req, res, parsedBody) {
1000
987
  await this.initialize();
1001
- const transport = new streamableHttp_js.StreamableHTTPServerTransport({
988
+ const transport = new StreamableHTTPServerTransport({
1002
989
  sessionIdGenerator: void 0,
1003
990
  // Stateless mode - no session tracking
1004
991
  enableJsonResponse: true
@@ -1022,7 +1009,7 @@ var McpDocsServer = class {
1022
1009
  */
1023
1010
  async handleWebRequest(request) {
1024
1011
  await this.initialize();
1025
- const transport = new webStandardStreamableHttp_js.WebStandardStreamableHTTPServerTransport({
1012
+ const transport = new WebStandardStreamableHTTPServerTransport({
1026
1013
  sessionIdGenerator: void 0,
1027
1014
  // Stateless mode
1028
1015
  enableJsonResponse: true
@@ -1064,26 +1051,6 @@ var McpDocsServer = class {
1064
1051
  }
1065
1052
  };
1066
1053
 
1067
- exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
1068
- exports.FlexSearchIndexer = FlexSearchIndexer;
1069
- exports.FlexSearchProvider = FlexSearchProvider;
1070
- exports.McpDocsServer = McpDocsServer;
1071
- exports.buildSearchIndex = buildSearchIndex;
1072
- exports.collectRoutes = collectRoutes;
1073
- exports.discoverHtmlFiles = discoverHtmlFiles;
1074
- exports.docsFetchTool = docsFetchTool;
1075
- exports.docsSearchTool = docsSearchTool;
1076
- exports.exportSearchIndex = exportSearchIndex;
1077
- exports.extractContent = extractContent;
1078
- exports.extractHeadingsFromMarkdown = extractHeadingsFromMarkdown;
1079
- exports.extractSection = extractSection;
1080
- exports.htmlToMarkdown = htmlToMarkdown;
1081
- exports.importSearchIndex = importSearchIndex;
1082
- exports.loadIndexer = loadIndexer;
1083
- exports.loadSearchProvider = loadSearchProvider;
1084
- exports.mcpServerPlugin = mcpServerPlugin;
1085
- exports.parseHtml = parseHtml;
1086
- exports.parseHtmlFile = parseHtmlFile;
1087
- exports.searchIndex = searchIndex;
1054
+ export { DEFAULT_OPTIONS, FlexSearchIndexer, FlexSearchProvider, McpDocsServer, buildSearchIndex, collectRoutes, mcpServerPlugin as default, discoverHtmlFiles, docsFetchTool, docsSearchTool, exportSearchIndex, extractContent, extractHeadingsFromMarkdown, extractSection, htmlToMarkdown, importSearchIndex, loadIndexer, loadSearchProvider, mcpServerPlugin, parseHtml, parseHtmlFile, searchIndex };
1088
1055
  //# sourceMappingURL=index.js.map
1089
1056
  //# sourceMappingURL=index.js.map