Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 13 additions & 16 deletions crates/mcp-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,20 @@ where
);

// Process the request using our service
let response = match service.call(request).await {
Ok(resp) => resp,
Err(e) => {
let error_msg = e.into().to_string();
tracing::error!(error = %error_msg, "Request processing failed");
JsonRpcResponse {
jsonrpc: "2.0".to_string(),
id,
result: None,
error: Some(mcp_core::protocol::ErrorData {
code: mcp_core::protocol::INTERNAL_ERROR,
message: error_msg,
data: None,
}),
}
let response = service.call(request).await.unwrap_or_else(|e| {
let error_msg = e.into().to_string();
tracing::error!(error = %error_msg, "Request processing failed");
JsonRpcResponse {
jsonrpc: "2.0".to_string(),
id,
result: None,
error: Some(mcp_core::protocol::ErrorData {
code: mcp_core::protocol::INTERNAL_ERROR,
message: error_msg,
data: None,
}),
}
};
});

// Serialize response for logging
let response_json = serde_json::to_string(&response)
Expand Down
42 changes: 1 addition & 41 deletions crates/mcp-server/src/router.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::{
future::Future,
pin::Pin,
task::{Context, Poll},
};

type PromptFuture = Pin<Box<dyn Future<Output = Result<String, PromptError>> + Send + 'static>>;
Expand All @@ -19,9 +18,8 @@ use mcp_core::{
ResourceContents,
};
use serde_json::Value;
use tower_service::Service;

use crate::{BoxError, RouterError};
use crate::RouterError;

/// Builder for configuring and constructing capabilities
pub struct CapabilitiesBuilder {
Expand Down Expand Up @@ -391,41 +389,3 @@ pub trait Router: Send + Sync + 'static {
}
}
}

pub struct RouterService<T>(pub T);

impl<T> Service<JsonRpcRequest> for RouterService<T>
where
T: Router + Clone + Send + Sync + 'static,
{
type Response = JsonRpcResponse;
type Error = BoxError;
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: JsonRpcRequest) -> Self::Future {
let this = self.0.clone();

Box::pin(async move {
let result = match req.method.as_str() {
"initialize" => this.handle_initialize(req).await,
"tools/list" => this.handle_tools_list(req).await,
"tools/call" => this.handle_tools_call(req).await,
"resources/list" => this.handle_resources_list(req).await,
"resources/read" => this.handle_resources_read(req).await,
"prompts/list" => this.handle_prompts_list(req).await,
"prompts/get" => this.handle_prompts_get(req).await,
_ => {
let mut response = this.create_response(req.id);
response.error = Some(RouterError::MethodNotFound(req.method).into());
Ok(response)
}
};

result.map_err(BoxError::from)
})
}
}
1 change: 1 addition & 0 deletions examples/servers/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
anyhow = "1.0"
tower-service = "0.3"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-appender = "0.2"
Expand Down
2 changes: 1 addition & 1 deletion examples/servers/src/axum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use tokio_util::codec::FramedRead;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

use anyhow::Result;
use mcp_server::router::RouterService;
use std::sync::Arc;
use tokio::{
io::{self, AsyncWriteExt},
Expand All @@ -22,6 +21,7 @@ use tokio::{
use tracing_subscriber::{self};
mod common;
use common::counter;
use common::counter::RouterService;

type C2SWriter = Arc<Mutex<io::WriteHalf<io::SimplexStream>>>;
type SessionId = Arc<str>;
Expand Down
46 changes: 44 additions & 2 deletions examples/servers/src/common/counter.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
use std::{future::Future, pin::Pin, sync::Arc};

use mcp_core::protocol::{JsonRpcRequest, JsonRpcResponse};
use mcp_core::{
handler::{PromptError, ResourceError},
prompt::{Prompt, PromptArgument},
protocol::ServerCapabilities,
Content, Resource, Tool, ToolError,
};
use mcp_server::router::CapabilitiesBuilder;
use mcp_server::{BoxError, Router, RouterError};
use serde_json::Value;
use std::task::{Context, Poll};
use std::{future::Future, pin::Pin, sync::Arc};
use tokio::sync::Mutex;
use tower_service::Service;


#[derive(Clone)]
pub struct CounterRouter {
Expand Down Expand Up @@ -182,3 +186,41 @@ impl mcp_server::Router for CounterRouter {
})
}
}

pub struct RouterService<T>(pub T);

impl<T> Service<JsonRpcRequest> for RouterService<T>
where
T: Router + Clone + Send + Sync + 'static,
{
type Response = JsonRpcResponse;
type Error = BoxError;
type Future = Pin<Box<dyn Future<Output =std::result::Result<Self::Response, Self::Error>> + Send>>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<std::result::Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: JsonRpcRequest) -> Self::Future {
let this = self.0.clone();

Box::pin(async move {
let result = match req.method.as_str() {
"initialize" => this.handle_initialize(req).await,
"tools/list" => this.handle_tools_list(req).await,
"tools/call" => this.handle_tools_call(req).await,
"resources/list" => this.handle_resources_list(req).await,
"resources/read" => this.handle_resources_read(req).await,
"prompts/list" => this.handle_prompts_list(req).await,
"prompts/get" => this.handle_prompts_get(req).await,
_ => {
let mut response = this.create_response(req.id);
response.error = Some(RouterError::MethodNotFound(req.method).into());
Ok(response)
}
};

result.map_err(BoxError::from)
})
}
}
2 changes: 1 addition & 1 deletion examples/servers/src/counter_server.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use anyhow::Result;
use mcp_server::router::RouterService;
use common::counter::RouterService;
use mcp_server::{ByteTransport, Server};
use tokio::io::{stdin, stdout};
use tracing_appender::rolling::{RollingFileAppender, Rotation};
Expand Down