MCP COMPREHENSIVE ARCHITECTURE REVIEW

Comprehensive guidelines for AI-assisted development within the Editor platform

MCP & Backend-AI-API: FINAL Architecture Plan

Date: February 4, 2026
Session: editor2-session-87
Status: FINAL - No More Revisions


The Hard Truth

121 tools is unacceptable. Period.

Both previous reviews were too accommodating. The backend services are well-built, but that's not the point. The point is: agents cannot effectively use 121 tools. LLMs have cognitive limits. Tool selection accuracy degrades exponentially with tool count.

The "sunk cost" argument ("we built it, so keep it") is a trap. Good engineering means ruthless consolidation.


FINAL Tool Architecture: 25 Tools

# Tool Name Type What It Replaces Chains Internally
1 mcp_init Entry - health check, mode selection, tool discovery
2 preflight Core - context, similar decisions, episodes (optional)
3 log_decision Core - auto-schedules outcome check
4 find_similar Core - -
5 session Gateway 7 session tools set, get, update, lock, register, summary, info
6 outcome Gateway 3 outcome tools report, track, validate
7 stats Gateway 3 stats tools basic, enhanced, session summary
8 convention Gateway 2 convention tools get, add
9 agent Gateway 10 multi-agent tools status, connect, events, handoff, respond, message, broadcast, find, call, watch
10 browser Gateway 9 browser tools navigate, click, fill, screenshot, extract, execute, wait, status, close
11 desktop Gateway 7 desktop tools read, write, list, execute, clipboard_get, clipboard_set, status
12 task Gateway 6 task tools create, execute, list, workflow_create, workflow_run, status
13 intelligence Gateway 29 tools ALL super intelligence, self-healing, calibration, evolution, code DNA, time machine
14 code Gateway 8 code tools review, test_gen, validate, analyze, suggest
15 platform Gateway 4 platform tools describe, query, mutate, automate
16 research Gateway 2 search tools web_search, docs_search
17 graph Existing Already consolidated -
18 behavior_mode Existing Already consolidated -
19 persona Existing Already consolidated -
20 token_efficiency Existing Already consolidated -
21 self_healing Existing Already consolidated -
22 docs_intelligence Existing Already consolidated -
23 workflow Existing Already consolidated -
24 space_generate Existing - -
25 discover_tools Discovery - -

Reduction: 121 → 25 tools (79% reduction)


The intelligence Gateway: The Key Innovation

This is where the magic happens. One tool that chains ALL intelligence services:

{
  name: 'intelligence',
  description: 'Unified AI intelligence gateway. Actions: recall (episodic memory), simulate (what-if), reflect (post-task learning), explain (causal reasoning), detect_gaps (knowledge gaps), diagnose (health), heal (self-repair), calibrate (confidence), evolve (agent tracking), analyze_dna (code conventions), enforce_dna (convention check), trace (decision history), pivot (find pivots), loops (detect patterns).',
  inputSchema: {
    type: 'object',
    properties: {
      action: {
        type: 'string',
        enum: [
          // Super Intelligence
          'recall', 'simulate', 'reflect', 'explain', 'detect_gaps', 'get_lessons',
          // Self-Healing
          'diagnose', 'heal', 'health_report',
          // Calibration
          'calibrate', 'calibration_curve',
          // Evolution
          'agent_evolution', 'predict_best_agent', 'specializations', 'complexity',
          // Code DNA
          'analyze_dna', 'enforce_dna', 'violations',
          // Time Machine
          'trace', 'pivots', 'simulate_alt', 'loops',
          // Collective (archived but accessible)
          'collective_join', 'collective_share', 'collective_query', 'collective_stats'
        ]
      },
      // Action-specific params follow...
    },
    required: ['action']
  }
}

Internal Chaining Example:

async function handleIntelligence(args: IntelligenceInput): Promise<any> {
  switch (args.action) {
    case 'recall':
      return handleSuperRecallEpisodes(args);
    
    case 'simulate':
      // Chain: recall similar episodes → run simulation → return combined result
      const episodes = await handleSuperRecallEpisodes({ situation: args.context, limit: 3 });
      const simulation = await handleSuperSimulate(args);
      return {
        ...simulation,
        relatedEpisodes: episodes.episodes,
        enhancedConfidence: calculateEnhancedConfidence(simulation, episodes)
      };
    
    case 'reflect':
      // Chain: reflect → detect gaps → suggest next learning
      const reflection = await handleSuperReflect(args);
      const gaps = await handleSuperDetectGaps({ domain: args.domain });
      return {
        ...reflection,
        knowledgeGaps: gaps.gaps,
        suggestedLearning: gaps.recommendations
      };
    
    case 'diagnose':
      // Chain: diagnose → auto-heal if safe → report
      const diagnosis = await handleSelfDiagnose();
      if (diagnosis.healthScore < 0.7 && args.autoHeal !== false) {
        const healing = await handleSelfHeal({ action: 'auto' });
        return { ...diagnosis, healingPerformed: healing };
      }
      return diagnosis;
    
    // ... other actions
  }
}

