11use anyhow:: Result ;
2- use mcp_core:: content:: Content ;
3- use mcp_core:: handler:: { PromptError , ResourceError } ;
4- use mcp_core:: prompt:: { Prompt , PromptArgument } ;
5- use mcp_core:: { handler:: ToolError , protocol:: ServerCapabilities , resource:: Resource , tool:: Tool } ;
6- use mcp_server:: router:: { CapabilitiesBuilder , RouterService } ;
7- use mcp_server:: { ByteTransport , Router , Server } ;
8- use serde_json:: Value ;
9- use std:: { future:: Future , pin:: Pin , sync:: Arc } ;
10- use tokio:: {
11- io:: { stdin, stdout} ,
12- sync:: Mutex ,
13- } ;
2+ use mcp_server:: router:: RouterService ;
3+ use mcp_server:: { ByteTransport , Server } ;
4+ use tokio:: io:: { stdin, stdout} ;
145use tracing_appender:: rolling:: { RollingFileAppender , Rotation } ;
156use tracing_subscriber:: { self , EnvFilter } ;
167
17- // A simple counter service that demonstrates the Router trait
18- #[ derive( Clone ) ]
19- struct CounterRouter {
20- counter : Arc < Mutex < i32 > > ,
21- }
22-
23- impl CounterRouter {
24- fn new ( ) -> Self {
25- Self {
26- counter : Arc :: new ( Mutex :: new ( 0 ) ) ,
27- }
28- }
29-
30- async fn increment ( & self ) -> Result < i32 , ToolError > {
31- let mut counter = self . counter . lock ( ) . await ;
32- * counter += 1 ;
33- Ok ( * counter)
34- }
35-
36- async fn decrement ( & self ) -> Result < i32 , ToolError > {
37- let mut counter = self . counter . lock ( ) . await ;
38- * counter -= 1 ;
39- Ok ( * counter)
40- }
41-
42- async fn get_value ( & self ) -> Result < i32 , ToolError > {
43- let counter = self . counter . lock ( ) . await ;
44- Ok ( * counter)
45- }
46-
47- fn _create_resource_text ( & self , uri : & str , name : & str ) -> Resource {
48- Resource :: new ( uri, Some ( "text/plain" . to_string ( ) ) , Some ( name. to_string ( ) ) ) . unwrap ( )
49- }
50- }
51-
52- impl Router for CounterRouter {
53- fn name ( & self ) -> String {
54- "counter" . to_string ( )
55- }
56-
57- fn instructions ( & self ) -> String {
58- "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." . to_string ( )
59- }
60-
61- fn capabilities ( & self ) -> ServerCapabilities {
62- CapabilitiesBuilder :: new ( )
63- . with_tools ( false )
64- . with_resources ( false , false )
65- . with_prompts ( false )
66- . build ( )
67- }
68-
69- fn list_tools ( & self ) -> Vec < Tool > {
70- vec ! [
71- Tool :: new(
72- "increment" . to_string( ) ,
73- "Increment the counter by 1" . to_string( ) ,
74- serde_json:: json!( {
75- "type" : "object" ,
76- "properties" : { } ,
77- "required" : [ ]
78- } ) ,
79- ) ,
80- Tool :: new(
81- "decrement" . to_string( ) ,
82- "Decrement the counter by 1" . to_string( ) ,
83- serde_json:: json!( {
84- "type" : "object" ,
85- "properties" : { } ,
86- "required" : [ ]
87- } ) ,
88- ) ,
89- Tool :: new(
90- "get_value" . to_string( ) ,
91- "Get the current counter value" . to_string( ) ,
92- serde_json:: json!( {
93- "type" : "object" ,
94- "properties" : { } ,
95- "required" : [ ]
96- } ) ,
97- ) ,
98- ]
99- }
100-
101- fn call_tool (
102- & self ,
103- tool_name : & str ,
104- _arguments : Value ,
105- ) -> Pin < Box < dyn Future < Output = Result < Vec < Content > , ToolError > > + Send + ' static > > {
106- let this = self . clone ( ) ;
107- let tool_name = tool_name. to_string ( ) ;
108-
109- Box :: pin ( async move {
110- match tool_name. as_str ( ) {
111- "increment" => {
112- let value = this. increment ( ) . await ?;
113- Ok ( vec ! [ Content :: text( value. to_string( ) ) ] )
114- }
115- "decrement" => {
116- let value = this. decrement ( ) . await ?;
117- Ok ( vec ! [ Content :: text( value. to_string( ) ) ] )
118- }
119- "get_value" => {
120- let value = this. get_value ( ) . await ?;
121- Ok ( vec ! [ Content :: text( value. to_string( ) ) ] )
122- }
123- _ => Err ( ToolError :: NotFound ( format ! ( "Tool {} not found" , tool_name) ) ) ,
124- }
125- } )
126- }
127-
128- fn list_resources ( & self ) -> Vec < Resource > {
129- vec ! [
130- self . _create_resource_text( "str:////Users/to/some/path/" , "cwd" ) ,
131- self . _create_resource_text( "memo://insights" , "memo-name" ) ,
132- ]
133- }
134-
135- fn read_resource (
136- & self ,
137- uri : & str ,
138- ) -> Pin < Box < dyn Future < Output = Result < String , ResourceError > > + Send + ' static > > {
139- let uri = uri. to_string ( ) ;
140- Box :: pin ( async move {
141- match uri. as_str ( ) {
142- "str:////Users/to/some/path/" => {
143- let cwd = "/Users/to/some/path/" ;
144- Ok ( cwd. to_string ( ) )
145- }
146- "memo://insights" => {
147- let memo =
148- "Business Intelligence Memo\n \n Analysis has revealed 5 key insights ..." ;
149- Ok ( memo. to_string ( ) )
150- }
151- _ => Err ( ResourceError :: NotFound ( format ! (
152- "Resource {} not found" ,
153- uri
154- ) ) ) ,
155- }
156- } )
157- }
158-
159- fn list_prompts ( & self ) -> Vec < Prompt > {
160- vec ! [ Prompt :: new(
161- "example_prompt" ,
162- Some ( "This is an example prompt that takes one required agrument, message" ) ,
163- Some ( vec![ PromptArgument {
164- name: "message" . to_string( ) ,
165- description: Some ( "A message to put in the prompt" . to_string( ) ) ,
166- required: Some ( true ) ,
167- } ] ) ,
168- ) ]
169- }
170-
171- fn get_prompt (
172- & self ,
173- prompt_name : & str ,
174- ) -> Pin < Box < dyn Future < Output = Result < String , PromptError > > + Send + ' static > > {
175- let prompt_name = prompt_name. to_string ( ) ;
176- Box :: pin ( async move {
177- match prompt_name. as_str ( ) {
178- "example_prompt" => {
179- let prompt = "This is an example prompt with your message here: '{message}'" ;
180- Ok ( prompt. to_string ( ) )
181- }
182- _ => Err ( PromptError :: NotFound ( format ! (
183- "Prompt {} not found" ,
184- prompt_name
185- ) ) ) ,
186- }
187- } )
188- }
189- }
8+ mod common;
1909
19110#[ tokio:: main]
19211async fn main ( ) -> Result < ( ) > {
@@ -206,7 +25,7 @@ async fn main() -> Result<()> {
20625 tracing:: info!( "Starting MCP server" ) ;
20726
20827 // Create an instance of our counter router
209- let router = RouterService ( CounterRouter :: new ( ) ) ;
28+ let router = RouterService ( common :: counter :: CounterRouter :: new ( ) ) ;
21029
21130 // Create and run the server
21231 let server = Server :: new ( router) ;
0 commit comments