Skip to main content

agentic_memory_mcp/tools/
memory_workspace_xref.rs

1//! Tool: memory_workspace_xref — Cross-reference a topic across memory contexts.
2
3use std::sync::Arc;
4use tokio::sync::Mutex;
5
6use serde::Deserialize;
7use serde_json::{json, Value};
8
9use crate::session::SessionManager;
10use crate::types::{McpError, McpResult, ToolCallResult, ToolDefinition};
11
12#[derive(Debug, Deserialize)]
13struct XrefParams {
14    workspace_id: String,
15    item: String,
16}
17
18/// Return the tool definition for memory_workspace_xref.
19pub fn definition() -> ToolDefinition {
20    ToolDefinition {
21        name: "memory_workspace_xref".to_string(),
22        description: Some(
23            "Cross-reference a topic to find which memory contexts contain it and \
24             which don't. Quick way to identify knowledge gaps across projects."
25                .to_string(),
26        ),
27        input_schema: json!({
28            "type": "object",
29            "required": ["workspace_id", "item"],
30            "properties": {
31                "workspace_id": {
32                    "type": "string",
33                    "description": "ID of the workspace"
34                },
35                "item": {
36                    "type": "string",
37                    "description": "Topic/concept to cross-reference"
38                }
39            }
40        }),
41    }
42}
43
44/// Execute the memory_workspace_xref tool.
45pub async fn execute(
46    args: Value,
47    session: &Arc<Mutex<SessionManager>>,
48) -> McpResult<ToolCallResult> {
49    let params: XrefParams =
50        serde_json::from_value(args).map_err(|e| McpError::InvalidParams(e.to_string()))?;
51
52    let session = session.lock().await;
53    let xref = session
54        .workspace_manager()
55        .cross_reference(&params.workspace_id, &params.item)?;
56
57    Ok(ToolCallResult::json(&json!({
58        "item": xref.item,
59        "present_in": xref.present_in,
60        "absent_from": xref.absent_from,
61        "coverage": format!("{}/{}", xref.present_in.len(), xref.present_in.len() + xref.absent_from.len())
62    })))
63}