Skip to content

Proposal: API for connecting to remote MCP servers #83

@hemanth

Description

@hemanth

The current WebMCP proposal focuses on client-side tools implemented in JavaScript. However, there's a significant use case for bridging existing remote MCP servers to browser AI agents.

Use Case

Many MCP servers already exist (Stripe, Slack, GitHub, Notion, etc.) that provide valuable tools. Currently, to expose these to browser AI agents via WebMCP, developers must:

  1. Manually fetch tools from the remote server via tools/list
  2. Create wrapper execute() functions that proxy calls via tools/call
  3. Handle authentication, session management, and SSE parsing
  4. Register each tool with navigator.modelContext.provideContext()

Example: Current Workaround

// Current approach requires manual bridging
async function bridgeRemoteMCP(serverUrl) {
  // Initialize MCP session
  const initRes = await fetch(serverUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Accept': 'application/json, text/event-stream' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'initialize',
      params: { protocolVersion: '2024-11-05', capabilities: { tools: {} } }
    })
  });
  
  const sessionId = initRes.headers.get('Mcp-Session-Id');
  
  // Fetch tools
  const toolsRes = await fetch(serverUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'Mcp-Session-Id': sessionId },
    body: JSON.stringify({ jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} })
  });
  
  const { result } = await toolsRes.json();
  
  // Manually wrap each tool for WebMCP
  const webMCPTools = result.tools.map(tool => ({
    name: tool.name,
    description: tool.description,
    inputSchema: tool.inputSchema,
    execute: async (args) => {
      const res = await fetch(serverUrl, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', 'Mcp-Session-Id': sessionId },
        body: JSON.stringify({
          jsonrpc: '2.0',
          id: Date.now(),
          method: 'tools/call',
          params: { name: tool.name, arguments: args }
        })
      });
      return res.json();
    }
  }));
  
  navigator.modelContext.provideContext({ tools: webMCPTools });
}

// Usage
bridgeRemoteMCP('https://tc39-mcp.deno.dev/mcp');

Proposed API

A native API would simplify this significantly:

// Connect to a remote MCP server
const connection = await navigator.modelContext.connectServer({
  url: 'https://tc39-mcp.deno.dev/mcp',
  auth: { type: 'bearer', token: '...' } // optional
});

// Tools are automatically discovered and registered
// Or manually control registration:
const tools = await connection.listTools();
navigator.modelContext.provideContext({ tools });

Benefits

  • Leverages existing MCP ecosystem without requiring servers to change
  • Enables human-in-the-loop workflows with remote services (as described in the proposal)
  • Maintains WebMCP's security model (user sees which tools are being used)
  • Complements, not replaces, client-side tools
  • Standardizes auth, session management, and SSE handling

Considerations

  • CORS requirements for remote MCP servers
  • OAuth flow coordination (dynamic client registration per RFC 7591)
  • Session management across page navigations
  • Whether this should be a separate API or extension of modelContext

This would make WebMCP a bridge between the broader MCP ecosystem and browser AI agents, enabling the collaborative human-agent workflows described in the proposal without requiring every service to implement client-side tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions