unch is a semantic code search MCP server with 7 tools covering repository indexing, code search, and remote CI binding. Tool definitions are present with explicit schemas and descriptions. Naming follows verb_noun convention (workspace_status, search_code, index_repository, etc.). Descriptions are substantial and explain WHEN to use each tool. However, several parameters lack descriptions (particularly in index_repository and remote_* tools), and output schemas are NOT documented, a critical gap for LLM reasoning. Error handling guidance is absent. Security considerations (path traversal, command injection) are not evident in the visible code. The 'directory' parameter appears in all tools but its handling and validation are not visible. Composition is reasonable, tools chain logically (workspace_status → search_code or index_repository → remote_sync_index). Parameters have enums and bounds where appropriate (search_code.mode, search_code.limit with min/max). However, tool definitions are inferred from the toolDefinitions() function structure rather than a documented type system, which slightly reduces confidence.
Bind this workspace manifest to a GitHub repository or unch remote-index workflow, enabling later remote_sync_index calls.
Create the default GitHub Actions workflow that builds and publishes a remote unch index. Use this when the user asks to set up CI-backed indexing.
Build or refresh the local index for this workspace. Call when workspace_status shows no index, search_code reports no active snapshot, files changed and fresh search is needed, or the user asks to rebuild. Avoid repeated rebuilds during normal exploration.
Download and activate a published unch index artifact for a specific commit without binding the workspace to ongoing remote sync.
Refresh the local index from a previously bound remote GitHub Actions workflow. Call this before local reindexing when workspace_status shows a remote_ci binding.
Search indexed code symbols before opening many files. Use concise natural-language queries for concepts, exact names with lexical mode, and details=true when signatures/docs/body snippets would help choose files to inspect.
NO OUTPUT SCHEMAS DOCUMENTED. All 7 tools lack documented return types. Callers and LLMs cannot know what fields to expect (e.g., does search_code return 'results' or 'matches'? does workspace_status return 'repo_root' or 'repository_root'?). This forces LLMs to guess field names, breaks downstream tool chaining, and causes extraction errors.
Parameter 'target' in bind_remote_ci, remote_sync_index, remote_download_index accepts 'GitHub repo URL or workflow URL' but is NOT formally constrained with an enum or regex. Description says 'such as https://github.com/owner/repo', example values in descriptions are anti-pattern; LLMs reuse examples literally. Should use a regex pattern or enum examples.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 69 | 2025-06-18+ | v2 |
Call this first. Returns the current repository root, .semsearch state directory, selected provider/model, manifest data, and whether a local index is already present.
Error handling guidance is absent. No tool description tells the LLM what to do on failure: 'If indexing fails, check excludes and gitignore' or 'If remote sync fails, call bind_remote_ci first.' This matches the feature flags (errorReporting=true, but no actionable error messages in definitions).
Parameter 'directory' appears in ALL 7 tools with identical description, but its handling and validation are not visible. Is it required or optional? What happens if it is invalid or missing? Does the server assume CWD? This parameter is critical to every tool but under-specified.
'comment_prefix' and 'context_prefix' in index_repository are marked 'Legacy fallback' with defaults, suggesting deprecation. Presence of deprecated parameters creates ambiguity for LLMs: should they pass these? When? Deprecation policy is not documented.