Skip to main content

McpServer

Struct McpServer 

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

MCP Server implementation

The main server struct that handles MCP protocol communication, manages resources, tools, and prompts, and processes client requests.

§Examples

§Basic Server Creation

use prism_mcp_rs::server::McpServer;

let server = McpServer::new("my-server".to_string(), "1.0.0".to_string());

§Using ServerBuilder

use prism_mcp_rs::server::ServerBuilder;

let server = ServerBuilder::new()
    .name("my-server")
    .version("1.0.0")
    .with_tools()
    .with_resources()
    .build();

§Adding Tools

use prism_mcp_rs::server::McpServer;
use prism_mcp_rs::core::{Tool, ToolHandler};
use prism_mcp_rs::core::error::McpError;
use serde_json::{json, Value};
use async_trait::async_trait;
use std::collections::HashMap;

struct MyTool;

#[async_trait]
impl ToolHandler for MyTool {
    async fn call(&self, _args: HashMap<String, Value>)
        -> Result<prism_mcp_rs::protocol::ToolResult, McpError>
    {
        Ok(prism_mcp_rs::protocol::ToolResult {
            content: vec![],
            is_error: Some(false),
            structured_content: None,
            meta: None,
        })
    }
}

let mut server = McpServer::new("server".to_string(), "1.0.0".to_string());

// Add tool using the add_tool method directly
server.add_tool(
    "my_tool",
    Some("My custom tool"),
    json!({}),
    MyTool
).await?;

Main MCP server implementation

Implementations§

Source§

impl McpServer

Source

pub async fn process_message( &self, msg: JsonRpcMessage, ) -> McpResult<JsonRpcMessage>

Process any JSON-RPC message asynchronously

This method handles all types of JSON-RPC messages (requests, responses, notifications, errors) and returns an appropriate response.

§Arguments
  • msg - The JSON-RPC message to process
§Returns

A result containing the response message or an error

§Examples
let server = McpServer::new("server".to_string(), "1.0.0".to_string());
let request = JsonRpcRequest::new(
    json!(1),
    "ping".to_string(),
    None::<serde_json::Value>
)?;
let message = JsonRpcMessage::Request(request);
let response = server.process_message(message).await?;
Source

pub async fn handle_notification( &self, notification: JsonRpcNotification, ) -> McpResult<()>

Handle a JSON-RPC notification asynchronously

Notifications are one-way messages that don’t expect a response.

§Arguments
  • notification - The notification to handle
§Returns

A result indicating success or failure of handling the notification

Source

pub async fn handle_requests_parallel( &self, requests: Vec<JsonRpcRequest>, ) -> Vec<McpResult<JsonRpcResponse>> ⓘ

Handle multiple requests in parallel

This method processes multiple requests concurrently and returns all responses once they’re complete.

§Arguments
  • requests - A vector of JSON-RPC requests to process
§Returns

A vector of results, one for each request

§Examples
let server = McpServer::new("server".to_string(), "1.0.0".to_string());
let requests = vec![
    JsonRpcRequest::new(json!(1), "ping".to_string(), None::<serde_json::Value>)?,
    JsonRpcRequest::new(json!(2), "tools/list".to_string(), None::<serde_json::Value>)?,
];
let responses = server.handle_requests_parallel(requests).await;
Source

pub async fn handle_request_with_processor<F, Fut>( &self, request: JsonRpcRequest, processor: F, ) -> McpResult<JsonRpcResponse>
where F: FnOnce(JsonRpcRequest) -> Fut, Fut: Future<Output = McpResult<JsonRpcRequest>>,

Handle requests with a custom async processor

This method allows you to provide a custom processor function that can modify or filter requests before they’re handled.

§Arguments
  • request - The request to process
  • processor - An async function that processes the request
§Returns

The processed response

Source

pub async fn run_with_processor<F, Fut>(&self, _processor: F) -> McpResult<()>
where F: FnMut(JsonRpcMessage) -> Fut + Send + 'static, Fut: Future<Output = McpResult<JsonRpcMessage>> + Send,

Run the server with a custom message processor

This method allows you to run the server with a custom async message processor that can handle incoming messages with custom logic.

§Arguments
  • processor - An async function that processes messages
§Returns

A result indicating success or failure

Source

pub async fn handle_batch(&self, batch: Vec<Value>) -> McpResult<Vec<Value>>

Handle a batch of JSON-RPC requests

This method processes a batch of requests according to the JSON-RPC batch specification.

§Arguments
  • batch - A JSON array of requests
§Returns

A JSON array of responses

Source

pub async fn handle_request_streaming<F>( &self, request: JsonRpcRequest, progress_callback: F, ) -> McpResult<JsonRpcResponse>
where F: FnMut(f32, String) + Send,

