Skip to content

Commit d7e7d48

Browse files
committed
fix mcp servers
1 parent 8ad4685 commit d7e7d48

File tree

7 files changed

+392
-471
lines changed

7 files changed

+392
-471
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ venv/
1111
*.db-shm
1212
*.db-wal
1313
design_docs/Chapter*
14+
15+
# Claude
16+
.mcp.json
17+
1418
# Documentation
1519
site/
1620

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ futures = "0.3"
3232
once_cell = "1.20"
3333
reqwest = { version = "0.12", features = ["json", "stream"] }
3434
rmcp = "0.7"
35+
schemars = "1.0"
3536
serde = { version = "1.0.228", features = ["derive"] }
3637
serde_json = "1.0.137"
3738
serde_yaml = "0.9.34"

src/bin/abathur-mcp-memory.rs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use anyhow::{Context, Result};
2626
use clap::Parser;
2727
use rmcp::{
2828
handler::server::wrapper::Parameters, model::ServerInfo, tool, tool_handler, tool_router,
29-
ErrorData as McpError, ServerHandler, ServiceExt,
29+
ErrorData as McpError, Json, ServerHandler, ServiceExt,
3030
};
3131
use schemars::JsonSchema;
3232
use serde::{Deserialize, Serialize};
@@ -106,6 +106,15 @@ struct MemoryDeleteRequest {
106106
key: String,
107107
}
108108

109+
/// Search results
110+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
111+
struct MemorySearchResult {
112+
/// Number of memories found
113+
count: usize,
114+
/// List of memories
115+
memories: Vec<Memory>,
116+
}
117+
109118
/// Memory MCP Server implementation
110119
#[derive(Clone)]
111120
struct MemoryServer {
@@ -132,7 +141,7 @@ impl MemoryServer {
132141
let memory_type: MemoryType = params
133142
.memory_type
134143
.parse()
135-
.map_err(|e| McpError::invalid_params(format!("Invalid memory_type: {}", e)))?;
144+
.map_err(|e| McpError::invalid_params(format!("Invalid memory_type: {}", e), None))?;
136145

137146
let memory = Memory::new(
138147
params.namespace,
@@ -152,7 +161,7 @@ impl MemoryServer {
152161
Err(McpError::internal_error(format!(
153162
"Failed to add memory: {}",
154163
e
155-
)))
164+
), None))
156165
}
157166
}
158167
}
@@ -162,7 +171,7 @@ impl MemoryServer {
162171
async fn memory_get(
163172
&self,
164173
params: Parameters<MemoryGetRequest>,
165-
) -> Result<serde_json::Value, McpError> {
174+
) -> Result<Json<Memory>, McpError> {
166175
let params = params.0;
167176

168177
match self
@@ -172,19 +181,18 @@ impl MemoryServer {
172181
{
173182
Ok(Some(memory)) => {
174183
info!("Memory found: {}", memory.namespace_path());
175-
serde_json::to_value(&memory)
176-
.map_err(|e| McpError::internal_error(format!("Serialization error: {}", e)))
184+
Ok(Json(memory))
177185
}
178186
Ok(None) => Err(McpError::invalid_params(format!(
179187
"Memory not found: {}:{}",
180188
params.namespace, params.key
181-
))),
189+
), None)),
182190
Err(e) => {
183191
error!("Failed to get memory: {}", e);
184192
Err(McpError::internal_error(format!(
185193
"Failed to get memory: {}",
186194
e
187-
)))
195+
), None))
188196
}
189197
}
190198
}
@@ -194,7 +202,7 @@ impl MemoryServer {
194202
async fn memory_search(
195203
&self,
196204
params: Parameters<MemorySearchRequest>,
197-
) -> Result<serde_json::Value, McpError> {
205+
) -> Result<Json<MemorySearchResult>, McpError> {
198206
let params = params.0;
199207

200208
let memory_type: Option<MemoryType> = params
@@ -209,18 +217,17 @@ impl MemoryServer {
209217
{
210218
Ok(memories) => {
211219
info!("Found {} memories", memories.len());
212-
serde_json::to_value(&serde_json::json!({
213-
"count": memories.len(),
214-
"memories": memories
220+
Ok(Json(MemorySearchResult {
221+
count: memories.len(),
222+
memories,
215223
}))
216-
.map_err(|e| McpError::internal_error(format!("Serialization error: {}", e)))
217224
}
218225
Err(e) => {
219226
error!("Failed to search memories: {}", e);
220227
Err(McpError::internal_error(format!(
221228
"Failed to search memories: {}",
222229
e
223-
)))
230+
), None))
224231
}
225232
}
226233
}
@@ -255,7 +262,7 @@ impl MemoryServer {
255262
Err(McpError::internal_error(format!(
256263
"Failed to update memory: {}",
257264
e
258-
)))
265+
), None))
259266
}
260267
}
261268
}
@@ -285,7 +292,7 @@ impl MemoryServer {
285292
Err(McpError::internal_error(format!(
286293
"Failed to delete memory: {}",
287294
e
288-
)))
295+
), None))
289296
}
290297
}
291298
}
@@ -295,8 +302,18 @@ impl MemoryServer {
295302
impl ServerHandler for MemoryServer {
296303
fn get_info(&self) -> ServerInfo {
297304
ServerInfo {
298-
name: "abathur-memory".to_string(),
299-
version: "1.0.0".to_string(),
305+
protocol_version: rmcp::model::ProtocolVersion::default(),
306+
capabilities: rmcp::model::ServerCapabilities::default(),
307+
server_info: rmcp::model::Implementation {
308+
name: "abathur-memory".to_string(),
309+
title: Some("Abathur Memory Management Server".to_string()),
310+
version: "1.0.0".to_string(),
311+
icons: None,
312+
website_url: None,
313+
},
314+
instructions: Some(
315+
"Memory management server for Abathur. Use tools to add, get, search, update, and delete memory entries.".to_string()
316+
),
300317
}
301318
}
302319
}
@@ -341,12 +358,14 @@ async fn main() -> Result<()> {
341358
info!("MCP server ready, listening on stdio");
342359

343360
// Run server with stdio transport
344-
server
345-
.serve(rmcp::transport::io::stdio())
361+
let (stdin, stdout) = (tokio::io::stdin(), tokio::io::stdout());
362+
let _running = server
363+
.serve((stdin, stdout))
346364
.await
347-
.map_err(|_| anyhow::anyhow!("Server initialization failed"))?
348-
.wait()
349-
.await;
365+
.map_err(|_| anyhow::anyhow!("Server initialization failed"))?;
366+
367+
// Keep running until interrupted
368+
tokio::signal::ctrl_c().await?;
350369

351370
Ok(())
352371
}

0 commit comments

Comments
 (0)