This is the chaining you asked for. One tool call triggers 2-3 internal operations intelligently.


The agent Gateway: Multi-Agent Simplified

{
  name: 'agent',
  description: 'Multi-agent operations. Actions: status, connect, events, handoff_create, handoff_respond, handoff_get, handoff_pending, message, broadcast, find, call, watch.',
  inputSchema: {
    type: 'object',
    properties: {
      action: {
        type: 'string',
        enum: ['status', 'connect', 'events', 'handoff_create', 'handoff_respond', 'handoff_get', 'handoff_pending', 'message', 'broadcast', 'find', 'call', 'watch']
      },
      // Action-specific params...
    },
    required: ['action']
  }
}

Replaces: agent_status, agent_connect, agent_events, create_handoff, respond_to_handoff, get_handoff, get_pending_handoffs, send_agent_message, agent_broadcast, find_agents_for_task, call_agent, watch_handoffs


The session Gateway: Session Management Unified

{
  name: 'session',
  description: 'Session management. Actions: set, get, update, lock, unlock, register, summary.',
  inputSchema: {
    type: 'object',
    properties: {
      action: {
        type: 'string',
        enum: ['set', 'get', 'update', 'lock', 'unlock', 'register', 'summary']
      },
      sessionNumber: { type: 'number' },
      subSessionNumber: { type: 'number' },
      description: { type: 'string' },
      lockSession: { type: 'boolean' }
    },
    required: ['action']
  }
}

Replaces: set_session, get_session_info, update_chat_session, lock_chat_session, register_chat_context, get_session_summary, get_chat_context


Enhanced preflight: The Smart Entry Point

{
  name: 'preflight',
  description: 'Intelligent context retrieval. Optionally chains to similar decisions, episodic memory, and health check.',
  inputSchema: {
    type: 'object',
    properties: {
      task: { type: 'string', description: 'Brief task description' },
      sessionNumber: { type: 'number' },
      subSessionNumber: { type: 'number' },
      lite: { type: 'boolean', default: false },
      // NEW: Auto-chaining options
      withSimilar: { type: 'boolean', default: true, description: 'Auto-fetch similar decisions' },
      withEpisodes: { type: 'boolean', default: false, description: 'Auto-fetch similar episodes from memory' },
      withHealth: { type: 'boolean', default: false, description: 'Include system health check' }
    },
    required: ['task']
  }
}

Internal Flow:

async function handlePreflight(args) {
  const context = await getPreflightContext(args.task);
  
  // Auto-chain: similar decisions
  if (args.withSimilar !== false) {
    context.similarDecisions = await handleFindSimilar({ query: args.task, limit: 3 });
  }
  
  // Auto-chain: episodic memory
  if (args.withEpisodes) {
    context.similarEpisodes = await handleSuperRecallEpisodes({ 
      situation: args.task, 
      limit: 3, 
      minRelevance: 0.5 
    });
  }
  
  // Auto-chain: health check
  if (args.withHealth) {
    context.systemHealth = await handleSelfDiagnose();
  }
  
  return context;
}

Enhanced log_decision: Auto-Outcome Scheduling

{
  name: 'log_decision',
  description: 'Log a decision. Auto-schedules outcome verification.',
  inputSchema: {
    type: 'object',
    properties: {
      type: { type: 'string', enum: ['architecture', 'implementation', 'refactor', 'bugfix', 'fix', 'pattern', 'convention', 'documentation', 'milestone'] },
      question: { type: 'string' },
      options: { type: 'array', items: { type: 'string' } },
      chosen: { type: 'string' },
      reasoning: { type: 'string' },
      confidence: { type: 'number' },
      files: { type: 'array', items: { type: 'string' } },
      // NEW: Auto-outcome options
      autoOutcome: { type: 'boolean', default: true, description: 'Auto-schedule outcome check' },
      outcomeDelayMs: { type: 'number', default: 300000, description: 'Delay before outcome check (default 5 min)' }
    },
    required: ['type', 'question', 'chosen', 'reasoning', 'confidence']
  }
}

