Description
fetch_node and explore_rpg advertise a batch mode via entity_ids (an Option<Vec<String>>), and the doc comment on entity_ids says it "overrides entity_id when provided". The handlers in crates/rpg-mcp/src/tools.rs are written for either-or semantics — they check entity_ids first and only fall back to entity_id.
But the serde deserialization rejects any call that omits entity_id, because the field is declared String (required) rather than Option<String>. So every batch-only call fails before the handler ever runs.
Reproduction
Caller payload (verbatim from a real session):
rpg.fetch_node({
"entity_ids": [
"docker/fetch-runtime-config.mjs:main",
"docker/fetch-runtime-config.mjs:fetchSsmEnv",
"docker/fetch-runtime-config.mjs:fetchSecrets"
],
"fields": "source,deps,features",
"source_max_lines": 220
})
Error: tool call error: tool call failed for `rpg/fetch_node`
Caused by:
Mcp error: -32602: failed to deserialize parameters: missing field `entity_id`
Same failure mode reproduces against explore_rpg with a batch-only payload.
Root cause
crates/rpg-mcp/src/params.rs:27-36 — FetchNodeParams.entity_id: String (required).
crates/rpg-mcp/src/params.rs:40-44 — ExploreRpgParams.entity_id: String (required).
Fallback logic in handlers that never gets a chance to run:
crates/rpg-mcp/src/tools.rs:173-177 (fetch_node)
crates/rpg-mcp/src/tools.rs:231-235 (explore_rpg)
Serde rejects the payload at the boundary, so the else { vec![params.entity_id.as_str()] } branch is the only one ever reachable — which means batch mode is unreachable for any caller that doesn't also pass a (typically dummy) entity_id.
Why it looks intermittent
It's not timing-dependent — it's call-shape-dependent:
- Calls with
entity_id (single) always work.
- Calls with
entity_ids only (batch) always fail.
- Calls with both fields work (and
entity_ids wins per the doc comment).
Suggested fix
Make entity_id an Option<String> in both FetchNodeParams and ExploreRpgParams, then have the handlers return a clear "either entity_id or entity_ids is required" error when both are None. Matches the documented semantics and is a one-line type change plus a small match update per handler.
The bug has been present since the initial commit (verified via git log -S "entity_ids: Option") — it just hadn't been hit until a caller used the pure batch form.
Priority
Medium — the tool advertises a feature (batch mode) that is unreachable in its intended form. Callers can work around by passing a throwaway entity_id alongside entity_ids, but that defeats the documented interface and the doc comment is actively misleading.
PR to follow.
Description
fetch_nodeandexplore_rpgadvertise a batch mode viaentity_ids(anOption<Vec<String>>), and the doc comment onentity_idssays it "overrides entity_id when provided". The handlers incrates/rpg-mcp/src/tools.rsare written for either-or semantics — they checkentity_idsfirst and only fall back toentity_id.But the serde deserialization rejects any call that omits
entity_id, because the field is declaredString(required) rather thanOption<String>. So every batch-only call fails before the handler ever runs.Reproduction
Caller payload (verbatim from a real session):
Same failure mode reproduces against
explore_rpgwith a batch-only payload.Root cause
crates/rpg-mcp/src/params.rs:27-36—FetchNodeParams.entity_id: String(required).crates/rpg-mcp/src/params.rs:40-44—ExploreRpgParams.entity_id: String(required).Fallback logic in handlers that never gets a chance to run:
crates/rpg-mcp/src/tools.rs:173-177(fetch_node)crates/rpg-mcp/src/tools.rs:231-235(explore_rpg)Serde rejects the payload at the boundary, so the
else { vec![params.entity_id.as_str()] }branch is the only one ever reachable — which means batch mode is unreachable for any caller that doesn't also pass a (typically dummy)entity_id.Why it looks intermittent
It's not timing-dependent — it's call-shape-dependent:
entity_id(single) always work.entity_idsonly (batch) always fail.entity_idswins per the doc comment).Suggested fix
Make
entity_idanOption<String>in bothFetchNodeParamsandExploreRpgParams, then have the handlers return a clear"either entity_id or entity_ids is required"error when both areNone. Matches the documented semantics and is a one-line type change plus a small match update per handler.The bug has been present since the initial commit (verified via
git log -S "entity_ids: Option") — it just hadn't been hit until a caller used the pure batch form.Priority
Medium — the tool advertises a feature (batch mode) that is unreachable in its intended form. Callers can work around by passing a throwaway
entity_idalongsideentity_ids, but that defeats the documented interface and the doc comment is actively misleading.PR to follow.