Stream responses for long-running operations

This method provides a way to stream responses for operations that may take a long time to complete.

§Arguments
  • request - The request to process
  • progress_callback - A callback function for progress updates
§Returns

The final response

Source

pub async fn handle_request_with_timeout( &self, request: JsonRpcRequest, timeout_ms: u64, ) -> McpResult<JsonRpcResponse>

Handle a request with timeout

This method processes a request with a specified timeout.

§Arguments
  • request - The request to process
  • timeout - The timeout duration in milliseconds
§Returns

The response or a timeout error

Source

pub async fn handle_request_with_retry( &self, request: JsonRpcRequest, max_retries: u32, retry_delay_ms: u64, ) -> McpResult<JsonRpcResponse>

Handle a request with retry logic

This method attempts to process a request with automatic retry on failure.

§Arguments
  • request - The request to process
  • max_retries - Maximum number of retry attempts
  • retry_delay_ms - Delay between retries in milliseconds
§Returns

The response or the last error after all retries

Source

pub async fn process_with_middleware<M>( &self, message: JsonRpcMessage, middleware: Vec<M>, ) -> McpResult<JsonRpcMessage>
where M: Fn(JsonRpcMessage) -> Pin<Box<dyn Future<Output = McpResult<JsonRpcMessage>> + Send>> + Send + Sync,

Process a message with middleware chain

This method allows you to process messages through a chain of middleware functions.

§Arguments
  • message - The message to process
  • middleware - A vector of middleware functions
§Returns

The processed message

Source§

impl McpServer

Source

pub fn new(name: String, version: String) -> Self

Create a new MCP server with the given name and version

Source

pub fn create(name: impl Into<String>, version: impl Into<String>) -> Self

Create a new MCP server with ergonomic string parameters

Source

pub fn with_config(name: String, version: String, config: ServerConfig) -> Self

Create a new MCP server with custom configuration

Source

pub fn with_plugin_manager(self, manager: PluginManager) -> Self

Attach a plugin manager to the server

Source

pub async fn sync_plugin_tools(&self) -> McpResult<()>

Internal method to sync plugin tools with server

Source

pub fn set_capabilities(&mut self, capabilities: ServerCapabilities)

Set server capabilities

Source

pub fn set_protocol_mode(&mut self, mode: ProtocolMode)

Select dual-stack, modern-only, or legacy-only server behavior.

Source

pub fn protocol_mode(&self) -> ProtocolMode

Return the configured protocol support policy.

Source

pub fn set_config(&mut self, config: ServerConfig)

Set server configuration

Source

pub fn set_request_policy(&mut self, policy: RequestPolicy)

Install authorization and rate-limiting controls for all requests.

Source

pub fn with_request_policy(self, policy: RequestPolicy) -> Self

Install authorization and rate-limiting controls using a builder style.

Source

pub fn set_initial_resources(&mut self, resources: HashMap<String, Resource>)

Set initial resources (used by ServerBuilder)

Source

pub fn set_initial_tools(&mut self, tools: HashMap<String, Tool>)

Set initial tools (used by ServerBuilder)

Source

pub fn set_initial_prompts(&mut self, prompts: HashMap<String, Prompt>)

Set initial prompts (used by ServerBuilder)

Source

pub fn set_initial_resource_templates( &mut self, templates: HashMap<String, ResourceTemplate>, )

Set initial resource templates (used by ServerBuilder)

Source

pub fn builder() -> ServerBuilder

Create a builder for constructing servers

Source

pub fn with_capabilities(self, capabilities: ServerCapabilities) -> Self

Configure this server with capabilities using a fluent API

Source

pub fn with_server_config(self, config: ServerConfig) -> Self

Configure this server with a specific configuration (fluent API)

Source

pub async fn add_tool<H>( &self, name: impl Into<String>, description: Option<impl Into<String>>, input_schema: Value, handler: H, ) -> McpResult<()>
where H: ToolHandler + 'static,

Add a tool to the server with a ToolHandler implementation

§Examples
ⓘ
// With a ToolHandler implementation
server.add_tool("my_tool", Some("description"), json!({}), MyToolHandler).await?;
Source

pub async fn add_multi_round_tool<H>( &self, name: impl Into<String>, description: Option<impl Into<String>>, input_schema: Value, handler: H, ) -> McpResult<()>
where H: MultiRoundToolHandler + 'static,

Add a tool that may return MCP 2026 input_required results.

Source

pub async fn add_multi_round_tool_detailed<H>( &self, info: ToolInfo, handler: H, ) -> McpResult<()>
where H: MultiRoundToolHandler + 'static,