Internal Flow:

async function handleLogDecision(args) {
  const decision = await saveDecision(args);
  
  // Auto-schedule outcome check
  if (args.autoOutcome !== false && decision.files?.length > 0) {
    scheduleOutcomeCheck(decision.id, {
      checkAfterMs: args.outcomeDelayMs || 5 * 60 * 1000,
      method: 'git_diff',
      files: decision.files
    });
  }
  
  // Auto-create episode for significant decisions
  if (decision.type === 'architecture' || decision.confidence >= 0.8) {
    await handleSuperReflect({
      taskSummary: decision.question,
      outcome: 'pending',
      lessonsLearned: [decision.reasoning]
    });
  }
  
  return decision;
}

Outcome Automation: The Missing Piece

Git-Based Outcome Detection (Backend Service)

// apis/backend-ai-api/src/app/learning/services/outcome-automation.service.ts
@Injectable()
export class OutcomeAutomationService {
  private pendingChecks: Map<string, NodeJS.Timeout> = new Map();
  
  scheduleCheck(decisionId: string, options: OutcomeCheckOptions) {
    const timeout = setTimeout(async () => {
      await this.performCheck(decisionId, options);
    }, options.checkAfterMs);
    
    this.pendingChecks.set(decisionId, timeout);
  }
  
  async performCheck(decisionId: string, options: OutcomeCheckOptions) {
    const decision = await this.decisionService.findById(decisionId);
    if (!decision || decision.outcome) return; // Already has outcome
    
    // Check git status of files
    const gitStatus = await this.gitService.checkFilesStatus(decision.files);
    
    const wasSuccessful = 
      !gitStatus.reverted && 
      !gitStatus.hasConflicts && 
      gitStatus.stillExists;
    
    // Auto-report outcome
    await this.outcomeService.report({
      decisionId,
      wasSuccessful,
      feedback: this.generateFeedback(gitStatus),
      rating: wasSuccessful ? 4 : 2,
      source: 'auto-git'
    });
    
    this.logger.log(`Auto-outcome for ${decisionId}: ${wasSuccessful ? 'SUCCESS' : 'FAILURE'}`);
  }
}

What Gets Removed (Archived, Not Deleted)

These tools move to MCP/mcp-gograb-ai/src/tools/archived/:

Tool Reason
mcp_init Keep (entry point)
select_mode Merged into mcp_init
poc_websocket_test POC complete, not needed
list_contexts Merged into discover_tools
load_tools Merged into discover_tools
self_modify_system Too dangerous for general use
get_modification_history Merged into intelligence
rollback_modification Merged into intelligence
debug_logs Dev-only, not for agents
git_session_analyzer Merged into session
All individual super_* tools Merged into intelligence
All individual self_* tools Merged into intelligence
All individual calibration tools Merged into intelligence
All individual evolution tools Merged into intelligence
All individual code DNA tools Merged into intelligence
All individual time machine tools Merged into intelligence
All individual collective tools Merged into intelligence
All individual browser_* tools Merged into browser
All individual desktop_* tools Merged into desktop
All individual task_* tools Merged into task
All individual agent_* tools Merged into agent
All individual session tools Merged into session
All individual outcome tools Merged into outcome
All individual stats tools Merged into stats

Archive, don't delete. The handlers still exist, they're just not exposed as individual tools.


Implementation Plan

Week 1: Core Gateways (P0)

Day Task Deliverable
1 Create session gateway Replace 7 tools → 1
2 Create agent gateway Replace 12 tools → 1
3 Create outcome gateway + auto-scheduling Replace 3 tools → 1, add automation
4 Create stats gateway Replace 3 tools → 1
5 Create convention gateway Replace 2 tools → 1

Week 1 Result: 121 → 94 tools

Week 2: Intelligence Gateway (P0)

Day Task Deliverable
1-2 Create intelligence gateway Replace 29 tools → 1
3 Implement internal chaining (recall → simulate, reflect → gaps) Smart tool chains
4 Create code gateway Replace 8 tools → 1
5 Create platform gateway Replace 4 tools → 1

Week 2 Result: 94 → 53 tools

Week 3: Automation Gateways (P1)

