A framework that enables websites to share tools, resources, and prompts with client-side LLMs without requiring API keys, allowing users to interact with web services using their preferred models.
A proposal and code for websites to support client side LLMs
WebMCP allows websites to share tools, resources, prompts, etc. to LLMs. In other words, WebMCP allows a website to be an MCP server. No sharing API Keys. Use any model you want.
Here's a simple website I built that is WebMCP-enabled
It comes in the form of a widget that a website owner can put on their site and expose tools to give client-side LLMs what they need to provide a great UX for the user or agent.
The look, feel, how it's used, and security are all absolutely open for contribution / constructive criticism. MCP Clients directly building WebMCP functionality seems like an ideal outcome.
An end-user can connect to any number of websites at a time - and tools are "scoped" (by name) based on the domain to simplify organization.
https://github.com/user-attachments/assets/61229470-1242-401e-a7d9-c0d762d7b519
Just specify your MCP client (claude
, cursor
, cline
, windsurf
, or a path to json)
npx -y @jason.today/webmcp@latest --config claude
If you're interested in setting it up manually, use the command npx -y @jason.today/webmcp@latest --mcp
.
Auto-install was inspired by Smithery, but their code is AGPL so I wrote this myself. If it doesn't work for you or you don't see your mcp client, please file an issue.
When you're ready to connect to a website, you can ask your model to generate you an mcp token.
Copy the token and paste it to the website's input. As soon as the website registers with it, it's thrown away and cannot be used for subsequent registrations or anything else. The website will receive its own session token for making requests.
If you'd rather your model / service never see the token, you can manually execute npx @jason.today/webmcp --new
instead.
Some MCP clients, including Claude Desktop, need to be restarted to get access to new tools. (at least at time of writing)
To disconnect, you can close the browser tab, click "disconnect", or shut down the server with npx @jason.today/webmcp -q
.
All configuration files are stored in ~/.webmcp
directory.
To use WebMCP, simply include webmcp.js
on your page (via src or directly):
The WebMCP widget will automatically initialize and appear in the bottom right corner of your page. Clicking on it will ask for a webmcp token which the end-user will generate.
https://github.com/user-attachments/assets/43ad160a-846d-48ad-9af9-f6d537e78473
The bridge between the MCP client and the website is a localhost-only (not accessible to requests outside your computer) websocket server. Because it is configured to allow requests from your local web browser, authentication / token exchange is required, in case you visit a website attempting to abuse this.
Ideally the web browser itself would have an explicit permission for this, like webcam or microphone use.
/mcp
path using the server token from .env
(auto-generated)--new
command)/register
endpoint with this token and its domain.sequenceDiagram participant User participant MCP as MCP Client participant Server as MCP Server participant WS as WebSocket Server participant Web as Website %% Initial connection MCP->>Server: Connect to /mcp with internal server token %% Website registration token User->>MCP: Request registration token MCP->>Server: Request registration token Server-->>MCP: Return registration token MCP-->>User: Display registration token %% Website registration User->>Web: Paste registration token Web->>WS: Connect to /register with token & domain (registration token deleted) WS-->>Web: Assign channel & session token Web->>WS: Connect to assigned channel %% Tool interaction MCP->>Server: Request tools list Server->>WS: Forward request WS->>Web: Request tools Web-->>WS: Return tools list WS-->>Server: Forward tools list Server-->>MCP: Return tools list %% Tool execution MCP->>Server: Tool request Server->>WS: Forward request WS->>Web: Execute tool Web-->>WS: Return result WS-->>Server: Forward result Server-->>MCP: Return result %% Disconnection User->>Web: Disconnect Web->>WS: Close connection
This is a super early project. I'm very interested in hardening security to prevent malicious extensions etc. from being able to perform prompt injection attacks and similar. If you have constructive ideas, please reach out or open an issue.
There is a Dockerfile
specifically for Smithery deployment.
If you'd like to use docker to run the websocket server, I've added a docker-compose.yml
for demonstration purposes.
If --docker
is provided to the mcp client config alongside --mcp
, it will assume the server is running. This will allow you to dockerize the main process (websocket server), and your mcp client will connect to your docker container via websocket. Similarly, websites will communicate with your docker container.
Discover shared experiences
Shared threads will appear here, showcasing real-world applications and insights from the community. Check back soon for updates!