Skip to main content

McpServer

Struct McpServer 

Source
pub struct McpServer { /* private fields */ }
Expand description

MCP server backed by the rmcp framework.

The struct is cloned per request by rmcp’s handler dispatch; the expensive bits (provider closure) are behind an Arc so cloning is cheap.

Implementations§

Source§

impl McpServer

Source

pub fn new(options: ServerOptions) -> Self

Source

pub fn builtins(&self) -> &BuiltinsConfig

Read the manifest-declared builtins: config. Downstream consumers (e.g. a graph_overview tool that wipes a temp/ directory when temp_cleanup: on_overview is set) call this to discover what flags the operator asked for. The framework itself does not act on this — that would force it to interpret graph-specific semantics it shouldn’t know about.

Source

pub fn tool_router_mut(&mut self) -> &mut ToolRouter<McpServer>

Mutable access to the tool router for dynamic tool registration.

Use only at server-construction time (before serve). Once dispatching starts, the router is cloned per request and mutation would race.

Source

pub fn prompt_router_mut(&mut self) -> &mut PromptRouter<McpServer>

Mutable access to the prompt router for dynamic skill / prompt registration. Same lifecycle contract as [tool_router_mut]: boot-time only. Most operators reach prompts via serve_prompts rather than touching the router directly.

Source

pub fn register_typed_tool<T, F>( &mut self, name: &'static str, description: &'static str, handler: F, )
where T: for<'de> Deserialize<'de> + JsonSchema + Default + Send + Sync + 'static, F: Fn(T) -> String + Send + Sync + 'static,

Register a typed dynamic tool with an infallible handler. Compresses the boilerplate of:

  1. Generating a JSON Schema for the args type via schemars.
  2. Building a rmcp::model::Tool attr from the schema + name + description.
  3. Deserialising the per-call JSON arguments via serde.
  4. Wrapping the handler in a rmcp::handler::server::router::tool::ToolRoute::new_dyn closure suitable for tool_router_mut.

The handler is Fn(T) -> String; it owns whatever state it needs through the closure environment (typically an Arc-clone of a domain-specific state handle). A String is the only outcome the handler can produce, so every call that reaches it reports a success envelope (isError: false). That makes this the entry point for tools that genuinely cannot fail, and for tools that deliberately render their own failures as ordinary prose the agent reads and moves on from — the “errors as values” shape the source / GitHub builtins use.

A tool whose failure the client should be able to branch on wants register_typed_tool_fallible instead: it takes Fn(T) -> Result<String, String> and routes the Err body through the MCP error envelope, so a caller sees isError: true rather than having to pattern-match the text.

Arguments that fail to deserialise are an error envelope on either method — a call the framework could not even hand to the handler is not a result the agent should read as one.

Source

pub fn register_typed_tool_fallible<T, F>( &mut self, name: &'static str, description: &'static str, handler: F, )
where T: for<'de> Deserialize<'de> + JsonSchema + Default + Send + Sync + 'static, F: Fn(T) -> Result<String, String> + Send + Sync + 'static,

Register a typed dynamic tool whose handler can fail.

Same shape as register_typed_tool — same schema generation, same argument deserialisation, same dyn route — except the handler is Fn(T) -> Result<String, String>. Ok(body) produces the usual success envelope; Err(body) produces an MCP error envelope (isError: true) carrying the error text verbatim. That string is what the agent reads, so write it for that reader rather than dumping a Debug of some internal type into it.

The consumer’s ResultPostprocessHook runs on both arms, with the same ResultCtx, and its footer is appended to the error text exactly as it is to a success body. A downstream server that stamps identity or rebuild state onto every result keeps that stamp on the failure path, where an unplaceable error would otherwise send the agent hunting in the wrong graph.

Source

pub fn ping_tool_attr() -> Tool

Generated tool metadata function for ping

Source

pub fn read_source_tool_attr() -> Tool

Generated tool metadata function for read_source

Source

pub fn grep_tool_attr() -> Tool

Generated tool metadata function for grep

Source

pub fn list_source_tool_attr() -> Tool

Generated tool metadata function for list_source

Source

pub fn repo_management_tool_attr() -> Tool

Generated tool metadata function for repo_management

Trait Implementations§

Source§

impl Clone for McpServer

Source§

fn clone(&self) -> McpServer

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl ServerHandler for McpServer

Source§

async fn on_initialized(&self, context: NotificationContext<RoleServer>)

notifications/initialized — the one point at which a client-advertised root can be adopted (see crate::server::roots).

rmcp dispatches every peer notification on a task it spawns (spawn_service_task, which is tokio::spawn unless rmcp’s local feature is enabled), and the response router lives in the same select loop, so awaiting a server→client roots/list request here cannot deadlock and cannot delay the client’s session. If rmcp’s local feature is ever enabled that becomes spawn_local and this reasoning must be re-checked.

Everything about adoption is opt-in and guarded inside the roots module: with no workspace.adopt_client_roots this returns after two field reads, having sent nothing.

Source§

async fn on_roots_list_changed(&self, context: NotificationContext<RoleServer>)

notifications/roots/list_changed — re-run adoption, unless the operator has claimed the root in the meantime.

Source§

fn get_info(&self) -> ServerInfo

Source§

async fn list_prompts( &self, _request: Option<PaginatedRequestParams>, _context: RequestContext<RoleServer>, ) -> Result<ListPromptsResult, McpError>

Source§

async fn get_prompt( &self, request: GetPromptRequestParams, context: RequestContext<RoleServer>, ) -> Result<GetPromptResponse, McpError>

Source§

async fn call_tool( &self, request: CallToolRequestParams, context: RequestContext<RoleServer>, ) -> Result<CallToolResponse, ErrorData>