Add a continuation-aware tool with a fully specified tool definition.

Source

pub async fn add_tool_with_closure<F>( &self, name: impl Into<String>, description: Option<impl Into<String>>, input_schema: Value, handler: F, ) -> McpResult<()>
where F: Fn(&HashMap<String, Value>) -> McpResult<Vec<ContentBlock>> + Send + Sync + 'static,

Add a tool using a closure

§Examples
ⓘ
server.add_tool_with_closure("echo", Some("Echo tool"), json!({}), |args| {
    Ok(vec![ContentBlock::text("Echo!")])
}).await?;
Source

pub async fn add_tool_built(&self, tool: Tool) -> McpResult<()>

Add a tool using the ToolBuilder result

Source

pub async fn add_task_tool<H>( &self, info: ToolInfo, handler: H, ) -> McpResult<()>
where H: TaskToolHandler + 'static,

Register a tool whose execution is represented by a durable SEP-2663 task.

Source

pub async fn add_task_tool_with_fallback<H, F>( &self, info: ToolInfo, handler: H, fallback: F, ) -> McpResult<()>
where H: TaskToolHandler + 'static, F: ToolHandler + 'static,

Register a durable task tool plus the synchronous behavior used when a client has not negotiated io.modelcontextprotocol/tasks.

Source

pub async fn add_composed_task_tool<P, H>( &self, info: ToolInfo, preflight: P, handler: H, ) -> McpResult<()>
where P: MultiRoundToolHandler + 'static, H: ComposedTaskToolHandler + 'static,

Register a required-task tool that gathers request-scoped input through MCP multi-round results before creating its durable task.

The preflight handler returns InputRequired for intermediate rounds and Complete when the durable phase may begin. Its completed value is only a readiness signal; the composed handler produces the task result and receives the entire final MultiRoundToolCall.

Source

pub fn info(&self) -> &ServerInfo

Get server information

Source

pub fn name(&self) -> &str

Get server name (for compatibility with tests)

Source

pub fn version(&self) -> &str

Get server version (for compatibility with tests)

Source

pub fn capabilities(&self) -> &ServerCapabilities

Get server capabilities

Source

pub fn config(&self) -> &ServerConfig

Get server configuration

Source

pub async fn add_resource<H>( &self, name: String, uri: String, handler: H, ) -> McpResult<()>
where H: ResourceHandler + 'static,

Add a resource to the server

Source

pub async fn add_resource_detailed<H>( &self, info: ResourceInfo, handler: H, ) -> McpResult<()>
where H: ResourceHandler + 'static,

Add a resource with detailed information

Source

pub async fn remove_resource(&self, uri: &str) -> McpResult<bool>

Remove a resource from the server

Source

pub async fn list_resources(&self) -> McpResult<Vec<ResourceInfo>>

List all registered resources

Source

pub async fn read_resource(&self, uri: &str) -> McpResult<Vec<ResourceContents>>

Read a resource

Source

pub async fn add_tool_detailed<H>( &self, info: ToolInfo, handler: H, ) -> McpResult<()>
where H: ToolHandler + 'static,

Add a tool with detailed information

Source

pub async fn remove_tool(&self, name: &str) -> McpResult<bool>

Remove a tool from the server

Source

pub async fn list_tools(&self) -> McpResult<Vec<ToolInfo>>

List all registered tools

Source

pub async fn call_tool( &self, name: &str, arguments: Option<HashMap<String, Value>>, ) -> McpResult<ToolResult>

Call a tool

Source

pub async fn add_prompt<H>(&self, info: PromptInfo, handler: H) -> McpResult<()>
where H: PromptHandler + 'static,

Add a prompt to the server

Source

pub async fn remove_prompt(&self, name: &str) -> McpResult<bool>

Remove a prompt from the server

Source

pub async fn list_prompts(&self) -> McpResult<Vec<PromptInfo>>

List all registered prompts

Source

pub async fn get_prompt( &self, name: &str, arguments: Option<HashMap<String, Value>>, ) -> McpResult<PromptResult>

Get a prompt

Source

pub async fn add_resource_template( &self, template: ResourceTemplate, ) -> McpResult<()>

Add a resource template to the server

Source

pub async fn list_resource_templates(&self) -> McpResult<Vec<ResourceTemplate>>

List resource templates

Source

pub async fn remove_resource_template(&self, name: &str) -> McpResult<bool>

Remove a resource template

Source

pub async fn add_completion_handler<H>( &self, ref_type: String, handler: H, ) -> McpResult<()>
where H: CompletionHandler + 'static,

Add completion handler for a specific reference type

Source

pub async fn remove_completion_handler(&self, ref_type: &str) -> McpResult<bool>

