@mcp-b/webmcp-extension installs WebMCP from a Chromium extension and
connects an isolated content script to the page’s imperative and declarative
tools. It returns the official MCP Client; websites continue to use
document.modelContext and annotated HTML forms.
Package metadata
Installation
Install packages
Extension layout
The template declares two staticdocument_start content scripts. Chrome 111
or newer is required for world: "MAIN".
manifest.json
all_frames, extension API permissions, a background
worker, and web_accessible_resources. It targets matching top-level pages.
MAIN-world entry
The MAIN-world bundle only installs the runtime:src/main-world.ts
Page code
Declarative form tools
The MAIN-world runtime also discovers annotated forms:Page form
@mcp-b/global adopts native declarative behavior when available and installs
the polyfilled form runtime otherwise. Form tools and JavaScript registrations
both appear in the isolated client’s listTools() result and run through
callTool(). listChanged.tools reports form additions, definition changes,
and removals.
The extension package adds no separate DOM scanner or declarative client API.
See the declarative API reference for the
upstream behavior and the polyfill’s documented compatibility boundary.
Document-tree scope
The template injects its MAIN-world runtime and isolated client into top-level pages only. Native Chrome’sgetTools() still includes tools owned by
same-origin active documents in the same frame tree. The extension client can
therefore list and call both JavaScript and declarative form tools from
same-origin child documents without child-frame injection.
The polyfilled path discovers only the top document. Cross-origin imperative
tools require allow="tools", child registration with exposedTo, and a
caller-supplied fromOrigins list. The extension client does not supply that
list. Declarative forms currently have no equivalent cross-origin exposure
attribute. See the WebMCP standard API and
Chrome’s cross-origin iframe guidance.
MCP tool names are global within one client connection. Use unique names across
the frame tree.
Navigation results
Chrome resolvesexecuteTool() with null when a tool triggers navigation.
The extension client reports that call as interrupted. It does not preserve the
call across document navigation or read JSON-LD from the destination document.
For a declarative tool that must return a result without navigation, cancel the
submission and use SubmitEvent.respondWith(). The upstream
declarative explainer
tracks the unresolved cross-document response design.
Isolated content-script entry
src/content-script.ts
client is the official Client from @modelcontextprotocol/client, not a
package-specific wrapper.
connectWebMCPClient()
Signature
The helper:
- Creates the official MCP
Clientwith automatic protocol version negotiation. - Applies the supplied
ClientOptions. - Connects a
TabClientTransportwithtargetOriginset towindow.location.origin. - Resolves with the connected client.
listTools(), callTool(), and close() methods.
The second argument also accepts official client features such as
listChanged.tools; the template uses it to follow tools registered after page
hydration.
Template build
The published package includes a copyabletemplate directory. Its build
requires Node 22.12 or newer.
Build the template
dist/ directory as an unpacked extension. The Vite+ config
bundles both entries as self-contained, minified IIFEs targeting Chrome 111 and
copies manifest.json into dist/. Content scripts cannot load bare npm
imports at runtime.
Security and scope
- Narrow the manifest match patterns before publishing.
- The template injects into top-level pages only. Native Chrome can still discover same-origin child-document tools.
- Add icons and Chrome Web Store listing metadata before publishing.
