MCP

Intent Surfaces

A reference manual for people who design and build MCP (Model Context Protocol) ecosystems

MCP

Intent Surfaces

A reference manual for people who design and build MCP (Model Context Protocol) ecosystems

MCP

Intent Surfaces

A reference manual for people who design and build MCP (Model Context Protocol) ecosystems

The Host with the Most

The Host with the Most

The Host with the Most

Meet the conductor of the MCP symphony • How Claude Desktop became the first citizen • The bouncer at the AI nightclub

Meet the conductor of the MCP symphony • How Claude Desktop became the first citizen • The bouncer at the AI nightclub

Meet the conductor of the MCP symphony • How Claude Desktop became the first citizen • The bouncer at the AI nightclub

The Maestro of Connections

The Maestro of Connections

Inside your computer, right now, an MCP host is doing something remarkable. It's not making billions of decisions per second—that would be fiction. But what it IS doing might be even more impressive: it's making AI truly useful.An MCP host is like a universal translator at the United Nations. When Claude wants to read your files, search your emails, or update your calendar, the host makes it happen. Not through magic, but through elegant orchestration.Let's see what a real MCP host does:

Inside your computer, right now, an MCP host is doing something remarkable. It's not making billions of decisions per second—that would be fiction. But what it IS doing might be even more impressive: it's making AI truly useful.An MCP host is like a universal translator at the United Nations. When Claude wants to read your files, search your emails, or update your calendar, the host makes it happen. Not through magic, but through elegant orchestration.Let's see what a real MCP host does:

MCP HOST

MCP HOST

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// What an MCP host actually manages (based on the specification)
interface MCPHost {
  // Manage client connections
  clients: Map<string, MCPClient>;
  
  // Route requests to the right client
  router: RequestRouter;
  
  // Handle security and permissions
  security: SecurityManager;
  
  // Track what each client can do
  capabilities: CapabilityRegistry;
}

// A day in the life of an MCP host
async function handleUserRequest(host: MCPHost, request: string) {
  // User: "Can you check my GitHub PRs and update my todo list?"
  
  // Host thinks: "I need the GitHub client and the Todo client"
  const githubClient = host.clients.get('github');
  const todoClient = host.clients.get('todo');
  
  // First, check permissions
  const canReadGitHub = await host.security.check(githubClient, 'read:pulls');
  const canWriteTodos = await host.security.check(todoClient, 'write:tasks');
  
  if (!canReadGitHub || !canWriteTodos) {
    // Ask user for permission - this is real, not fiction
    const granted = await host.requestPermission([
      'Allow Claude to read your GitHub pull requests?',
      'Allow Claude to update your todo list?'
    ]);
    
    if (!granted) return "I need permission to help with that.";
  }
  
  // Now orchestrate the actual work
  const prs = await githubClient.call('list_pulls', { state: 'open' });
  const todos = prs.map(pr => ({
    title: `Review PR: ${pr.title}`,
    url: pr.url
  }));
  
  await todoClient.call('create_tasks', { tasks: todos });
  
  return `Added ${todos.length} PR reviews to your todo list!`;
}

Send Request

Send Request

5.1 Control Room

5.1 Control Room

How Claude Desktop Actually Works

How Claude Desktop Actually Works

When you launch Claude Desktop, here's what really happens (based on the actual implementation):

When you launch Claude Desktop, here's what really happens (based on the actual implementation):

MCP Config

MCP Config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// The real MCP configuration in Claude Desktop
// (Located in ~/Library/Application Support/Claude/claude_desktop_config.json on Mac)
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/username/Documents"]
    },
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "github_pat_..."
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
    }
  }
}

// What happens when Claude Desktop starts
class ClaudeDesktopHost {
  async initialize() {
    // Read configuration
    const config = await this.loadConfig();
    
    // For each configured server
    for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
      try {
        // Launch the MCP server process
        const process = spawn(serverConfig.command, serverConfig.args, {
          env: { ...process.env, ...serverConfig.env }
        });
        
        // Connect via stdio (standard input/output)
        const client = new StdioMCPClient(process);
        
        // Perform the MCP handshake
        await client.initialize();
        
        // Register the client
        this.clients.set(name, client);
        
        console.log(`Connected to ${name} MCP server`);
      } catch (error) {
        console.error(`Failed to connect to ${name}:`, error);
      }
    }
  }
}

5.2 How claude works

5.2 How claude works

This isn't pseudocode—this is how Claude Desktop actually launches and connects to MCP servers. Each server runs as a separate process, communicating through standard input/output streams.

This isn't pseudocode—this is how Claude Desktop actually launches and connects to MCP servers. Each server runs as a separate process, communicating through standard input/output streams.

