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

# @mcp-b/mcp-iframe

> Reference for the iframe bridge custom element and its event contract.

A Web Component that wraps an iframe and bridges its MCP tools, resources, and prompts to the parent page's `document.modelContext`. Items from the iframe are namespaced with the element's `id` to prevent collisions.

## Installation

```bash theme={null}
pnpm add @mcp-b/mcp-iframe @modelcontextprotocol/sdk
```

The iframe page must have `@mcp-b/global` (or any `document.modelContext` implementation) installed.

## Minimal example

<Snippet file="snippets/packages/mcp-iframe-quickstart.html" />

## Usage

```html theme={null}
<mcp-iframe src="./child-app.html" id="my-app"></mcp-iframe>

<script type="module">
  import '@mcp-b/mcp-iframe';

  const el = document.querySelector('mcp-iframe');
  el.addEventListener('mcp-iframe-ready', (e) => {
    console.log('Exposed tools:', e.detail.tools);
    // e.g. ["my-app_calculate", "my-app_get_data"]
  });
</script>
```

Importing `@mcp-b/mcp-iframe` auto-registers the `<mcp-iframe>` custom element. No additional setup is required.

***

## Attributes

| Attribute          | Type     | Default             | Description                                                                                       |
| ------------------ | -------- | ------------------- | ------------------------------------------------------------------------------------------------- |
| `src`              | `string` | --                  | URL of the iframe page.                                                                           |
| `id`               | `string` | `"iframe"`          | Used as the tool name prefix. Sanitized to match `[a-zA-Z0-9_-]`.                                 |
| `target-origin`    | `string` | Inferred from `src` | Override the `postMessage` target origin. If omitted, the origin is extracted from the `src` URL. |
| `channel`          | `string` | `"mcp-iframe"`      | Channel ID for the underlying `IframeParentTransport`.                                            |
| `call-timeout`     | `number` | `30000`             | Timeout in milliseconds for tool calls, resource reads, and prompt gets.                          |
| `prefix-separator` | `string` | `"_"`               | Separator between the prefix and the item name. Must contain only `[a-zA-Z0-9_-]` characters.     |

Standard iframe attributes (`sandbox`, `allow`, `width`, `height`, `loading`, `referrerpolicy`, `name`, `srcdoc`, `allowfullscreen`, `credentialless`) are mirrored to the internal `<iframe>` element.

***

## Events

| Event                      | Detail type                                                   | Fired when                                                                             |
| -------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `mcp-iframe-ready`         | `{ tools: string[], resources: string[], prompts: string[] }` | The element connects to the iframe's MCP server and registers all items on the parent. |
| `mcp-iframe-error`         | `{ error: unknown }`                                          | Connection to the iframe's MCP server fails.                                           |
| `mcp-iframe-tools-changed` | `{ tools: string[], resources: string[], prompts: string[] }` | Items are refreshed via the `refresh()` method.                                        |

All `tools`, `resources`, and `prompts` arrays contain the prefixed names as registered on the parent.

***

## Name prefixing

Tools and prompts from the iframe are registered on the parent as `{id}{separator}{name}`:

| Iframe tool name | Element `id` | Separator     | Parent tool name   |
| ---------------- | ------------ | ------------- | ------------------ |
| `calculate`      | `my-app`     | `_` (default) | `my-app_calculate` |
| `get_data`       | `billing`    | `_`           | `billing_get_data` |
| `help`           | `assistant`  | `-`           | `assistant-help`   |

Prefixed names must match the MCP name pattern `^[a-zA-Z0-9_-]{1,128}$`. Names that exceed 128 characters or contain invalid characters are skipped with a console error.

Resource URIs are prefixed the same way: a resource `config://settings` in an iframe with `id="my-app"` becomes `my-app_config://settings` on the parent.

***

## Properties

| Property           | Type                        | Description                                                  |
| ------------------ | --------------------------- | ------------------------------------------------------------ |
| `iframe`           | `HTMLIFrameElement \| null` | The wrapped iframe element.                                  |
| `client`           | `Client \| null`            | The MCP client connected to the iframe's server.             |
| `ready`            | `boolean`                   | Whether the element is connected to the iframe's MCP server. |
| `exposedTools`     | `string[]`                  | Prefixed tool names registered on the parent.                |
| `exposedResources` | `string[]`                  | Prefixed resource URIs registered on the parent.             |
| `exposedPrompts`   | `string[]`                  | Prefixed prompt names registered on the parent.              |
| `mcpTools`         | `Tool[]`                    | Raw tools from the iframe (without prefix).                  |
| `mcpResources`     | `Resource[]`                | Raw resources from the iframe (without prefix).              |
| `mcpPrompts`       | `Prompt[]`                  | Raw prompts from the iframe (without prefix).                |
| `itemPrefix`       | `string`                    | The computed prefix string (`{id}{separator}`).              |

***

## Methods

| Method      | Returns         | Description                                                                                                                                                          |
| ----------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `refresh()` | `Promise<void>` | Re-fetches all tools, resources, and prompts from the iframe, unregisters the old items, and registers the new ones. Fires `mcp-iframe-tools-changed` on completion. |

***

## Programmatic registration

To register the custom element with a different tag name:

```typescript theme={null}
import { registerMCPIframeElement } from '@mcp-b/mcp-iframe';

registerMCPIframeElement('my-mcp-frame');
```

If you import `@mcp-b/mcp-iframe` without calling `registerMCPIframeElement`, the element is auto-registered as `<mcp-iframe>` in browser environments.

***

## Lifecycle

1. On `connectedCallback`, the element creates an internal `<iframe>` and mirrors attributes.
2. When the iframe fires its `load` event, the element creates an `IframeParentTransport` and an MCP `Client`, then connects.
3. On successful connection, tools, resources, and prompts are fetched from the iframe's MCP server.
4. Each item is registered on the parent's `document.modelContext` with the element's prefix.
5. The `mcp-iframe-ready` event fires.
6. On `disconnectedCallback`, all registered items are unregistered and the client and transport are closed.

Changing `src`, `srcdoc`, `target-origin`, or `channel` while connected triggers a reconnection cycle.

***

## Related

* [Bridge tools across iframes](/how-to/bridge-tools-across-iframes) for a step-by-step guide
* [@mcp-b/transports](/packages/transports/reference) for the underlying `IframeParentTransport` and `IframeChildTransport`
* [Transports and bridges](/explanation/architecture/transports-and-bridges) for the architectural context