Day Task Deliverable
1 Create browser gateway Replace 9 tools → 1
2 Create desktop gateway Replace 7 tools → 1
3 Create task gateway Replace 6 tools → 1
4 Create research gateway Replace 2 tools → 1
5 Cleanup: archive old tools, update docs Final cleanup

Week 3 Result: 53 → 25 tools

Week 4: Polish & Testing (P2)

Day Task Deliverable
1-2 Enhance preflight with auto-chaining withSimilar, withEpisodes, withHealth
3 Enhance log_decision with auto-outcome autoOutcome, outcomeDelayMs
4 Update mcp_init with tool discovery Show relevant tools per task
5 Integration testing, documentation Production-ready

Success Metrics

Metric Current Target (30 days) Target (90 days)
Tool count 121 25 25
Tool usage coverage 21% 60% 85%
Outcome feedback rate 0.3% 50% 80%
Avg tools per task 4+ 1-2 1
Agent cognitive load HIGH MEDIUM LOW

Phase 5: Backend-AI-API Hardening

5.1 VITTO Resilience

VITTO is currently a single point of failure. If it crashes, all autonomous handoffs stop.

Issue Current State Fix Priority
Single point of failure VITTO runs inside NestJS process Run as separate process with PM2/systemd P1
No rate limiting Direct Anthropic API calls without throttling Add @nestjs/throttler to Claude API calls P0
Memory bloat In-memory triggerIndex in EpisodicMemoryService Move to Redis with TTL eviction P2
No circuit breaker External API failures cascade Add circuit breaker pattern for Anthropic/external calls P1
No graceful shutdown Pending handoffs lost on restart Persist handoff queue to Redis/MongoDB P1

Implementation: VITTO Process Isolation

# ecosystem.config.js for PM2
module.exports = {
  apps: [
    {
      name: 'backend-ai-api',
      script: 'dist/apis/backend-ai-api/main.js',
      instances: 1,
      env: {
        VITTO_AUTO_START: false  // Don't start VITTO in main process
      }
    },
    {
      name: 'vitto-orchestrator',
      script: 'dist/apis/backend-ai-api/vitto-standalone.js',
      instances: 1,
      max_restarts: 10,
      restart_delay: 5000,
      env: {
        VITTO_STANDALONE: true
      }
    }
  ]
};

Implementation: Rate Limiting for Anthropic API

// apis/backend-ai-api/src/app/vitto/vitto-orchestrator.service.ts
import { Throttle } from '@nestjs/throttler';
import Bottleneck from 'bottleneck';

@Injectable()
export class VittoOrchestratorService {
  private readonly limiter = new Bottleneck({
    maxConcurrent: 3,           // Max 3 concurrent Claude calls
    minTime: 1000,              // At least 1 second between calls
    reservoir: 60,              // 60 requests per minute
    reservoirRefreshAmount: 60,
    reservoirRefreshInterval: 60 * 1000
  });
  
  private async executeWithAI(step: ExecutionStep, handoff: Handoff): Promise<string> {
    return this.limiter.schedule(async () => {
      return this.anthropic.messages.create({
        model: 'claude-sonnet-4-20250514',
        max_tokens: 4096,
        messages: [/* ... */]
      });
    });
  }
}

Implementation: Redis-Based Trigger Index

// apis/backend-ai-api/src/app/super-intelligence/services/episodic-memory.service.ts
@Injectable()
export class EpisodicMemoryService {
  constructor(
    @InjectRedis() private readonly redis: Redis,
    // ...
  ) {}
  
  // Replace in-memory Map with Redis
  private async addToTriggerIndex(trigger: string, episodeId: string): Promise<void> {
    await this.redis.sadd(`triggers:${trigger}`, episodeId);
    await this.redis.expire(`triggers:${trigger}`, 7 * 24 * 60 * 60); // 7 day TTL
  }
  
  private async getTriggerEpisodes(trigger: string): Promise<string[]> {
    return this.redis.smembers(`triggers:${trigger}`);
  }
}

5.2 MCP Error Boundaries

Currently, tool failures can crash the MCP server or return cryptic errors. We need defensive wrappers.

Implementation: Safe Tool Call Wrapper

// MCP/mcp-gograb-ai/src/utils/safe-tool-call.ts
import { debugLogger } from './debug-logger.js';

export interface SafeToolResult<T = any> {
  success: boolean;
  data?: T;
  error?: string;
  errorCode?: string;
  recoverable: boolean;
  duration: number;
}

