MCP server exposing Hoogle search over local Haskell dependencies
Server defines 6 tools with clear names and reasonable descriptions. All tools have input schemas with typed parameters and descriptions. However, output schemas are not documented, LLMs cannot predict what fields to expect from search results or regeneration status. Error handling is minimal (generic 'No database loaded' messages). Parameter descriptions lack format constraints and validation rules. Tool names are verb-forward (Search, LookupModule, RegenerateDatabase) which is good, but descriptions could be more concise and action-oriented. No tool annotations (readOnlyHint, destructiveHint) despite clear risk profiles.
Search for all exports of a given module name. Example: 'Data.Map'
Regenerate the Hoogle database asynchronously. Returns immediately — use regeneration_status to poll progress. Requires ghcBinPath so ghc-pkg can be found. Find it with: nix-shell --run 'dirname $(which ghc-pkg)'
Check the status of an asynchronous database regeneration. Reports idle, in-progress (with elapsed time), completed, or failed.
Reload the Hoogle database from disk without regenerating. Use after running 'mcp-hoogle generate' externally via a bash command.
Search Hoogle by function name, type signature, or keyword. Returns matching functions with their types, packages, and documentation.
Search Hoogle specifically by type signature. Example: 'a -> [a]' or '[a] -> Int'
Output schemas not documented. LLMs cannot predict what fields Search, SearchType, LookupModule, or RegenerationStatus return. Formatters like formatTargets() exist but their output structure is invisible to the agent.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). RegenerateDatabase and ReloadDatabase are marked WRITE risk but lack destructiveHint annotation. Search/SearchType/LookupModule are READ_ONLY but lack readOnlyHint. Agents cannot infer safety properties.
Parameter descriptions lack format constraints. ghcBinPath says 'Path to GHC's bin directory' but does not specify: must be absolute? must exist? what if not found? reloadPath accepts 'empty string for default' but no validation guidance. LLMs will pass invalid paths.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Error handling is generic. 'No database loaded' appears in Search, SearchType, LookupModule but does not guide recovery. Should say: 'No database loaded. Call regenerate_database(ghcBinPath=...) first, or reload_database() if you have a .hoo file.'
RegenerationStatus has no input parameters but description does not clarify: does it return the status of the most recent regeneration? Is there a request ID? How does the agent know which regeneration to poll if multiple are queued?