> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-b-sync-npm-packages-docs-bf03420.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# @mcp-b/transports

> Browser-specific transport implementations for Model Context Protocol including TabServerTransport, IframeTransport, and ExtensionServerTransport for web and extension MCP communication.

Transports are the communication layer that routes MCP messages between different browser contexts. Think of them as the plumbing that lets your tools talk to agents, whether they're in the same tab, different tabs, or extension pages.

## Prerequisites

* **@modelcontextprotocol/sdk** - Official MCP SDK
* **Modern browser** with ES2020+ support
* **TypeScript 5.0+** (recommended for type safety)
* **Chrome Extension Manifest V3** (for extension transports)
* Understanding of async/await and Promises

## Installation

```bash icon="npm" theme={null}
npm install @mcp-b/transports @modelcontextprotocol/sdk
```

## Transport Types

### Tab Transports (In-Page Communication)

Use `TabServerTransport` and `TabClientTransport` when your MCP server and client are running in the same browser tab. The transport uses `window.postMessage` for secure communication with origin validation.

### Iframe Transports (Parent-Child Communication)

Use `IframeParentTransport` and `IframeChildTransport` for cross-origin communication between a parent page and an iframe. These transports are specifically designed for iframe scenarios and support cross-origin messaging.

### Extension Transports (Cross-Context Communication)

Use `ExtensionClientTransport` and `ExtensionServerTransport` for communication between browser extension components (sidebar, popup, background) and web pages with MCP servers.

## Tab Transport Examples

### Server Setup (Web Page)

Create an MCP server in your web page and expose it via `TabServerTransport`:

```typescript "server.ts - Tab server setup" twoslash lines icon="server" expandable highlight={36-39} theme={null}
import { TabServerTransport } from "@mcp-b/transports";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

// Create MCP server with tools
const server = new McpServer(
  {
    name: "TODO-APP",
    version: "1.0.0",
  },
  {
    instructions:
      "You are a helpful assistant that can create, update, and delete todos.",
  }
);

// Register a tool
server.tool(
  "createTodo",
  "Creates a new todo item for the current user",
  {
    todoText: z.string().describe("The content of the todo item."),
  },
  async (args) => {
    // Implementation here
    return {
      content: [
        {
          type: "text",
          text: `Todo created: "${args.todoText}"`,
        },
      ],
    };
  }
);

// Connect to transport with CORS configuration
const transport = new TabServerTransport({
  allowedOrigins: ["*"], // Configure based on your security needs
});
await server.connect(transport);
```

### Client Setup (Same Page)

Connect to the server from within the same page or from an extension content script:

```typescript "client.ts - Tab client setup" twoslash lines icon="plug" highlight={5-7,10-13,20-23} theme={null}
import { TabClientTransport } from "@mcp-b/transports";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

// Create transport with target origin
const transport = new TabClientTransport({
  targetOrigin: window.location.origin,
});

// Discover available servers
const availableServers = await transport.discover();
if (availableServers.length > 0) {
  console.log(`Found server: ${availableServers[0].implementation.name}`);
}

// Create and connect client
const client = new Client({
  name: "ExtensionProxyClient",
  version: "1.0.0",
});

await client.connect(transport);

// Use the client
const result = await client.callTool({
  name: "createTodo",
  arguments: { todoText: "Buy groceries" },
});
```

## Iframe Transport Examples

### Server Setup (Inside Iframe)

Create an MCP server inside an iframe that can be accessed by the parent page:

```typescript "iframe-server.ts - Iframe child setup" twoslash lines icon="window" expandable highlight={52-56} theme={null}
import { IframeChildTransport } from "@mcp-b/transports";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { z } from "zod";

// Create MCP server
const server = new Server(
  {
    name: "IframeApp",
    version: "1.0.0",
  },
  {
    capabilities: {
      tools: {},
    },
  }
);

// Register tools
server.setRequestHandler('tools/list', async () => {
  return {
    tools: [
      {
        name: "getIframeData",
        description: "Get data from the iframe application",
        inputSchema: {
          type: "object",
          properties: {
            key: { type: "string", description: "Data key to retrieve" }
          },
          required: ["key"]
        }
      }
    ]
  };
});

server.setRequestHandler('tools/call', async (request) => {
  if (request.params.name === "getIframeData") {
    const { key } = request.params.arguments;
    return {
      content: [
        {
          type: "text",
          text: `Retrieved: ${key}`,
        },
      ],
    };
  }
  throw new Error(`Unknown tool: ${request.params.name}`);
});

// Connect to iframe transport
const transport = new IframeChildTransport({
  allowedOrigins: ["https://parent-app.com"], // Parent page origin
  // or use ['*'] to allow any origin (less secure)
});

await server.connect(transport);
```

