Semantic code search MCP server using Qdrant and OpenAI-compatible embeddings
mcp-codesearch demonstrates solid fundamentals with 12 clearly-named tools using consistent verb_noun conventions (list_*, delete_*, search_*, find_*, code_*, repair_*, etc.). All tools have descriptions present. However, significant gaps exist: (1) Parameter descriptions are minimal or missing for several tools, e.g., cleanup_orphans has NO input schema visible despite being a destructive tool; (2) Output schemas are entirely undocumented, the code shows tools returning results but never specifies what fields/structure agents should expect; (3) Error handling is not documented in any tool description; (4) Some parameter descriptions lack actionable constraints (e.g., 'collection' in delete_collection is just 'Collection name to delete' with no guidance on valid formats, length, or recovery if wrong). The naming is generally strong ('code_search', 'find_references', 'search_changed' are all clear and action-oriented), and tool composition appears reasonable (search vs. index vs. delete are separate). Risk annotations (READ_ONLY, DESTRUCTIVE, WRITE) are present in metadata but not reflected in schema-level destructiveHint/idempotentHint tool annotations. Descriptions are functional but brief (most 40-80 chars), lacking the 50-200 char optimized range that helps LLMs reason about tool selection.
Remove orphaned collections (collections without corresponding directories)
Search indexed codebases semantically
Delete an indexed codebase collection
Find all usages of a symbol
Find code similar to a snippet
Force complete re-indexing of a codebase
Check indexing status for a codebase
cleanup_orphans has NO visible input schema despite being a DESTRUCTIVE operation. The tool definition shows no parameters, yet destructive tools absolutely require confirmation patterns or at minimum clear warnings.
Output schemas are completely undocumented across all 12 tools. The source shows the tools exist and return results (e.g., indexing_service.py shows complex PointStruct, ChangeSet, and vocabulary structures), but tool descriptions never specify what fields the LLM should expect. This forces agents to guess field names and invites chaining errors.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 55 | <=2025-11-25 | v2 |
List indexed codebases (collections)
Preview what would be indexed without actually indexing
Audit or repair codesearch's global sparse vocabulary
Search in recently changed files (git-aware)
Search across multiple codebases
Parameter descriptions lack actionable constraints. E.g., 'collection' in delete_collection is described as just 'Collection name to delete', no guidance on valid format, length, or what happens if the name is invalid. 'Query' in code_search has no length limit, language, or syntax guidance. Parameters should follow the '(type, constraint, example)' pattern.
Destructive tools (delete_collection, cleanup_orphans, force_reindex with full=true) are not protected by confirmation patterns or dry-run options. Agents can invoke irreversible operations without a safety gate. Risk metadata exists in the server code but is not surfaced to the LLM via tool annotations.
No error recovery guidance in any tool description. Tools that could fail (e.g., index_status on a non-existent path, code_search with no matches) do not tell the LLM what to do next. Should include 'If path not found, try ...' or 'If no results, consider ...'. Agents need actionable error hints.
Tool descriptions are uniformly brief (40-80 chars), falling short of the 50-200 char optimized range. Many lack context about WHEN to use the tool vs. alternatives. E.g., 'Search indexed codebases semantically' (code_search) vs. 'Find code similar to a snippet' (find_similar), the distinction is not explained. Agents cannot reason about which to choose.
Risk annotations (READ_ONLY, DESTRUCTIVE, WRITE) are present in server metadata but NOT exposed via schema-level tool annotations (destructiveHint, readOnlyHint, idempotentHint). Modern MCP 2.0 spec supports these; they should be added to tool definitions to let clients and LLMs make safer decisions.
Parameter 'since' in search_changed expects a 'Git revision' but provides no format guidance. Is it a branch name, tag, commit SHA, or date? This ambiguity forces the LLM to guess or fail. Should be: 'Git revision in any format recognized by git (SHA, branch, tag, date string YYYY-MM-DD).'