export async function safeToolCall<T>(
  toolName: string,
  handler: () => Promise<T>,
  options: { timeout?: number; retries?: number } = {}
): Promise<SafeToolResult<T>> {
  const startTime = Date.now();
  const { timeout = 30000, retries = 0 } = options;
  
  let lastError: Error | null = null;
  
  for (let attempt = 0; attempt <= retries; attempt++) {
    try {
      debugLogger.info('tool_call_start', { 
        tool: toolName, 
        attempt: attempt + 1,
        maxAttempts: retries + 1 
      });
      
      // Wrap with timeout
      const result = await Promise.race([
        handler(),
        new Promise<never>((_, reject) => 
          setTimeout(() => reject(new Error(`Tool ${toolName} timed out after ${timeout}ms`)), timeout)
        )
      ]);
      
      const duration = Date.now() - startTime;
      debugLogger.info('tool_call_success', { tool: toolName, duration });
      
      return {
        success: true,
        data: result,
        recoverable: true,
        duration
      };
    } catch (error: any) {
      lastError = error;
      debugLogger.warn('tool_call_attempt_failed', { 
        tool: toolName, 
        attempt: attempt + 1,
        error: error.message 
      });
      
      if (attempt < retries) {
        await new Promise(resolve => setTimeout(resolve, 1000 * (attempt + 1))); // Exponential backoff
      }
    }
  }
  
  const duration = Date.now() - startTime;
  debugLogger.error('tool_call_failed', { 
    tool: toolName, 
    error: lastError?.message,
    duration 
  });
  
  return {
    success: false,
    error: `Tool ${toolName} failed: ${lastError?.message}`,
    errorCode: classifyError(lastError),
    recoverable: isRecoverableError(lastError),
    duration
  };
}

function classifyError(error: Error | null): string {
  if (!error) return 'UNKNOWN';
  const msg = error.message.toLowerCase();
  if (msg.includes('timeout')) return 'TIMEOUT';
  if (msg.includes('network') || msg.includes('fetch')) return 'NETWORK';
  if (msg.includes('auth') || msg.includes('401')) return 'AUTH';
  if (msg.includes('rate') || msg.includes('429')) return 'RATE_LIMIT';
  if (msg.includes('not found') || msg.includes('404')) return 'NOT_FOUND';
  return 'INTERNAL';
}

function isRecoverableError(error: Error | null): boolean {
  if (!error) return false;
  const code = classifyError(error);
  return ['TIMEOUT', 'NETWORK', 'RATE_LIMIT'].includes(code);
}

Usage in Gateway Handlers:

// MCP/mcp-gograb-ai/src/tools/gateways/intelligence-gateway.ts
export async function handleIntelligence(args: IntelligenceInput): Promise<any> {
  return safeToolCall('intelligence', async () => {
    switch (args.action) {
      case 'recall':
        return handleSuperRecallEpisodes(args);
      case 'simulate':
        const episodes = await handleSuperRecallEpisodes({ situation: args.context, limit: 3 });
        const simulation = await handleSuperSimulate(args);
        return { ...simulation, relatedEpisodes: episodes.episodes };
      // ... other actions
    }
  }, { timeout: 15000, retries: 1 });
}

5.3 Observability & Monitoring

Component Current Target Implementation
Tool call metrics None Per-tool latency, success rate Prometheus + Grafana
VITTO health None Healthcheck endpoint /health/vitto
Decision pipeline Partial Full tracing OpenTelemetry spans
Error alerting None Slack/PagerDuty Alert on error rate > 5%

Implementation: Healthcheck Endpoint

// apis/backend-ai-api/src/app/health/health.controller.ts
@Controller('health')
export class HealthController {
  constructor(
    private readonly vittoService: VittoOrchestratorService,
    private readonly learningService: LearningService,
    private readonly selfHealingService: SelfHealingService,
  ) {}
  
  @Get('vitto')
  async vittoHealth(): Promise<HealthCheckResult> {
    return {
      status: this.vittoService.isConnected ? 'healthy' : 'degraded',
      uptime: this.vittoService.getUptime(),
      pendingHandoffs: this.vittoService.getPendingCount(),
      lastActivity: this.vittoService.getLastActivityTime(),
      websocketState: this.vittoService.getSocketState(),
    };
  }
  
  @Get('learning')
  async learningHealth(): Promise<HealthCheckResult> {
    const metrics = await this.selfHealingService.collectMetrics();
    return {
      status: metrics.every(m => m.status !== 'critical') ? 'healthy' : 'degraded',
      metrics,
      lastHealthCheck: this.selfHealingService.getLastCheckTime(),
    };
  }
  
