Successfully initiated a major refactoring of the Rust MCP SDK server architecture to separate protocol handling from transport management. This enables deployment to WASM/WASI environments and aligns with the TypeScript SDK architecture.
- Transport-independent server implementation
- Implements new
ProtocolHandlertrait - Stateless request handling suitable for serverless
- No direct transport dependencies
pub trait ProtocolHandler: Send + Sync {
async fn handle_request(&self, id: RequestId, request: Request) -> JSONRPCResponse;
async fn handle_notification(&self, notification: Notification) -> Result<()>;
fn capabilities(&self) -> &ServerCapabilities;
fn info(&self) -> &Implementation;
}pub trait TransportAdapter: Send + Sync {
async fn serve(&self, handler: Arc<dyn ProtocolHandler>) -> Result<()>;
fn transport_type(&self) -> &'static str;
}Fluent API for constructing ServerCore instances:
let server = ServerCoreBuilder::new()
.name("my-server")
.version("1.0.0")
.tool("my-tool", MyTool)
.capabilities(ServerCapabilities::tools_only())
.build()?;- GenericTransportAdapter: Works with any Transport trait implementation
- StdioAdapter: Standard input/output for CLI tools
- HttpAdapter: Stateless HTTP for serverless
- WebSocketAdapter: Real-time bidirectional communication
- MockAdapter: Testing support
Special adapter for WASI environments:
- Stateless request handling
- Optional session management
- Compatible with wit-bindgen
- Ready for Cloudflare Workers deployment
- Protocol logic independent of transport
- Easier testing and maintenance
- Better code organization
- Same core logic works everywhere
- Native servers (tokio-based)
- WASI/WASM environments
- Serverless platforms
- Similar architecture patterns
- Easier cross-SDK understanding
- Consistent approach across languages
Use the new architecture directly:
use pmcp::server::builder::ServerCoreBuilder;
use pmcp::server::adapters::StdioAdapter;
let server = ServerCoreBuilder::new()
.name("server")
.version("1.0.0")
.build()?;
let adapter = StdioAdapter::new();
adapter.serve(Arc::new(server)).await?;The old Server struct remains available. Migration is optional and can be done incrementally.
- Type Compatibility: Some internal types need adjustment for full compatibility
- Authorization: Auth context needs to be passed from transport layer
- Session Management: Stateful operations in stateless environments need platform support
- WASI Compilation: Requires proper feature flags and wit-bindgen setup
- Fix remaining type compatibility issues
- Complete WASI example with proper wit-bindgen integration
- Add integration tests for all adapters
- Update documentation
- Implement streaming support in adapters
- Add connection pooling for HTTP adapter
- Optimize for serverless cold starts
- Create deployment guides for major platforms
- Deprecate old Server API (after stability period)
- Extract transport adapters to separate crate (if needed)
- Add more platform-specific adapters
- Performance optimizations for WASM
Run tests with:
cargo test --all-featuresRun the example:
cargo run --example refactored_server_exampleMain refactoring issue: paiml#48
- No backward compatibility - Clean break for simpler architecture
- Follow WASI/TypeScript patterns - Use existing solutions
- Single crate structure - Match TypeScript SDK
- No migration support - Rely on Cargo versioning
- Platform-level auth - Delegate to WASI/serverless platforms