GitHub - ra0x3/mcpkit-rs: Rust SDK for the Model Context Protocol focused on Web Assembly (WASM) execution

5 min read Original article ↗

Crates.io Version Coverage

Warning

Early Development: This repository is not production ready yet. It is in early development and may change significantly.

Overview

This fork provides a Rust-native MCP SDK with:

  • Multiple WASM Runtime Support: Both WASI (wasm32-wasip2) and WasmEdge runtimes
  • Tokio 1.36: Downgraded from 1.40+ for broader compatibility
  • Portable Tool Development: Build once, run anywhere with WebAssembly

Quick Start

See the examples directory for working implementations.

WebAssembly Runtime Support

This fork enables portable MCP tools through WebAssembly, supporting multiple runtimes for different use cases:

Supported Runtimes

  • WASI (wasm32-wasip2): Standard WebAssembly System Interface for general-purpose tools
  • WasmEdge: Extended runtime with PostgreSQL and HTTP client support for full-stack applications

Runtime Functionality Comparison

Problem Wasmtime WasmEdge
Outbound TCP/HTTP ✗ Pre-opened FDs only ✓ Full sockets
Inbound TCP (servers) ⚠ Awkward ✓ Native
Database connections ✓ Postgres, MySQL
LLM inference (GGML)
Whisper/audio
TensorFlow/PyTorch ⚠ OpenVINO only ✓ Multiple backends
Docker Desktop ✓ (ships built-in)
Edge K8s (KubeEdge, etc.) ✓ First-class
Plugin system
TLS built-in

Why WebAssembly?

Current MCP ecosystem suffers from massive duplication - everyone writes the same tools. These tools are:

  • Deterministic and non-differentiating
  • Expensive to maintain relative to value
  • Perfect candidates for community reuse

WebAssembly provides:

  • Portability: Compile once, run on any runtime
  • Security: Sandboxed execution with explicit capabilities
  • Simplicity: Standard interfaces, no FFI complexity
  • Reproducibility: Same tool version = same behavior
  • Distribution: Share tools as binaries, not services

Comparison with Wassette

mcpkit-rs vs Wassette Feature Comparison

Feature mcpkit-rs Wassette
Primary Focus Fast development with more features out-of-box Enterprise-focused with minimal feature set
Architecture MCP SDK that compiles to WASM Bridge between WASM Components and MCP
Language Rust Rust
MCP Implementation Full MCP SDK (client/server) MCP server only
WASM Runtime Support Wasmtime + WasmEdge Wasmtime only
Component Model Direct WASM compilation WASM Components (WIT)
Database Support ✓ (via WasmEdge)
HTTP Client ✓ (via WasmEdge) ✗ (pre-opened FDs only)
LLM/ML Support ✓ (via WasmEdge)
Permission System Fine-grained config.yaml Fine-grained policy.yaml
OCI Registry Support
Security Model Runtime sandboxing Capability-based + interactive
Network Hosting ✓ (planned)
Development Model Write MCP tools in any WASM language Write generic WASM Components
Tool Distribution Binary/source/OCI registry OCI registry
Zero Dependencies ✗ (requires WASI runtime) ✗ (requires WASI runtime)
Supported Languages JavaScript, Go, Python, Rust JS, Python, Rust, Go

When to Use Which?

Choose mcpkit-rs when:

  • Building MCP tools that need database or HTTP access
  • Requiring ML/AI inference capabilities in tools
  • Needing both MCP client and server functionality
  • Wanting direct control over MCP implementation
  • Needing flexibility to choose between multiple WASM runtimes

Choose Wassette when:

  • Building language-agnostic WASM Components
  • Requiring fine-grained security policies
  • Distributing tools via OCI registries
  • Needing network-hosted MCP servers
  • Working with existing WASM Components

OCI Distribution

mcpkit-rs supports distributing MCP tools as OCI bundles, similar to Wassette. This enables sharing compiled WASM tools through container registries like Docker Hub or GitHub Container Registry.

