locus_mcp/tools/
get_graph.rs1use locus_sdk::application::memory_graph::MemoryGraphService;
2use locus_sdk::domain::graph::MemoryGraphRequest;
3use locus_sdk::domain::memory::{MemoryFilter, MemoryScope};
4use serde_json::json;
5use tracing::error;
6
7use crate::{GetGraphRequest, SttpMcpServer, to_json_string, tool_error, validate_limit};
8
9pub(crate) async fn execute(server: &SttpMcpServer, request: GetGraphRequest) -> String {
10 let limit = match validate_limit(request.limit, "limit") {
11 Ok(value) => value,
12 Err(message) => return tool_error("InvalidArgument", &message),
13 };
14
15 let graph_service = MemoryGraphService::new(server.node_store.clone())
16 .with_semantic_index(server.semantic_index.clone());
17
18 let graph_result = match graph_service
19 .execute(&MemoryGraphRequest {
20 scope: MemoryScope {
21 tenant_id: None,
22 session_ids: request.session_id.map(|session| vec![session]),
23 tiers: None,
24 from_utc: None,
25 to_utc: None,
26 },
27 filter: MemoryFilter {
28 indexed_tags: request.semantic_tags,
29 link_rel: request.link_rel,
30 link_target: request.link_target,
31 links_to_ref: request.links_to_ref,
32 tag_prefix: request.tag_prefix,
33 has_semantic_links: request.has_semantic_links,
34 ..Default::default()
35 },
36 include_lineage: request.include_lineage.unwrap_or(true),
37 include_semantic: request.include_semantic.unwrap_or(true),
38 include_session_topology: request.include_session_topology.unwrap_or(true),
39 rel: request.rel,
40 target_prefix: request.target_prefix,
41 limit,
42 })
43 .await
44 {
45 Ok(result) => result,
46 Err(err) => {
47 error!(error = %err, "get_graph failed");
48 return tool_error("GetGraphFailure", &err.to_string());
49 }
50 };
51
52 to_json_string(json!({
53 "retrieved": graph_result.retrieved,
54 "sessions": graph_result.sessions,
55 "nodes": graph_result.nodes,
56 "edges": graph_result.edges,
57 }))
58}