### Client Setup (Parent Page)

Connect from the parent page to the iframe's MCP server:

```typescript "parent-client.ts - Iframe parent setup" twoslash lines icon="window-maximize" expandable highlight={9-13,26-31} theme={null}
import { IframeParentTransport } from "@mcp-b/transports";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

// Get reference to iframe element
const iframe = document.querySelector('iframe');

// Wait for iframe to load
iframe.addEventListener('load', async () => {
  // Create transport targeting the iframe
  const transport = new IframeParentTransport({
    iframe: iframe,
    targetOrigin: 'https://iframe-app.com', // Iframe page origin
  });

  // Create MCP client
  const client = new Client(
    {
      name: "ParentPage",
      version: "1.0.0",
    },
    {
      capabilities: {}
    }
  );

  // Connect and use
  await client.connect(transport);

  // List available tools from iframe
  const tools = await client.listTools();
  console.log("Tools from iframe:", tools.tools);

  // Call a tool from the iframe
  const result = await client.callTool({
    name: "getIframeData",
    arguments: { key: "user-preferences" },
  });
});
```

## Extension Transport Examples

### Background Script Setup

The extension background script acts as a hub, aggregating tools from multiple tabs:

```typescript "background.ts - Extension hub" twoslash lines icon="layer-group" expandable highlight={16-23,26-31} theme={null}
import { ExtensionServerTransport } from "@mcp-b/transports";
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

class McpHub {
  private server: McpServer;

  constructor() {
    this.server = new McpServer({
      name: "Extension-Hub",
      version: "1.0.0",
    });

    this.setupConnections();
  }

  private setupConnections() {
    chrome.runtime.onConnect.addListener((port) => {
      if (port.name === "mcp") {
        this.handleUiConnection(port);
      } else if (port.name === "mcp-content-script-proxy") {
        this.handleContentScriptConnection(port);
      }
    });
  }

  private async handleUiConnection(port: chrome.runtime.Port) {
    const transport = new ExtensionServerTransport(port, {
      keepAlive: true,
      keepAliveInterval: 25_000,
    });
    await this.server.connect(transport);
  }
}
```

### Content Script Bridge

Content scripts act as a bridge between the page's MCP server and the extension:

```typescript "content-script.ts - Bridge to background" twoslash lines icon="bridge" expandable highlight={5-7,14-17,20-23,30-42} theme={null}
import { TabClientTransport } from "@mcp-b/transports";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

// Connect to the page's MCP server
const transport = new TabClientTransport({
  targetOrigin: window.location.origin,
});

const client = new Client({
  name: "ExtensionProxyClient",
  version: "1.0.0",
});

// Connect to extension background
const backgroundPort = chrome.runtime.connect({
  name: "mcp-content-script-proxy",
});

// Discover and connect to page server
await client.connect(transport);
const pageTools = await client.listTools();

// Register tools with background hub
backgroundPort.postMessage({
  type: "register-tools",
  tools: pageTools.tools,
});

// Handle tool execution requests from background
backgroundPort.onMessage.addListener(async (message) => {
  if (message.type === "execute-tool") {
    const result = await client.callTool({
      name: message.toolName,
      arguments: message.args || {},
    });

    backgroundPort.postMessage({
      type: "tool-result",
      requestId: message.requestId,
      data: { success: true, payload: result },
    });
  }
});
```

### Extension UI Client

Connect from the extension's sidebar or popup to use tools from all connected pages:

```typescript "sidepanel.ts - Extension UI" twoslash lines icon="sidebar" highlight={5-7,15-17,20-24} theme={null}
import { ExtensionClientTransport } from "@mcp-b/transports";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";

// Create transport - connects to the extension's background script
const transport = new ExtensionClientTransport({
  portName: "mcp",
});

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

// Connect and use
await client.connect(transport);

// List all available tools from all connected tabs
const tools = await client.listTools();

// Call a tool from a specific website
const result = await client.callTool({
  name: "website_tool_example_com_createTodo",
  arguments: { todoText: "Review PR" },
});
```

## Configuration Options

### ExtensionServerTransport Options

| Option              | Type                  | Required | Description                                  |
| ------------------- | --------------------- | -------- | -------------------------------------------- |
| `port`              | `chrome.runtime.Port` | Yes      | Chrome runtime port object                   |
| `keepAlive`         | `boolean`             | No       | Enable keep-alive ping/pong (default: false) |
| `keepAliveInterval` | `number`              | No       | Keep-alive interval in ms (default: 30000)   |

