#[non_exhaustive]pub struct ServerConfig {Show 35 fields
pub listen_addr: String,
pub listen_port: u16,
pub tls_cert_path: Option<PathBuf>,
pub tls_key_path: Option<PathBuf>,
pub tls_handshake_timeout: String,
pub max_concurrent_tls_handshakes: usize,
pub shutdown_timeout: String,
pub request_timeout: String,
pub max_request_body: usize,
pub allowed_origins: Vec<String>,
pub stdio_enabled: bool,
pub tool_rate_limit: Option<u32>,
pub tool_rate_limit_burst: Option<u32>,
pub extra_route_rate_limit: Option<u32>,
pub extra_route_rate_limit_burst: Option<u32>,
pub extra_route_rate_limit_exempt_paths: Vec<String>,
pub key_eviction_policy: KeyEvictionPolicy,
pub trusted_proxies: Vec<String>,
pub trusted_forwarder_max_entries: usize,
pub forwarded_header: Option<ForwardedHeaderMode>,
pub session_idle_timeout: String,
pub session_binding: bool,
pub session_binding_secret: Option<SecretString>,
pub task_binding: bool,
pub sse_keep_alive: String,
pub public_url: Option<String>,
pub compression_enabled: bool,
pub compression_min_size: u16,
pub max_concurrent_requests: Option<usize>,
pub admin_enabled: bool,
pub admin_role: String,
pub auth: Option<AuthConfig>,
pub tool_list_filtering: bool,
pub expose_build_metadata: bool,
pub security_headers: SecurityHeadersConfig,
}Expand description
Server listener configuration (reusable across MCP projects).
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.listen_addr: StringListen address (IP or hostname). Default: 127.0.0.1.
listen_port: u16Listen TCP port. Default: 8443.
tls_cert_path: Option<PathBuf>Path to the TLS certificate (PEM). Required for TLS/mTLS.
tls_key_path: Option<PathBuf>Path to the TLS private key (PEM). Required for TLS/mTLS.
tls_handshake_timeout: StringPer-handshake deadline on the TLS accept path, parsed via
humantime. Idle or slow-loris connections are dropped once it
elapses. Startup-only (not hot-reloadable); ignored unless TLS is
configured. Default: 10s.
max_concurrent_tls_handshakes: usizeCap on concurrently in-flight TLS handshakes. At saturation the
acceptor stops pulling new connections from the kernel backlog
(backpressure). Startup-only (not hot-reloadable); ignored unless
TLS is configured. Default: 256.
shutdown_timeout: StringGraceful shutdown timeout, parsed via humantime.
request_timeout: StringPer-request timeout, parsed via humantime.
max_request_body: usizeMaximum request body size in bytes. Default: 1 MiB.
allowed_origins: Vec<String>Allowed Origin header values for DNS rebinding protection (MCP spec). Requests with an Origin not in this list are rejected with 403. Requests without an Origin header are always allowed (non-browser).
stdio_enabled: boolAllow the stdio transport subcommand. Disabled by default because stdio mode bypasses auth, RBAC, TLS, and Origin validation.
tool_rate_limit: Option<u32>Maximum tool invocations per source IP per minute.
When set, enforced by the RBAC middleware on tools/call requests.
Protects against both abuse and runaway LLM loops.
tool_rate_limit_burst: Option<u32>Burst capacity for the tool rate limiter (bucket size; sustained
rate stays tool_rate_limit). Requires tool_rate_limit; must
be greater than zero.
extra_route_rate_limit: Option<u32>Maximum requests per source IP per minute on application routes
merged via McpServerConfig::with_extra_router (which bypass
auth/RBAC). Opt-in; must be greater than zero when set.
Keyed by the direct socket peer - no X-Forwarded-For
interpretation. Startup-only.
extra_route_rate_limit_burst: Option<u32>Burst capacity for the extra-route rate limiter (bucket size;
sustained rate stays extra_route_rate_limit). Requires
extra_route_rate_limit; must be greater than zero.
extra_route_rate_limit_exempt_paths: Vec<String>Exact-match request paths exempt from the extra-route rate
limiter. Raw string comparison against the request path - no
globs, no normalization; fail-closed (anything not listed stays
limited). Requires extra_route_rate_limit; entries must be
non-empty and start with /. Startup-only.
key_eviction_policy: KeyEvictionPolicyFull-table policy for per-IP rate limiters. Default: evict_lru.
trusted_proxies: Vec<String>Trusted reverse-proxy networks (CIDRs or bare IPs) for trusted-forwarder mode. Empty (default) = off. When the direct peer is inside one of these networks, the client IP is resolved from the forwarding header (rightmost-untrusted walk) and all per-IP rate limiters key by it. Startup-only.
trusted_forwarder_max_entries: usizeMaximum forwarding-chain entries scanned per request in
trusted-forwarder mode. Longer chains are treated as a header bomb
and resolution falls back to the direct peer. Default 16, valid
range 1..=64. Startup-only.
forwarded_header: Option<ForwardedHeaderMode>Which forwarding header trusted-forwarder mode reads:
"x-forwarded-for" (default when unset) or "forwarded"
(RFC 7239). Requires trusted_proxies to be nonempty.
session_idle_timeout: StringIdle timeout for MCP sessions. Sessions with no activity for this duration are closed automatically. Default: 20 minutes.
session_binding: boolBind MCP session IDs to the authenticated identity using a stateless signed wrapper. Default: true. Disabling reinstates CWE-384 risk.
session_binding_secret: Option<SecretString>Shared HMAC secret used for session binding across server instances.
Necessary but not sufficient for cross-instance session continuity: this
makes a session token minted by one instance verifiable by another. The
session itself lives in rmcp’s session store, so continuity also requires
a shared store via crate::transport::McpServerConfig::with_session_store.
Without one, a session does not survive a restart or a hop to another
instance even when this secret is shared.
Also used by Self::task_binding; the two are domain-separated.
task_binding: boolBind MCP task IDs (SEP-2663) to the authenticated identity that created
them, preventing cross-identity tasks/get, tasks/update, and
tasks/cancel. Default: false, because enabling it changes the wire
format of taskId values.
This is an opt-in compatibility control, not a staged default-flip promise.
sse_keep_alive: StringInterval for SSE keep-alive pings sent to the client. Prevents proxies and load balancers from killing idle connections. Default: 15 seconds.
public_url: Option<String>Externally reachable base URL (e.g. https://mcp.example.com).
When set, OAuth metadata endpoints advertise this URL instead of
the listen address. Required when the server binds to 0.0.0.0
behind a reverse proxy or inside a container.
compression_enabled: boolEnable gzip/br response compression for MCP responses.
compression_min_size: u16Minimum response size (bytes) before compression kicks in.
Only used when compression_enabled is true. Default: 1024.
max_concurrent_requests: Option<usize>Global cap on in-flight HTTP requests. When reached, excess requests receive 503 Service Unavailable (via load shedding).
admin_enabled: boolEnable /admin/* diagnostic endpoints.
admin_role: StringRBAC role required to access admin endpoints.
auth: Option<AuthConfig>Authentication configuration (API keys, mTLS, OAuth).
tool_list_filtering: boolFilter tools/list through RBAC visibility when RBAC is enabled.
Default: true.
expose_build_metadata: boolExpose build metadata on the unauthenticated /version endpoint.
security_headers: SecurityHeadersConfigPer-header OWASP security-header overrides.
Implementations§
Source§impl ServerConfig
impl ServerConfig
Sourcepub fn apply_env_overrides(
&mut self,
) -> Result<Vec<EnvOverride>, RmcpServerKitError>
pub fn apply_env_overrides( &mut self, ) -> Result<Vec<EnvOverride>, RmcpServerKitError>
Applies RMCP_SERVER_KIT__SERVER__* environment overrides onto this config.
Includes the nested OAuth variables under
RMCP_SERVER_KIT__SERVER__AUTH__OAUTH__*. This method is opt-in:
constructors, validators, and server startup do not call it.
§Errors
Returns RmcpServerKitError::Config when an override cannot be parsed, when an
OAuth override lacks a declared [server.auth.oauth] parent, or when an
OAuth override is used in a build without the oauth feature.
§Examples
The full config-file pipeline lives in
examples/config_file_server.rs.
use rmcp_server_kit::config::ServerConfig;
let mut server = ServerConfig::default();
// Do not set process env in doctests: rustdoc examples share a process.
let report = server.apply_env_overrides()?;
let _applied_fields: Vec<&str> = report
.iter()
.map(|entry| entry.target_field.as_str())
.collect();Sourcepub fn apply_to_mcp_config(
&self,
base: McpServerConfig,
) -> Result<McpServerConfig, RmcpServerKitError>
pub fn apply_to_mcp_config( &self, base: McpServerConfig, ) -> Result<McpServerConfig, RmcpServerKitError>
Apply this TOML server schema to a programmatic MCP server base.
Replacement semantics are used for every bridgeable transport field:
None and false values in TOML clear the corresponding value from
base. Only runtime-only fields such as name, version, RBAC,
readiness callbacks, extra routers, reload callbacks, and metrics
listener settings are preserved from base.
Chain application-code builder overrides after this method when those overrides should take precedence over TOML. This method is side-effect free and never reads process environment variables.
§Errors
Returns RmcpServerKitError::Config when a duration string cannot be parsed.
§Examples
The full config-file pipeline lives in
examples/config_file_server.rs.
use rmcp_server_kit::config::{ServerConfig, validate_server_config};
use rmcp_server_kit::transport::McpServerConfig;
let server = ServerConfig::default();
validate_server_config(&server)?;
let config = server.apply_to_mcp_config(McpServerConfig::new(
"placeholder:0",
"my-server",
"0.1.0",
))?;
let _validated = config.validate()?;Trait Implementations§
Source§impl Debug for ServerConfig
Hand-written so tls_key_path never reaches a log.
impl Debug for ServerConfig
Hand-written so tls_key_path never reaches a log.
SECURITY: a derived Debug renders the private-key path verbatim, and the
whole config is easy to log accidentally (tracing::debug!(?config), a
panic message, an error chain). Presence is still reported so diagnostics
remain useful; only the location is withheld.
Every field is listed deliberately rather than using
finish_non_exhaustive, and server_config_debug_lists_every_field fails
if a field is added here without being rendered.