Skip to main content

Tool Surface Map

Reference / evidence, not a decision. This document maps the MCP tool surface and scores it against current tool-call best practices so removal and refactor candidates are visible in one place. It authorises nothing. Which tools exist is decided by ADR-023; consolidation of the deferred clusters by ADR-024; tool-call conformance by ADR-026. Any actual removal runs through an ADR Decision, then retirement.py per asset, then its own admission. Candidates below are discoveries.

Measured on main, 2026-09-02. Line references drift; re-verify with the command in each row before relying on one.

How the surface worksโ€‹

ConcernWhereNote
Wire registration (tools/list)src/mcp-adr-analysis-server.ts:235Calls getToolListForMCP({ mode: 'full' }), which returns the canonical MCP_TOOL_SCHEMAS array (src/tools/mcp-tool-schemas.ts) = 72 tools over the wire. src/index.ts is now a 79-line shim โ€” the tool list is no longer hardcoded there.
Catalog (metadata for search_tools)src/tools/tool-catalog.ts68 declared TOOL_CATALOG.set(...) entries (category, tokenCost, requiresAI, hasCEMCPDirective, inputSchema) + 4 backfilled from the wire by the loop at :2103 = 72 at runtime.
Dispatch + CE-MCP gatingsrc/mcp-adr-analysis-server.ts:241-304CallToolRequestSchema handler; CE-MCP directive check (shouldUseCEMCPDirective) at :266-300 short-circuits 12 directive tools before dispatchTool() at :304 (src/tools/tool-dispatch.ts:30).
CE-MCP directivessrc/tools/ce-mcp-tools.ts:1406-144712 case entries.
Lightweight listing (exists, wired in, configured full)src/tools/tool-dispatcher.ts:139-171getToolListForMCP({mode}) is the live tools/list source (#1416). It is called with mode: 'full' (all 72 full schemas); a mode: 'lightweight' path (:151-166) already exists but is unused. Not dead code โ€” a configuration choice.
search_tools meta-toolgetSearchToolsDefinition() in src/tools/mcp-tool-schemas.ts:9; executor executeSearchTools at src/tools/tool-dispatcher.ts:77Category enum at mcp-tool-schemas.ts:19-30 lists 10 categories and omits aggregator.

Best-practices scorecardโ€‹

Basis: MCP Client Best Practices, 2026-07-28 ยท Tools spec.

PracticeVerdictEvidence (reproduce)
outputSchema on tools (enables code mode / typed calling)โŒ 0 of 72rg -n "outputSchema" src โ†’ only prompt-composition.ts:232-255, an unrelated helper.
MCP annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint, title)โŒ nonerg -c "readOnlyHint|destructiveHint|idempotentHint|openWorldHint" src โ†’ 0. read_file is read-only, write_file/smart_git_push are destructive โ€” unmarked.
Progressive discovery deferred to hostโŒ reimplementedServer ships search_tools/load_prompt; spec assigns this to the host (OpenAI/Anthropic ship it).
Token budget < 1โ€“5% of contextโŒ 3โ€“12ร— over~94,571 B / ~24K tokens (ADR-023:38); 11.8% of 200K, 2.4% of 1M.
Uses lightweight listing when over budgetโŒ configured to fullgetToolListForMCP() (tool-dispatcher.ts:139) is the live wire source and ships all 72 full schemas; its mode: 'lightweight' path (:151-166) exists but is not selected. One-line config, not dead code.
Catalog integrity (every wire tool discoverable)โš ๏ธ backfilled, not classifiedget_gaps, search_codebase, set_project_path, update_knowledge have no explicit catalog entry; the backfill loop (tool-catalog.ts:2103) folds them in with default utility metadata, so search_tools does find them โ€” but mis-categorised and under-described (get_gaps duplicates analyze_gaps). search_tools enum still drops aggregator (10 tools unfilterable).
Tool count within selection-accuracy bandโŒ 72 (band is ~30โ€“50)Anthropic: tool-selection accuracy degrades past ~30โ€“50 tools; under ~10 the full list is fine; above, use host tool search. ADR-023's 54 is still at the top of the band; ADR-024 consolidation gets inside it.
Fewer, single-domain toolsโš ๏ธ 72 tools, 11 categoriesSpec: "five well-described tools beat fifty." ADR-023 cuts to 54 supported.

Per-tool inventoryโ€‹

72 over the wire (68 explicitly declared in TOOL_CATALOG + 4 backfilled from the wire at load, so 72 catalogued at runtime). outputSchema = false and annotations = none for every tool โ€” omitted from the table as uniform. Cand. = candidate disposition (discovery): K keep ยท Rm remove (host-native / dead) ยท Rf refactor (needs directive/schema/annotations/consolidation) ยท D deferred to ADR-024 ยท Agg aggregator (ADR-023 "separate commercial question").

