rmcp-actix-web

Crates.iormcp-actix-web
lib.rsrmcp-actix-web
version0.4.1
created_at2025-07-05 19:48:54.184408+00
updated_at2025-08-29 11:27:38.613753+00
descriptionactix-web transport implementations for RMCP (Rust Model Context Protocol)
homepagehttps://gitlab.com/lx-industries/rmcp-actix-web
repositoryhttps://gitlab.com/lx-industries/rmcp-actix-web
max_upload_size
id1739432
size276,250
Jean-Marc Le Roux (JMLX42)

documentation

README

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::SseService;
use actix_web::{App, HttpServer};
use std::sync::Arc;

#[actix_web::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let sse_service = SseService::builder()
        .service_factory(Arc::new(|| Ok(MyMcpService::new())))
        .build();

    HttpServer::new(move || {
        App::new()
            .service(sse_service.clone().scope())
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await?;
    
    Ok(())
}

Framework-Level Composition

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

use rmcp_actix_web::{SseService, 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>> {
    // SSE service with builder pattern
    let sse_service = SseService::builder()
        .service_factory(Arc::new(|| Ok(MyMcpService::new())))
        .sse_path("/events".to_string())
        .post_path("/messages".to_string())
        .build();

    // StreamableHttp service with builder pattern (shared across workers)
    let http_service = StreamableHttpService::builder()
        .service_factory(Arc::new(|| Ok(MyMcpService::new())))
        .session_manager(Arc::new(LocalSessionManager::default()))
        .stateful_mode(true)
        .build();

    HttpServer::new(move || {
        App::new()
            // Your existing routes
            .route("/health", web::get().to(|| async { "OK" }))
            // Mount MCP services at custom paths
            .service(web::scope("/api/v1/sse-calc").service(sse_service.clone().scope()))
            .service(web::scope("/api/v1/http-calc").service(http_service.clone().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 Service: SseService::builder().build() with .scope() method for mounting at custom paths
  • StreamableHttp: StreamableHttpService::builder().build() with .scope() for composition
  • Multi-Service: Compose multiple MCP services with different transports in one app
  • Unified Builder API: Consistent builder pattern across all transport services

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

Commit count: 80

cargo fmt