A Rust WebAssembly-based browser client for MCP (Message Control Protocol) that runs as a service worker, enabling multi-tab communication capabilities.
- Python 3.x
- Node.js
- Rust (latest stable version)
- Install via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- Install via rustup:
.
├── src/ # Rust source code
│ ├── lib.rs # Main Rust implementation and MCP protocol
│ └── build_info.rs # Generated build metadata
├── public/ # Web assets and service worker
│ ├── mcp_browser_client_bg.wasm # Compiled WASM module
│ ├── mcp_browser_client.js # Generated JS bindings
│ ├── sw.js # Service worker
│ ├── index.html # Web interface
│ └── styles.css # UI styles
├── venv/ # Python virtual environment
├── node_modules/ # Node.js dependencies
├── .cursor/ # Cursor IDE configuration
├── Cargo.toml # Rust project configuration
├── package.json # Node.js configuration
├── requirements.txt # Python dependencies
├── wasm-build.sh # WASM build script
├── generate-build-info.sh # Build metadata generator
└── setup.sh # Project setup script
-
Build Info Generation
generate-build-info.shcreatessrc/build_info.rs- Tracks source file changes via SHA256 hashes
- Includes build timestamp and source hash
-
WASM Build Process
wasm-build.shorchestrates the build:- Generates build info
- Ensures wasm-bindgen-cli is installed
- Builds WASM module with
cargo build - Generates JS bindings with
wasm-bindgen - Outputs to
public/directory
-
Service Worker Integration
- WASM module loaded by service worker
- JS bindings provide Rust-WASM interface
- Multi-tab communication via service worker
- Run the setup script:
./setup.sh- Start the web server:
npm start- (Optional) Start the mock MCP server for testing:
npm run start:mock-mcpnpm start: Start the web servernpm run build: Build the WASM modulenpm run start:mock-mcp: Start the mock MCP server for testing
- Edit
src/lib.rsfor MCP protocol implementation - Rebuild WASM:
./wasm-build.sh- Refresh your browser
- Edit files in the
publicdirectory - Refresh your browser
The included mock MCP server provides:
- Echo service on port 8081
- Message logging to
mcp_server.log - Terminal output for debugging
Test the system by:
- Starting the mock MCP server:
npm run start:mock-mcp - Opening multiple browser tabs to
http://localhost:8080 - Using the web interface to:
- Check WASM status
- Initialize MCP connection
- List available tools
- Send test messages
-
Service Worker Issues
- Check browser console for errors
- Verify WASM files in
public/directory - Clear browser cache if needed
-
MCP Connection Problems
- Verify MCP server is running
- Check
mcp_server.log - Ensure port 8081 is available
- Verify connection settings in
src/lib.rs
-
WASM Loading Failures
- Check
public/for correct WASM files - Verify build script completion
- Check browser console for errors
- Check
This project is designed for secure, multi-server, browser-based MCP communication. The architecture includes:
- User: Interacts with the web interface in the browser.
- UI (Web Interface): The user input, output, and control layer. Handles all user interaction, displays results, and provides controls for MCP operations.
- Browser: Hosts the web UI and registers the service worker.
- Service Worker (Interface Layer): The interface between the UI and the protocol logic. The service worker loads and uses the WASM module (Rust MCP Client), and routes messages between the UI and MCP servers. It manages multi-tab communication and state.
- WASM Module (Rust MCP Client): The actual MCP client, implemented in Rust and compiled to WASM. This module is loaded by the service worker and performs all protocol logic, message processing, and communication with MCP servers. The service worker acts as a host and communication layer, while the Rust MCP Client (WASM) does the heavy lifting.
- MCP Servers: One or more remote servers implementing the MCP protocol.
- Model Provider: An external service (can be an MCP server) that provides model-based responses or tools.
flowchart TD
User[User (Web UI)]
Browser[Browser]
SW[Service Worker]
WASM[WASM Module (Rust)]
MCP1[MCP Server 1]
MCP2[MCP Server 2]
Model[Model Provider (MCP Server)]
User -- UI Events --> Browser
Browser -- Message --> SW
SW -- Call/Response --> WASM
SW -- JSON-RPC, Tools, Status --> Browser
SW -- HTTP/WebSocket --> MCP1
SW -- HTTP/WebSocket --> MCP2
MCP2 -- (optional) --> Model
- User interacts with the UI (Web Interface), providing input and receiving output.
- The UI sends requests (e.g., tool calls, status checks) to the Service Worker.
- The Service Worker acts as the interface layer, loading and using the WASM Module (Rust MCP Client) for protocol logic and message processing.
- The Service Worker communicates with one or more MCP Servers over HTTP or WebSocket.
- An MCP Server may itself act as a Model Provider or proxy requests to a model provider.
- Responses and status updates flow back through the service worker and WASM to the UI, and are presented to the user.
This architecture enables secure, multi-server, and high-performance MCP operations in the browser, with a clear separation of concerns and robust protocol handling.
This project implements its core logic in Rust, compiled to WebAssembly (WASM), for several reasons:
- Security & Code Signing: WASM binaries are easy to sign, verify, and distribute. You can ship a single
.wasmfile and know exactly what's running in the browser. - Dependency Management: Rust's package management (Cargo) is robust and avoids the dependency hell and supply chain issues common in the JavaScript/TypeScript ecosystem.
- Safety & Maintainability: Rust's type system and memory safety features make it much harder to introduce bugs or vulnerabilities. Refactoring and maintaining a Rust codebase is often easier in the long run.
- Performance: Rust/WASM is highly performant for protocol handling, parsing, and compute-heavy tasks.
- Code Reuse: Rust code can be shared between backend and frontend, reducing duplication and inconsistencies.
While TypeScript is a great choice for many browser projects, we found Rust/WASM to be a better fit for our goals of security, maintainability, and performance.
Q: Why not use a TypeScript MCP client?
A: TypeScript is great for UI and browser APIs, but for protocol logic, Rust/WASM offers better safety, performance, and distribution guarantees. We also avoid the complexity and churn of the npm ecosystem.
Q: Can you do socket-level networking in browser WASM?
A: No. Browser WASM is sandboxed and limited to the same networking APIs as JavaScript: HTTP(S), WebSocket, and WebRTC. Raw TCP/UDP sockets are not available in the browser for security reasons.
Q: Isn't Rust/WASM harder to debug and integrate?
A: There is some extra complexity, but the benefits in safety, performance, and code signing outweigh the downsides for this project. We keep JS glue code minimal and let Rust handle the core logic.
Q: What if I want to use TypeScript for the UI?
A: You can! This project is designed so that the UI can be written in JS/TS, while the protocol and core logic remain in Rust/WASM. This hybrid approach gives you the best of both worlds.
Q: Is this project open to contributions?
A: Yes! We welcome contributions and feedback. Please see CONTRIBUTING.md for guidelines.
MIT License