1use crate::{error::Error, peer::Peer};
7use async_trait::async_trait;
8use mcp_sdk_rs::{
9 error::Error as McpError,
10 server::{Server as McpServer, ServerHandler},
11 transport::websocket::WebSocketTransport,
12 types::*,
13};
14use serde::{Deserialize, Serialize};
15use serde_json::{json, Value};
16use std::sync::Arc;
17use tokio::net::TcpListener;
18use tokio_tungstenite::accept_async;
19
20#[derive(Default)]
22pub struct ServerBuilder {
23 peers: Vec<Peer>,
24 prompts: Vec<Prompt>,
25 resources: Vec<Resource>,
26 tools: Vec<Tool>,
27}
28
29impl ServerBuilder {
30 pub fn new() -> ServerBuilder {
32 ServerBuilder {
33 ..Default::default()
34 }
35 }
36
37 pub fn with_peers(mut self, peers: Vec<Peer>) -> ServerBuilder {
39 self.peers = peers;
40 self
41 }
42
43 pub fn with_peer(mut self, peer: Peer) -> ServerBuilder {
45 self.peers.push(peer);
46 self
47 }
48
49 pub fn with_prompt(mut self, prompt: Prompt) -> ServerBuilder {
51 self.prompts.push(prompt);
52 self
53 }
54
55 pub fn with_prompts(mut self, prompts: Vec<Prompt>) -> ServerBuilder {
57 self.prompts = prompts;
58 self
59 }
60
61 pub fn with_resource(mut self, resource: Resource) -> ServerBuilder {
63 self.resources.push(resource);
64 self
65 }
66
67 pub fn with_resources(mut self, resources: Vec<Resource>) -> ServerBuilder {
69 self.resources = resources;
70 self
71 }
72
73 pub fn with_tool(mut self, tool: Tool) -> ServerBuilder {
75 self.tools.push(tool);
76 self
77 }
78
79 pub fn with_tools(mut self, tools: Vec<Tool>) -> ServerBuilder {
81 self.tools = tools;
82 self
83 }
84
85 pub async fn build(self) -> Result<Server, Error> {
90 let mut caps = ServerCapabilities::default();
91 if !self.peers.is_empty() {
93 caps.experimental = Some(json!({"peers": {}}));
94 }
95 if !self.prompts.is_empty() {
96 caps.prompts = Some(json!({}));
97 }
98 if !self.resources.is_empty() {
99 caps.resources = Some(json!({}));
100 }
101 if !self.tools.is_empty() {
102 caps.tools = Some(json!({}));
103 }
104 Ok(Server {
105 peers: self.peers,
106 capabilities: caps,
107 prompts: self.prompts,
108 resources: self.resources,
109 tools: self.tools,
110 })
111 }
112}
113
114pub struct Server {
116 pub capabilities: ServerCapabilities,
117 pub peers: Vec<Peer>,
118 pub prompts: Vec<Prompt>,
119 pub resources: Vec<Resource>,
120 pub tools: Vec<Tool>,
121}
122
123impl Server {
124 pub async fn start(&self, addr: &str) -> Result<(), Error> {
132 let listener = TcpListener::bind(addr).await.map_err(|_| Error::Internal)?;
133 println!("WebSocket server listening on ws://{}", addr);
134
135 while let Ok((stream, addr)) = listener.accept().await {
136 println!("New connection from: {}", addr);
137 let ws_stream = accept_async(stream)
138 .await
139 .map_err(|e| {
140 println!("Error during WebSocket handshake: {}", e);
141 e
142 })
143 .unwrap();
144
145 let transport = WebSocketTransport::from_stream(ws_stream);
146 let handler = CommuneHandler {
147 peers: self.peers.clone(),
148 prompts: self.prompts.clone(),
149 tools: self.tools.clone(),
150 resources: self.resources.clone(),
151 };
152 let server = McpServer::new(Arc::new(transport), Arc::new(handler));
153
154 tokio::spawn(async move {
155 println!("Starting server for connection from {}", addr);
156 if let Err(e) = server.start().await {
157 eprintln!("Error in WebSocket connection from {}: {}", addr, e);
158 }
159 println!("Connection from {} closed", addr);
160 });
161 }
162 Ok(())
163 }
164}
165
166struct CommuneHandler {
168 peers: Vec<Peer>,
169 prompts: Vec<Prompt>,
170 tools: Vec<Tool>,
171 resources: Vec<Resource>,
172}
173
174#[async_trait]
175impl ServerHandler for CommuneHandler {
176 async fn initialize(
185 &self,
186 implementation: Implementation,
187 _capabilities: ClientCapabilities,
188 ) -> Result<ServerCapabilities, McpError> {
189 println!(
190 "Client connected: {} v{}",
191 implementation.name, implementation.version
192 );
193 Ok(ServerCapabilities::default())
194 }
195
196 async fn handle_method(&self, method: &str, _params: Option<Value>) -> Result<Value, McpError> {
205 match method {
206 "peers/list" => Ok(serde_json::to_value(ListPeersResult {
207 peers: self.peers.clone(),
208 next_cursor: None,
209 })?),
210 "prompts/list" => Ok(serde_json::to_value(ListPromptsResult {
211 prompts: self.prompts.clone(),
212 next_cursor: None,
213 })?),
214 "tools/list" => Ok(serde_json::to_value(ListToolsResult {
215 tools: self.tools.clone(),
216 next_cursor: None,
217 })?),
218 "resources/list" => Ok(serde_json::to_value(ListResourcesResult {
219 resources: self.resources.clone(),
220 next_cursor: None,
221 })?),
222 _ => Err(McpError::Other("unknown method".to_string())),
223 }
224 }
225
226 async fn shutdown(&self) -> Result<(), McpError> {
231 println!("Server shutting down");
232 Ok(())
233 }
234}
235
236#[derive(Clone, Serialize, Deserialize)]
238pub struct ListPeersRequest {
239 #[serde(skip_serializing_if = "Option::is_none")]
240 pub cursor: Option<Cursor>,
241}
242
243#[derive(Clone, Serialize, Deserialize)]
245pub struct ListPeersResult {
246 pub peers: Vec<Peer>,
247 #[serde(skip_serializing_if = "Option::is_none")]
248 pub next_cursor: Option<Cursor>,
249}