About Rmcp Server Kit
Rmcp Server Kit is an MCP server in the Security category: reusable Rust framework for building authenticated, observable MCP (Model Context Protocol) servers over Streamable HTTP.
Install
git clone https://github.com/andrico21/rmcp-server-kitThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Rmcp Server Kit
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
5 checks have not been run yet.
README
rmcp-server-kit
rmcp-server-kit is a production-grade, reusable framework for building Model Context Protocol servers in Rust. It provides a Streamable HTTP transport with TLS/mTLS, structured observability, authentication (Bearer / mTLS / OAuth 2.1 JWT), role-based access control (RBAC), per-IP rate limiting, and optional Prometheus metrics -- all wired up and ready to go.
You supply a rmcp::handler::server::ServerHandler implementation; rmcp-server-kit
handles everything else.
Quick Start
[dependencies]
rmcp-server-kit = "1"
rmcp = { version = "1.5", features = ["server", "macros"] }
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal"] }
The minimal example below uses default features only. Enable the
oauthfeature (features = ["oauth"]) to validate JWTs against a JWKS, ormetricsfor the Prometheus/metricsendpoint -- see the Cargo features table below.
use rmcp_server_kit::transport::{McpServerConfig, serve};
use rmcp::handler::server::ServerHandler;
use rmcp::model::{ServerCapabilities, ServerInfo};
#[derive(Clone)]
struct MyHandler;
impl ServerHandler for MyHandler {
fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_tools().build())
}
}
#[tokio::main]
async fn main() -> rmcp_server_kit::Result<()> {
let _ = rmcp_server_kit::observability::init_tracing("info,my_server=debug");
let config = McpServerConfig::new("127.0.0.1:8080", "my-server", "0.1.0")
.with_request_timeout(std::time::Duration::from_secs(30))
.enable_request_header_logging();
serve(config.validate()?, || MyHandler).await
}
Full API documentation and worked examples live in docs/GUIDE.md. Two runnable end-to-end examples ship in the repository:
cargo run --example minimal_server
cargo run --example api_key_rbac
cargo run --example oauth_server --features oauth
Common configurations
API key + RBAC + per-tool argument allowlist:
use rmcp_server_kit::auth::{ApiKeyEntry, AuthConfig, generate_api_key};
use rmcp_server_kit::rbac::{ArgumentAllowlist, RbacConfig, RbacPolicy, RoleConfig};
use std::sync::Arc;
let (token, hash) = generate_api_key()?;
let auth = AuthConfig::with_keys(vec![
ApiKeyEntry::new("viewer-key", hash, "viewer"),
]);
let viewer = RoleConfig::new("viewer", vec!["echo".into()], vec!["*".into()])
.with_argument_allowlists(vec![ArgumentAllowlist::new(
"echo", "message", vec!["hello".into(), "ping".into()],
)]);
let rbac = Arc::new(RbacPolicy::new(&RbacConfig::with_roles(vec![viewer])));
OAuth 2.1 resource server (JWT validation against JWKS):
use rmcp_server_kit::auth::AuthConfig;
use rmcp_server_kit::oauth::OAuthConfig;
let oauth = OAuthConfig::builder(
"https://auth.example.com/",
"my-mcp-server",
"https://auth.example.com/.well-known/jwks.json",
)
.scope("mcp:admin", "admin")
.scope("mcp:read", "viewer")
.build();
let mut auth = AuthConfig::with_keys(vec![]);
auth.oauth = Some(oauth);
The OAuth fetcher and the shared
OauthHttpClientenforce a strict per-hop SSRF guard and a fail-closed cap on JWKS key counts. Construct the client viaOauthHttpClient::with_config(&oauth_config)so the configured CA bundle, the SSRF guard, and the HTTPS-downgrade-rejecting redirect policy are all wired in one call. SeeSECURITY.mdfor the trust model.
OAuth in-cluster IdP (private/loopback IdP target, opt-in):
use rmcp_server_kit::oauth::{OAuthConfig, OAuthSsrfAllowlist};
// `OAuthSsrfAllowlist` is `#[non_exhaustive]`; build it via
// `Default::default()` and push into the public fields.
let mut allowlist = OAuthSsrfAllowlist::default();
allowlist.hosts.push("rhbk.ops.example.com".into());
allowlist.cidrs.push("10.0.0.0/8".into());
let oauth = OAuthConfig::builder(
"https://rhbk.ops.example.com/realms/main",
"my-mcp-server",
"https://rhbk.ops.example.com/realms/main/protocol/openid-connect/certs",
)
.ssrf_allowlist(allowlist)
.build();
The default fail-closed SSRF guard blocks targets that resolve into private (RFC 1918), loopback, CGNAT, or unique-local space. Use
ssrf_allowlistonly when the IdP legitimately lives there (e.g. a KeycloakServiceClusterIP). Cloud-metadata addresses (AWS / GCP / Alibaba) remain unbypassable regardless of the allowlist contents. Seedocs/GUIDE.mdand the "Operator allowlist" subsection ofSECURITY.mdfor the full trust model.
Prometheus metrics on a separate listener:
let config = McpServerConfig::new("127.0.0.1:8080", "my-server", "0.1.0")
.with_metrics("127.0.0.1:9090".parse().unwrap());
TLS:
let config = McpServerConfig::new("127.0.0.1:8443", "my-server", "0.1.0")
.with_tls("/etc/certs/server.crt", "/etc/certs/server.key");
Features
- Transport: Streamable HTTP (
/mcp), health (/healthz,/readyz), admin diagnostics, graceful shutdown, configurable TLS and mTLS. - Auth: API-key (Argon2 hashed), mTLS client certs, OAuth 2.1 JWT validation against JWKS (feature-gated).
- RBAC: Tool-scoped allow-lists with per-role argument constraints and
task-local
current_role()/current_identity()accessors. - Observability: Tracing, JSON logs, optional audit-file sink.
- Hardening: Per-IP rate limiting (governor), request-body caps, OWASP security headers, configurable CORS and Host allow-lists.
- Metrics: Prometheus
/metricsendpoint (opt-in viametricsfeature).
Cargo features
| Feature | Default | Description |
|---|---|---|
oauth |
No | OAuth 2.1 JWT validation via JWKS. |
metrics |
No | Prometheus metrics registry and /metrics. |
Minimum supported Rust
rmcp-server-kit targets stable Rust 1.95 or newer (tracks edition = "2024").
Repository
- GitHub (canonical): https://github.com/andrico21/rmcp-server-kit
The canonical release artifact is the rmcp-server-kit crate on crates.io.
License
Dual-licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual-licensed as above, without any additional terms or conditions.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.