mcp_ectors/router/
system_router.rs

1use 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/// **A simple Hello World router**
8#[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