CheckPriceResult in frontend/src/lib/mcp.ts:911-920 declares three fields that
the check_price tool has never returned, so all three are permanently undefined.
// frontend/src/lib/mcp.ts:911-920
export interface CheckPriceResult {
success: boolean;
tool_id?: string;
tool_name?: string;
base_cost?: number; // <- never returned
effective_cost?: number; // <- never returned
cost?: number; // alternate field name some wheel versions return <- never returned
error?: string;
error_code?: string;
}
The UI is NOT broken — but only because both consumers work around the type
Unlike the sibling frontends, optionality genuinely consumes checkPrice(), and
both call sites already fall through to the real field names via as unknown casts:
frontend/src/components/Optionality.tsx:1990-1994 — deal price on the setup screen:
const eff = r.effective_cost ?? r.cost
?? ((r as unknown as { effective_cost_api_sats?: number }).effective_cost_api_sats)
?? ((r as unknown as { base_cost_api_sats?: number }).base_cost_api_sats);
frontend/src/components/Welcome.tsx:36-50 — readCost() walks the same four
candidates in the same order.
In both, the first two candidates are statically dead and the third is what
actually supplies the number. Prices render correctly today. Hence sev/low,
not sev/medium — this is a correctness/clarity defect, not a user-visible outage.
Why it is still worth fixing
The workaround is load-bearing and invisible. The declared type says the typed
fields work and the cast fields are the fallback; the truth is the exact opposite.
The comment on cost — "alternate field name some wheel versions return" — is
also inaccurate: no wheel version has ever returned it.
Fixing the interface lets both call sites drop the as unknown casts entirely and
read r.effective_cost_api_sats ?? r.base_cost_api_sats against a type that is
actually true.
Evidence (live, wheel 0.89.0)
check_price against https://goodearth-mcp.fastmcp.app/mcp returns:
{"success":true,"tool_id":"...","tool_name":"...","constraints_enabled":false,
"constraint_effects":[],"pricing_type":"flat",
"base_cost_api_sats":0,"effective_cost_api_sats":0}
The wheel's authoritative source is tollbooth-dpyc/src/tollbooth/tools/pricing.py
(build_pricing_preview), which sets only base_cost_api_sats / effective_cost_api_sats.
This was never right
The unsuffixed spellings are not a rename — they never existed. Verified with a
pickaxe over the SDK's entire history:
git log --all -S '"effective_cost"' -- '*.py' -> no commits
git log --all -S '"base_cost"' -- '*.py' -> no commits
*_api_sats has been the shape since 0.1.126 (2026-03-27, commit ca3a22f).
So this type has been fiction since the day it was written, in every copy.
Fix
Rename the three fields to the wheel's actual names (and drop cost, which the
SDK has never returned):
base_cost_api_sats?: number;
effective_cost_api_sats?: number;
goodearth-mcp/frontend/src/lib/mcp.ts already carries the corrected interface,
plus pricing_type / constraints_enabled / constraint_effects, if you want a
reference shape.
Related
The same stale interface is present in every frontend that copied this file
(excalibur-mcp, cypher-mcp, roastify-mcp, optionality-mcp). The structural cause —
five hand-copied forks of the identity/MCP-client stack — is filed separately in
lonniev/dpyc-community.
Filed by Scout after verifying the field names against the live service and the
SDK source. No source files were modified.
CheckPriceResultinfrontend/src/lib/mcp.ts:911-920declares three fields thatthe
check_pricetool has never returned, so all three are permanentlyundefined.The UI is NOT broken — but only because both consumers work around the type
Unlike the sibling frontends, optionality genuinely consumes
checkPrice(), andboth call sites already fall through to the real field names via
as unknowncasts:frontend/src/components/Optionality.tsx:1990-1994— deal price on the setup screen:frontend/src/components/Welcome.tsx:36-50—readCost()walks the same fourcandidates in the same order.
In both, the first two candidates are statically dead and the third is what
actually supplies the number. Prices render correctly today. Hence
sev/low,not
sev/medium— this is a correctness/clarity defect, not a user-visible outage.Why it is still worth fixing
The workaround is load-bearing and invisible. The declared type says the typed
fields work and the cast fields are the fallback; the truth is the exact opposite.
The comment on
cost— "alternate field name some wheel versions return" — isalso inaccurate: no wheel version has ever returned it.
Fixing the interface lets both call sites drop the
as unknowncasts entirely andread
r.effective_cost_api_sats ?? r.base_cost_api_satsagainst a type that isactually true.
Evidence (live, wheel 0.89.0)
check_priceagainsthttps://goodearth-mcp.fastmcp.app/mcpreturns:{"success":true,"tool_id":"...","tool_name":"...","constraints_enabled":false, "constraint_effects":[],"pricing_type":"flat", "base_cost_api_sats":0,"effective_cost_api_sats":0}The wheel's authoritative source is
tollbooth-dpyc/src/tollbooth/tools/pricing.py(
build_pricing_preview), which sets onlybase_cost_api_sats/effective_cost_api_sats.This was never right
The unsuffixed spellings are not a rename — they never existed. Verified with a
pickaxe over the SDK's entire history:
*_api_satshas been the shape since0.1.126(2026-03-27, commitca3a22f).So this type has been fiction since the day it was written, in every copy.
Fix
Rename the three fields to the wheel's actual names (and drop
cost, which theSDK has never returned):
goodearth-mcp/frontend/src/lib/mcp.tsalready carries the corrected interface,plus
pricing_type/constraints_enabled/constraint_effects, if you want areference shape.
Related
The same stale interface is present in every frontend that copied this file
(excalibur-mcp, cypher-mcp, roastify-mcp, optionality-mcp). The structural cause —
five hand-copied forks of the identity/MCP-client stack — is filed separately in
lonniev/dpyc-community.Filed by Scout after verifying the field names against the live service and the
SDK source. No source files were modified.