Commit 68805e7
fix(mcp): make invalid API key recovery reach the agent (#365)
* fix(mcp): make invalid API key recovery reach the agent
An invalid or revoked API key on /v2/mcp returned HTTP 401 at initialize and
tools/list. MCP clients treat a 401 at connect as "server unavailable" and
never surface the response body to the model, so the CREDENTIAL_INVALID
recovery payload — the whole point of #363 for this case — was unreachable in
a real agent session. The agent saw "no Firecrawl tools connected" and fell
back to generic, often outdated setup advice.
Fix: on the keyless+API-key endpoint, admit a supplied-but-invalid credential
as a session flagged credentialError instead of throwing a 401. The connection
succeeds, tools list, and every tool call returns the CREDENTIAL_INVALID
recovery payload as a 200 isError result — the same agent-legible path keyless
quota recovery already uses. No credential is forwarded and no tool executes,
so this grants zero functional access (strictly less than the previously
rejected "downgrade to keyless" option).
Scope: only profiles that accept API keys as a valid auth mode (allowKeyless).
OAuth-only surfaces such as /v2/mcp-search keep their hard 401 credential
rejection unchanged.
Verified end to end: a live claude session wired to an invalid-key server now
receives the payload and relays both recovery options to the human without
asking for a key in chat. Smoke suite updated to the 200/isError contract;
no net-new failures vs main.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* chore(mcp): bump to 3.23.8 for the invalid-key recovery fix
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): stop CREDENTIAL_INVALID payload from advertising unusable keyless tools
The credentialError guard in guardHostedTool's execute() runs before the
keyless branch, so no tool (including keyless ones) is actually callable in a
CREDENTIAL_INVALID session. recoveryPayload() was still including
available_tools: KEYLESS_TOOL_NAMES for this code, which could send the agent
into a retry loop against tools that just return the same recovery error.
Omit available_tools when code is CREDENTIAL_INVALID, matching the existing
isKeylessAccessUnavailable carve-out.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(mcp): scope CREDENTIAL_INVALID tools/list to the keyless surface; pin next_actions shape
canList previously returned true for every registered tool in a
credentialError session, so tools/list disclosed the full authenticated tool
schema (including non-keyless tools) to any request carrying an unrecognized
or invalid credential -- more schema disclosure than a real keyless session
gets. Scope it to the same keyless-tool surface a keyless session already
lists; recovery guidance still surfaces on any listed tool call since
execute() gates on credentialError before the keyless branch either way.
Also tighten the invalid-key next_actions assertion in mcp-smoke.test.mjs
from a loose non-empty-array check to pinning the human_reconnect_account /
operator_configure_api_key kinds and their consent flags, so a regression
that drops or reorders the recovery actions is caught.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent 2eb135a commit 68805e7
3 files changed
Lines changed: 77 additions & 36 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
| 3 | + | |
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
535 | 535 | | |
536 | 536 | | |
537 | 537 | | |
538 | | - | |
539 | | - | |
540 | | - | |
541 | | - | |
542 | | - | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
543 | 557 | | |
544 | 558 | | |
545 | 559 | | |
| |||
1128 | 1142 | | |
1129 | 1143 | | |
1130 | 1144 | | |
1131 | | - | |
| 1145 | + | |
| 1146 | + | |
| 1147 | + | |
| 1148 | + | |
| 1149 | + | |
| 1150 | + | |
1132 | 1151 | | |
1133 | 1152 | | |
1134 | 1153 | | |
| |||
1232 | 1251 | | |
1233 | 1252 | | |
1234 | 1253 | | |
1235 | | - | |
1236 | | - | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
1237 | 1264 | | |
1238 | 1265 | | |
1239 | 1266 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2081 | 2081 | | |
2082 | 2082 | | |
2083 | 2083 | | |
2084 | | - | |
2085 | | - | |
2086 | | - | |
2087 | | - | |
2088 | | - | |
2089 | | - | |
2090 | | - | |
2091 | | - | |
2092 | | - | |
2093 | | - | |
2094 | | - | |
2095 | | - | |
2096 | | - | |
2097 | | - | |
2098 | | - | |
2099 | | - | |
2100 | | - | |
2101 | | - | |
| 2084 | + | |
| 2085 | + | |
| 2086 | + | |
| 2087 | + | |
| 2088 | + | |
2102 | 2089 | | |
2103 | 2090 | | |
2104 | 2091 | | |
| |||
2108 | 2095 | | |
2109 | 2096 | | |
2110 | 2097 | | |
2111 | | - | |
2112 | | - | |
2113 | | - | |
| 2098 | + | |
| 2099 | + | |
| 2100 | + | |
| 2101 | + | |
| 2102 | + | |
| 2103 | + | |
2114 | 2104 | | |
2115 | 2105 | | |
2116 | 2106 | | |
| |||
2120 | 2110 | | |
2121 | 2111 | | |
2122 | 2112 | | |
2123 | | - | |
2124 | | - | |
2125 | | - | |
| 2113 | + | |
| 2114 | + | |
| 2115 | + | |
| 2116 | + | |
| 2117 | + | |
| 2118 | + | |
| 2119 | + | |
| 2120 | + | |
| 2121 | + | |
| 2122 | + | |
| 2123 | + | |
| 2124 | + | |
| 2125 | + | |
| 2126 | + | |
| 2127 | + | |
| 2128 | + | |
| 2129 | + | |
| 2130 | + | |
| 2131 | + | |
| 2132 | + | |
| 2133 | + | |
| 2134 | + | |
| 2135 | + | |
| 2136 | + | |
| 2137 | + | |
| 2138 | + | |
| 2139 | + | |
2126 | 2140 | | |
2127 | 2141 | | |
2128 | 2142 | | |
| |||
2134 | 2148 | | |
2135 | 2149 | | |
2136 | 2150 | | |
2137 | | - | |
2138 | | - | |
2139 | | - | |
| 2151 | + | |
| 2152 | + | |
| 2153 | + | |
2140 | 2154 | | |
2141 | 2155 | | |
2142 | 2156 | | |
| |||
0 commit comments