  @Get()
  async fullHealth(): Promise<HealthCheckResult> {
    const [vitto, learning] = await Promise.all([
      this.vittoHealth(),
      this.learningHealth(),
    ]);
    
    return {
      status: vitto.status === 'healthy' && learning.status === 'healthy' ? 'healthy' : 'degraded',
      components: { vitto, learning },
      timestamp: new Date().toISOString(),
    };
  }
}

Implementation: Tool Metrics

// MCP/mcp-gograb-ai/src/utils/metrics.ts
interface ToolMetrics {
  calls: number;
  successes: number;
  failures: number;
  totalDuration: number;
  lastCall: Date | null;
}

class MetricsCollector {
  private metrics: Map<string, ToolMetrics> = new Map();
  
  recordCall(toolName: string, success: boolean, duration: number): void {
    const existing = this.metrics.get(toolName) || {
      calls: 0, successes: 0, failures: 0, totalDuration: 0, lastCall: null
    };
    
    existing.calls++;
    existing.totalDuration += duration;
    existing.lastCall = new Date();
    if (success) existing.successes++;
    else existing.failures++;
    
    this.metrics.set(toolName, existing);
  }
  
  getMetrics(): Record<string, ToolMetrics & { avgDuration: number; successRate: number }> {
    const result: Record<string, any> = {};
    for (const [name, m] of this.metrics) {
      result[name] = {
        ...m,
        avgDuration: m.calls > 0 ? m.totalDuration / m.calls : 0,
        successRate: m.calls > 0 ? m.successes / m.calls : 0,
      };
    }
    return result;
  }
}

export const metricsCollector = new MetricsCollector();

Phase 6: Code Quality & Cleanup

6.1 Naming Standardization

Current Issue Fix
log_decision snake_case Keep (consistent with MCP convention)
handleLogDecision camelCase handler Keep (TypeScript convention)
Tool descriptions use "camelCase" Inconsistent Standardize to snake_case in descriptions
super_recall_episodes Verbose Consolidate into intelligence gateway

Rule: All tool names use snake_case. All TypeScript functions use camelCase.

6.2 Dead Code Removal

File Issue Action
server.ts:538 References "Session 1007" Remove comment
poc_websocket_test POC complete Archive to tools/archived/
list_contexts, load_tools Superseded by discover_tools Archive
self_modify_system Too dangerous Archive with warning

6.3 Prompts Audit

32 prompts exist in /Users/fguijarro/.cursor/projects/Users-fguijarro-developer-repos-editor2/mcps/user-mcp-gograb-ai/prompts/.

Prompt Usage Verdict
preflight.json HIGH Keep
log.json HIGH Keep
find_similar.json HIGH Keep
session.json MEDIUM Keep
graph_*.json (6) LOW Consolidate into graph.json
validate_outcomes.json ZERO Archive
learn_outcomes.json ZERO Archive
transfer.json ZERO Archive

Action: Reduce from 32 prompts to ~15 prompts by consolidating and archiving unused.


Phase 7: Advanced Enhancements

7.1 Predictive Tool Suggestion

When mcp_init is called, suggest tools based on task classification:

// MCP/mcp-gograb-ai/src/tools/mcp-init.ts
const TASK_TOOL_MAP: Record<string, string[]> = {
  'debug': ['intelligence', 'code', 'find_similar'],
  'implement': ['preflight', 'code', 'intelligence'],
  'refactor': ['code', 'intelligence', 'convention'],
  'test': ['code', 'intelligence'],
  'review': ['code', 'convention'],
  'deploy': ['task', 'agent'],
  'research': ['research', 'intelligence'],
};

function classifyTask(task: string): string {
  const taskLower = task.toLowerCase();
  if (taskLower.includes('bug') || taskLower.includes('error') || taskLower.includes('fix')) return 'debug';
  if (taskLower.includes('implement') || taskLower.includes('create') || taskLower.includes('add')) return 'implement';
  if (taskLower.includes('refactor') || taskLower.includes('clean')) return 'refactor';
  if (taskLower.includes('test')) return 'test';
  if (taskLower.includes('review')) return 'review';
  if (taskLower.includes('deploy') || taskLower.includes('release')) return 'deploy';
  if (taskLower.includes('research') || taskLower.includes('find') || taskLower.includes('search')) return 'research';
  return 'implement'; // Default
}

