rust-mcp-actix
Actix-web HTTP server integration for rust-mcp-sdk.
Provides a production-ready Actix-web layer for MCP servers supporting Streamable HTTP and SSE transports. Choose this crate when you want to build on Actix-web or add MCP to an existing Actix application.
Prefer Axum? See
rust-mcp-axumfor an equivalent integration built on Axum. Both crates expose the same feature set and follow the same usage patterns.
Features
- Turnkey server —
create_actix_server().start().await - BYO-server —
mcp_scope()+McpMountOptionsto mount MCP endpoints on any existing Actix-web app - Streamable HTTP + SSE transports (SSE enabled by default for backward compatibility)
- Multi-client concurrency with internal session management
- Resumability via pluggable
EventStore(built-inInMemoryEventStore) - MCP Tasks support via pluggable
TaskStore(built-inInMemoryTaskStore) - OAuth authentication via
AuthProvider - DNS rebinding protection (enabled by default)
- HTTP health check endpoint (optional)
- TLS/SSL support (via
sslcargo feature) - Custom session ID generators and session stores
- Message observer hook for telemetry & monitoring
Quick Start
Add to your Cargo.toml:
[]
= "0.10"
= "0.1"
= { = "1", = ["full"] }
= "0.1"
Turnkey Server
use ;
use ;
use Arc;
// Implement your handler ...
;
async
Once running, the server exposes:
- Streamable HTTP at
http://127.0.0.1:8080/mcp - SSE at
http://127.0.0.1:8080/sse(for backward-compatible clients)
Test with MCP Inspector:
# Then open: http://localhost:6274/?transport=streamable-http&serverUrl=http://localhost:8080/mcp
BYO-server (Mount on an Existing Actix App)
Use mcp_scope() with McpMountOptions to integrate MCP into any existing Actix-web application:
use ;
use ;
use ;
use InMemorySessionStore;
use UuidGenerator;
use Arc;
// Build the shared MCP state
let state = new;
let http_handler = new;
let mount = McpMountOptions ;
new
.bind?
.run
.await?;
👉 See the full working example: examples/byo-server.rs
ActixServerOptions Reference
All fields are optional except host and port (which have defaults). Use ..Default::default() for any fields you don't need.
| Field | Type | Default | Description |
|---|---|---|---|
host |
String |
"127.0.0.1" |
Bind address |
port |
u16 |
8080 |
TCP port |
sse_support |
bool |
true |
Enable SSE transport for backward compat |
event_store |
Option<Arc<dyn EventStore>> |
None |
Enables resumability |
task_store |
Option<Arc<ServerTaskStore>> |
None |
Handles server-side MCP tasks |
client_task_store |
Option<Arc<ClientTaskStore>> |
None |
Tracks client-side MCP tasks |
session_store |
Option<Arc<dyn SessionStore>> |
None (bounded in-memory) |
Custom session backend |
session_id_generator |
Option<Arc<dyn IdGenerator<SessionId>>> |
None (UUID) |
Custom session ID strategy |
auth |
Option<Arc<dyn AuthProvider>> |
None |
OAuth authentication provider |
health_endpoint |
Option<String> |
None (disabled) |
Path for health check, e.g. "/health" |
health_handler |
Option<Arc<dyn HealthHandler>> |
None (200 OK) |
Custom health response handler |
message_observer |
Option<Arc<dyn McpObserver<...>>> |
None |
Telemetry / monitoring hook |
dns_rebinding |
DnsRebindingOptions |
enabled | DNS rebinding protection config |
ping_interval |
Duration |
12 seconds | Keep-alive ping frequency |
enable_json_response |
Option<bool> |
false |
Return JSON instead of SSE stream |
max_request_body_size |
Option<usize> |
4 MiB | Maximum request body size |
enable_ssl |
bool |
false |
Enable TLS (requires ssl feature) |
ssl_cert_path |
Option<String> |
None |
Path to PEM certificate file |
ssl_key_path |
Option<String> |
None |
Path to PEM private key file |
custom_streamable_http_endpoint |
Option<String> |
None (/mcp) |
Override Streamable HTTP path |
custom_sse_endpoint |
Option<String> |
None (/sse) |
Override SSE path |
custom_messages_endpoint |
Option<String> |
None (/messages) |
Override SSE messages path |
transport_options |
Arc<TransportOptions> |
default | Shared transport config |
Full Example with Common Options
use ;
use ;
use Arc;
let server = create_actix_server;
server.start.await?;
Cargo Features
| Feature | Description |
|---|---|
ssl |
Enables TLS/SSL via Actix-web + rustls. Requires ssl_cert_path and ssl_key_path in options. |
Note: Unlike
rust-mcp-axum, Actix-web has no optional crypto provider split, so there is notls-no-providervariant.
# With TLS/SSL
= { = "0.1", = ["ssl"] }
Security Considerations
When using Streamable HTTP transport, follow these best practices:
- DNS rebinding protection is enabled by default. If
allowed_hostsis not set, it is auto-derived fromhost:port. For wildcard binds (0.0.0.0,::), explicitly configureallowed_hostsinDnsRebindingOptions. - In local development, bind only to
127.0.0.1rather than0.0.0.0. - Use TLS/HTTPS for any production or internet-facing deployment (enable the
sslfeature).
Examples
| Example | Description |
|---|---|
hello-world-server.rs |
Minimal turnkey Actix MCP server |
byo-server.rs |
Mount MCP on an existing Actix-web app via mcp_scope() |
Run them with:
License
MIT
Part of the rust-mcp-sdk ecosystem — a high-performance, asynchronous toolkit for building MCP servers and clients in Rust.