doc_search
Search local documentation folders for keywords across markdown, text, JSON, YAML, and code files to find relevant information quickly.
Instructions
Searches all documents in a local docs/ folder (or any directory) for one or more keywords. Supports case-insensitive multi-keyword search across markdown, text, JSON, YAML, code, and other text files. Returns matching lines with surrounding context. Searchable extensions: .md, .txt, .rst, .html, .json, .yaml, .ts, .js, .py, .sh, .bat, .ps1, and more.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| docs_path | Yes | Absolute path to the docs folder to search. Windows example: C:\Users\YourName\Projects\my-repo\docs | |
| keywords | Yes | List of keywords to search for. All keywords must appear on the same line (AND logic). | |
| case_sensitive | No | Whether the search is case-sensitive. Default: false. | |
| file_extension_filter | No | Optional: only search files with this extension (e.g., '.md', '.txt'). Leave blank to search all supported file types. |
Implementation Reference
- src/tools/docSearch.ts:140-230 (handler)The handler implementation for the doc_search tool. It performs directory traversal, file filtering, and line-by-line keyword matching.
async handler(args: { docs_path: string; keywords: string[]; case_sensitive?: boolean; file_extension_filter?: string; }): Promise<string> { const { keywords, case_sensitive = false, file_extension_filter } = args; const docsPath = path.resolve(args.docs_path); if (!fs.existsSync(docsPath)) { return `ERROR: Docs path does not exist: ${docsPath}`; } if (!fs.statSync(docsPath).isDirectory()) { return `ERROR: Path is not a directory: ${docsPath}`; } if (!keywords.length || keywords.some((k) => !k.trim())) { return `ERROR: Please provide at least one non-empty keyword.`; } let files = walkDirectory(docsPath); if (file_extension_filter) { const ext = file_extension_filter.startsWith(".") ? file_extension_filter.toLowerCase() : `.${file_extension_filter.toLowerCase()}`; files = files.filter((f) => path.extname(f).toLowerCase() === ext); } if (files.length === 0) { return `No searchable files found in: ${docsPath}`; } const results: SearchResult[] = []; let totalMatches = 0; for (const file of files) { const matches = searchFileForKeywords(file, keywords, case_sensitive); if (matches.length > 0) { results.push({ file: path.relative(docsPath, file).replace(/\\/g, "/"), matchCount: matches.length, matches, }); totalMatches += matches.length; if (totalMatches >= MAX_RESULTS) break; } } if (results.length === 0) { return ( `## Doc Search Results\n` + `**Query:** \`${keywords.join(" AND ")}\` | **Directory:** ${docsPath}\n\n` + `No matches found across ${files.length} files.` ); } const sections: string[] = [ `## Doc Search Results`, `**Query:** \`${keywords.join(" AND ")}\` | **Case Sensitive:** ${case_sensitive}`, `**Directory:** ${docsPath}`, `**Files searched:** ${files.length} | **Files with matches:** ${results.length} | **Total matches:** ${totalMatches}${totalMatches >= MAX_RESULTS ? " (capped)" : ""}`, ]; for (const result of results) { sections.push(`\n### 📄 ${result.file} *(${result.matchCount} match${result.matchCount !== 1 ? "es" : ""})*`); for (const match of result.matches) { const contextLines: string[] = []; if (match.contextBefore.length > 0) { match.contextBefore.forEach((line, i) => { const lineNum = match.lineNumber - match.contextBefore.length + i; contextLines.push(` ${String(lineNum).padStart(4)} │ ${line}`); }); } contextLines.push(`▶ ${String(match.lineNumber).padStart(4)} │ ${match.line}`); if (match.contextAfter.length > 0) { match.contextAfter.forEach((line, i) => { const lineNum = match.lineNumber + i + 1; contextLines.push(` ${String(lineNum).padStart(4)} │ ${line}`); }); } sections.push(`\`\`\`\n${contextLines.join("\n")}\n\`\`\``); } } return sections.join("\n"); }, - src/tools/docSearch.ts:112-139 (schema)The JSON schema for the inputs required by the doc_search tool.
inputSchema: { type: "object", properties: { docs_path: { type: "string", description: "Absolute path to the docs folder to search. " + "Windows example: C:\\Users\\YourName\\Projects\\my-repo\\docs", }, keywords: { type: "array", items: { type: "string" }, description: "List of keywords to search for. All keywords must appear on the same line (AND logic).", }, case_sensitive: { type: "boolean", description: "Whether the search is case-sensitive. Default: false.", }, file_extension_filter: { type: "string", description: "Optional: only search files with this extension (e.g., '.md', '.txt'). " + "Leave blank to search all supported file types.", }, }, required: ["docs_path", "keywords"], }, - src/index.ts:34-34 (registration)Registration of the doc_search tool in the main index file.
docSearchTool(),