async function handleMcpInit(args: McpInitInput): Promise<any> {
  const result = await initializeSession(args);
  
  if (args.task) {
    const taskType = classifyTask(args.task);
    result.suggestedTools = TASK_TOOL_MAP[taskType] || [];
    result.taskClassification = taskType;
  }
  
  return result;
}

7.2 Tool Chain Learning

Track which tool sequences lead to successful outcomes, then suggest optimal chains:

// Backend service
@Injectable()
export class ToolChainLearningService {
  async recordChain(chain: string[], outcome: 'success' | 'failure'): Promise<void> {
    const chainKey = chain.join('→');
    await this.chainModel.updateOne(
      { chain: chainKey },
      { 
        $inc: { 
          totalUses: 1, 
          successes: outcome === 'success' ? 1 : 0 
        },
        $set: { lastUsed: new Date() }
      },
      { upsert: true }
    );
  }
  
  async suggestNextTool(currentChain: string[]): Promise<string | null> {
    // Find chains that start with currentChain and have high success rate
    const candidates = await this.chainModel.find({
      chain: { $regex: `^${currentChain.join('→')}→` },
      totalUses: { $gte: 5 },
    }).sort({ successRate: -1 }).limit(3);
    
    if (candidates.length === 0) return null;
    
    // Extract the next tool from the best chain
    const bestChain = candidates[0].chain.split('→');
    return bestChain[currentChain.length] || null;
  }
}

7.3 Automatic Fallback Chains

When a tool fails, automatically try alternative approaches:

// MCP/mcp-gograb-ai/src/utils/fallback-chains.ts
const FALLBACK_CHAINS: Record<string, string[]> = {
  'intelligence:recall': ['find_similar', 'research'],
  'browser:navigate': ['desktop:execute_command'],
  'code:review': ['intelligence:analyze_dna'],
};

export async function executeWithFallback(
  toolName: string,
  action: string,
  args: any
): Promise<any> {
  const key = `${toolName}:${action}`;
  const fallbacks = FALLBACK_CHAINS[key] || [];
  
  // Try primary
  const result = await safeToolCall(toolName, () => executeGateway(toolName, action, args));
  if (result.success) return result;
  
  // Try fallbacks
  for (const fallback of fallbacks) {
    const [fbTool, fbAction] = fallback.includes(':') 
      ? fallback.split(':') 
      : [fallback, action];
    
    const fbResult = await safeToolCall(fbTool, () => executeGateway(fbTool, fbAction, args));
    if (fbResult.success) {
      return { ...fbResult, usedFallback: fallback };
    }
  }
  
  return result; // Return original failure
}

Complete Implementation Roadmap

Phase Week Days Deliverable Tools After
1 1 1-5 Core gateways (session, agent, outcome, stats, convention) 94
2 2 1-5 Intelligence + code + platform gateways 53
3 3 1-5 Automation gateways (browser, desktop, task, research) 25
4 4 1-3 Preflight/log_decision enhancements, mcp_init discovery 25
5 4 4-5 VITTO resilience (PM2, rate limiting) 25
6 5 1-2 Error boundaries, safe tool calls 25
7 5 3-4 Observability (healthchecks, metrics) 25
8 5 5 Code cleanup, naming standardization 25
9 6 1-3 Prompts audit, dead code removal 25
10 6 4-5 Advanced: predictive suggestions, chain learning 25

Total: 6 weeks / ~30 engineering days


Success Metrics (Complete)