analysis (4) โ€” tool-catalog.ts:132-233โ€‹

toolwhat it doestokensAICE-MCPCand.
analyze_project_ecosystemComprehensive project + architectural analysis8000-15000โœ“โœ“K/Rf
get_architectural_contextRetrieve architectural context + knowledge graph2000-5000โ€“โ€“K
analyze_environmentAnalyse deployment environment config2000-4000โœ“โœ“K
smart_scoreCode-quality / architecture scores3000-6000โœ“โœ“K

adr (12) โ€” tool-catalog.ts:234-451, 758-767โ€‹

toolwhat it doestokensAICE-MCPCand.
suggest_adrsADR suggestions from analysis3000-6000โœ“โœ“K
generate_adr_from_decisionADR from a decision2000-4000โœ“โ€“Rf
generate_adrs_from_prdADRs from a PRD4000-8000โœ“โœ“K
discover_existing_adrsFind + index ADRs500-1500โ€“โ€“K
validate_adrValidate one ADR500-1500โ€“โ€“K
validate_all_adrsValidate all ADRs1000-3000โ€“โ€“K
analyze_adr_timelineADR evolution over time1500-3000โœ“โ€“Rf
compare_adr_progressCompare implementation progress2000-4000โœ“โ€“Rf
review_existing_adrsReview existing ADRs2000-4000โœ“โ€“Rf
generate_adr_bootstrapBootstrap ADR infra500-1500โ€“โ€“K
interactive_adr_planningInteractive planning session3000-6000โœ“โœ“K
generate_adr_todoTODO.md from ADRs (TDD pairing)800-3000โ€“โ€“K

content-security (6) โ€” tool-catalog.ts:469-583โ€‹

toolwhat it doestokensAICE-MCPCand.
analyze_content_securityScan content for security concerns1500-3000โœ“โ€“Rf
generate_content_maskingGenerate masking rules1000-2500โœ“โ€“Rf
apply_basic_content_maskingApply basic masking200-500โ€“โ€“K
configure_custom_patternsConfigure masking patterns200-500โ€“โ€“K
validate_content_maskingValidate masking300-800โ€“โ€“K
configure_output_maskingConfigure output masking200-400โ€“โ€“K

research (4) โ€” tool-catalog.ts:598-671โ€‹

toolwhat it doestokensAICE-MCPCand.
perform_researchResearch a topic4000-10000โœ“โœ“K/Rf
incorporate_researchIncorporate findings2000-4000โœ“โ€“D
generate_research_questionsGenerate questions1500-3000โœ“โ€“D
create_research_templateCreate template500-1000โ€“โ€“D

deployment (7) โ€” tool-catalog.ts:687-878โ€‹

toolwhat it doestokensAICE-MCPCand.
deployment_readinessCheck deployment readiness2000-4000โœ“โœ“K
release_trackingReleases mapped to ADR decisions2000-6000โ€“โ€“K
smart_git_pushIntelligent git push (destructive)1000-2500โ€“โ€“K/Rf
bootstrap_validation_loopGuided validation loop3000-6000โœ“โ€“Rf
analyze_deployment_progressAnalyse deployment progress1500-3000โ€“โ€“K
generate_deployment_guidanceGenerate guidance2000-4000โœ“โ€“Rf
troubleshoot_guided_workflowGuided troubleshooting3000-7000โœ“โœ“K

memory (6) โ€” tool-catalog.ts:895-1003 โ€” cluster deferred to ADR-024โ€‹

toolwhat it doestokensAICE-MCPCand.
memory_loadingLoad memory context500-2000โ€“โ€“D
expand_memoryExpand memory300-800โ€“โ€“D
query_conversation_historyQuery history500-1500โ€“โ€“D
get_conversation_snapshotConversation snapshot300-800โ€“โ€“D
get_memory_statsMemory statistics200-400โ€“โ€“D
expand_analysis_sectionExpand analysis section1500-3000โœ“โ€“D

