use mcpkit_core::capability::{ServerCapabilities, ServerInfo};
use mcpkit_core::error::McpError;
use mcpkit_core::types::{
CancelTaskResult, CompleteRequest, CompleteResult, GetPromptResult, GetTaskResult,
ListTasksResult, Object, Prompt, Resource, ResourceContents, ResourceTemplate, TaskId, Tool,
ToolOutput,
};
use serde_json::Value;
use std::future::Future;
use crate::context::Context;
pub trait ServerHandler: Send + Sync {
fn server_info(&self) -> ServerInfo;
fn capabilities(&self) -> ServerCapabilities {
ServerCapabilities::default()
}
fn instructions(&self) -> Option<String> {
None
}
fn on_initialized(&self, _ctx: &Context<'_>) -> impl Future<Output = ()> + Send {
async {}
}
fn on_roots_list_changed(&self, _ctx: &Context<'_>) -> impl Future<Output = ()> + Send {
async {}
}
fn on_shutdown(&self) -> impl Future<Output = ()> + Send {
async {}
}
fn set_log_level(
&self,
_level: LogLevel,
_ctx: &Context<'_>,
) -> impl Future<Output = Result<(), McpError>> + Send {
async { Ok(()) }
}
}
pub trait ToolHandler: Send + Sync {
fn list_tools(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Tool>, McpError>> + Send;
fn call_tool(
&self,
name: &str,
args: Object,
ctx: &Context<'_>,
) -> impl Future<Output = Result<ToolOutput, McpError>> + Send;
fn on_tools_changed(&self) -> impl Future<Output = ()> + Send {
async {}
}
}
pub trait ResourceHandler: Send + Sync {
fn list_resources(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Resource>, McpError>> + Send;
fn list_resource_templates(
&self,
_ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<ResourceTemplate>, McpError>> + Send {
async { Ok(vec![]) }
}
fn read_resource(
&self,
uri: &str,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<ResourceContents>, McpError>> + Send;
fn subscribe(
&self,
_uri: &str,
_ctx: &Context<'_>,
) -> impl Future<Output = Result<bool, McpError>> + Send {
async { Ok(false) }
}
fn unsubscribe(
&self,
_uri: &str,
_ctx: &Context<'_>,
) -> impl Future<Output = Result<bool, McpError>> + Send {
async { Ok(false) }
}
}
pub trait PromptHandler: Send + Sync {
fn list_prompts(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Prompt>, McpError>> + Send;
fn get_prompt(
&self,
name: &str,
args: Option<serde_json::Map<String, Value>>,
ctx: &Context<'_>,
) -> impl Future<Output = Result<GetPromptResult, McpError>> + Send;
}
pub trait TaskHandler: Send + Sync {
fn list_tasks(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<ListTasksResult, McpError>> + Send;
fn get_task(
&self,
id: &TaskId,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Option<GetTaskResult>, McpError>> + Send;
fn cancel_task(
&self,
id: &TaskId,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Option<CancelTaskResult>, McpError>> + Send;
}
pub trait CompletionHandler: Send + Sync {
fn complete(
&self,
request: &CompleteRequest,
ctx: &Context<'_>,
) -> impl Future<Output = Result<CompleteResult, McpError>> + Send;
}
pub use mcpkit_core::types::LoggingLevel as LogLevel;
use std::sync::Arc;
impl<T: ServerHandler> ServerHandler for Arc<T> {
fn server_info(&self) -> ServerInfo {
(**self).server_info()
}
fn capabilities(&self) -> ServerCapabilities {
(**self).capabilities()
}
fn instructions(&self) -> Option<String> {
(**self).instructions()
}
fn on_initialized(&self, ctx: &Context<'_>) -> impl Future<Output = ()> + Send {
(**self).on_initialized(ctx)
}
fn on_roots_list_changed(&self, ctx: &Context<'_>) -> impl Future<Output = ()> + Send {
(**self).on_roots_list_changed(ctx)
}
fn on_shutdown(&self) -> impl Future<Output = ()> + Send {
(**self).on_shutdown()
}
}
impl<T: ToolHandler> ToolHandler for Arc<T> {
fn list_tools(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Tool>, McpError>> + Send {
(**self).list_tools(ctx)
}
fn call_tool(
&self,
name: &str,
args: Object,
ctx: &Context<'_>,
) -> impl Future<Output = Result<ToolOutput, McpError>> + Send {
(**self).call_tool(name, args, ctx)
}
fn on_tools_changed(&self) -> impl Future<Output = ()> + Send {
(**self).on_tools_changed()
}
}
impl<T: ResourceHandler> ResourceHandler for Arc<T> {
fn list_resources(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Resource>, McpError>> + Send {
(**self).list_resources(ctx)
}
fn list_resource_templates(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<ResourceTemplate>, McpError>> + Send {
(**self).list_resource_templates(ctx)
}
fn read_resource(
&self,
uri: &str,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<ResourceContents>, McpError>> + Send {
(**self).read_resource(uri, ctx)
}
fn subscribe(
&self,
uri: &str,
ctx: &Context<'_>,
) -> impl Future<Output = Result<bool, McpError>> + Send {
(**self).subscribe(uri, ctx)
}
fn unsubscribe(
&self,
uri: &str,
ctx: &Context<'_>,
) -> impl Future<Output = Result<bool, McpError>> + Send {
(**self).unsubscribe(uri, ctx)
}
}
impl<T: PromptHandler> PromptHandler for Arc<T> {
fn list_prompts(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Vec<Prompt>, McpError>> + Send {
(**self).list_prompts(ctx)
}
fn get_prompt(
&self,
name: &str,
args: Option<serde_json::Map<String, Value>>,
ctx: &Context<'_>,
) -> impl Future<Output = Result<GetPromptResult, McpError>> + Send {
(**self).get_prompt(name, args, ctx)
}
}
impl<T: TaskHandler> TaskHandler for Arc<T> {
fn list_tasks(
&self,
ctx: &Context<'_>,
) -> impl Future<Output = Result<ListTasksResult, McpError>> + Send {
(**self).list_tasks(ctx)
}
fn get_task(
&self,
id: &TaskId,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Option<GetTaskResult>, McpError>> + Send {
(**self).get_task(id, ctx)
}
fn cancel_task(
&self,
id: &TaskId,
ctx: &Context<'_>,
) -> impl Future<Output = Result<Option<CancelTaskResult>, McpError>> + Send {
(**self).cancel_task(id, ctx)
}
}
impl<T: CompletionHandler> CompletionHandler for Arc<T> {
fn complete(
&self,
request: &CompleteRequest,
ctx: &Context<'_>,
) -> impl Future<Output = Result<CompleteResult, McpError>> + Send {
(**self).complete(request, ctx)
}
}
#[cfg(test)]
mod tests {
use super::*;
struct TestServer;
impl ServerHandler for TestServer {
fn server_info(&self) -> ServerInfo {
ServerInfo::new("test", "1.0.0")
}
}
#[test]
fn test_server_handler() {
let server = TestServer;
let info = server.server_info();
assert_eq!(info.name, "test");
assert_eq!(info.version, "1.0.0");
}
#[test]
fn test_log_level_ordering() {
assert!(LogLevel::Debug < LogLevel::Error);
assert!(LogLevel::Info < LogLevel::Warning);
assert!(LogLevel::Emergency > LogLevel::Alert);
}
#[test]
fn test_arc_server_handler() {
let server = Arc::new(TestServer);
let info = server.server_info();
assert_eq!(info.name, "test");
assert_eq!(info.version, "1.0.0");
}
}