search_docs
Find documentation by searching titles and content with keyword matching. Returns relevant documents with scores for precise information retrieval.
Instructions
Search documentation using keyword matching (semantic search ready)
Args:
query: Search query string
max_results: Maximum number of results to return
search_content: Whether to search in document content
search_titles: Whether to search in document titles
Returns:
List of matching documents with relevance scores
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No | ||
| search_content | No | ||
| search_titles | No |
Implementation Reference
- src/main.py:204-267 (handler)The primary handler for the 'search_docs' MCP tool. This function is decorated with @mcp.tool() and implements keyword-based search across all markdown documentation files in the docs directory. It searches titles and content, computes relevance scores, extracts snippets around matches, and returns the top results sorted by score.@mcp.tool() def search_docs( query: str, max_results: int = 5, search_content: bool = True, search_titles: bool = True, ) -> List[Dict[str, Any]]: """ Search documentation using keyword matching (semantic search ready) Args: query: Search query string max_results: Maximum number of results to return search_content: Whether to search in document content search_titles: Whether to search in document titles Returns: List of matching documents with relevance scores """ query_lower = query.lower() results = [] for file_path in DOCS_DIR.rglob('*.md'): if not file_path.is_file(): continue score = 0 metadata = get_doc_metadata(file_path) # Title matching if search_titles and query_lower in metadata['title'].lower(): score += 10 # Content matching if search_content: try: content = file_path.read_text().lower() # Count occurrences occurrences = content.count(query_lower) if occurrences > 0: score += min(occurrences, 5) # Cap at 5 points for content # Find snippet around first occurrence idx = content.find(query_lower) start = max(0, idx - 100) end = min(len(content), idx + 100) snippet = content[start:end] if start > 0: snippet = '...' + snippet if end < len(content): snippet = snippet + '...' metadata['snippet'] = snippet except (OSError, UnicodeDecodeError): pass if score > 0: metadata['relevance_score'] = score results.append(metadata) # Sort by relevance score results.sort(key=lambda x: x['relevance_score'], reverse=True) return results[:max_results]
- src/main.py:125-151 (helper)Helper function 'get_doc_metadata' used by search_docs to retrieve metadata (title, path, modified time, size, hash) for each documentation file, including extracting title from the first heading.def get_doc_metadata(file_path: Path) -> Dict[str, Any]: """Extract metadata from markdown files""" if file_path in METADATA_CACHE: return METADATA_CACHE[file_path] metadata = { 'title': file_path.stem.replace('-', ' ').title(), 'path': str(file_path.relative_to(DOCS_DIR)), 'modified': datetime.fromtimestamp(file_path.stat().st_mtime).isoformat(), 'size': file_path.stat().st_size, 'hash': hashlib.md5(file_path.read_bytes()).hexdigest(), } # Try to extract title from first # heading try: content = file_path.read_text() lines = content.split('\n') for line in lines[:10]: # Check first 10 lines if line.startswith('# '): metadata['title'] = line[2:].strip() break except (OSError, UnicodeDecodeError): pass METADATA_CACHE[file_path] = metadata return metadata
- src/main.py:204-204 (registration)The @mcp.tool() decorator on search_docs registers it as an available MCP tool.@mcp.tool()