The Security Guardian

The Security Guardian

MCP hosts take security seriously—not through "quantum models" but through practical, understandable rules:

MCP hosts take security seriously—not through "quantum models" but through practical, understandable rules:

MCP_Security_Manager.ts

MCP_Security_Manager.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// How MCP actually handles security
class MCPSecurityManager {
  // Permission model based on the spec
  private permissions: Map<string, Set<Permission>> = new Map();
  
  async requestPermission(
    client: string, 
    capability: string,
    context: PermissionContext
  ): Promise<boolean> {
    // Check if already granted
    const existing = this.permissions.get(client);
    if (existing?.has(capability)) {
      return true;
    }
    
    // Show user a real dialog (not fiction)
    const dialog = {
      title: 'Permission Request',
      message: `${client} wants to ${this.describeCapability(capability)}`,
      detail: this.explainRisks(capability),
      buttons: ['Allow', 'Deny', 'Allow Once']
    };
    
    const result = await this.showDialog(dialog);
    
    if (result === 'Allow') {
      // Remember this decision
      if (!existing) {
        this.permissions.set(client, new Set());
      }
      this.permissions.get(client).add(capability);
      return true;
    }
    
    return result === 'Allow Once';
  }
  
  private explainRisks(capability: string): string {
    // Real, helpful explanations - not scare tactics
    const risks = {
      'filesystem:write': 'This allows creating and modifying files in the specified directory.',
      'github:write': 'This allows creating issues, PRs, and comments in your repositories.',
      'email:send': 'This allows sending emails on your behalf.',
    };
    
    return risks[capability] || 'This grants access to the requested capability.';
  }
}

5.3 Permission Request

5.3 Permission Request

How Hosts Route Requests

How Hosts Route Requests

The real magic of a host is in routing—figuring out which client can handle what:

The real magic of a host is in routing—figuring out which client can handle what:

Request Router

Request Router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// How routing actually works in MCP
class RequestRouter {
  constructor(private clients: Map<string, MCPClient>) {}
  
  async route(userRequest: string): Promise<any> {
    // Step 1: Understand what the user wants
    const intent = this.parseIntent(userRequest);
    
    // Step 2: Find capable clients
    const capableClients = [];
    
    for (const [name, client] of this.clients) {
      const capabilities = await client.getCapabilities();
      
      // Check if this client can help
      if (this.canHandle(intent, capabilities)) {
        capableClients.push({ name, client, capabilities });
      }
    }
    
    // Step 3: Execute the request
    if (capableClients.length === 0) {
      return "I don't have access to tools that can help with that.";
    }
    
    // Simple case: one client can handle it
    if (capableClients.length === 1) {
      const { client } = capableClients[0];
      return await this.executeOn(client, intent);
    }
    
    // Complex case: need multiple clients
    return await this.orchestrate(capableClients, intent);
  }
  
  private async orchestrate(clients, intent) {
    // Example: "Analyze my code and create documentation"
    // Needs: GitHub client + Document generator
    
    const results = {};
    
    // Step 1: Get code from GitHub
    const githubClient = clients.find(c => c.name === 'github');
    if (githubClient) {
      results.code = await githubClient.client.request('tools/call', {
        name: 'get_repository_content',
        arguments: { repo: intent.repo }
      });
    }
    
    // Step 2: Generate documentation
    const docClient = clients.find(c => c.name === 'markdown');
    if (docClient && results.code) {
      results.docs = await docClient.client.request('tools/call', {
        name: 'generate_docs',
        arguments: { code: results.code }
      });
    }
    
    return results;
  }
}

MCP Host

Request Intent

Final Response

Read my emails and summarize them

MCP Host

Request Intent

Final Response

Read my emails and summarize them

MCP Host

Request Intent

Final Response

Read my emails and summarize them

5.4 Requester

5.4 Requester

Performance: The Real Numbers

Performance: The Real Numbers

Let's talk about actual performance, not fiction:

Let's talk about actual performance, not fiction:

Performance Metrics

Performance Metrics

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Real-world MCP performance characteristics
const performanceMetrics = {
  // Typical latencies (not nanoseconds!)
  handshake: '50-200ms',        // Initial connection
  simpleRequest: '5-50ms',       // Reading a file
  complexRequest: '100-500ms',   // Database query
  
  // Realistic throughput
  requestsPerSecond: '10-1000',  // Depends on complexity
  
  // Actual bottlenecks
  bottlenecks: [
    'Process spawn time (50-100ms)',
    'Network latency for HTTP transports',
    'Tool execution time (varies widely)',
    'JSON parsing (usually negligible)'
  ]
};

// How to measure performance in your MCP host
class PerformanceMonitor {
  constructor() {
    this.metrics = [];
  }
  
