
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@mcp-b/transports
Advanced tools
Browser transport implementations for Model Context Protocol (MCP) - postMessage, Chrome extension messaging, and iframe communication for AI agents and LLMs
Browser transport implementations for Model Context Protocol (MCP) - Connect AI agents like Claude, ChatGPT, and Gemini to web applications
Full Documentation | Quick Start | Transport Concepts
@mcp-b/transports provides browser-native MCP transport implementations that enable AI agents and LLMs to communicate with web applications. Whether you're building Chrome extensions, embedded iframes, or in-page AI integrations, this library provides the secure messaging layer you need.
| Feature | Benefit |
|---|---|
| Multiple Transport Types | Choose the right transport for your architecture - Tab, Iframe, or Extension |
| Secure by Default | Origin validation, CORS configuration, and Chrome's secure messaging APIs |
| AI-Agent Ready | Built specifically for MCP, the standard protocol for AI tool integration |
| TypeScript First | Full type safety with comprehensive type definitions |
| Zero Dependencies | Only requires zod for schema validation |
| Works Everywhere | Chrome, Firefox, Edge, and any Chromium-based browser |
npm install @mcp-b/transports
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.
Use ExtensionClientTransport and ExtensionServerTransport for communication between browser extension components (sidebar, popup, background) and web pages with MCP servers.
Use ExtensionExternalClientTransport and ExtensionExternalServerTransport for communication between different browser extensions, enabling one extension to access MCP servers hosted by another extension.
Create an MCP server in your web page and expose it via TabServerTransport:
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);
Connect to the server from within the same page or from an extension content script:
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" },
});
targetOrigin (required): Origin expected from the server window (for security).channelId: Override the default channel identifier (default: mcp-default).allowedOrigins (required): Whitelist of origins allowed to connect (for security).channelId: Override the default channel identifier (default: mcp-default).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.
Create an MCP server inside an iframe that can be accessed by the parent page:
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.tool(
"getIframeData",
"Get data from the iframe application",
{
key: z.string().describe("Data key to retrieve"),
},
async (args) => {
return {
content: [
{
type: "text",
text: `Retrieved: ${args.key}`,
},
],
};
}
);
// 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);
Connect from the parent page to the iframe's MCP server:
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",
});
// 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" },
});
});
iframe (required): Reference to the HTMLIFrameElementtargetOrigin (required): Expected origin of the iframe (for security)channelId: Override the default channel identifier (default: mcp-iframe)checkReadyRetryMs: Interval to retry the ready handshake if iframe isn't ready yet (default: 250ms)allowedOrigins (required): Whitelist of parent origins allowed to connect (for security)channelId: Override the default channel identifier (default: mcp-iframe)serverReadyRetryMs: Interval to retry broadcasting ready signal to parent (default: 250ms)Iframe transports are designed for cross-origin communication:
postMessage APIThe extension background script acts as a hub, aggregating tools from multiple tabs:
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);
await this.server.connect(transport);
}
}
Content scripts act as a bridge between the page's MCP server and the extension:
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 },
});
}
});
Connect from the extension's sidebar or popup to use tools from all connected pages:
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" },
});
Create an MCP server in Extension 1 that can be accessed by other extensions:
import { ExtensionExternalServerTransport } 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: "MyExtensionAPI",
version: "1.0.0",
},
{
instructions: "Extension API for cross-extension communication",
}
);
// Register tools
server.tool("getBookmarks", "Retrieves user bookmarks", {}, async () => {
const bookmarks = await chrome.bookmarks.getTree();
return {
content: [
{
type: "text",
text: JSON.stringify(bookmarks, null, 2),
},
],
};
});
// Set up external connection listener in background script
chrome.runtime.onConnectExternal.addListener(async (port) => {
if (port.name === "mcp") {
// Optional: Add connection validation here
if (port.sender?.id !== "allowed-extension-id") {
port.disconnect();
return;
}
const transport = new ExtensionServerTransport(port);
await server.connect(transport);
}
});
Connect from Extension 2 to use Extension 1's MCP server:
import { ExtensionExternalClientTransport } from "@mcp-b/transports";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
// Create transport targeting Extension 1
const transport = new ExtensionClientTransport({
extensionId: "server-extension-id",
portName: "mcp",
});
// Create MCP client
const client = new Client({
name: "ClientExtension",
version: "1.0.0",
});
// Connect and use
await client.connect(transport);
// List available tools from Extension 1
const tools = await client.listTools();
console.log("Available tools:", tools.tools);
// Call a tool from Extension 1
const result = await client.callTool({
name: "getBookmarks",
arguments: {},
});
runtime.onConnectExternal APITabServerTransport and listens for messages via window.postMessageTabClientTransport to connect to the server using the same channelTabServerTransportExtensionServerTransportExtensionClientTransport to access all toolsExtensionExternalServerTransport and listens on chrome.runtime.onConnectExternalExtensionExternalClientTransport targeting Extension 1's IDexternally_connectable manifest configurationallowedOrigins appropriately for your use caseMCP is an open protocol that standardizes how AI applications connect to external tools and data sources. It's used by AI agents like Claude, ChatGPT, Cursor, and Copilot to interact with external systems. Learn more at modelcontextprotocol.io.
| Scenario | Recommended Transport |
|---|---|
| Same-page communication | TabServerTransport / TabClientTransport |
| Parent page to iframe | IframeParentTransport / IframeChildTransport |
| Browser extension to webpage | ExtensionClientTransport / ExtensionServerTransport |
| Extension to extension | ExtensionExternalClientTransport / ExtensionExternalServerTransport |
Yes! These transports implement the MCP standard, making them compatible with any MCP client. Use @mcp-b/chrome-devtools-mcp to connect desktop AI agents to browser-based tools.
All transports support origin validation. Configure allowedOrigins on server transports and targetOrigin on client transports to control which origins can communicate.
Yes! TabServerTransport and TabClientTransport work entirely within a web page using window.postMessage. No extension required.
| Feature | @mcp-b/transports | Raw postMessage | WebSocket |
|---|---|---|---|
| MCP Protocol Support | Yes | No | Manual |
| Type Safety | Full TypeScript | Manual | Manual |
| Origin Validation | Built-in | Manual | N/A |
| Extension Support | Native | Limited | Complex |
| Server Discovery | Automatic | Manual | Manual |
@mcp-b/global - W3C Web Model Context API polyfill for registering tools@mcp-b/react-webmcp - React hooks for MCP tool registration@mcp-b/extension-tools - 62+ Chrome Extension API tools for MCP@mcp-b/chrome-devtools-mcp - Connect desktop AI agents to browser tools@modelcontextprotocol/sdk - Official MCP SDKMIT - see LICENSE for details
FAQs
Browser transport implementations for Model Context Protocol (MCP) - postMessage, Chrome extension messaging, and iframe communication for AI agents and LLMs
We found that @mcp-b/transports demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.