ADR-014: CE-MCP (Code Execution with MCP) Architecture
Statusโ
Accepted
Dateโ
2025-12-09
Decision Makersโ
- Architecture Team
- AI Integration Team
Contextโ
The MCP ADR Analysis Server has evolved into a comprehensive platform with 82 tools and 6,145 lines of prompt definitions. Analysis of the current implementation reveals significant token inefficiencies:
Both figures are as-measured in 2025-12 and are left as written. On 2026-08-27 the server exposes 75 tools and
src/prompts/is 6,498 lines. An ADR records what was true when the decision was taken; rewriting its Context to today's numbers would make the reasoning unfalsifiable. See Corrections.The analysis this cited โ a CE-MCP refactoring assessment written to a temp path โ no longer exists and never was in the repository. Nothing can reconstruct it, so the citation is removed rather than left pointing into a void (#1463). The path itself is not repeated here: a dead reference quoted in a note is still a dead reference to a checker.
| Metric | Current State | Impact |
|---|---|---|
| Tools loaded per ListTools | 82 complete definitions | ~15K tokens per call |
| Prompt code loaded | 6,145 lines | ~28K tokens in memory |
| Per-analysis overhead | 9K-12K tokens | Context assembly before LLM |
| AI call points | 121+ instances | Sequential dependencies |
Root Causes of Inefficiencyโ
-
Monolithic Tool Loading (the
ListToolsRequestSchemahandler insrc/index.ts): all tools with fullinputSchemareturned on every ListTools call -
Context Over-Assembly (
analyzeProjectEcosystem, viagenerateArchitecturalKnowledgeandexecuteWithReflexion): sequential context building (knowledge โ reflexion โ base โ environment) assembles 9,000+ tokens BEFORE any LLM call -
Intermediate Result Round-Trips: Pattern of LLM call โ embed result in context โ LLM call causes token multiplication (3,500 optimal โ 10,500 actual)
-
Eager Prompt Loading: All 10 prompt files imported when any tool uses prompts, only 10-15% utilized
Protocol Evolution Contextโ
- November 2024: MCP launched by Anthropic (direct tool-calling model)
- 2025: CE-MCP paradigm introduced as recommended best practice
- Key Shift: LLM role changes from step-by-step planner to holistic code generator
Decisionโ
We will adopt the CE-MCP (Code Execution with MCP) architecture to address token inefficiencies through:
1. Progressive Tool Discoveryโ
Replace monolithic tool loading with on-demand discovery:
Current: ListTools โ 82 tools (15K tokens)
CE-MCP: ListTools โ 20 meta-tools (5K tokens) + search_tools() function
Implementation approach:
- Expose tools via file-based directory structure (
./servers/{category}/{tool}/action.ts) - Return tool metadata catalog instead of full definitions
- LLM requests specific tools on-demand via
search_tools(category, query)
2. In-Sandbox Context Assemblyโ
Shift context composition from tools to sandbox execution:
Current:
Tool assembles context โ Tool calls LLM โ LLM returns result โ Tool embeds in new context
CE-MCP:
Tool returns composition directive โ LLM orchestrates sandbox โ Sandbox returns final result
Tools return composition directives:
{
"compose": {
"sections": [
{ "source": "knowledge_generation", "key": "knowledge" },
{ "source": "file_analysis", "key": "files" },
{ "source": "environment_analysis", "key": "environment" }
],
"template": "ecosystem_analysis_v2"
}
}
3. Lazy Prompt Loadingโ
Implement prompt registry with on-demand loading:
Current: import * from './prompts/' โ 28K tokens loaded
CE-MCP: Prompt catalog registered โ load_prompt('adr_suggestion') โ 500 tokens loaded
Prompt service architecture:
- Register prompt catalog with metadata (line count, category, dependencies)
- LLM requests specific prompts via
load_prompt(name, section) - Cache loaded prompts for session duration
4. Sandbox Data Compositionโ
Eliminate recursive tool calls by keeping intermediate data in sandbox:
Current:
analyzeProjectEcosystem()
โ calls analyzeEnvironment() [tool call]
โ embeds result in prompt [context bloat]
โ sends to LLM
CE-MCP:
analyzeProjectEcosystem()
โ returns sandbox operations
โ LLM executes in sandbox
โ intermediate results stay in sandbox memory
โ only final summary returns to context
5. Stateful Tool Chainsโ
Replace sequential LLM calls with state machine composition:
Current (rule generation):
AI Call 1: templates โ AI Call 2: validation โ AI Call 3: refinement
CE-MCP:
Return state machine definition
LLM executes transitions in sandbox
State passed through sandbox memory, not context
Implementation Prioritiesโ
| Priority | Target | Current | After | Savings | Effort |
|---|---|---|---|---|---|
| P1 | analyzeProjectEcosystem | 12K tokens | 4K tokens | 67% | 3-4 hours |
| P2 | Prompt service | 28K loaded | 1K on-demand | 96% | 6-8 hours |
| P3 | Dynamic tool discovery | 15K per call | 5K per call | 67% | 4-5 hours |
| P4 | Sandbox composition | 8K overhead | 2K overhead | 75% | 5-6 hours |
Specific Code Locations for Refactoringโ
High Priorityโ
-
analyzeProjectEcosystem main loop
- Symbol:
McpAdrAnalysisServer.analyzeProjectEcosystem(src/index.ts) - Issue: Sequential context assembly
- Fix: Return composition directives
- Symbol:
-
Prompt module organization
- Files:
src/prompts/*.ts - Issue: Eager loading of the whole prompt tree
- Fix: Lazy-loading prompt registry
- Files:
-
Tool list in ListTools handler
- Symbol: the
ListToolsRequestSchemahandler (src/index.ts) - Issue: every tool returned complete
- Fix: Return metadata + dynamic discovery
- Symbol: the
-
Tool invocation switch statement
- Symbol: the
CallToolRequestSchemahandler'sswitch (name)(src/index.ts) - Issue: one static case arm per tool
- Fix: Dynamic tool dispatcher
- Symbol: the
Medium Priorityโ
- Environment analysis recursion (
McpAdrAnalysisServer.analyzeEnvironment) - Knowledge context assembly (
generateArchitecturalKnowledge, loaded dynamically) - Rule generation tool chain (
src/tools/rule-generation-tool.ts) - ADR suggestion enhancements (
suggestAdrsinsrc/tools/adr-suggestion-tool.ts)
Correctionsโ
2026-08-27 (#1463) โ every citation in this ADR was dead.
Five src/index.ts line ranges were written when the file was roughly 3,000 lines. It is
9,787 today, and all five now point at unrelated code:
| cited | what is actually there now |
|---|---|
:225-3170 | a comment continuation |
:3209-3409 | a closing brace |
:4383-4830 | a mimeType literal |
:4489-4519 | const { uri } = request.params |
:4556-4577 | a comment continuation |
All five are now symbol references, deliberately. #1416 removes roughly 4,000 lines
from src/index.ts; any line number written today would be wrong again within one PR, and
re-anchoring twice is the mistake this correction exists to stop.
The source-of-truth analysis was written to a temp path, was never in the repository, and
cannot be recovered. Cited twice; removed both times, and the path is not reproduced even
in this note โ check-adr-drift.sh scans for it, and correctly does not care why an ADR
names a file that does not exist. Same disposition as ADR-016 in #1415: an acknowledged gap
beats an invented record.
The 82 tools and 6,145 lines figures in Context are left as written. They were true
when this decision was taken; today the numbers are 75 and 6,498. An ADR that silently
updates its own evidence to match the present cannot be checked against anything.
Consequencesโ
Positiveโ
- 60-70% token reduction in average tool execution cost
- Faster response times through fewer LLM roundtrips
- Lower API costs aligned with usage patterns
- Better composability with LLM-orchestrated tool chains
- Improved maintainability without context embedding logic
- Alignment with Anthropic's recommended MCP best practices
Negativeโ
- Significant refactoring effort (estimated 20-25 hours total)
- Breaking changes to tool invocation patterns
- Learning curve for new sandbox composition model
- Testing complexity for state machine tool chains
- Migration period where both patterns may coexist
Risksโ
- Sandbox security requires careful process isolation
- State machine complexity may introduce debugging challenges
- Backward compatibility with existing clients during transition
Compatibility with Existing ADRsโ
| ADR | Relationship | Notes |
|---|---|---|
| ADR-001 | Evolves | SSE/JSON-RPC remains transport; MCP's role shifts to RPC interface for code-executing agents |
| ADR-002 | Evolves | LLM role shifts from step-by-step planner to holistic code generator |
| ADR-003 | Compatible | JSON storage, knowledge graph supports sandbox state management |
| ADR-010 | Aligns | DAG executor already implements CE-MCP concepts (deterministic orchestration) |
| ADR-012 | Aligns | File-based YAML patterns match CE-MCP progressive discovery model |
Related ADRsโ
- ADR-001: MCP Protocol Implementation Strategy (evolved by this ADR)
- ADR-002: AI Integration and Advanced Prompting Strategy (evolved by this ADR)
- ADR-010: Bootstrap Deployment Architecture (aligns with CE-MCP execution model)
- ADR-012: Validated Patterns Framework (aligns with progressive discovery)
Referencesโ
CE-MCP Refactoring Assessmentโ gone. Written to a temp path, never committed, unrecoverable. Removed 2026-08-27 (#1463).- Anthropic MCP Documentation: Protocol evolution and best practices
- Token optimization research: 2025 CE-MCP paradigm studies
- Migration guide: CE-MCP Migration Playbook