  async measureRequest(client, method, params) {
    const start = Date.now();
    
    try {
      const result = await client.request(method, params);
      const duration = Date.now() - start;
      
      this.metrics.push({
        client: client.name,
        method,
        duration,
        success: true,
        timestamp: new Date()
      });
      
      return result;
    } catch (error) {
      const duration = Date.now() - start;
      
      this.metrics.push({
        client: client.name,
        method,
        duration,
        success: false,
        error: error.message,
        timestamp: new Date()
      });
      
      throw error;
    }
  }
  
  getStats() {
    const successful = this.metrics.filter(m => m.success);
    const durations = successful.map(m => m.duration);
    
    return {
      totalRequests: this.metrics.length,
      successRate: (successful.length / this.metrics.length) * 100,
      avgDuration: durations.reduce((a, b) => a + b, 0) / durations.length,
      p95Duration: this.percentile(durations, 0.95),
      p99Duration: this.percentile(durations, 0.99)
    };
  }
}

5.5 The Real Number

5.5 The Real Number

The Claude Desktop Experience

The Claude Desktop Experience

Here's what it's actually like to use Claude Desktop with MCP:

Here's what it's actually like to use Claude Desktop with MCP:

Real World Example

Real World Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Real user interaction with Claude Desktop
async function realWorldExample() {
  // User types in Claude Desktop
  const userMessage = "Can you analyze my project's code quality?";
  
  // Claude Desktop's host springs into action
  // 1. Check available MCP servers
  const availableServers = ['filesystem', 'github', 'eslint'];
  
  // 2. Determine which ones we need
  const requiredServers = ['filesystem', 'eslint'];
  
  // 3. Ask for permission if needed
  const permissionGranted = await requestPermission({
    servers: requiredServers,
    operations: ['read files', 'run code analysis']
  });
  
  if (!permissionGranted) {
    return "I need permission to analyze your code.";
  }
  
  // 4. Execute the analysis
  const files = await mcp.filesystem.listFiles({ 
    directory: './src',
    pattern: '*.js'
  });
  
  const issues = [];
  for (const file of files) {
    const content = await mcp.filesystem.readFile(file);
    const analysis = await mcp.eslint.analyze({
      code: content,
      filename: file
    });
    issues.push(...analysis.issues);
  }
  
  // 5. Present results to user
  return {
    summary: `Analyzed ${files.length} files, found ${issues.length} issues`,
    topIssues: issues.slice(0, 5),
    recommendation: "Consider addressing the critical issues first."
  };
}

MCP Panel

Request: "Organize my downloads folder"

→ Server: FileSystem

→ Permission: [Allow] [Deny]

→ Result: ✅ 23 files organized (142ms)

Run Code

Next Step

5.6 Claude Experiences

5.6 Claude Experiences

Common Patterns and Best Practices

Common Patterns and Best Practices

Based on real usage, here are patterns that work:

Based on real usage, here are patterns that work:

Real World Example

Real World Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// Pattern 1: Graceful Degradation
class ResilientHost {
  async executeWithFallback(primary, fallback) {
    try {
      return await primary();
    } catch (error) {
      console.warn('Primary failed, trying fallback:', error.message);
      return await fallback();
    }
  }
}

// Pattern 2: Request Batching
class BatchingHost {
  constructor() {
    this.pendingRequests = [];
    this.batchTimer = null;
  }
  
  async request(client, method, params) {
    return new Promise((resolve, reject) => {
      this.pendingRequests.push({
        client, method, params, resolve, reject
      });
      
      if (!this.batchTimer) {
        this.batchTimer = setTimeout(() => this.flush(), 10);
      }
    });
  }
  
  async flush() {
    const batch = this.pendingRequests.splice(0);
    this.batchTimer = null;
    
    // Group by client
    const byClient = this.groupBy(batch, 'client');
    
    // Send batched requests
    for (const [client, requests] of Object.entries(byClient)) {
      const batchRequest = {
        method: 'batch',
        params: requests.map(r => ({
          method: r.method,
          params: r.params
        }))
      };
      
      try {
        const results = await client.request(batchRequest);
        requests.forEach((r, i) => r.resolve(results[i]));
      } catch (error) {
        requests.forEach(r => r.reject(error));
      }
    }
  }
}

// Pattern 3: Capability Caching
class CachingHost {
  constructor() {
    this.capabilityCache = new Map();
    this.cacheTimeout = 5 * 60 * 1000; // 5 minutes
  }
  
