This example demonstrates a single MCP (Model Context Protocol) server implementation in Rust that compiles to WebAssembly and runs on multiple platforms. The same core code deploys to both Cloudflare Workers and Fermyon Spin, showcasing true platform portability.
One Implementation, Multiple Deployments:
- Single Rust codebase (
src/lib.rs) - Compiles to WebAssembly
- Deploys to multiple WASI/WASM platforms
- Full MCP protocol support
wasm-mcp-server/
βββ src/
β βββ lib.rs # Core MCP server implementation (shared)
βββ Cargo.toml # Rust dependencies
βββ deployments/ # Platform-specific deployment configs
β βββ cloudflare/ # Cloudflare Workers deployment
β β βββ wrangler.toml # Cloudflare configuration
β β βββ worker-rust.js # WASM wrapper for Workers
β β βββ Makefile # Build & deploy commands
β β βββ README.md # Cloudflare-specific docs
β βββ fermyon-spin/ # Fermyon Spin deployment
β βββ spin.toml # Spin configuration
β βββ Makefile # Build & deploy commands
β βββ README.md # Spin-specific docs
βββ README.md # This file
# Build the core WASM module (once for all platforms)
cargo build --target wasm32-unknown-unknown --releasecd deployments/cloudflare
make deploy
# Your deployment will be available at: https://<your-worker-name>.workers.devcd deployments/fermyon-spin
make deploy
# Your deployment will be available at: https://<your-app-name>.fermyon.app/The core MCP server uses the WasmMcpServer from the pmcp SDK:
use pmcp::server::wasm_server::{WasmMcpServer, SimpleTool};
// Create server with tools
let server = WasmMcpServer::builder()
.name("wasm-mcp-server")
.version("1.0.0")
.capabilities(ServerCapabilities {
tools: Some(Default::default()),
resources: None,
prompts: None,
})
.tool("calculator", SimpleTool::new(...))
.tool("weather", SimpleTool::new(...))
.tool("system_info", SimpleTool::new(...))
.build();Each platform provides a thin adapter layer:
#[event(fetch)]
async fn main(req: Request, env: Env, ctx: Context) -> Result<Response> {
// Adapt Workers Request/Response to MCP
}#[http_component]
fn handle_request(req: Request) -> Result<impl IntoResponse> {
// Adapt Spin Request/Response to MCP
}The server implements three example tools:
Performs arithmetic operations (add, subtract, multiply, divide)
Returns mock weather information for a location
Reports the runtime environment (Cloudflare vs Fermyon)
The repository includes comprehensive test scenarios that can be run with the mcp-tester tool:
# Test with simple calculator scenario
mcp-tester scenario <deployment-url> test-scenarios/calculator-simple.json
# Test with comprehensive calculator tests (including error cases)
mcp-tester scenario <deployment-url> test-scenarios/calculator-test.yaml
# Test with minimal tool listing
mcp-tester scenario <deployment-url> test-scenarios/minimal-test.json# From the rust-mcp-sdk root directory
# Replace <your-worker-name> with your Cloudflare Worker subdomain
./target/release/mcp-tester scenario \
https://<your-worker-name>.workers.dev \
examples/wasm-mcp-server/test-scenarios/calculator-test.yaml# From the rust-mcp-sdk root directory
# Replace <your-app-name> with your Fermyon app URL
./target/release/mcp-tester scenario \
https://<your-app-name>.fermyon.app/ \
examples/wasm-mcp-server/test-scenarios/calculator-test.yaml-
calculator-simple.json- Basic calculator operations- Tests addition, multiplication, division, and subtraction
- Validates correct results for each operation
-
calculator-test.yaml- Comprehensive calculator test suite- Tests all arithmetic operations with various inputs
- Tests negative numbers and decimals
- Tests error handling (division by zero, invalid operations, missing parameters)
- Tests large numbers and edge cases
-
minimal-test.json- Minimal connectivity test- Simply lists available tools
- Quick smoke test for deployment health
You can also test deployments manually:
# Initialize connection
curl -X POST <deployment-url> \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'
# List available tools
curl -X POST <deployment-url> \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"2","method":"tools/list","params":{}}'
# Call a tool
curl -X POST <deployment-url> \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"3","method":"tools/call","params":{"name":"calculator","arguments":{"operation":"add","a":5,"b":3}}}'If you need to build the mcp-tester tool:
# From the rust-mcp-sdk root directory
cargo build --release --package mcp-server-tester
# The binary will be at: ./target/release/mcp-tester| Platform | Build Target | Runtime | Global Edge | Cold Start | State Management |
|---|---|---|---|---|---|
| Cloudflare Workers | wasm32-unknown-unknown | V8 Isolates | β Yes (200+ locations) | 50-200ms | KV, Durable Objects |
| Fermyon Spin | wasm32-wasip1 | Wasmtime | β No (single region) | 100-300ms | Built-in SQLite |
cd deployments/cloudflare
# Uses wasm-pack for reliable builds
wasm-pack build --target web --out-dir pkg --no-opt
# Deploy with wrangler
wrangler deploycd deployments/fermyon-spin
# Build with Spin's toolchain
spin build
# Deploy to Fermyon Cloud
spin deployThe core server is stateless and handles each request independently:
- Parse JSON-RPC request
- Route based on method (
initialize,tools/list,tools/call) - Process with
WasmMcpServer - Return JSON-RPC response
- Missing capabilities field: Auto-adds empty
{}if not present - CORS support: Enabled for browser-based clients
- Error handling: Graceful degradation with proper error codes
- Code Reuse: Single implementation for all platforms
- Type Safety: Rust's compile-time guarantees
- Performance: Native WASM execution speed
- Portability: Deploy anywhere WASM runs
- Maintainability: Fix once, deploy everywhere
To deploy to a new WASM platform:
- Create
deployments/<platform>/folder - Add platform-specific config files
- Write thin adapter layer for request/response
- Use the same core
WasmMcpServerimplementation
- Production Deployment Guide - Cloudflare configuration, security best practices, and layered architecture
- Fermyon Spin Deployment Guide
- Architecture Overview
- MCP Protocol Specification
When adding features:
- Implement in core
src/lib.rs - Test on all platforms
- Update documentation
MIT
Example Deployments for Testing: You can test the MCP protocol with these example deployments:
- π Cloudflare Example: https://mcp-sdk-worker.guy-ernest.workers.dev
- π Fermyon Example: https://mcp-fermyon-spin-3juc7zc4.fermyon.app/
Note: These are example deployments for testing. Deploy your own instances using the instructions above.