Metric Current Target (30 days) Target (90 days) How to Measure
Tool count 121 25 25 ls tools/*.json | wc -l
Tool usage coverage 21% 60% 85% Usage log analysis
Outcome feedback rate 0.3% 50% 80% report_outcome / log_decision
Preflight cache hit rate Unknown 50% 70% Add metric to preflight handler
VITTO uptime Unknown 95% 99.9% Healthcheck endpoint
Avg tool latency Unknown <500ms <200ms Metrics collector
Tool error rate Unknown <10% <2% Error boundary logs
Agent cognitive load HIGH MEDIUM LOW User feedback

What This Achieves (Complete)

  1. Cognitive Simplicity: 25 tools is manageable. Agents can learn and remember them.

  2. Intelligent Chaining: One intelligence call can trigger recall → simulate → reflect internally.

  3. Auto-Outcome: Every log_decision automatically schedules outcome verification.

  4. Preserved Investment: All backend services remain. Only the MCP surface changes.

  5. Discoverability: mcp_init shows relevant tools. discover_tools provides full catalog.

  6. Backward Compatibility: Old tool names can be aliased to new gateways during transition.

  7. Resilience: VITTO runs as separate process with rate limiting and circuit breakers.

  8. Observability: Healthchecks, metrics, and error tracking for all components.

  9. Self-Healing: Error boundaries with automatic fallback chains.

  10. Continuous Learning: Tool chain learning improves suggestions over time.


What This Does NOT Do


Risk Mitigation

Risk Likelihood Impact Mitigation
Gateway consolidation breaks existing scripts MEDIUM HIGH Maintain aliases for 90 days
VITTO process isolation introduces latency LOW MEDIUM Use Unix sockets for IPC
Redis dependency adds complexity MEDIUM LOW Make Redis optional with in-memory fallback
Error boundaries mask real issues LOW MEDIUM Log all errors, alert on patterns
Tool chain learning suggests bad chains LOW LOW Require minimum 5 uses before suggesting

The Bottom Line

121 tools was a mistake. Not because the features are bad, but because the surface area is unmanageable.

25 tools is the target. Each tool is either:

The backend is solid. The MCP layer needs surgery.

Operational hardening is critical. VITTO resilience, error boundaries, and observability are not optional.

This is the final plan. Execute it.


Appendix A: Gateway Implementation Template

// Example: session gateway
export async function handleSession(args: SessionGatewayInput): Promise<any> {
  return safeToolCall('session', async () => {
    switch (args.action) {
      case 'set':
        return handleSetSession({
          sessionNumber: args.sessionNumber,
          subSessionNumber: args.subSessionNumber,
          description: args.description
        });
      
      case 'get':
        return handleGetSessionInfo({ projectId: args.projectId });
      
      case 'update':
        return handleUpdateChatSession({
          sessionNumber: args.sessionNumber,
          subSessionNumber: args.subSessionNumber,
          reason: args.reason,
          forceSwitch: args.forceSwitch,
          relock: args.relock,
          continueExisting: args.continueExisting
        });
      
      case 'lock':
        return handleLockChatSession({ lock: true });
      
      case 'unlock':
        return handleLockChatSession({ lock: false });
      
      case 'register':
        return handleRegisterChatContext({
          taskDescription: args.taskDescription,
          sessionNumber: args.sessionNumber,
          subSessionNumber: args.subSessionNumber,
          lockSession: args.lockSession
        });
      
      case 'summary':
        return handleGetSessionSummary({ sessionID: args.sessionID });
      
      default:
        throw new Error(`Unknown session action: ${args.action}`);
    }
  }, { timeout: 10000 });
}

Appendix B: File Changes Summary

File/Directory Action Details
MCP/mcp-gograb-ai/src/server.ts MODIFY Replace 121 tool definitions with 25
MCP/mcp-gograb-ai/src/tools/gateways/ CREATE New directory for gateway handlers
MCP/mcp-gograb-ai/src/tools/archived/ CREATE Archive old individual tools
MCP/mcp-gograb-ai/src/utils/safe-tool-call.ts CREATE Error boundary wrapper
MCP/mcp-gograb-ai/src/utils/metrics.ts CREATE Tool metrics collector
apis/backend-ai-api/src/app/health/ CREATE Healthcheck endpoints
apis/backend-ai-api/src/app/vitto/vitto-standalone.ts CREATE Standalone VITTO entry point
apis/backend-ai-api/ecosystem.config.js CREATE PM2 configuration
prompts/*.json ARCHIVE Reduce from 32 to ~15

Appendix C: Migration Guide

For Existing Scripts Using Old Tool Names

// Alias mapping (temporary, remove after 90 days)
const TOOL_ALIASES: Record<string, { gateway: string; action: string }> = {
  'set_session': { gateway: 'session', action: 'set' },
  'get_session_info': { gateway: 'session', action: 'get' },
  'create_handoff': { gateway: 'agent', action: 'handoff_create' },
  'super_recall_episodes': { gateway: 'intelligence', action: 'recall' },
  'self_diagnose': { gateway: 'intelligence', action: 'diagnose' },
  // ... etc
};

// In server.ts tool router
if (TOOL_ALIASES[toolName]) {
  const { gateway, action } = TOOL_ALIASES[toolName];
  console.warn(`DEPRECATED: ${toolName} is deprecated. Use ${gateway}({ action: '${action}' }) instead.`);
  return handleGateway(gateway, { action, ...args });
}

End of Final Plan

Next Action: Start Week 1, Day 1 - Create session gateway.