feat(mcp-oauth): stdin paste-back fallback for headless OAuth flow#32053
Merged
Conversation
When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative.
Contributor
🔎 Lint report:
|
teknium1
added a commit
that referenced
this pull request
May 25, 2026
…MCP OAuth (#32067) Follow-up to #32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor.
daletkc
pushed a commit
to daletkc/hermes-agent
that referenced
this pull request
May 25, 2026
…ousResearch#32053) When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative.
daletkc
pushed a commit
to daletkc/hermes-agent
that referenced
this pull request
May 25, 2026
…MCP OAuth (NousResearch#32067) Follow-up to NousResearch#32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor.
1 task
mathias3
pushed a commit
to mathias3/hermes-agent
that referenced
this pull request
May 28, 2026
…ousResearch#32053) When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative.
mathias3
pushed a commit
to mathias3/hermes-agent
that referenced
this pull request
May 28, 2026
…MCP OAuth (NousResearch#32067) Follow-up to NousResearch#32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor.
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
…ousResearch#32053) When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative. #AI commit#
Bryce-huang
pushed a commit
to wbkunlun/hermes-agent
that referenced
this pull request
May 29, 2026
…MCP OAuth (NousResearch#32067) Follow-up to NousResearch#32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor. #AI commit#
mosaiq-systems
pushed a commit
to mosaiq-systems/hermes-agent
that referenced
this pull request
May 29, 2026
…ousResearch#32053) When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative.
mosaiq-systems
pushed a commit
to mosaiq-systems/hermes-agent
that referenced
this pull request
May 29, 2026
…MCP OAuth (NousResearch#32067) Follow-up to NousResearch#32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor.
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…ousResearch#32053) When the user runs OAuth on a remote/SSH machine without a port forward, the OAuth provider redirects to http://127.0.0.1:<port>/callback which only the listener on the remote machine can receive — the user's browser on another box just shows a connection error. _wait_for_callback() now races the HTTP listener against a stdin reader on interactive TTYs. The user can copy the URL from the browser's address bar after authorization (which contains code=...&state=...) and paste it back at the prompt. Whichever fills the result dict first wins; the HTTP listener remains the primary path for local sessions and SSH tunnels. Accepts any of: - Full local redirect URL: http://127.0.0.1:N/callback?code=...&state=... - Provider URL after redirect: https://mcp.linear.app/callback?code=...&state=... - Just the query string: ?code=...&state=... or code=...&state=... The paste thread only spawns when _is_interactive() is true, preserving the existing 'no input() in headless runs' invariant — verified by TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractive. The SSH-session hint in _redirect_handler is updated to surface the paste option as the primary remedy, with ssh -L tunneling as the alternative.
gweeteve
pushed a commit
to gweeteve/hermes-agent
that referenced
this pull request
Jun 2, 2026
…MCP OAuth (NousResearch#32067) Follow-up to NousResearch#32053. The OAuth-over-SSH guide and the MCP feature page previously only covered xAI and Spotify. Now that MCP servers can complete OAuth via stdin paste-back on remote/headless hosts, document it. oauth-over-ssh.md: - Add MCP servers to the 'Which Providers Need This' table. - New 'MCP Servers' section covering: paste-back (no setup, works anywhere), SSH port forward (same pattern as xAI/Spotify), and the 30s config-auto-reload race pitfall (use 'hermes mcp login <server>' from a fresh terminal instead of editing config from inside a running session). mcp.md: - New 'OAuth-authenticated HTTP servers' section under HTTP servers, covering auth: oauth config, token cache path, paste-back vs SSH tunnel for headless hosts, and the same reload-race pitfall. - Cross-links to the OAuth-over-SSH guide anchor.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MCP OAuth on a remote/SSH box without a port forward now completes via stdin paste-back — no more being stuck when the browser is on another machine.
Root cause
On a remote session the OAuth provider redirects to
http://127.0.0.1:<port>/callbackwhich only the listener on the remote machine can receive. A browser on a different host sees a connection error and has no way to deliver the code back. The only existing workaround wasssh -Ltunneling, which requires a second terminal and editing the host's SSH config.Changes
tools/mcp_oauth.py:_wait_for_callbackraces the HTTP listener against a stdin reader on interactive TTYs. Whichever fills the result dict first wins. New_paste_callback_readerparses any of: full local redirect URL, provider's own callback URL (e.g.https://mcp.linear.app/callback?code=…), or just the?code=…&state=…query string.tools/mcp_oauth.py: SSH-session hint in_redirect_handlernow leads with the paste option, withssh -Ltunneling as the alternative.tests/tools/test_mcp_oauth.py: 11 new tests covering paste parsing (3 URL shapes, error param, garbage input, EOF, stdin OSError swallowed, HTTP-wins race) and the interactive/non-interactive gating.Invariants preserved
_is_interactive()is true —TestWaitForCallbackPasteIntegration.test_paste_prompt_NOT_shown_when_noninteractivekeeps the existing "noinput()in headless runs" rule intact.Validation
ssh -Lsetup