mcp_ectors/router/
system_router.rs1use actix::ResponseFuture;
2use serde_json::Value;
3
4use crate::router::{router::CapabilitiesBuilder, router_registry::ROUTER_SEPERATOR, Router};
5use mcp_spec::{handler::ResourceError, prompt::Prompt, protocol::{CallToolResult, GetPromptResult, ReadResourceResult, ServerCapabilities}, Resource, ResourceContents::{self, TextResourceContents}, Tool, ToolError};
6
7#[derive(Clone)]
9pub struct SystemRouter{
10 resources: Vec<ResourceContents>,
11}
12
13impl SystemRouter {
14 pub fn new() -> Self {
15 let resources = vec![];
16 Self {
17 resources,
18 }
19 }
20}
21
22impl Router for SystemRouter {
23 fn name(&self) -> String {
24 "system".to_string()
25 }
26
27 fn instructions(&self) -> String {
28 format!("This is the system router who offers information about what is installed in this server. To get a list do resources/read uri: system{}all",ROUTER_SEPERATOR)
29 }
30
31 fn capabilities(&self) -> ServerCapabilities {
32 CapabilitiesBuilder::new()
33 .with_resources(true, true)
34 .build()
35 }
36
37 fn list_tools(&self) -> Vec<Tool> {
38 vec![]
39 }
40
41 fn call_tool(
42 &self,
43 tool_name: &str,
44 _arguments: Value,
45 ) -> ResponseFuture<Result<CallToolResult, ToolError>> {
46 let tool_name = tool_name.to_string();
47
48 Box::pin(async move {
49 Err(ToolError::NotFound(format!("Tool {} not found", tool_name)))
50 })
51 }
52
53 fn list_resources(&self) -> Vec<Resource> {
54 vec![Resource{
55 uri: "all".to_string(),
56 name: "all resources, prompts, tools,... registered in this mcp multi router server".to_string(),
57 description: Some("this gives a description of all the resources, prompts, tools,... which different routers offer that have been installed in this multi-router mcp server.".to_string()),
58 mime_type: "text/plain".to_string(),
59 annotations: None }]
60 }
61
62 fn read_resource(
63 &self,
64 uri: &str,
65 ) -> ResponseFuture<Result<ReadResourceResult, ResourceError>> {
66 let mut resources = self.resources.clone();
67 resources.push(TextResourceContents{
68 uri: "all".to_string(),
69 mime_type: Some("plain/text".to_string()),
70 text: "This multi-router mcp server currently has two routers installed:\n
71 counter_router: This server provides a counter tool that can increment and decrement values. The counter starts at 0 and can be modified using the 'increment' and 'decrement' tools. Use 'get_value' to check the current count.\n
72 hellow_world: This server responds with a greeting, 'Hello {name}', where 'name' is the parameter passed.
73 ".to_string()});
74 let uri_clone = uri.to_string();
75 Box::pin(async move {
76 match uri_clone.as_str() {
77 "all" => {Ok(ReadResourceResult{ contents: resources })},
78 name => Err(ResourceError::NotFound(format!("Resource {} not found", name)))
79 }
80
81 })
82 }
83
84 fn list_prompts(&self) -> Vec<Prompt> {
85 vec![]
86 }
87
88 fn get_prompt(&self, _prompt_name: &str) -> ResponseFuture<Result<GetPromptResult, ResourceError>> {
89
90 let result = GetPromptResult{ description: None, messages: vec![] };
91 Box::pin(async move {
92 Ok(result)
93 })
94 }
95}
96