pub struct Server { /* private fields */ }Expand description
An MCP server instance.
Servers are built using ServerBuilder and can run on various
transports (stdio, SSE, WebSocket).
Implementations§
Source§impl Server
impl Server
Sourcepub fn into_http_endpoint(
self,
legacy_origin: impl Into<String>,
) -> Result<ServerHttpEndpoint, ServerHttpEndpointError>
pub fn into_http_endpoint( self, legacy_origin: impl Into<String>, ) -> Result<ServerHttpEndpoint, ServerHttpEndpointError>
Consumes this server into a live dual-era HTTP endpoint.
legacy_origin is used only for the exact MCP 2024-11-05 SSE endpoint
event. Modern Streamable HTTP remains at the configured MCP path.
Sourcepub async fn bind_http(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<BoundHttpServer>
pub async fn bind_http( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<BoundHttpServer>
Binds the HTTP listener on the caller-owned Cx.
This performs only listener setup. Call BoundHttpServer::serve to
accept connections, or use Self::serve_http for the turnkey
lifecycle. In a legacy-enabled build, the exact SSE endpoint derives
its advertised authority from the client’s Host header, with the
resolved local address as the fallback for direct embeddings.
Sourcepub async fn serve_http(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<HttpServerShutdown>
pub async fn serve_http( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<HttpServerShutdown>
Binds and accepts a turnkey HTTP server on the caller’s context. This method never creates or owns an async runtime.
Source§impl Server
impl Server
Sourcepub fn new(name: impl Into<String>, version: impl Into<String>) -> ServerBuilder
pub fn new(name: impl Into<String>, version: impl Into<String>) -> ServerBuilder
Creates a new server builder.
Sourcepub fn info(&self) -> &ServerInfo
pub fn info(&self) -> &ServerInfo
Returns the server info.
Sourcepub fn capabilities(&self) -> &ServerCapabilities
pub fn capabilities(&self) -> &ServerCapabilities
Returns the server capabilities.
Sourcepub const fn protocol_policy(&self) -> ProtocolPolicy
pub const fn protocol_policy(&self) -> ProtocolPolicy
Returns the immutable protocol-era policy selected by the builder.
Sourcepub fn extension_handler_registry(&self) -> Option<&ExtensionHandlerRegistry>
pub fn extension_handler_registry(&self) -> Option<&ExtensionHandlerRegistry>
Returns the installed frozen extension handler registry, if configured.
Sourcepub fn extension_registry_receipt(&self) -> Option<&ExtensionRegistryReceipt>
pub fn extension_registry_receipt(&self) -> Option<&ExtensionRegistryReceipt>
Returns the canonical descriptor receipt for the installed registry.
Sourcepub fn publish_subscription_notification(
&self,
notification: ServerNotification,
) -> McpResult<usize>
pub fn publish_subscription_notification( &self, notification: ServerNotification, ) -> McpResult<usize>
Publishes one final catalog or resource change notification to every
live subscriptions/listen request whose accepted filter matches it.
The server tags each delivered notification with that request’s exact subscription ID. Request-scoped notifications such as progress and messages are rejected rather than being broadcast.
§Errors
Returns InvalidParams when notification is not a final
subscription event, or an internal error when it cannot be encoded.
Sourcepub fn open_subscription_listen(
&self,
subscription_id: RequestId,
notifications: SubscriptionFilter,
notification_sender: NotificationSender,
) -> McpResult<SubscriptionListenHandle>
pub fn open_subscription_listen( &self, subscription_id: RequestId, notifications: SubscriptionFilter, notification_sender: NotificationSender, ) -> McpResult<SubscriptionListenHandle>
Opens one in-process subscriptions/listen stream.
The returned handle keeps the stream registered. Dropping it
unregisters the listener. Events are delivered through
notification_sender; this method does not block on stream lifetime.
Wire transports should keep using their owned listen dispatch.
§Errors
Returns InvalidRequest when subscription_id is not a valid JSON-RPC
id, InvalidParams when the filter cannot be admitted, or a capacity
error when the server already holds the maximum number of streams.
Sourcepub fn terminate_subscription_streams(&self) -> usize
pub fn terminate_subscription_streams(&self) -> usize
Begins graceful termination for all live final subscription streams.
Stdio subscriptions/listen streams receive one correlated final
notifications/cancelled control. Modern HTTP streams instead end
gracefully with their correlated terminal response; client
cancellation is response-body closure, never an MCP cancellation
notification.
Sourcepub fn negotiate_extensions(
&self,
client: &ClientExtensionDiscovery,
) -> Result<NegotiatedExtensionSet, ServerExtensionNegotiationError>
pub fn negotiate_extensions( &self, client: &ClientExtensionDiscovery, ) -> Result<NegotiatedExtensionSet, ServerExtensionNegotiationError>
Negotiates currently advertised client extension settings against this server.
The resulting set is bound to this server’s frozen descriptor receipt and
can only admit modern extension calls through
Self::dispatch_negotiated_extension. Exact MCP 2024-11-05 uses no
extension registry path.
Sourcepub fn server_discovery(&self) -> McpResult<ServerDiscoverResult>
pub fn server_discovery(&self) -> McpResult<ServerDiscoverResult>
Returns the final discovery result for this constructed server.
Discovery is explicitly unauthenticated at this server boundary, just
like the rest of the modern stateless surface: transports authenticate
raw credentials before constructing InboundRequestContext, while
this method receives only already-sanitized request facts. The result
derives from the immutable router catalog and cannot grant access to a
method or notification path that is not installed.
Sourcepub fn resource_templates(&self) -> Vec<ResourceTemplate>
pub fn resource_templates(&self) -> Vec<ResourceTemplate>
Lists all registered resource templates.
Sourcepub fn dispatch_negotiated_extension(
&self,
request_ctx: &McpContext,
negotiated: &NegotiatedExtensionSet,
request: &JsonRpcRequest,
) -> McpResult<Value>
pub fn dispatch_negotiated_extension( &self, request_ctx: &McpContext, negotiated: &NegotiatedExtensionSet, request: &JsonRpcRequest, ) -> McpResult<Value>
Dispatches an already-negotiated modern extension request.
This public seam preserves the caller’s request-owned context and only invokes a handler when its descriptor is active in the supplied frozen current-exchange capability set.
Sourcepub fn into_router(self) -> Router
pub fn into_router(self) -> Router
Consumes the server and returns its router.
This is used for mounting one server’s components into another.
Sourcepub fn has_tools(&self) -> bool
pub fn has_tools(&self) -> bool
Returns the capabilities this server provides.
This is useful when determining what components a server has before mounting.
Sourcepub fn has_resources(&self) -> bool
pub fn has_resources(&self) -> bool
Returns whether this server has resources.
Sourcepub fn has_prompts(&self) -> bool
pub fn has_prompts(&self) -> bool
Returns whether this server has prompts.
Sourcepub fn stats(&self) -> Option<StatsSnapshot>
pub fn stats(&self) -> Option<StatsSnapshot>
Returns a point-in-time snapshot of server statistics.
Returns None if statistics collection is disabled.
Sourcepub fn stats_collector(&self) -> Option<&ServerStats>
pub fn stats_collector(&self) -> Option<&ServerStats>
Returns the raw statistics collector.
Useful for advanced scenarios where you need direct access.
Returns None if statistics collection is disabled.
Sourcepub fn display_stats(&self)
pub fn display_stats(&self)
Renders a stats panel to stderr, if stats are enabled.
Sourcepub fn console_config(&self) -> &ConsoleConfig
pub fn console_config(&self) -> &ConsoleConfig
Returns the console configuration.
Sourcepub fn dispatch_stateless(
&self,
inbound: &InboundRequestContext,
request: &JsonRpcRequest,
) -> Option<JsonRpcResponse>
pub fn dispatch_stateless( &self, inbound: &InboundRequestContext, request: &JsonRpcRequest, ) -> Option<JsonRpcResponse>
Processes one modern request through the final dispatch surface.
The transport owns raw headers and retains a native authorization field
only in crate-private inbound custody. Each call creates a fresh request
authority, authenticates before extension middleware, and delegates only
to the router’s final dispatch surface. It neither reads nor mutates a
legacy Session. A transport that supplies a connection-bound
InboundRequestContext also carries its durable MRTR partition and
retained-continuation cancellation authority.
Requests that require connection-local lifecycle state remain available exclusively through the legacy adapter. Modern list results still come from the immutable router catalog and never depend on previous request data.
Sourcepub fn dispatch_with_protocol_policy(
&self,
policy: ProtocolPolicy,
inbound: &InboundRequestContext,
request: &JsonRpcRequest,
) -> Option<JsonRpcResponse>
pub fn dispatch_with_protocol_policy( &self, policy: ProtocolPolicy, inbound: &InboundRequestContext, request: &JsonRpcRequest, ) -> Option<JsonRpcResponse>
Processes a modern request under an explicit protocol policy.
ModernOnly declines every request that lacks the exact final-era
marker before parameter decoding or any legacy session lookup. Final
server/discover remains a valid first request when it carries that
marker.
Sourcepub fn dispatch_http_with_protocol_policy(
&self,
policy: ProtocolPolicy,
inbound: &InboundRequestContext,
request: &JsonRpcRequest,
) -> HttpResponse
pub fn dispatch_http_with_protocol_policy( &self, policy: ProtocolPolicy, inbound: &InboundRequestContext, request: &JsonRpcRequest, ) -> HttpResponse
Maps an explicit-policy modern dispatch result onto the HTTP response status required for an explicit-policy cross-era refusal.
The transport still owns raw HTTP parsing, origin checks, and
authentication before it constructs InboundRequestContext. This
helper owns only the transport-neutral JSON-RPC result and its final
HTTP status mapping.
Sourcepub fn dispatch_request(
&self,
cx: &Cx,
session: &mut Session,
request: JsonRpcRequest,
notification_sender: &NotificationSender,
request_sender: &RequestSender,
) -> Option<JsonRpcResponse>
pub fn dispatch_request( &self, cx: &Cx, session: &mut Session, request: JsonRpcRequest, notification_sender: &NotificationSender, request_sender: &RequestSender, ) -> Option<JsonRpcResponse>
Processes a single JSON-RPC request through the full server dispatch pipeline (initialization checks, middleware, routing, tool/resource/prompt execution, error masking, and statistics recording).
This is the public equivalent of the internal handle_request method that
the stdio and custom transport paths use. It allows
external code to drive the server from a custom transport or embedding
without going through a Transport abstraction.
§Parameters
cx— The cancellation / budget context for this request.session— Mutable reference to the session for this connection. The caller is responsible for session lifecycle (creation, sharing, locking if shared across threads).request— The incoming JSON-RPC request (or notification).notification_sender— Callback used to push server-initiated notifications (e.g. progress) back to the client.request_sender— Sender for server-to-client requests (sampling, elicitation, roots).
§Returns
Some(JsonRpcResponse) for normal requests, or None for
notifications (JSON-RPC messages without an id).
§Example
use std::sync::Arc;
use fastmcp_rust::{
Server, Session, JsonRpcRequest, NotificationSender,
bidirectional::RequestSender,
};
use fastmcp_core::Cx;
let server = Arc::new(
Server::new("my-server", "1.0.0").build(),
);
let mut session = Session::new();
let cx = Cx::for_request();
let notify: NotificationSender = Arc::new(|_| {});
let req_sender = RequestSender::noop();
let request: JsonRpcRequest = /* ... */;
let response = server.dispatch_request(
&cx, &mut session, request, ¬ify, &req_sender,
);Sourcepub fn dispatch_request_concurrent(
&self,
cx: &Cx,
session: &Arc<Mutex<Session>>,
request: JsonRpcRequest,
notification_sender: &NotificationSender,
request_sender: &RequestSender,
) -> Option<JsonRpcResponse>
pub fn dispatch_request_concurrent( &self, cx: &Cx, session: &Arc<Mutex<Session>>, request: JsonRpcRequest, notification_sender: &NotificationSender, request_sender: &RequestSender, ) -> Option<JsonRpcResponse>
Processes a single JSON-RPC request against a shared session.
This is the concurrent counterpart of dispatch_request.
Use it when the session is shared across threads behind an
Arc<Mutex<Session>> (e.g. in HTTP or WebSocket transports where
multiple requests may arrive simultaneously).
The mutex is held for the full handler duration. MCP tool annotations are advisory hints, and every handler context can mutate session state or perform nested calls, so treating a hint as an execution-safety boundary would permit lost updates.
Mutex poisoning is recovered from automatically (the poisoned inner value is used), matching the behaviour of the internal HTTP handler.
§Parameters
cx— The cancellation / budget context for this request.session— Shared, mutex-protected session for this connection.request— The incoming JSON-RPC request (or notification).notification_sender— Callback used to push server-initiated notifications (e.g. progress) back to the client.request_sender— Sender for server-to-client requests (sampling, elicitation, roots).
§Returns
Some(JsonRpcResponse) for normal requests, or None for
notifications (JSON-RPC messages without an id).
§Example
use std::sync::{Arc, Mutex};
use fastmcp_rust::{
Server, Session, JsonRpcRequest, NotificationSender,
bidirectional::RequestSender,
};
use fastmcp_core::Cx;
let server = Arc::new(
Server::new("my-server", "1.0.0").build(),
);
let session = Arc::new(Mutex::new(Session::new()));
let cx = Cx::for_request();
let notify: NotificationSender = Arc::new(|_| {});
let req_sender = RequestSender::noop();
let request: JsonRpcRequest = /* ... */;
let response = server.dispatch_request_concurrent(
&cx, &session, request, ¬ify, &req_sender,
);Sourcepub fn run_stdio(self) -> !
pub fn run_stdio(self) -> !
Runs the server on stdio transport.
This is the primary way to run MCP servers as subprocesses. The blocking stdio pump runs as a caller-owned blocking child, leaving the caller runtime free to schedule bounded, request-owned modern children.
Sourcepub async fn run_stdio_with_cx(self, cx: &Cx) -> !
pub async fn run_stdio_with_cx(self, cx: &Cx) -> !
Runs the server on stdio with a provided Cx.
On Unix, the receive pump uses readiness polling so cancellation from a
failed dispatch worker remains observable while stdin is silent or a
pipe frame is incomplete. Unix responses use nonblocking writes with a
bounded commit deadline for ordinary pipes and sockets; regular files
and some devices may ignore O_NONBLOCK. Other targets use the
sequential server loop: that avoids a worker failing while the receive
side is blocked, but generic blocking stdin reads and stdout writes
remain observable only at frame boundaries or I/O completion.
If an arbitrary handler does not quiesce within the bounded worker shutdown deadline, the process exits unsuccessfully without running the shutdown hook; running a hook concurrently with a live handler would violate the hook’s quiescence contract.
Sourcepub fn run_transport<T>(self, transport: T) -> !
pub fn run_transport<T>(self, transport: T) -> !
Runs the server on a custom transport under one ambient server context.
This is useful for SSE/WebSocket integrations where the transport is provided by an external server framework.
Sourcepub fn run_transport_with_cx<T>(self, cx: &Cx, transport: T) -> !
pub fn run_transport_with_cx<T>(self, cx: &Cx, transport: T) -> !
Runs the server on a custom transport with a provided Cx.
This allows integration with a real asupersync runtime.
Sourcepub fn run_transport_returning_with_cx<T>(
self,
cx: &Cx,
transport: T,
) -> McpResult<()>
pub fn run_transport_returning_with_cx<T>( self, cx: &Cx, transport: T, ) -> McpResult<()>
Runs the server on a custom transport until clean closure, cancellation, or failure.
Unlike run_transport_with_cx, this does not call
std::process::exit on shutdown. This is useful for tests and embedding where you need
the server loop to be joinable. Clean EOF and cancellation return
Ok(()); startup, protocol, fatal receive, and fatal send failures
return an error.
Transport failures carry fixed stage and kind fields in the error
data without copying peer-controlled I/O or codec text.
§Errors
Returns an error when startup fails, a fatal receive/protocol failure is
observed, the server cannot send a required response, or transport
close fails. A simultaneous run and close failure retains both
structured errors under data.run and data.close.
Sourcepub fn run_split_transport_returning_with_cx<R, S>(
self,
cx: &Cx,
recv_half: R,
send_half: S,
) -> McpResult<()>
pub fn run_split_transport_returning_with_cx<R, S>( self, cx: &Cx, recv_half: R, send_half: S, ) -> McpResult<()>
Runs independently owned receive and send halves under the dual-era dispatcher.
Modern requests receive bounded request-owned child contexts and may
progress while the receive half blocks for another frame. Exact
MCP 2024-11-05 traffic remains serialized through its lifecycle adapter.
Use this entry point for genuinely full-duplex transports; an unsplit
Transport cannot safely promise concurrent receive and response I/O.
Shutdown retains ownership of the dispatch worker. If an arbitrary handler ignores cancellation past the bounded shutdown deadline, this returning API continues waiting for that worker to quiesce instead of orphaning it merely to return. Once it does quiesce, the call reports the timeout failure and then performs the normal owned cleanup.
Sourcepub fn run_split_transport_returning_with_dispatch_cx<R, S>(
self,
pump_cx: &Cx,
dispatch_cx: &Cx,
recv_half: R,
send_half: S,
) -> McpResult<()>
pub fn run_split_transport_returning_with_dispatch_cx<R, S>( self, pump_cx: &Cx, dispatch_cx: &Cx, recv_half: R, send_half: S, ) -> McpResult<()>
Runs independently owned receive and send halves with an explicit caller-owned context for modern request dispatch.
A split receive pump may itself be placed on the caller’s blocking
pool. In that arrangement pump_cx owns ingress cancellation, while
dispatch_cx must remain the runtime context that owns the blocking
pool used by concurrent modern request children.
Sourcepub fn run_transport_returning<T>(self, transport: T) -> McpResult<()>
pub fn run_transport_returning<T>(self, transport: T) -> McpResult<()>
Runs the server on a custom transport until clean closure, cancellation, or failure.
This uses one ambient server Cx, but unlike
run_transport it does not exit the process.
Independently owned per-request child contexts are not yet provided by
this legacy loop. Clean EOF and cancellation return Ok(()); failures
are returned to the caller.
§Errors
Returns an error when startup fails, a fatal receive/protocol failure is observed, the server cannot send a required response, or transport close fails.
Sourcepub fn run_sse<W, R>(
self,
writer: W,
request_source: R,
endpoint_url: impl Into<String>,
) -> !
pub fn run_sse<W, R>( self, writer: W, request_source: R, endpoint_url: impl Into<String>, ) -> !
Runs the server using SSE transport with a testing Cx.
This is a convenience wrapper around SseServerTransport.
Sourcepub async fn run_sse_with_cx<W, R>(
self,
cx: &Cx,
writer: W,
request_source: R,
endpoint_url: impl Into<String>,
) -> !
pub async fn run_sse_with_cx<W, R>( self, cx: &Cx, writer: W, request_source: R, endpoint_url: impl Into<String>, ) -> !
Runs the server using SSE transport with a provided Cx.
Sourcepub async fn run_http(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<HttpServerShutdown>
pub async fn run_http( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<HttpServerShutdown>
Runs the turnkey dual-era HTTP server on a caller-owned Cx.
This is an async lifecycle rather than a runtime constructor: callers drive it from their existing asupersync region and retain cancellation, deadlines, and task ownership throughout socket acceptance.
Sourcepub async fn run_http_with_cx(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<HttpServerShutdown>
pub async fn run_http_with_cx( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<HttpServerShutdown>
Named compatibility entry point for callers that already pass a
context. It is exactly Self::run_http and never creates a runtime.
Sourcepub async fn run_http_returning(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<HttpServerShutdown>
pub async fn run_http_returning( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<HttpServerShutdown>
Returning form of Self::run_http for embedders that select the
shutdown boundary themselves.
Sourcepub async fn run_http_returning_with_cx(
self,
cx: &Cx,
addr: impl Into<String>,
) -> McpResult<HttpServerShutdown>
pub async fn run_http_returning_with_cx( self, cx: &Cx, addr: impl Into<String>, ) -> McpResult<HttpServerShutdown>
Returning form with an explicit caller-owned context.