Skip to content

Proposal: Standard MCP-to-WebMCP tool format converter #84

@hemanth

Description

@hemanth

Context

This proposal complements #83 (API for connecting to remote MCP servers). Even if WebMCP doesn't natively support remote MCP connections, there should be a standardized way to convert MCP tool definitions to WebMCP format.

Problem

MCP and WebMCP tool schemas are similar but not identical. Currently, developers bridging MCP servers to WebMCP must manually handle:

  1. Schema mapping: MCP inputSchema → WebMCP inputSchema (mostly compatible, but edge cases exist)
  2. Response format: MCP content arrays → WebMCP content format
  3. Error handling: MCP JSON-RPC errors → WebMCP error responses
  4. Metadata preservation: Tool descriptions, annotations, etc.

Current Manual Conversion

// MCP tool from tools/list response
const mcpTool = {
  name: "search_proposals",
  description: "Search TC39 proposals by keyword",
  inputSchema: {
    type: "object",
    properties: {
      query: { type: "string", description: "Search term" },
      stage: { type: "number", description: "Filter by stage" }
    },
    required: ["query"]
  }
};

// Manual conversion to WebMCP format
const webMCPTool = {
  name: mcpTool.name,
  description: mcpTool.description || '',
  inputSchema: mcpTool.inputSchema || { type: 'object', properties: {} },
  execute: async (args) => {
    // Developer must implement the bridge logic
    const response = await fetch(mcpServerUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: Date.now(),
        method: 'tools/call',
        params: { name: mcpTool.name, arguments: args }
      })
    });
    
    const result = await response.json();
    
    // Convert MCP response format to WebMCP
    if (result.error) {
      return { content: [{ type: 'text', text: `Error: ${result.error.message}` }] };
    }
    
    // Handle MCP content array format
    if (result.result?.content) {
      return result.result;
    }
    
    // Wrap raw results
    return {
      content: [{
        type: 'text',
        text: typeof result.result === 'string' 
          ? result.result 
          : JSON.stringify(result.result, null, 2)
      }]
    };
  }
};

navigator.modelContext.provideContext({ tools: [webMCPTool] });

Proposed Solution

A utility function or class in the WebMCP spec that standardizes this conversion:

// Option A: Static utility
const webMCPTools = WebMCPToolConverter.fromMCP(mcpTools, {
  executor: (toolName, args) => callRemoteMCP(toolName, args)
});

// Option B: Built into modelContext
navigator.modelContext.registerMCPTools(mcpTools, {
  endpoint: 'https://example.com/mcp',
  headers: { 'Authorization': 'Bearer ...' }
});

// Option C: Conversion helper only (no execution)
const schema = WebMCPToolConverter.convertSchema(mcpInputSchema);

Benefits

  1. Interoperability: Easy bridging between MCP ecosystem and WebMCP
  2. Consistency: Standard error handling and response formatting
  3. Reduced boilerplate: Developers don't reinvent the conversion logic
  4. Forward compatibility: Single place to update when formats evolve

Considerations

  • Should this be normative spec or informative guidance?
  • Should it handle streaming responses from MCP servers?
  • How to handle MCP-specific features not in WebMCP (resources, prompts, sampling)?

This would lower the barrier for developers wanting to expose existing MCP tools to browser AI agents.

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