Handle a tools/call request from a client. Read more
Source§

async fn list_tools( &self, _request: Option<PaginatedRequestParams>, context: RequestContext<RoleServer>, ) -> Result<ListToolsResult, ErrorData>

Source§

fn get_tool(&self, name: &str) -> Option<Tool>

Get a tool definition by name. Read more
Source§

fn ping( &self, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

Source§

fn initialize( &self, request: InitializeRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<InitializeResult, ErrorData>> + MaybeSendFuture

Source§

fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]>

Return the protocol versions supported by this server. Read more
Source§

fn discover( &self, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<DiscoverResult, ErrorData>> + MaybeSendFuture

Return this server’s discovery information.
Source§

fn complete( &self, request: CompleteRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<CompleteResult, ErrorData>> + MaybeSendFuture

Source§

fn set_level( &self, request: SetLevelRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

Source§

fn list_resources( &self, request: Option<PaginatedRequestParams>, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<ListResourcesResult, ErrorData>> + MaybeSendFuture

Source§

fn list_resource_templates( &self, request: Option<PaginatedRequestParams>, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<ListResourceTemplatesResult, ErrorData>> + MaybeSendFuture

Source§

fn read_resource( &self, request: ReadResourceRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<ReadResourceResponse, ErrorData>> + MaybeSendFuture

Source§

fn accepted_subscription_filter( &self, requested: &SubscriptionFilter, ) -> Option<SubscriptionFilter>

Return the subset of a requested notification filter this server accepts. Read more
Source§

fn listen( &self, context: SubscriptionContext, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

Run one established subscription until it is cancelled or closed gracefully. Read more
Source§

fn subscribe( &self, request: SubscribeRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

👎Deprecated:

resources/subscribe is legacy-only; implement accepted_subscription_filter and listen for protocol version 2026-07-28

Source§

fn unsubscribe( &self, request: UnsubscribeRequestParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

👎Deprecated:

resources/unsubscribe is legacy-only; subscriptions/listen is cancelled through its request lifecycle

Source§

fn on_custom_request( &self, request: CustomRequest, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<CustomResult, ErrorData>> + MaybeSendFuture

Source§

fn on_cancelled( &self, notification: CancelledNotificationParam, context: NotificationContext<RoleServer>, ) -> impl Future<Output = ()> + MaybeSendFuture

Source§

fn on_progress( &self, notification: ProgressNotificationParam, context: NotificationContext<RoleServer>, ) -> impl Future<Output = ()> + MaybeSendFuture

Source§

fn on_custom_notification( &self, notification: CustomNotification, context: NotificationContext<RoleServer>, ) -> impl Future<Output = ()> + MaybeSendFuture

Source§

fn get_task( &self, request: GetTaskParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<GetTaskResult, ErrorData>> + MaybeSendFuture

SEP-2663 tasks/get: return the current DetailedTask state.
Source§

fn update_task( &self, request: UpdateTaskParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

SEP-2663 tasks/update: accept responses to outstanding in-task input requests. Returns an empty acknowledgement on success.
Source§

fn cancel_task( &self, request: CancelTaskParams, context: RequestContext<RoleServer>, ) -> impl Future<Output = Result<(), ErrorData>> + MaybeSendFuture

SEP-2663 tasks/cancel: cooperative cancellation. Returns an empty acknowledgement; the task’s observable status may lag.

Auto Trait Implementations§

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<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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<R, S> DynService<R> for S
where R: ServiceRole, S: Service<R>,

Source§

fn handle_request( &self, request: <R as ServiceRole>::PeerReq, context: RequestContext<R>, ) -> Pin<Box<dyn Future<Output = Result<<R as ServiceRole>::Resp, ErrorData>> + Send + '_>>

Source§

fn handle_notification( &self, notification: <R as ServiceRole>::PeerNot, context: NotificationContext<R>, ) -> Pin<Box<dyn Future<Output = Result<(), ErrorData>> + Send + '_>>

Source§

fn get_info(&self) -> <R as ServiceRole>::Info

Source§

fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]>

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: 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> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<H> Service<RoleServer> for H
where H: ServerHandler,

Source§

async fn handle_request( &self, request: <RoleServer as ServiceRole>::PeerReq, context: RequestContext<RoleServer>, ) -> Result<<RoleServer as ServiceRole>::Resp, ErrorData>

Source§

async fn handle_notification( &self, notification: <RoleServer as ServiceRole>::PeerNot, context: NotificationContext<RoleServer>, ) -> Result<(), ErrorData>

Source§

fn get_info(&self) -> <RoleServer as ServiceRole>::Info

Source§

fn supported_protocol_versions(&self) -> Cow<'static, [ProtocolVersion]>

The protocol versions this service can speak, bounding what initialize negotiation may agree to. Read more
Source§

impl<S> ServiceExt<RoleServer> for S
where S: Service<RoleServer>,

Source§

fn serve_with_ct<T, E, A>( self, transport: T, ct: CancellationToken, ) -> impl Future<Output = Result<RunningService<RoleServer, S>, ServerInitializeError>> + MaybeSendFuture
where T: IntoTransport<RoleServer, E, A>, E: Error + Send + Sync + 'static, S: Sized,

Source§

fn into_dyn(self) -> Box<dyn DynService<R>>

Convert this service to a dynamic boxed service Read more
Source§

fn serve<T, E, A>( self, transport: T, ) -> impl Future<Output = Result<RunningService<R, Self>, <R as ServiceRole>::InitializeError>> + MaybeSendFuture
where T: IntoTransport<R, E, A>, E: Error + Send + Sync + 'static, Self: Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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<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