Skip to content

Commit 5e9e49e

Browse files
refactor(daemon): name the MCP bootstrap outcome enum
1 parent 2609ff2 commit 5e9e49e

2 files changed

Lines changed: 44 additions & 27 deletions

File tree

src/daemon.rs

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,32 +2615,47 @@ fn attach_initialize_route_metadata(
26152615
result["_meta"]["tracedecayInitializeRoute"] = json!(route);
26162616
}
26172617

2618-
/// Returns `None` for project-dependent requests, `Some(None)` for handled
2619-
/// notifications, and `Some(Some(response))` for static MCP bootstrap calls.
2618+
/// A static MCP bootstrap call the daemon answers without opening a project.
2619+
enum DaemonBootstrap {
2620+
/// A notification that needs no response written back.
2621+
Handled,
2622+
/// A static response to write back to the client.
2623+
Respond(JsonRpcResponse),
2624+
}
2625+
2626+
/// Returns `None` for project-dependent requests, which the caller must route
2627+
/// to a project server instead.
26202628
fn daemon_bootstrap_response(
26212629
request: &JsonRpcRequest,
26222630
route: Option<&InitializeRouteMetadata>,
26232631
project_node_count: Option<u64>,
2624-
) -> Option<Option<JsonRpcResponse>> {
2632+
) -> Option<DaemonBootstrap> {
26252633
match classify_mcp_method(&request.method) {
2626-
McpMethod::Initialize => Some(request.id.clone().map(|id| {
2627-
let mut response = JsonRpcResponse::success(id, initialize_result(SERVER_INSTRUCTIONS));
2628-
if let Some(route) = route {
2629-
attach_initialize_route_metadata(&mut response, route);
2634+
McpMethod::Initialize => Some(match request.id.clone() {
2635+
Some(id) => {
2636+
let mut response =
2637+
JsonRpcResponse::success(id, initialize_result(SERVER_INSTRUCTIONS));
2638+
if let Some(route) = route {
2639+
attach_initialize_route_metadata(&mut response, route);
2640+
}
2641+
DaemonBootstrap::Respond(response)
26302642
}
2631-
response
2632-
})),
2633-
McpMethod::InitializedAck => Some(None),
2634-
McpMethod::ToolsList => Some(request.id.clone().map(|id| {
2635-
let tools = project_node_count.map_or_else(
2636-
|| get_tool_definitions_with_warming_budget(10),
2637-
|node_count| {
2638-
let budget = explore_call_budget(node_count);
2639-
get_tool_definitions_with_budget(node_count, budget)
2640-
},
2641-
);
2642-
JsonRpcResponse::success(id, json!({ "tools": tools }))
2643-
})),
2643+
None => DaemonBootstrap::Handled,
2644+
}),
2645+
McpMethod::InitializedAck => Some(DaemonBootstrap::Handled),
2646+
McpMethod::ToolsList => Some(match request.id.clone() {
2647+
Some(id) => {
2648+
let tools = project_node_count.map_or_else(
2649+
|| get_tool_definitions_with_warming_budget(10),
2650+
|node_count| {
2651+
let budget = explore_call_budget(node_count);
2652+
get_tool_definitions_with_budget(node_count, budget)
2653+
},
2654+
);
2655+
DaemonBootstrap::Respond(JsonRpcResponse::success(id, json!({ "tools": tools })))
2656+
}
2657+
None => DaemonBootstrap::Handled,
2658+
}),
26442659
_ => None,
26452660
}
26462661
}
@@ -2855,7 +2870,7 @@ async fn serve_broker_socket_client(
28552870
} else {
28562871
None
28572872
};
2858-
if let Some(response) =
2873+
if let Some(bootstrap) =
28592874
daemon_bootstrap_response(&request, initialize_route.as_ref(), project_node_count)
28602875
{
28612876
// Keep catalog-refresh bookkeeping consistent with the regular MCP
@@ -2874,7 +2889,7 @@ async fn serve_broker_socket_client(
28742889
engine.spawn_project_server_warmup(handshake.clone(), request);
28752890
}
28762891
drop(setup_activity);
2877-
if let Some(response) = response {
2892+
if let DaemonBootstrap::Respond(response) = bootstrap {
28782893
write_json_rpc_response(&mut transport, &response).await?;
28792894
}
28802895
return Ok(());
@@ -3033,7 +3048,7 @@ async fn serve_windows_broker_client(
30333048
} else {
30343049
None
30353050
};
3036-
if let Some(response) =
3051+
if let Some(bootstrap) =
30373052
daemon_bootstrap_response(&request, initialize_route.as_ref(), project_node_count)
30383053
{
30393054
if matches!(classify_mcp_method(&request.method), McpMethod::Initialize)
@@ -3050,7 +3065,7 @@ async fn serve_windows_broker_client(
30503065
);
30513066
}
30523067
drop(setup_activity);
3053-
if let Some(response) = response {
3068+
if let DaemonBootstrap::Respond(response) = bootstrap {
30543069
write_json_rpc_response(&mut transport, &response).await?;
30553070
}
30563071
return Ok(());

src/daemon/tests.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ fn bootstrap_tool_catalog_uses_project_node_count() {
3939
"method": "tools/list"
4040
}))
4141
.expect("tools/list request");
42-
let response = super::daemon_bootstrap_response(&request, None, Some(65_395))
43-
.expect("bootstrap response")
44-
.expect("tools/list response");
42+
let super::DaemonBootstrap::Respond(response) =
43+
super::daemon_bootstrap_response(&request, None, Some(65_395)).expect("bootstrap response")
44+
else {
45+
panic!("tools/list must produce a response");
46+
};
4547
let result = response.result.expect("tools/list result");
4648
let context_description = result["tools"]
4749
.as_array()

0 commit comments

Comments
 (0)