file-system (5) โ€” tool-catalog.ts:1019-1110 โ€” host-native, ADR-023 REMOVE โ€” deprecation landed (#1639)โ€‹

All five now carry deprecated: true in the catalog and a [DEPRECATED host-native, ADR-023] marker on their wire descriptions. Next step is per-asset retirement.py, not another marker.

toolwhat it doestokensAICE-MCPCand.
read_fileRead file (host provides)100-5000โ€“โ€“Rm
write_fileWrite file (host provides, destructive)100-1000โ€“โ€“Rm
read_directoryRead directory (host provides)100-1000โ€“โ€“Rm
list_directoryList directory (host provides)100-500โ€“โ€“Rm
list_rootsList roots (MCP roots capability)50-200โ€“โ€“Rm

rules (3) โ€” tool-catalog.ts:1122-1177โ€‹

toolwhat it doestokensAICE-MCPCand.
generate_rulesGenerate validation rules3000-6000โœ“โœ“K
validate_rulesValidate rules vs codebase1500-3000โ€“โ€“K
create_rule_setCreate rule set500-1000โ€“โ€“K

workflow (5) โ€” tool-catalog.ts:1190-1298 โ€” get_*_guidance deferred to ADR-024โ€‹

toolwhat it doestokensAICE-MCPCand.
get_workflow_guidanceWorkflow guidance1500-3000โœ“โ€“D
get_development_guidanceDevelopment guidance1500-3000โœ“โ€“D
mcp_planningMCP planning assistant3000-6000โœ“โœ“K
tool_chain_orchestratorOrchestrate tool chains2000-5000โœ“โœ“K
request_action_confirmationRequest confirmation100-300โ€“โ€“K

utility (6) โ€” tool-catalog.ts:1299-1387, search_tools ~1823โ€‹

toolwhat it doestokensAICE-MCPCand.
manage_cacheCache operations100-500โ€“โ€“K
check_ai_execution_statusCheck AI execution mode100-300โ€“โ€“Rm (dies with AI layer)
get_server_contextServer context200-500โ€“โ€“K
get_current_datetimeCurrent date/time (host provides)50-100โ€“โ€“Rm (deprecated #1639)
load_promptOn-demand prompt (CE-MCP meta)100-500โ€“โ€“Rm (host discovery; deprecated #1639)
search_toolsTool search meta-tool (host provides)100-300โ€“โ€“Rm (host discovery; deprecated #1639)

aggregator (10) โ€” tool-catalog.ts:1424-1774 โ€” ADR-023 "separate commercial question"โ€‹

toolwhat it doestokensAICE-MCPCand.
sync_to_aggregatorSync ADRs to Aggregator platform1000-3000โ€“โ€“Agg
get_adr_contextADR context from aggregator500-1500โ€“โ€“Agg
get_staleness_reportADR staleness report300-800โ€“โ€“Agg
get_adr_templatesADR templates300-1000โ€“โ€“Agg
get_adr_diagramsMermaid diagrams (Pro+)500-1500โ€“โ€“Agg
validate_adr_complianceCompliance check (Pro+)1000-2500โ€“โ€“Agg
get_knowledge_graphKnowledge graph (Team)1000-3000โ€“โ€“Agg
update_implementation_statusUpdate impl status (Pro+)300-800โ€“โ€“Agg
get_adr_prioritiesADR priorities for roadmap500-1500โ€“โ€“Agg
analyze_gapsGaps between ADRs and codebase800-3000โ€“โ€“Agg

BACKFILLED (4) โ€” no explicit catalog entry; folded in with default utility metadataโ€‹

Dispatched from src/tools/tool-dispatch.ts. Each is in the wire (MCP_TOOL_SCHEMAS) but has no TOOL_CATALOG.set(...) of its own, so the backfill loop (tool-catalog.ts:2103) classifies it as utility with placeholder tokenCost and name-split keywords. search_tools can surface them, but mis-categorised and under-described โ€” the fix is a proper catalog entry per tool.

tooldispatchCand.
search_codebasetool-dispatch.ts:142Rm/Rf (host Grep/Glob overlap)
update_knowledgetool-dispatch.ts:228Rf (catalogue or remove)
set_project_pathtool-dispatch.ts:251Rf (catalogue or remove)
get_gapstool-dispatch.ts:324Rm/Rf โ€” overlaps catalogued analyze_gaps

Candidate summary (discoveries โ€” not decisions)โ€‹

GroupCountRoute
Remove โ€” host-native (ADR-023)8 exposed (read_file, write_file, read_directory, list_directory, list_roots, get_current_datetime, search_tools, load_prompt) + 3 already absent (llm_*)Deprecation DONE (#1639, merged, closed #1638): all 8 carry deprecated: true + [DEPRECATED host-native, ADR-023] wire markers. Next: per-asset retirement.py โ†’ Cleanup milestone.
Dies with the AI layer1 (check_ai_execution_status)Goes with ADR-021 migration Batch 7 / retirement
Deferred cluster15 (memory 6, workflow 5, research 4)ADR-024, pending usage data
Aggregator10ADR-023 "separate commercial question"
Backfilled, not classified4 (esp. get_gaps vs analyze_gaps overlap)ADR-026 / #1416: give each a proper TOOL_CATALOG entry so it is categorised, not defaulted to utility
Refactor (quality)all survivorsADR-026: add outputSchema + annotations, defer discovery, fix the aggregator enum, flip the wire listing from mode: 'full' to mode: 'lightweight'

Sourcesโ€‹