Skip to content

fix(cli,mcp): keep live authorize alive through the OAuth flow#281

Merged
warren618 merged 1 commit into
HKUDS:mainfrom
Robin1987China:fix-live-authorize-oauth-timeout
Jun 22, 2026
Merged

fix(cli,mcp): keep live authorize alive through the OAuth flow#281
warren618 merged 1 commit into
HKUDS:mainfrom
Robin1987China:fix-live-authorize-oauth-timeout

Conversation

@Robin1987China

Copy link
Copy Markdown
Contributor

Summary

Fixes #259vibe-trading connector authorize <broker> times out before the OAuth token is persisted, so connector check still reports OAuth token: missing even though the browser sign-in succeeded.

The reporter's follow-up log (after the earlier init_timeout bump) pins down two root causes:

  1. The widened timeout was the wrong one. The FastMCP OAuth flow is driven lazily by the first request to the server — the list_tools discovery handshake — which is bounded by the per-call tool_timeout (default 30s), not the init_timeout that the authorize command already raised to 300s. A Robinhood face-scan sign-in takes longer than 30s, so list_tools times out mid-flow.

  2. The retry orphaned a successful authorization. The 30s timeout is treated as transient, so list_tools was retried. The retry opens a fresh client context that starts a second OAuth callback server on a new port, abandoning the sign-in the user had just completed on the first one. The log shows exactly this — callback on :58132, timeout + retry, then a new callback on :58173.

Changes

  • agent/cli/_legacy.pycmd_live_authorize now raises both tool_timeout and init_timeout to a configurable authorize deadline (raise-only; a larger user-configured value is preserved). The deadline is read from VIBE_LIVE_AUTHORIZE_TIMEOUT_SECONDS (default 300s) via a new _authorize_timeout_seconds() resolver.
  • agent/cli/_legacy.py — the authorize handshake runs a single, non-retried list_tools attempt (build_mcp_tool_wrappers(..., max_list_tools_attempts=1)), so a transient failure can't spawn a duplicate OAuth flow.
  • agent/src/tools/mcp.pybuild_mcp_tool_wrappers and MCPServerAdapter accept a max_list_tools_attempts (default 2); _run_with_retry takes a configurable attempts cap instead of a hard-coded 2. Runtime/registry callers are unchanged (still one transient retry).

Why this is enough

FastMCP's OAuth provider already persists the token when the browser callback returns. The fix just keeps the single handshake alive long enough for the human flow and stops a retry from starting a competing callback server — which is sufficient to land the token. (Decoupling persistence from discovery entirely would be a larger FastMCP-side change; left out of scope.)

Test Plan

  • ruff check — clean
  • pytest agent/tests/test_cli_live.py agent/tests/test_mcp_client_adapter.py — 85 passed
  • Full suite excl e2e — 4368 passed, 1 skipped, no regressions

New tests:

  • authorize widens tool_timeout to the deadline (regression for the wrong-knob bug)
  • authorize preserves an already-larger configured timeout (raise-only)
  • VIBE_LIVE_AUTHORIZE_TIMEOUT_SECONDS override honored; invalid/empty/non-positive → 300s default
  • adapter makes exactly one list_tools attempt with max_list_tools_attempts=1 (no duplicate OAuth flow); default still retries once

Closes #259

The connector authorize OAuth handshake timed out before the token was
persisted (HKUDS#259). Two root causes:

1. The OAuth flow is driven lazily by the list_tools discovery request,
   which is bounded by the per-call tool_timeout (default 30s), not
   init_timeout. The prior fix widened only init_timeout, so a Robinhood
   face-scan sign-in (>30s) still tripped the handshake.
2. The 30s timeout was retried, and the retry opened a fresh client
   context that started a SECOND OAuth callback server on a new port,
   orphaning the sign-in the user had just completed.

Fix:
- cmd_live_authorize now raises BOTH tool_timeout and init_timeout to a
  configurable authorize deadline (VIBE_LIVE_AUTHORIZE_TIMEOUT_SECONDS,
  default 300s), raise-only so a larger user value is preserved.
- The authorize handshake runs a single non-retried list_tools attempt
  via build_mcp_tool_wrappers(..., max_list_tools_attempts=1), so a
  transient failure cannot spawn a duplicate OAuth flow.
- _run_with_retry takes a configurable attempts cap; runtime/registry
  callers keep the default 2 (one transient retry) unchanged.

Closes HKUDS#259

Signed-off-by: Robin1987China <41602358+Robin1987China@users.noreply.github.com>
@warren618 warren618 merged commit a530ced into HKUDS:main Jun 22, 2026
1 check passed
warren618 added a commit that referenced this pull request Jun 22, 2026
Live-authorize OAuth fix (#281, closes #259), Alpha Zoo headline
double-count fix (#287, closes #286), and scheduled-research usage
docs (#288). Rolls the 0.1.10 (06-19) entry into the Earlier-news
fold to keep three entries visible.
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.

[Bug] Robinhood oauth timeout

2 participants