Skip to main content

Server

Struct Server 

Source
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

Source

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.

Source

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.

Source

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

Source

pub fn new(name: impl Into<String>, version: impl Into<String>) -> ServerBuilder

Creates a new server builder.

Source

pub fn info(&self) -> &ServerInfo

Returns the server info.

Source

pub fn capabilities(&self) -> &ServerCapabilities

Returns the server capabilities.

Source

pub const fn protocol_policy(&self) -> ProtocolPolicy

Returns the immutable protocol-era policy selected by the builder.

Source

pub fn extension_handler_registry(&self) -> Option<&ExtensionHandlerRegistry>

Returns the installed frozen extension handler registry, if configured.

Source

pub fn extension_registry_receipt(&self) -> Option<&ExtensionRegistryReceipt>

Returns the canonical descriptor receipt for the installed registry.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn tools(&self) -> Vec<Tool>

Lists all registered tools.

Source

pub fn resources(&self) -> Vec<Resource>

Lists all registered resources.

Source

pub fn resource_templates(&self) -> Vec<ResourceTemplate>

Lists all registered resource templates.

Source

pub fn prompts(&self) -> Vec<Prompt>

Lists all registered prompts.

Source

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.

Source

pub fn into_router(self) -> Router

Consumes the server and returns its router.

This is used for mounting one server’s components into another.

Source

pub fn has_tools(&self) -> bool

Returns the capabilities this server provides.

This is useful when determining what components a server has before mounting.

Source

pub fn has_resources(&self) -> bool

Returns whether this server has resources.

Source

pub fn has_prompts(&self) -> bool

Returns whether this server has prompts.

Source

pub fn stats(&self) -> Option<StatsSnapshot>

Returns a point-in-time snapshot of server statistics.

Returns None if statistics collection is disabled.

Source

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.

Source

pub fn display_stats(&self)

Renders a stats panel to stderr, if stats are enabled.

Source

pub fn console_config(&self) -> &ConsoleConfig

Returns the console configuration.

Source

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.

Source

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.

Source

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.

Source

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, &notify, &req_sender,
);
Source

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, &notify, &req_sender,
);
Source

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.

Source

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.

Source

pub fn run_transport<T>(self, transport: T) -> !
where T: Transport + Send + 'static,

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.

Source

pub fn run_transport_with_cx<T>(self, cx: &Cx, transport: T) -> !
where T: Transport + Send + 'static,

Runs the server on a custom transport with a provided Cx.

This allows integration with a real asupersync runtime.

Source

pub fn run_transport_returning_with_cx<T>( self, cx: &Cx, transport: T, ) -> McpResult<()>
where T: Transport + Send + 'static,

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.

Source

pub fn run_split_transport_returning_with_cx<R, S>( self, cx: &Cx, recv_half: R, send_half: S, ) -> McpResult<()>
where R: TransportRecvHalf + Send + 'static, S: TransportSendHalf + 'static,

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.

Source

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<()>
where R: TransportRecvHalf + Send + 'static, S: TransportSendHalf + 'static,

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.

Source

pub fn run_transport_returning<T>(self, transport: T) -> McpResult<()>
where T: Transport + Send + 'static,

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.

Source

pub fn run_sse<W, R>( self, writer: W, request_source: R, endpoint_url: impl Into<String>, ) -> !
where W: Write + Send + 'static, R: Iterator<Item = JsonRpcRequest> + Send + 'static,

Runs the server using SSE transport with a testing Cx.

This is a convenience wrapper around SseServerTransport.

Source

pub async fn run_sse_with_cx<W, R>( self, cx: &Cx, writer: W, request_source: R, endpoint_url: impl Into<String>, ) -> !
where W: Write + Send + 'static, R: Iterator<Item = JsonRpcRequest> + Send + 'static,

Runs the server using SSE transport with a provided Cx.

Source

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.

Source

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.

Source

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.

Source

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.

Auto Trait Implementations§

§

impl !Freeze for Server

§

impl !RefUnwindSafe for Server

§

impl !UnwindSafe for Server

§

impl Send for Server

§

impl Sync for Server

§

impl Unpin for Server

§

impl UnsafeUnpin for Server

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, _span: NoopSpan) -> Self

Instruments this future with a span (no-op when disabled).
Source§

fn in_current_span(self) -> Self

Instruments this future with the current span (no-op when disabled).
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more