MCPcopy Create free account
hub / github.com/ScriptedAlchemy/tracedecay / handle_tools_call

Method handle_tools_call

src/mcp/server.rs:2343–2702  ·  view source on GitHub ↗

Handles the `tools/call` method, dispatching to the appropriate tool handler.

(
        &self,
        id: Value,
        params: Option<&Value>,
        timings_enabled: bool,
        route_cache: &HookProjectRouteCache,
        implicit_project_path: Option<&Path>,
    )

Source from the content-addressed store, hash-verified

2341
2342 /// Handles the `tools/call` method, dispatching to the appropriate tool handler.
2343 async fn handle_tools_call(
2344 &self,
2345 id: Value,
2346 params: Option<&Value>,
2347 timings_enabled: bool,
2348 route_cache: &HookProjectRouteCache,
2349 implicit_project_path: Option<&Path>,
2350 ) -> JsonRpcResponse {
2351 let Some(params) = params else {
2352 return JsonRpcResponse::error(
2353 id,
2354 ErrorCode::InvalidParams,
2355 "missing params for tools/call".to_string(),
2356 );
2357 };
2358
2359 let Some(tool_name) = params.get("name").and_then(|v| v.as_str()) else {
2360 return JsonRpcResponse::error(
2361 id,
2362 ErrorCode::InvalidParams,
2363 "missing 'name' in tools/call params".to_string(),
2364 );
2365 };
2366
2367 let arguments = params.get("arguments").cloned().unwrap_or(json!({}));
2368 let analytics_arguments = arguments.clone();
2369 let analytics_session_id = mcp_analytics_session_id(&arguments);
2370
2371 // Branch-drift hot-swap: if the working tree switched branches since
2372 // the served instance opened, reopen onto the live branch's DB so
2373 // this call reads the right index. Cheap no-op check when no drift.
2374 let cg = self.reopen_if_branch_drifted().await;
2375
2376 // Notification-free freshness is useful before tools that edit source
2377 // files in the index. Read-only graph queries should not block behind
2378 // a full project walk; on very large indexes (especially when
2379 // node_modules was intentionally included) that turns diagnostics and
2380 // search into sync operations.
2381 if needs_lazy_sync_before_dispatch(tool_name) {
2382 self.maybe_sync_if_stale().await;
2383 } else {
2384 // D4: sync-on-read (never blocking). Read tools serve the current
2385 // answer IMMEDIATELY and, when the read-refresh cooldown has
2386 // elapsed, kick a single-flighted background refresh so the *next*
2387 // read sees fresh data. This heals read-only sessions that never
2388 // touch an edit tool without ever making a query wait behind a
2389 // project walk.
2390 self.maybe_spawn_read_refresh(&cg);
2391 }
2392
2393 self.stats.tool_calls.fetch_add(1, Ordering::Relaxed);
2394 eprintln!("[tracedecay] tool call: {tool_name}");
2395 if let Ok(mut counts) = self.tool_call_counts.lock() {
2396 *counts.entry(tool_name.to_string()).or_insert(0) += 1;
2397 }
2398
2399 let server_stats = if tool_name == "tracedecay_status" {
2400 Some(self.server_stats_json().await)

Calls 15

errorFunction · 0.85
mcp_analytics_session_idFunction · 0.85
is_skill_view_toolFunction · 0.85
write_entryFunction · 0.85
current_timestampFunction · 0.85
mcp_tool_analytics_eventFunction · 0.85
staleness_bannerFunction · 0.85

Tested by

no test coverage detected