  async getCapabilities(client) {
    const cached = this.capabilityCache.get(client.id);
    
    if (cached && Date.now() - cached.timestamp < this.cacheTimeout) {
      return cached.capabilities;
    }
    
    const capabilities = await client.request('capabilities/list');
    
    this.capabilityCache.set(client.id, {
      capabilities,
      timestamp: Date.now()
    });
    
    return capabilities;
  }
}

Degradation

Performance

Caching

Pattern

Graceful Degradation

Problem

Primary call may fail (network error, timeout).

Solution

Try primary(); if it fails → use fallback()

> Run: primary() failed (120ms) → fallback() succeeded (18ms)

Result: "Served from fallback"

Degradation

Performance

Caching

Pattern

Graceful Degradation

Problem

Primary call may fail (network error, timeout).

Solution

Try primary(); if it fails → use fallback()

> Run: primary() failed (120ms) → fallback() succeeded (18ms)

Result: "Served from fallback"

Degradation

Performance

Caching

Pattern

Graceful Degradation

Problem

Primary call may fail (network error, timeout).

Solution

Try primary(); if it fails → use fallback()

> Run: primary() failed (120ms) → fallback() succeeded (18ms)

Result: "Served from fallback"

The Future is Already Here

The Future is Already Here

MCP hosts are evolving based on real user needs:

MCP hosts are evolving based on real user needs:

MCP Host Roadmap

MCP Host Roadmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// What's actually being developed (not speculation)
interface MCPHostRoadmap {
  // Coming soon (based on GitHub discussions)
  inDevelopment: {
    // Better error handling
    structuredErrors: 'Standardized error codes and recovery suggestions',
    
    // Performance improvements  
    connectionPooling: 'Reuse connections for better performance',
    
    // Enhanced security
    sandboxing: 'Run MCP servers in isolated environments',
    
    // Developer experience
    debugging: 'Better tools for debugging MCP connections'
  };
  
  // Community requests (from actual GitHub issues)
  communityWishlist: [
    'Hot-reload configuration changes',
    'Built-in health checks for servers',
    'Automatic retry with exponential backoff',
    'Request/response logging and replay',
    'Load balancing across multiple instances'
  ];
}

// Real example: Community-built enhancement
class EnhancedHost extends BasicHost {
  // Auto-retry failed requests (popular request)
  async requestWithRetry(client, method, params, maxRetries = 3) {
    let lastError;
    
    for (let i = 0; i < maxRetries; i++) {
      try {
        return await client.request(method, params);
      } catch (error) {
        lastError = error;
        
        // Exponential backoff
        const delay = Math.min(1000 * Math.pow(2, i), 10000);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
    
    throw lastError;
  }
  
  // Health checking (another popular request)
  async startHealthChecks() {
    setInterval(async () => {
      for (const [name, client] of this.clients) {
        try {
          await client.request('ping', {});
          console.log(`✓ ${name} is healthy`);
        } catch (error) {
          console.log(`✗ ${name} is unhealthy:`, error.message);
          this.reconnect(name);
        }
      }
    }, 30000); // Every 30 seconds
  }
}

5.7 Workflow

5.7 Workflow

Making It Real

Making It Real

The true power of MCP hosts isn't in fictional metrics—it's in solving real problems:

The true power of MCP hosts isn't in fictional metrics—it's in solving real problems:

MCP Host Roadmap

MCP Host Roadmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// A real automation that MCP makes possible
async function weeklyReportAutomation(host) {
  console.log('Starting weekly report generation...');
  
  // Gather data from multiple sources
  const githubData = await host.clients.get('github').request('tools/call', {
    name: 'get_weekly_activity',
    arguments: { repos: ['my-project'] }
  });
  
  const calendarData = await host.clients.get('calendar').request('tools/call', {
    name: 'get_past_events',
    arguments: { days: 7 }
  });
  
  const emailData = await host.clients.get('email').request('tools/call', {
    name: 'search_messages',
    arguments: { query: 'is:important from:last-week' }
  });
  
  // Generate report
  const report = `
# Weekly Report - ${new Date().toLocaleDateString()}

## Development Activity
- Commits: ${githubData.commitCount}
- PRs Merged: ${githubData.mergedPRs.length}
- Issues Closed: ${githubData.closedIssues.length}

## Meetings
${calendarData.events.map(e => `- ${e.title} (${e.duration})`).join('\n')}

## Important Communications  
${emailData.messages.map(m => `- ${m.subject} from ${m.sender}`).join('\n')}
`;
  
  // Save the report
  await host.clients.get('filesystem').request('tools/call', {
    name: 'write_file',
    arguments: {
      path: `./reports/week-${Date.now()}.md`,
      content: report
    }
  });
  
  console.log('Report generated successfully!');
  return report;
}

// This is real - you can build this today

5.8 Your MCP Journey

5.8 Your MCP Journey