Skip to main content

CE-MCP Migration Playbook

This guide documents the process for migrating tools from legacy OpenRouter-based execution to CE-MCP (Claude-Enriched Model Context Protocol) directive-based architecture.

Overviewโ€‹

CE-MCP migration converts tools from direct AI execution to orchestration directive returns, achieving:

  • 60-70% token reduction across tool calls
  • Elimination of intermediate LLM calls
  • Improved composability with host LLM
  • Standardized sandbox operations

Migration Patternโ€‹

Before: Legacy Toolโ€‹

// Legacy: Direct AI execution
async function analyzeProjectLegacy(args: AnalyzeArgs): Promise<ToolResult> {
// 1. Eager context assembly (~9K tokens)
const knowledge = await generateArchitecturalKnowledge();
const memories = await retrieveRelevantMemories();
const structure = await analyzeProjectStructure();
const environment = await analyzeEnvironment();

// 2. Direct OpenRouter call
const result = await aiExecutor.execute({
prompt: buildAnalysisPrompt(knowledge, memories, structure, environment),
// Total: ~12K tokens per call
});

return { content: [{ type: 'text', text: result }] };
}

After: CE-MCP Directiveโ€‹

// CE-MCP: Return orchestration directive
function createAnalyzeProjectDirective(args: AnalyzeArgs): OrchestrationDirective {
return {
type: 'orchestration_directive',
version: '1.0',
tool: 'analyze_project',
description: 'Comprehensive project analysis',
sandbox_operations: [
{ op: 'analyzeFiles', args: { patterns: ['**/*.ts'] }, store: 'files' },
{ op: 'scanEnvironment', store: 'environment' },
{ op: 'loadKnowledge', args: { domain: 'architecture' }, store: 'knowledge' },
{ op: 'loadPrompt', args: { name: 'analysis' }, store: 'prompt' },
{
op: 'composeResult',
inputs: ['files', 'environment', 'knowledge', 'prompt'],
return: true,
},
],
metadata: {
estimated_tokens: 4000, // Down from ~12K
cacheable: true,
},
};
}

Step-by-Step Migration Processโ€‹

Step 1: Identify Tool Complexityโ€‹

Categorize your tool:

CategoryCharacteristicsDirective Type
SimpleSingle operation, no stateOrchestrationDirective
Medium2-3 sequential operationsOrchestrationDirective
ComplexMulti-step with branchingStateMachineDirective

Step 2: Map Operations to Sandbox Operationsโ€‹

Available sandbox operations:

type SandboxOperationType =
| 'loadKnowledge' // Load domain knowledge
| 'loadPrompt' // Lazy load prompts
| 'analyzeFiles' // Scan project files
| 'scanEnvironment' // Read environment config
| 'generateContext' // Build combined context
| 'validateOutput' // Validate results
| 'cacheResult' // Cache for reuse
| 'retrieveCache' // Retrieve cached data
| 'composeResult'; // Final composition

Step 3: Create Directive Functionโ€‹

For OrchestrationDirective (simple/medium tools):

export function createMyToolDirective(args: MyToolArgs): OrchestrationDirective {
return {
type: 'orchestration_directive',
version: '1.0',
tool: 'my_tool',
description: 'Tool description',
sandbox_operations: [
// Map legacy operations to sandbox ops
],
metadata: {
estimated_tokens: 1500, // Target token count
cacheable: true,
cache_key: `my-tool:${args.projectPath}`,
},
};
}

For StateMachineDirective (complex tools):

export function createMyComplexToolDirective(args: MyToolArgs): StateMachineDirective {
return {
type: 'state_machine_directive',
version: '1.0',
initial_state: { ...args },
transitions: [
{
name: 'step_1',
from: 'initial',
operation: { op: 'loadKnowledge' },
next_state: 'step_2',
on_error: 'skip', // or 'abort' for critical steps
},
// Additional transitions...
],
final_state: 'done',
};
}

Step 4: Register with CE-MCP Dispatcherโ€‹

Add to src/tools/ce-mcp-tools.ts:

// 1. Add to cemcpTools list
const cemcpTools = [
'analyze_project_ecosystem',
'suggest_adrs',
'my_tool', // Add your tool
// ...
];

// 2. Add case to getCEMCPDirective
export function getCEMCPDirective(toolName: string, args: Record<string, unknown>) {
switch (toolName) {
case 'my_tool':
return createMyToolDirective(args as MyToolArgs);
// ...
}
}

Step 5: Write Migration Testsโ€‹

Create tests in tests/integration/:

describe('my_tool Migration', () => {
it('should produce equivalent output schema', () => {
const directive = createMyToolDirective({ projectPath: '/test' });

expect(isOrchestrationDirective(directive)).toBe(true);
expect(directive.tool).toBe('my_tool');
// Verify output schema matches legacy
});

it('should achieve 60%+ token reduction', () => {
const directive = createMyToolDirective({ projectPath: '/test' });

const legacyTokens = 4000; // Your legacy token count
const directiveTokens = directive.metadata?.estimated_tokens ?? 0;
const reduction = ((legacyTokens - directiveTokens) / legacyTokens) * 100;

expect(reduction).toBeGreaterThanOrEqual(60);
});
});

Step 6: Update IMPLEMENTATION-PLAN.mdโ€‹

Track migration status in docs/planning/IMPLEMENTATION-PLAN.md:

| Tool      | Current Tokens | Directive Tokens | Status |
| --------- | -------------- | ---------------- | ------ |
| `my_tool` | 4K | 1.5K | โœ… |

Rollback Procedureโ€‹

If CE-MCP directive fails:

1. Immediate Rollbackโ€‹

Set execution mode to legacy:

export EXECUTION_MODE=full

This bypasses CE-MCP directives and uses OpenRouter directly.

2. Per-Tool Rollbackโ€‹

Remove tool from cemcpTools list:

const cemcpTools = [
'analyze_project_ecosystem',
// 'my_tool', // Commented out - rolled back
];

3. Verify Rollbackโ€‹

Run migration tests to confirm legacy behavior:

npm test -- tests/integration/ce-mcp-migration.test.ts

Token Savings Referenceโ€‹

ToolLegacy TokensCE-MCP TokensReduction
analyze_project_ecosystem12,0004,00067%
suggest_adrs3,5001,50057%
generate_rules4,0001,50062.5%
analyze_environment2,5001,00060%
deployment_readiness2,00080060%

Validation Checklistโ€‹

Before marking migration complete:

  • Directive produces valid structure
  • Output schema matches legacy format
  • Token reduction >= 60%
  • Migration tests passing
  • Rollback tested
  • Documentation updated