Skip to content

fix(mcp): Agent MCP keyless recovery prefers API key - #362

Open
Max17190 wants to merge 6 commits into
mainfrom
fix/agent-mcp-keyless-recovery-api-key
Open

fix(mcp): Agent MCP keyless recovery prefers API key#362
Max17190 wants to merge 6 commits into
mainfrom
fix/agent-mcp-keyless-recovery-api-key

Conversation

@Max17190

@Max17190 Max17190 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

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

  • Keyless quota / limit / access recovery leads with configure_api_key + signup_url
  • retry_after_seconds and retry_later use the live TTL from eligibility/429 when present (not a hardcoded 3600)
  • Account-only tools while keyless return continue_keyless plus optional API-key upgrade
  • Drop OAuth-first next_actions / client_commands from Agent MCP keyless recovery

Test plan

  • npm test -- --test-name-pattern='keyless' (66 passing)
  • Confirm quota message interpolates real retry_after_seconds when eligibility/429 returns a TTL
  • Confirm account-only tool (e.g. crawl) still offers Search/Scrape/Parse continue path

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with 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.

  • Bug Fixes
    • Start next_actions with configure_api_key (includes signup_url https://www.firecrawl.dev/app/api-keys), then connect_oauth with requires_user_consent: true.
    • Use dynamic retry_after_seconds; remove retry_later for quota/429.
    • For account-only tools while keyless, return continue_keyless plus the API key and OAuth options.
    • Update messages: “continue now on this MCP server” and an ask-before-switch note to https://mcp.firecrawl.dev/v2/mcp-oauth; tighten free-tier tool wording.

Written for commit 749ee8a. Summary will update on new commits.

Review in cubic

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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/index.ts Outdated
Comment on lines +1012 to +1013
? [{ ...CONFIGURE_API_KEY_ACTION }]
: isToolUnavailable

@cubic-dev-ai cubic-dev-ai Bot Aug 7, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Suggested change
? [{ ...CONFIGURE_API_KEY_ACTION }]
: isToolUnavailable
: isKeylessAccessUnavailable
? [
{ ...CONFIGURE_API_KEY_ACTION },
...(retryLaterAction ? [retryLaterAction] : []),
]
Fix with cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/index.ts
kind: 'continue_keyless',
tools: [...KEYLESS_TOOL_NAMES],
},
...AUTH_UPGRADE_ACTIONS,

@cubic-dev-ai cubic-dev-ai Bot Aug 8, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant