Overview

The @mcp-b/transports package provides comprehensive transport implementations for the Model Context Protocol (MCP), enabling communication between MCP clients and servers across different browser environments including Chrome extensions, browser tabs, WebSockets, and Web Workers. These transports are production-tested and designed to work seamlessly with the official @modelcontextprotocol/sdk.

Installation

npm install @mcp-b/transports

Transport Types

ExtensionServerTransport

Used by Chrome extensions to accept MCP connections from other extensions or web pages. This is the primary transport for building MCP-enabled Chrome extensions.
import { ExtensionServerTransport } from '@mcp-b/transports';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// In your Chrome extension's background script
chrome.runtime.onConnectExternal.addListener((port) => {
  const server = new McpServer({
    name: 'my-extension-server',
    version: '1.0.0'
  });
  
  // Create transport with keep-alive for persistent connections
  const transport = new ExtensionServerTransport(port, {
    keepAlive: true,
    keepAliveInterval: 25000 // 25 seconds
  });
  
  server.connect(transport);
  
  // Handle disconnection
  port.onDisconnect.addListener(() => {
    server.close();
    transport.close();
  });
});

ExtensionClientTransport

Used to connect to Chrome extensions that expose MCP servers. Supports auto-reconnection and is commonly used in sidepanels and popups.
import { ExtensionClientTransport } from '@mcp-b/transports';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

// Create transport with auto-reconnect
const transport = new ExtensionClientTransport({
  portName: 'mcp',
  autoReconnect: true
});

// Create and connect MCP client
const client = new Client({
  name: 'Extension Sidepanel',
  version: '1.0.0'
});

await client.connect(transport);

TabServerTransport

Used by MCP servers running in browser tabs to accept connections.
import { TabServerTransport } from '@mcp-b/transports';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// Create MCP server
const server = new McpServer({
  name: 'PersonalAIWebsite',
  version: '1.0.0',
});

// Create transport with allowed origins
const transport = new TabServerTransport({
  allowedOrigins: ['*'] // Or specify specific origins for security
});

// Connect server to transport
await server.connect(transport);

TabClientTransport

Used by MCP clients to connect to servers in the same browser context.
import { TabClientTransport } from '@mcp-b/transports';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

// Create transport targeting current origin
const transport = new TabClientTransport({
  targetOrigin: window.location.origin
});

// Create and connect MCP client
const client = new Client({
  name: 'web-client',
  version: '1.0.0'
}, {
  capabilities: {}
});

await client.connect(transport);

WebSocketClientTransport & WebSocketServerTransport

For real-time bidirectional communication over WebSockets.
import { WebSocketClientTransport, WebSocketServerTransport } from '@mcp-b/transports';

// Client side
const clientTransport = new WebSocketClientTransport({
  url: 'ws://localhost:3000',
  autoReconnect: true
});

// Server side (Node.js or similar)
const serverTransport = new WebSocketServerTransport({
  port: 3000
});

WebWorkerClientTransport & WebWorkerServerTransport

For running MCP servers in Web Workers for background processing.
// In main thread
import { WebWorkerClientTransport } from '@mcp-b/transports';

const worker = new Worker('/mcp-worker.js');
const transport = new WebWorkerClientTransport(worker);

// In worker (mcp-worker.js)
import { WebWorkerServerTransport } from '@mcp-b/transports';

const transport = new WebWorkerServerTransport();
const server = new McpServer({ name: 'worker-server', version: '1.0.0' });
server.connect(transport);

Production Usage Examples

Chrome Extension with MCP Server

From the actual WebMCP Chrome extension implementation:

Counter Application (Vanilla TypeScript)

From the vanilla-ts example:
import { TabServerTransport } from '@mcp-b/transports';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import z from 'zod';

const server = new McpServer({
  name: 'PersonalAIWebsite',
  version: '1.0.0',
});

// Register tools with the server
server.addTool({
  name: 'incrementCounter',
  description: 'Increment the counter',
  inputSchema: z.object({}),
  handler: async () => {
    counter++;
    updateDisplay();
    return {
      content: [{ 
        type: 'text', 
        text: `Counter incremented to ${counter}` 
      }]
    };
  }
});

// Set up transport
const transport = new TabServerTransport({
  allowedOrigins: ['*']
});

