rmcp-actix-web 0.2.3

actix-web transport implementations for RMCP (Rust Model Context Protocol)
Documentation

rmcp-actix-web

actix-web transport implementations for RMCP (Rust Model Context Protocol)

This crate provides actix-web-based transport implementations for the Model Context Protocol, offering a complete alternative to the default Axum-based transports in the main RMCP crate.

Overview

rmcp-actix-web provides:

  • SSE (Server-Sent Events) transport: Real-time, unidirectional communication
  • Streamable HTTP transport: Bidirectional communication with session management
  • Framework-level composition: Mount MCP services at custom paths using actix-web Scope
  • Full MCP compatibility: Implements the complete MCP protocol specification
  • RMCP ecosystem alignment: APIs that follow RMCP patterns for maximum consistency

Installation

Add this to your Cargo.toml:

[dependencies]
rmcp-actix-web = "0.2"
rmcp = "0.3"
actix-web = "4"

Feature Flags

Control which transports are compiled:

# Default: both transports enabled
rmcp-actix-web = "0.2"

# Only SSE transport
rmcp-actix-web = { version = "0.2", default-features = false, features = ["transport-sse-server"] }

# Only StreamableHttp transport
rmcp-actix-web = { version = "0.2", default-features = false, features = ["transport-streamable-http-server"] }

Compatibility Matrix

rmcp-actix-web rmcp
0.2.2 0.3.0
0.2.x 0.2.x
0.1.x 0.2.x

Quick Start

Simple SSE Server

use rmcp_actix_web::SseServer;

#[actix_web::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Start server with default configuration
    let server = SseServer::serve("127.0.0.1:8080".parse()?).await?;

    // Attach your MCP service
    let ct = server.with_service(|| MyMcpService::new());

    // Wait for shutdown
    ct.cancelled().await;
    Ok(())
}

Framework-Level Composition

Mount MCP services at custom paths within existing actix-web applications:

use rmcp_actix_web::{SseServer, SseServerConfig, StreamableHttpService};
use rmcp::transport::streamable_http_server::session::local::LocalSessionManager;
use actix_web::{App, HttpServer, web};
use std::sync::Arc;

#[actix_web::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    HttpServer::new(|| {
        // SSE service at custom path
        let sse_config = SseServerConfig {
            bind: "127.0.0.1:0".parse().unwrap(),
            sse_path: "/sse".to_string(),
            post_path: "/message".to_string(),
            ct: tokio_util::sync::CancellationToken::new(),
            sse_keep_alive: None,
        };
        let (sse_server, sse_scope) = SseServer::new(sse_config);
        let _ct = sse_server.with_service(|| MyMcpService::new());

        // StreamableHttp service at custom path
        let http_service = Arc::new(StreamableHttpService::new(
            || Ok(MyMcpService::new()),
            LocalSessionManager::default().into(),
            Default::default(),
        ));
        let http_scope = StreamableHttpService::scope(http_service);

        App::new()
            // Your existing routes
            .route("/health", web::get().to(health_check))
            // Mount MCP services at custom paths
            .service(web::scope("/api/v1/sse-calc").service(sse_scope))
            .service(web::scope("/api/v1/http-calc").service(http_scope))
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await?;

    Ok(())
}

Examples

See the examples/ directory for complete working examples:

Basic Examples

  • counter_sse.rs - SSE server with a simple counter service
  • counter_streamable_http.rs - Streamable HTTP server example

Composition Examples

  • composition_sse_example.rs - SSE server with framework-level composition
  • composition_streamable_http_example.rs - StreamableHttp with custom mounting
  • multi_service_example.rs - Multiple MCP services with different transports

Running Examples

# Basic SSE server
cargo run --example counter_sse

# Framework composition with SSE
cargo run --example composition_sse_example

# Multi-service example with both transports
cargo run --example multi_service_example

Each example includes detailed documentation and curl commands for testing.

Key Features

Framework-Level Composition

  • SSE Server: SseServer::new() returns (SseServer, Scope) for mounting at custom paths
  • StreamableHttp: StreamableHttpService::scope() returns configured Scope for composition
  • Multi-Service: Compose multiple MCP services with different transports in one app
  • RMCP Alignment: APIs follow RMCP ecosystem patterns for consistency

Protocol Support

  • Full MCP Compatibility: Implements complete MCP protocol specification
  • Bidirectional Communication: Both request/response and streaming patterns
  • Session Management: Stateful and stateless modes for StreamableHttp
  • Keep-Alive: Configurable keep-alive intervals for connection health

Integration

  • Drop-in Replacement: Same service implementations work with Axum or actix-web
  • Middleware Support: Full integration with actix-web middleware stack
  • Custom Paths: Mount services at any path using actix-web's Scope system
  • Built on actix-web: Leverages the mature actix-web framework

License

MIT License - see LICENSE file for details.

Contributing

This project is part of the Model Context Protocol ecosystem. Contributions are welcome!

References