Remove completion handler for a reference type

Source

pub async fn handle_completion( &self, reference: &CompletionReference, argument: &CompletionArgument, context: Option<&CompletionContext>, ) -> McpResult<Vec<String>>

Handle completion request

Source

pub async fn send_client_request( &self, _request: JsonRpcRequest, ) -> McpResult<JsonRpcResponse>

Send a request to the client (server-initiated)

Source

pub async fn request_sampling( &self, params: CreateMessageParams, ) -> McpResult<CreateMessageResult>

Request LLM sampling from client

Source

pub async fn request_roots(&self) -> McpResult<ListRootsResult>

Request root directories from client

Source

pub async fn request_elicitation( &self, params: ElicitParams, ) -> McpResult<ElicitResult>

Request user input via elicitation

Source

pub async fn request_list_roots(&self) -> McpResult<ListRootsResult>

Request list of roots from the client

Method allows the server to request access to specific directories or files on the client’s file system.

Source

pub async fn notify_roots_list_changed(&self) -> McpResult<()>

Send a notification that the roots list has changed

This notification informs the client that the list of roots the server needs access to has changed.

Source

pub async fn notify_tools_list_changed(&self) -> McpResult<()>

Notify active MCP 2026 subscriptions that the tool catalog changed.

Source

pub async fn notify_prompts_list_changed(&self) -> McpResult<()>

Notify active MCP 2026 subscriptions that the prompt catalog changed.

Source

pub async fn notify_resources_list_changed(&self) -> McpResult<()>

Notify active MCP 2026 subscriptions that the resource catalog changed.

Source

pub async fn start<T>(&mut self, transport: T) -> McpResult<()>
where T: ServerTransport + 'static,

Start the server with the given transport

Source

pub async fn stop(&self) -> McpResult<()>

Stop the server

Source

pub async fn is_running(&self) -> bool

Check if the server is running

Source

pub async fn state(&self) -> ServerState

Get the current server state

Source

pub async fn run_with_transport<T>(self, transport: T) -> McpResult<()>
where T: ServerTransport + 'static,

Start server with custom transport and run until interrupted

This is a convenience method that:

  1. Starts the server with the provided transport
  2. Waits for Ctrl+C signal
  3. smoothly shuts down the server
§Arguments
  • transport - The transport to use for communication
§Example
ⓘ
use prism_mcp_rs::prelude::*;

#[cfg(feature = "stdio")]
use prism_mcp_rs::transport::stdio::StdioServerTransport;

#[tokio::main]
async fn main() -> McpResult<()> {
    let mut server = McpServer::new("my-server".to_string(), "1.0.0".to_string());
    // . add tools, resources, prompts ...

    #[cfg(feature = "stdio")]
    {
        let transport = StdioServerTransport::new();
        server.run_with_transport(transport).await?;
    }
     
    Ok(())
}
Source

pub async fn handle_request( &self, request: JsonRpcRequest, ) -> McpResult<JsonRpcResponse>

Handle an incoming JSON-RPC request

Source

pub async fn handle_request_with_context( &self, request: JsonRpcRequest, context: RequestContext, ) -> McpResult<JsonRpcResponse>

Handle a request with transport-supplied identity and correlation data.

Custom transports and authentication middleware should call this method after validating credentials and constructing a RequestContext.

Source

pub async fn is_initialized(&self) -> bool

Check if the server has been initialized

Source

pub async fn is_stopped(&self) -> bool

Check if the server is stopping or stopped

Source

pub async fn get_state(&self) -> ServerState

Get the current server state (alias for existing state method)

Source

pub async fn has_tools(&self) -> bool

Check if the server has any registered tools

Source

pub async fn has_resources(&self) -> bool

Check if the server has any registered resources

Source

pub async fn has_prompts(&self) -> bool

Check if the server has any registered prompts

Source

pub async fn tool_count(&self) -> usize

Get the number of registered tools

Source

pub async fn resource_count(&self) -> usize

Get the number of registered resources

Source

pub async fn prompt_count(&self) -> usize

Get the number of registered prompts

Source

pub async fn has_tool(&self, name: &str) -> bool

Check if a specific tool is registered

Source

pub async fn has_resource(&self, uri: &str) -> bool

Check if a specific resource is registered

Source

pub async fn has_prompt(&self, name: &str) -> bool

Check if a specific prompt is registered

Source

pub async fn initialize(&self) -> McpResult<()>

Initialize the server (sets state to Running)

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
§

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

§

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.

§

impl<T> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

impl<T> Instrument for T

§

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

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

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.

§

impl<T> IntoRequest<T> for T

§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in [Layered].
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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