Successfully refactored the MCP SDK to provide environment-agnostic WASM/WASI support, enabling developers to build MCP servers that focus on business logic (tools, resources, prompts) while deployment to different WASI environments is handled through thin adapters.
- Removed platform-specific dependencies from WASM builds
- Made
reqwestconditionally compiled for native targets only - Created stub modules for WASM-incompatible features
- SDK now compiles cleanly for
wasm32-unknown-unknownandwasm32-wasip1targets
pub struct WasmMcpServer {
tools: HashMap<String, Box<dyn WasmTool>>,
resources: HashMap<String, Box<dyn WasmResource>>,
prompts: HashMap<String, Box<dyn WasmPrompt>>,
}Key Features:
- Full type safety maintained (no JSON value manipulation)
- Support for all MCP features (tools, resources, prompts)
- Builder pattern for easy configuration
- Platform-independent core logic
- Target:
wasm32-unknown-unknown - Uses
workercrate for Cloudflare-specific bindings - Thin wrapper around
WasmMcpServer - Successfully compiles and maintains type safety
- Target:
wasm32-wasip1(standard WASI) - Uses
spin-sdkfor Spin-specific bindings - Same
WasmMcpServerAPI as Cloudflare - Demonstrates true environment independence
// Lost type safety, manual JSON construction
match serde_json::to_value(&*client_request) {
Ok(req_value) => {
if let Some(method) = req_value.get("method").and_then(|m| m.as_str()) {
// Manual JSON handling...// Full type safety maintained
match request {
Request::Client(client_req) => match *client_req {
ClientRequest::Initialize(params) => self.handle_initialize(params),
ClientRequest::ListTools(params) => self.handle_list_tools(params),
// Typed handlers...let server = WasmMcpServer::builder()
.name("my-mcp-server")
.tool("add", SimpleTool::new(...))
.resource("files", FileResource::new(...))
.prompt("template", TemplatePrompt::new(...))
.build();Cloudflare Workers:
#[event(fetch)]
async fn main(req: Request, _env: Env, _ctx: Context) -> Result<Response>Fermyon Spin:
#[http_component]
fn handle_mcp_request(req: Request) -> anyhow::Result<impl IntoResponse>Key Insight: Only the HTTP handler differs; MCP logic remains identical.
- Environment Independence: Same MCP code runs on Cloudflare, Spin, or any WASI runtime
- Type Safety: Full MCP type system preserved in WASM
- Complete Feature Set: Tools, resources, and prompts all supported
- Simple Migration: Easy to move between deployment targets
- Developer Focus: Write MCP logic once, deploy anywhere
Developers now write environment-agnostic MCP servers:
// 1. Define your MCP logic (tools, resources, prompts)
struct MyTool;
impl WasmTool for MyTool {
fn execute(&self, args: Value) -> Result<Value> {
// Business logic only
}
}
// 2. Build the server
let server = WasmMcpServer::builder()
.tool("my_tool", MyTool)
.build();
// 3. Choose deployment target with minimal wrapper
// - Cloudflare: Use worker crate
// - Spin: Use spin-sdk crate
// - Wasmtime: Use WASI CLIsrc/lib.rs- Removed WASM gates from server modulesrc/server/mod.rs- Added WASM modules and conditional compilationsrc/server/wasm_server.rs- New environment-agnostic serversrc/server/wasm_core.rs- Enhanced with tool registrysrc/server/wasi_adapter.rs- HTTP adapter for WASI
examples/cloudflare-worker-rust/- Cloudflare Workers exampleexamples/fermyon-spin-rust/- Fermyon Spin example
docs/WASM_TARGETS.md- Guide to WASM/WASI targetsdocs/WASM_ARCHITECTURE_ANALYSIS.md- Architecture analysisdocs/WASM_IMPLEMENTATION_SUMMARY.md- This summary
| Environment | Target | Compilation | Type Safety | Features |
|---|---|---|---|---|
| Cloudflare Workers | wasm32-unknown-unknown |
✅ Success | ✅ Full | Tools ✅ |
| Fermyon Spin | wasm32-wasip1 |
✅ Success | ✅ Full | Tools ✅ |
| SDK Core | Both targets | ✅ Success | ✅ Full | All ✅ |
- Add Resource Support: Extend examples to demonstrate resources
- Add Prompt Support: Extend examples to demonstrate prompts
- More Environments: Add examples for Fastly, Wasmtime CLI
- Streaming Support: Investigate WASI streaming capabilities
- Performance Testing: Benchmark across different runtimes
The MCP SDK now provides true environment-agnostic WASM/WASI support, enabling developers to write MCP servers once and deploy them to any WASI-compatible platform with minimal platform-specific code. The architecture maintains full type safety while providing maximum portability.