fix(mcp): Agent MCP keyless recovery prefers API key - #362
Conversation
Quota and gated-tool errors on /v2/mcp now lead with configure_api_key and use the live retry TTL when the API supplies one, instead of pushing OAuth retarget.
Credential failures are not keyless quota — either Human MCP reconnect or a new API key is a valid recovery.
Steer credential errors to API key only for now; OAuth reconnect can return later as a mode-aware secondary.
Prefer natural phrasing: continue now on this MCP server.
There was a problem hiding this comment.
1 issue found and verified against the latest diff
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/index.ts">
<violation number="1" location="src/index.ts:1012">
P3: When the eligibility/429 response supplies a retry TTL for a non-quota denial (KEYLESS_ACCESS_NOT_AVAILABLE), the payload still emits the top-level `retry_after_seconds`, but the new `next_actions` only attaches a `retry_later` action in the quota-exhausted branch. As a result the user sees a retry window with no corresponding `retry_later` action and the access-unavailable message doesn't mention the TTL. Consider attaching `retryLaterAction` to the keyless-access-unavailable branch as well (or dropping `retry_after_seconds` when no `retry_later` is offered) so the recovery surface is consistent across codes.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
| ? [{ ...CONFIGURE_API_KEY_ACTION }] | ||
| : isToolUnavailable |
There was a problem hiding this comment.
P3: When the eligibility/429 response supplies a retry TTL for a non-quota denial (KEYLESS_ACCESS_NOT_AVAILABLE), the payload still emits the top-level retry_after_seconds, but the new next_actions only attaches a retry_later action in the quota-exhausted branch. As a result the user sees a retry window with no corresponding retry_later action and the access-unavailable message doesn't mention the TTL. Consider attaching retryLaterAction to the keyless-access-unavailable branch as well (or dropping retry_after_seconds when no retry_later is offered) so the recovery surface is consistent across codes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/index.ts, line 1012:
<comment>When the eligibility/429 response supplies a retry TTL for a non-quota denial (KEYLESS_ACCESS_NOT_AVAILABLE), the payload still emits the top-level `retry_after_seconds`, but the new `next_actions` only attaches a `retry_later` action in the quota-exhausted branch. As a result the user sees a retry window with no corresponding `retry_later` action and the access-unavailable message doesn't mention the TTL. Consider attaching `retryLaterAction` to the keyless-access-unavailable branch as well (or dropping `retry_after_seconds` when no `retry_later` is offered) so the recovery surface is consistent across codes.</comment>
<file context>
@@ -966,41 +976,49 @@ function recoveryPayload(
+ ...(retryLaterAction ? [retryLaterAction] : []),
+ ]
+ : isKeylessAccessUnavailable
+ ? [{ ...CONFIGURE_API_KEY_ACTION }]
+ : isToolUnavailable
+ ? [
</file context>
| ? [{ ...CONFIGURE_API_KEY_ACTION }] | |
| : isToolUnavailable | |
| : isKeylessAccessUnavailable | |
| ? [ | |
| { ...CONFIGURE_API_KEY_ACTION }, | |
| ...(retryLaterAction ? [retryLaterAction] : []), | |
| ] |
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
Keep wait guidance in retry_after_seconds and the message; next_actions stay API-key-only for now.
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
API key stays first; connect_oauth with requires_user_consent is second. Messages add one ask-before-switch line.
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/index.ts">
<violation number="1" location="src/index.ts:1024">
P2: Account-only recovery now offers `connect_oauth`, but its message still presents an API key as the only way to unlock the tool. Updating this branch’s copy to mention the consented OAuth alternative and its endpoint would keep the textual guidance aligned with `next_actions`.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
| kind: 'continue_keyless', | ||
| tools: [...KEYLESS_TOOL_NAMES], | ||
| }, | ||
| ...AUTH_UPGRADE_ACTIONS, |
There was a problem hiding this comment.
P2: Account-only recovery now offers connect_oauth, but its message still presents an API key as the only way to unlock the tool. Updating this branch’s copy to mention the consented OAuth alternative and its endpoint would keep the textual guidance aligned with next_actions.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/index.ts, line 1024:
<comment>Account-only recovery now offers `connect_oauth`, but its message still presents an API key as the only way to unlock the tool. Updating this branch’s copy to mention the consented OAuth alternative and its endpoint would keep the textual guidance aligned with `next_actions`.</comment>
<file context>
@@ -1001,18 +1012,18 @@ function recoveryPayload(
tools: [...KEYLESS_TOOL_NAMES],
},
- { ...CONFIGURE_API_KEY_ACTION },
+ ...AUTH_UPGRADE_ACTIONS,
]
- : [{ ...CONFIGURE_API_KEY_ACTION }],
</file context>
Why
Agent MCP (
/v2/mcp) same-URL upgrade is an API key. Soft-limit recovery was leading with OAuth /claude mcp add …/mcp-oauth, which is unreliable mid-session and fights the Agent vs Human MCP split.Summary
configure_api_key+signup_urlretry_after_secondsandretry_lateruse the live TTL from eligibility/429 when present (not a hardcoded 3600)continue_keylessplus optional API-key upgradenext_actions/ client_commands from Agent MCP keyless recoveryTest plan
npm test -- --test-name-pattern='keyless'(66 passing)retry_after_secondswhen eligibility/429 returns a TTLNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Agent MCP keyless recovery now leads with API key setup and adds a consented OAuth option as a secondary path. Responses use live TTLs and clearer copy.
next_actionswithconfigure_api_key(includessignup_urlhttps://www.firecrawl.dev/app/api-keys), thenconnect_oauthwithrequires_user_consent: true.retry_after_seconds; removeretry_laterfor quota/429.continue_keylessplus the API key and OAuth options.https://mcp.firecrawl.dev/v2/mcp-oauth; tighten free-tier tool wording.Written for commit 749ee8a. Summary will update on new commits.