build_index
Generate a search index for your documents, enabling quick content retrieval. Optionally force a full rebuild.
Instructions
Build search index for docs
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| force | No | Whether to force rebuild index |
Implementation Reference
- src/index.ts:574-583 (handler)The tool handler for 'build_index' in the CallToolRequestSchema switch statement. It calls searchEngine.buildIndex(docDir) and returns a response with the count of documents indexed.
case "build_index": { const force = Boolean(request.params.arguments?.force); await searchEngine.buildIndex(docDir); return { content: [{ type: "text", text: `Index built with ${Object.keys(searchEngine['docStore']).length} documents` }] }; } - src/index.ts:448-459 (schema)The input schema definition for the 'build_index' tool, registered in ListToolsRequestSchema. Defines an optional 'force' property of type boolean.
{ name: "build_index", description: "Build search index for docs", inputSchema: { type: "object", properties: { force: { type: "boolean", description: "Whether to force rebuild index" } } } - src/index.ts:404-531 (registration)The duplicate registration of 'build_index' (lines 489-501) in the ListToolsRequestSchema handler, alongside all other tool registrations.
server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: "enable_doc", description: "Enable crawling for a specific doc", inputSchema: { type: "object", properties: { name: { type: "string", description: "Name of the doc to enable" } }, required: ["name"] } }, { name: "disable_doc", description: "Disable crawling for a specific doc", inputSchema: { type: "object", properties: { name: { type: "string", description: "Name of the doc to disable" } }, required: ["name"] } }, { name: "crawl_docs", description: "Start crawling enabled docs", inputSchema: { type: "object", properties: { force: { type: "boolean", description: "Whether to force re-crawl all docs, ignoring previous crawl records" } } } }, { name: "build_index", description: "Build search index for docs", inputSchema: { type: "object", properties: { force: { type: "boolean", description: "Whether to force rebuild index" } } } }, { name: "search_docs", description: "Search documentation", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query" }, max_results: { type: "number", description: "Maximum number of results", default: 3 }, doc_name: { type: "string", description: "Filter by document category" }, offset: { type: "number", description: "Number of results to skip", default: 0 } }, required: ["query"] } }, { name: "build_index", description: "Build search index for docs", inputSchema: { type: "object", properties: { force: { type: "boolean", description: "Whether to force rebuild index" } } } }, { name: "list_enabled_docs", description: "List all enabled docs with their cache status", inputSchema: { type: "object", properties: { verbose: { type: "boolean", description: "Whether to show detailed information", default: false } } } }, { name: "list_all_docs", description: "List all available docs including disabled ones", inputSchema: { type: "object", properties: { verbose: { type: "boolean", description: "Whether to show detailed information", default: false } } } } ] }; - src/search.ts:32-84 (helper)The actual implementation of the buildIndex method on the SearchEngine class. Collects markdown docs from the docs directory, builds a lunr search index, stores documents, and saves the index to a JSON file.
async buildIndex(docsDir: string) { const docs = await this.collectDocs(docsDir); this.index = lunr(function() { this.ref('path'); this.field('title'); this.field('content'); docs.forEach(doc => { this.add(doc); }); }); // Store documents separately docs.forEach(doc => { this.docStore[doc.path] = doc; }); await this.saveIndex(); } private async collectDocs(docsDir: string): Promise<DocEntry[]> { const docs: DocEntry[] = []; const docCategories = await fs.readdir(docsDir); for (const category of docCategories) { const categoryPath = path.join(docsDir, category); if ((await fs.stat(categoryPath)).isDirectory()) { const files = await fs.readdir(categoryPath); for (const file of files) { if (file.endsWith('.md')) { const filePath = path.join(categoryPath, file); const content = await fs.readFile(filePath, 'utf-8'); docs.push({ path: filePath, title: `${category}/${path.basename(file, '.md')}`, content }); } } } } return docs; } private async saveIndex() { await fs.writeJson(this.indexPath, { version: new Date().toISOString(), index: this.index.toJSON(), docStore: this.docStore }); }