How It Works

Bundle your WASM binary and configuration into an OCI artifact, push it to any OCI-compliant registry, and pull it on any system with mcpkit-rs installed.

Example Workflow

# Project structure
$ tree .
.
├── config.yaml           # MCP tool configuration
├── target/
│   └── wasm32-wasip1/
│       └── release/
│           └── my-tool.wasm  # Compiled WASM binary
└── Cargo.toml

# Build the bundle
$ mcpk bundle build --config config.yaml --wasm target/wasm32-wasip1/release/my-tool.wasm --output my-tool-bundle.tar
✓ Bundle created: my-tool-bundle.tar (2.3 MB)

# Push to OCI registry
$ mcpk bundle push --bundle my-tool-bundle.tar --uri oci://ghcr.io/myorg/my-tool:v1.0.0
✓ Pushed to ghcr.io/myorg/my-tool:v1.0.0
  Digest: sha256:abc123...

# Pull and run on another system
$ mcpk bundle pull --uri oci://ghcr.io/myorg/my-tool:v1.0.0
✓ Downloaded my-tool:v1.0.0
  Extracted to: ~/.mcpkit/tools/my-tool/

Installation

Prerequisites

  • Rust 1.75+
  • Tokio 1.36 (included in dependencies)
  • WebAssembly runtime (choose based on your needs):
    • WASI/Wasmtime: For standard WASI tools
    • WasmEdge: For tools requiring PostgreSQL or HTTP client

Runtime Installation

WASI Runtime (Wasmtime)

# Install wasmtime
$ curl https://wasmtime.dev/install.sh -sSf | bash

# Add WASI compilation target
$ rustup target add wasm32-wasip2

WasmEdge Runtime

# Install WasmEdge with plugins
$ curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- --plugins wasmedge_rustls

# Add WasmEdge compilation target (uses wasm32-wasip1)
$ rustup target add wasm32-wasip1

Cargo Dependencies

rmcp = { version = "0.13.0", features = ["server"] }

# For WASI compilation
[target.wasm32-wasip2.dependencies]
rmcp = { version = "0.13.0", features = ["server", "wasi"] }

# For WasmEdge compilation
[target.wasm32-wasip1.dependencies]
rmcp = { version = "0.13.0", features = ["server", "wasmedge"] }

OCI Distribution

MCPKit ships MCP servers as OCI artifacts - WebAssembly modules bundled with configuration, pushed to any OCI registry. Similar to Microsoft's Wazero approach for portable WASM distribution.

$ echo "Building WASM module..."
$ cargo build --target wasm32-wasip1 --release
    Finished release [optimized] target(s) in 0.12s

$ mcpk bundle push \
    --wasm target/wasm32-wasip1/release/calculator.wasm \
    --config config.yaml \
    --uri oci://ghcr.io/myorg/calculator:v1.0.0
Creating bundle...
✓ Added module.wasm (2.1 MB)
✓ Added config.yaml (512 B)
✓ Generated manifest.json
Pushing to oci://ghcr.io/myorg/calculator:v1.0.0...
✓ Layer sha256:a3ed95ca... (2.1 MB)
✓ Layer sha256:b4d3f2c8... (1.0 KB)
✓ Manifest sha256:7f8a9b2c...
✓ Push complete: ghcr.io/myorg/calculator:v1.0.0

$ mcpk bundle pull oci://ghcr.io/myorg/calculator:v1.0.0 --output ./dist
Pulling from oci://ghcr.io/myorg/calculator:v1.0.0...
✓ Downloaded sha256:a3ed95ca... (2.1 MB)
✓ Downloaded sha256:b4d3f2c8... (1.0 KB)
✓ Extracted to ./dist
✓ Pull complete: 2 files

$ ls ./dist
module.wasm  config.yaml  manifest.json

Authenticate with GITHUB_USER and GITHUB_TOKEN environment variables. See examples/wasm/wasmtime/calculator for a complete implementation.

Resources

Development