### ExtensionClientTransport Options

| Option          | Type      | Required | Description                                   |
| --------------- | --------- | -------- | --------------------------------------------- |
| `portName`      | `string`  | No       | Port name for connection (default: 'mcp')     |
| `autoReconnect` | `boolean` | No       | Auto-reconnect on disconnect (default: false) |
| `extensionId`   | `string`  | No       | Target extension ID (for cross-extension)     |

### TabServerTransport Options

| Option           | Type       | Required | Description                                 |
| ---------------- | ---------- | -------- | ------------------------------------------- |
| `allowedOrigins` | `string[]` | Yes      | Array of allowed origins or `['*']` for all |

### TabClientTransport Options

| Option         | Type     | Required | Description                 |
| -------------- | -------- | -------- | --------------------------- |
| `targetOrigin` | `string` | Yes      | Origin of the target window |

### IframeParentTransport Options

| Option              | Type                | Required | Description                                             |
| ------------------- | ------------------- | -------- | ------------------------------------------------------- |
| `iframe`            | `HTMLIFrameElement` | Yes      | Reference to the iframe element                         |
| `targetOrigin`      | `string`            | Yes      | Expected origin of the iframe (for security)            |
| `channelId`         | `string`            | No       | Channel identifier (default: 'mcp-iframe')              |
| `checkReadyRetryMs` | `number`            | No       | Retry interval for ready handshake in ms (default: 250) |

### IframeChildTransport Options

| Option               | Type       | Required | Description                                                       |
| -------------------- | ---------- | -------- | ----------------------------------------------------------------- |
| `allowedOrigins`     | `string[]` | Yes      | Whitelist of parent origins allowed to connect                    |
| `channelId`          | `string`   | No       | Channel identifier (default: 'mcp-iframe')                        |
| `serverReadyRetryMs` | `number`   | No       | Retry interval for broadcasting ready signal in ms (default: 250) |

## Key Features

* **Automatic Server Discovery**: Tab clients can discover available servers
* **Cross-Origin Support**: Configure CORS for tab and iframe transports
* **Parent-Child Communication**: Iframe transports enable secure cross-origin iframe communication
* **Ready Handshake Protocol**: Iframe transports handle iframe loading timing issues automatically
* **Cross-Extension Communication**: Extensions can expose APIs to other extensions
* **Tool Namespacing**: Extension hub prefixes tools to avoid conflicts
* **Connection Management**: Automatic cleanup when tabs close
* **Keep-Alive Support**: Maintain persistent connections
* **Type Safety**: Full TypeScript support with proper typing

## Security Considerations

* **Tab transports** respect origin restrictions
* **Iframe transports** validate origins on both parent and child sides
  * Always specify explicit `targetOrigin` (never use `'*'` in production)
  * Configure `allowedOrigins` to whitelist only trusted parent domains
  * Use `postMessage` API for secure cross-origin communication
* **Extension transports** use Chrome's secure message passing
* **External extension transports** require `externally_connectable` manifest configuration
* Server extensions should validate incoming connections from other extensions
* Configure `allowedOrigins` appropriately for your use case
* Tools execute in their original context (web page, iframe, or extension)

## Related Documentation

<CardGroup cols={2}>
  <Card title="@mcp-b/global" icon="globe" href="/packages/global">
    Web Model Context API polyfill
  </Card>

  <Card title="@mcp-b/react-webmcp" icon="react" href="/packages/react-webmcp">
    React hooks for MCP
  </Card>

  <Card title="@mcp-b/extension-tools" icon="puzzle-piece" href="/packages/extension-tools">
    Chrome Extension API wrappers
  </Card>

  <Card title="Core Concepts" icon="diagram-project" href="/concepts/overview">
    Transport architecture diagrams
  </Card>
</CardGroup>

**See also:**

* [Advanced Patterns](/advanced) - Extension and multi-tab scenarios
* [Security Guide](/security) - Origin validation and transport security
* [Troubleshooting](/troubleshooting) - Common transport issues

## External Resources

* [@modelcontextprotocol/sdk](https://www.npmjs.com/package/@modelcontextprotocol/sdk) - Official MCP SDK
* [MCP Protocol Specification](https://modelcontextprotocol.io) - Protocol details
* [Chrome Extension Development](https://developer.chrome.com/docs/extensions) - Extension APIs
* [GitHub Repository](https://github.com/WebMCP-org/npm-packages) - Source code
