webconnect
Connect any MCP server to Chrome's WebMCP API
Installation
npx webmcp-connectAsk AI about webconnect
Powered by Claude Β· Grounded in docs
I know everything about webconnect. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
webmcp-connect
Connect any MCP server to the browser via the WebMCP API.
Three lines. That's it.
import { WebMCP } from 'webmcp-connect';
const mcp = new WebMCP('https://api.githubcopilot.com/mcp/');
await mcp.connect();
// Done. Tools are auto-registered with the browser's AI.
npm install webmcp-connect
Why?
MCP servers are everywhere β GitHub, Slack, databases, you name it. But they're trapped behind desktop clients and CLI tools.
Why should using an MCP tool require Cursor or Claude Desktop?
webmcp-connect gives any webpage access to any MCP server. The browser becomes the agent surface.
Examples
Connect to GitHub Copilot MCP
import { WebMCP } from 'webmcp-connect';
const github = new WebMCP('https://api.githubcopilot.com/mcp/');
github.setAuth({ type: 'bearer', token: 'ghp_...' });
const { tools } = await github.connect();
// connect() auto-registers tools with the browser:
// navigator.modelContext.addTool({ name, description, inputSchema, handler })
// β the browser's AI can now call them autonomously
// You can also call tools directly:
const result = await github.callTool('search_repos', { query: 'webmcp' });
console.log(result.content[0].text);
With Chrome's Prompt API
const github = new WebMCP('https://api.githubcopilot.com/mcp/', { autoRegister: false });
github.setAuth({ type: 'bearer', token: 'ghp_...' });
const { tools } = await github.connect();
// Map MCP tools β Prompt API tools with execute callbacks
const session = await LanguageModel.create({
tools: tools.map(t => ({
name: t.name,
description: t.description,
inputSchema: t.inputSchema,
async execute(args) {
const result = await github.callTool(t.name, args);
return JSON.stringify(result.content);
}
}))
});
// The model calls the right tool(s) automatically
const result = await session.prompt('Find repos about webmcp');
Enrich every tool call with page context
const mcp = new WebMCP('https://api.githubcopilot.com/mcp/', {
enrichContext: (toolName, args) => ({
...args,
page_url: location.href,
page_title: document.title,
selected_text: window.getSelection().toString(),
}),
});
await mcp.connect();
// Every tool call now carries page context β the AI knows what you're looking at
Audit every tool call
const mcp = new WebMCP('https://api.githubcopilot.com/mcp/', {
onToolCall: (name, args) => {
analytics.track('mcp_tool_call', { tool: name, args });
},
onResponse: (name, result) => {
console.log(`[${name}]`, result);
return result;
},
onError: (name, err) => {
Sentry.captureException(err, { extra: { tool: name } });
},
});
Mix remote + local tools
await mcp.connect();
mcp.register([
{
name: 'get_selection',
description: 'Get the currently selected text on the page',
inputSchema: { type: 'object', properties: {} },
execute: async () => ({
content: [{ type: 'text', text: window.getSelection().toString() }],
}),
},
{
name: 'get_page_html',
description: 'Get the full HTML of the current page',
inputSchema: { type: 'object', properties: {} },
execute: async () => ({
content: [{ type: 'text', text: document.documentElement.outerHTML }],
}),
},
]);
// Remote MCP tools + page-local tools, all registered together
Call tools directly (no WebMCP needed)
const mcp = new WebMCP('https://api.githubcopilot.com/mcp/');
await mcp.connect();
// Use tools programmatically β works without navigator.modelContext
const result = await mcp.callTool('search', { query: 'webmcp' });
console.log(result.content[0].text);
Custom headers
const mcp = new WebMCP('https://api.githubcopilot.com/mcp/', {
headers: {
'X-Tenant-ID': 'acme-corp',
'Authorization': 'Bearer sk-...',
},
});
Headers are merged into every request. setAuth() headers go first, custom headers override.
API
new WebMCP(serverUrl, options?)
| Option | Type | Description |
|---|---|---|
autoRegister | boolean | Auto-register tools on connect (default: true) |
headers | object | Custom headers merged into every request |
enrichContext | (name, args) => args | Enrich tool args before proxying |
onToolCall | (name, args) => void | Called before each tool call |
onResponse | (name, result) => result | Transform responses |
onError | (name, error) => void | Error handler |
logger | object | Custom logger (default: console) |
Methods
| Method | Returns | Description |
|---|---|---|
connect() | { tools, prompts, resources } | Initialize + discover |
register(extraTools?) | tool[] | Register with WebMCP |
callTool(name, args) | result | Call a tool |
getPrompt(name, args) | result | Get a prompt |
readResource(uri) | result | Read a resource |
setAuth({ type, token }) | β | Set auth (bearer, apikey, basic) |
disconnect() | β | Clear context + logout |
CORS
This module runs in the browser, so the MCP server must allow cross-origin requests. If you control the server, add Access-Control-Allow-Origin headers. Most MCP SDKs support this out of the box.
No CORS = the browser blocks the request before it reaches your code. That's a browser security feature, not a bug.
Requirements
- A browser with WebMCP support
connect()andcallTool()work without WebMCP β you just can'tregister()
License
MIT