// Connect and start serving
await server.connect(transport);
console.log('MCP Server running in browser tab');

React Flow Voice Agent

From the ReactFlowVoiceAgent example:
import { TabClientTransport } from '@mcp-b/transports';

async function mcpConnect() {
  // Create transport for same-origin communication
  const transport = new TabClientTransport({
    targetOrigin: window.location.origin
  });
  
  // Use with MCP client
  const client = new Client({
    name: 'voice-agent',
    version: '1.0.0'
  }, {
    capabilities: {}
  });
  
  await client.connect(transport);
  
  // Now you can list and call tools
  const tools = await client.listTools();
  console.log('Available tools:', tools);
}

External Extension Connection Manager

Handling connections from other extensions:
import { ExtensionServerTransport } from '@mcp-b/transports';
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

interface ExternalConnection {
  server: McpServer;
  transport: ExtensionServerTransport;
}

export function initExternalExtensionPortListener(
  serverFactory: (extensionId: string) => McpServer
) {
  const connectionsByExtensionId = new Map<string, ExternalConnection>();

  chrome.runtime.onConnectExternal.addListener((port) => {
    const extensionId = port.sender?.id;
    if (!extensionId) return;

    // Close existing connection if present
    const existing = connectionsByExtensionId.get(extensionId);
    if (existing) {
      existing.server.close();
      existing.transport.close();
      connectionsByExtensionId.delete(extensionId);
    }

    const server = serverFactory(extensionId);
    const transport = new ExtensionServerTransport(port, {
      keepAlive: true,
      keepAliveInterval: 25_000,
    });
    
    server.connect(transport);
    connectionsByExtensionId.set(extensionId, { server, transport });

    port.onDisconnect.addListener(() => {
      const tracked = connectionsByExtensionId.get(extensionId);
      if (tracked) {
        tracked.server.close();
        tracked.transport.close();
        connectionsByExtensionId.delete(extensionId);
      }
    });
  });
}

Configuration Options

ExtensionServerTransport Options

OptionTypeRequiredDescription
portchrome.runtime.PortYesChrome runtime port object
keepAlivebooleanNoEnable keep-alive ping/pong (default: false)
keepAliveIntervalnumberNoKeep-alive interval in ms (default: 30000)

ExtensionClientTransport Options

OptionTypeRequiredDescription
portNamestringNoPort name for connection (default: ‘mcp’)
autoReconnectbooleanNoAuto-reconnect on disconnect (default: false)
extensionIdstringNoTarget extension ID (for cross-extension)

TabServerTransport Options

OptionTypeRequiredDescription
allowedOriginsstring[]YesArray of allowed origins or ['*'] for all
handleConnectionfunctionNoCallback when client connects
handleDisconnectionfunctionNoCallback when client disconnects

TabClientTransport Options

OptionTypeRequiredDescription
targetOriginstringYesOrigin of the target window

Usage with MCP SDK

This package is designed to work with the official MCP SDK:
import { TabServerTransport } from '@mcp-b/transports';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// Or for clients:
import { TabClientTransport } from '@mcp-b/transports';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

TypeScript Support

Full TypeScript definitions are included. The transports implement the standard MCP transport interfaces:
interface Transport {
  // Implementation details handled by the transport
  start(): Promise<void>;
  send(message: JSONRPCMessage): Promise<void>;
  close(): Promise<void>;
}

Browser Compatibility

  • Chrome/Chromium: Full support
  • Firefox: Tab transports supported, extension transport requires adaptation
  • Safari: Tab transports supported, no extension support
  • Edge: Full support (Chromium-based)

Security Considerations

CORS and Origins

When using TabServerTransport, always specify explicit allowed origins in production:
// ❌ Don't use wildcards in production
const transport = new TabServerTransport({
  allowedOrigins: ['*']
});

// ✅ Specify exact origins
const transport = new TabServerTransport({
  allowedOrigins: [
    'https://myapp.com',
    'https://app.myapp.com'
  ]
});

Extension Permissions

When using ExtensionClientTransport, ensure your extension manifest includes appropriate permissions:
{
  "permissions": ["tabs", "scripting"],
  "host_permissions": ["<all_urls>"],
  "externally_connectable": {
    "matches": ["*://*.yourdomain.com/*"]
  }
}

Resources