Headless OAuth
/install headless-oauth
Headless OAuth
Authorize CLI tools that require OAuth on a headless server — no browser needed on the server side.
⚠️ Agent Context: You Are on a Remote Server
You (the agent) are running on a remote VPS. The user is on a separate local machine with a browser.
This means:
- You cannot open a browser yourself
- The server's
localhostis NOT accessible from the user's browser - The user must open all auth URLs on their own machine
- When a redirect goes to a local address like
http://127.0.0.1:PORT/callback?code=..., it will fail to load in the user's browser — that is expected and normal - The user should copy the full URL from the address bar (even if the page shows an error) and send it to you
- You then forward that URL to the waiting server process via
curl
Always make this explicit when asking the user to authorize. Example:
"Open this URL in your browser, log in, and approve. The page will likely fail to load — that's fine. Copy the full URL from the address bar and send it to me."
The Pattern
Split the browser flow across two machines:
SERVER LOCAL MACHINE
------ -------------
1. Generate auth URL → 2. Open URL in browser
3. Log in + grant permissions
4. Copy redirect URL or code
5. Exchange for token ←
6. Store token locally
Most OAuth CLIs support this via flags like:
--no-launch-browser— gh (GitHub CLI), gcloud--remote --step 1/2— gog (Google Workspace CLI)--manual— some generic CLIs- Device flow (code + URL, no redirect) — gh, some others
Keyring on Headless Servers
Many CLIs store tokens in a system keyring that requires an interactive terminal session to unlock. Check the CLI's documentation for a flag or environment variable that sets the keyring password non-interactively. Set it only for the duration of the auth step — do not persist it in shell configs or agent-global environment. Prefer injecting it from a secrets manager or an ephemeral shell session.
Google Workspace — gog CLI
gog supports headless auth via --remote --step 1/2. See the official gog docs for setup details.
Important: Use Desktop app OAuth client type in Google Cloud Console — not Web application. gog uses a random port for the callback, which Web clients reject with
redirect_uri_mismatch.
GitHub CLI — gh
gh auth login --hostname github.com --git-protocol https --no-launch-browser
# → prints a one-time code and a URL
# Open https://github.com/login/device locally, enter the code
# gh polls and completes automatically once you approve
gcloud (Google Cloud CLI)
gcloud auth login --no-launch-browser
# → prints a URL
# Open in local browser, log in, copy the verification code shown, paste back
Generic Device Flow
If a CLI supports device flow (prints a short code + URL):
- Note the code and URL printed by the CLI
- Open the URL on any device
- Enter the code
- CLI polls and completes automatically — no redirect URL to copy
Manual Callback Relay (mcporter, custom OAuth servers)
Some tools (e.g. mcporter) start a local HTTP server on the server to catch the OAuth callback,
but the user's browser can't reach that address on the remote server.
How to handle it:
- Start the auth command with a longer timeout so it doesn't expire while waiting for the user. Check the tool's docs for a timeout flag or environment variable.
- The tool usually prints a message like:
Send that URL to the user.If the browser did not open, visit https://... manually. - Tell the user:
"Open this URL, log in and approve. The page will fail to load — that's normal. Copy the full URL from the address bar and send it to me."
- The user sends back something like:
http://127.0.0.1:PORT/callback?code=...&state=... - Forward it to the waiting server with curl:
curl -s "http://127.0.0.1:PORT/callback?code=...&state=..." - The tool receives the code, exchanges it for a token, and completes authorization.
Troubleshooting
| Error | Fix |
|---|---|
redirect_uri_mismatch |
Use Desktop app OAuth client, not Web application |
| No TTY / keyring unlock fails | Check the CLI's docs for a non-interactive keyring option |
Access blocked (testing mode) |
Add your email as test user in Google consent screen settings |
| Commands fail silently | Check if the CLI requires an account env var to be set |
| Token expired | Re-run auth steps; most CLIs handle refresh automatically |
Applying This Pattern to Any CLI
- Check
--helpfor flags like--no-launch-browser,--remote,--manual, or--headless - Check docs for "device flow" or "offline access"
- If the tool starts a local callback server but has no headless flag — use the Manual Callback Relay pattern above
- If none of the above work: use
ssh -Lport forwarding to tunnel the callback to your local machine
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install headless-oauth - After installation, invoke the skill by name or use
/headless-oauth - Provide required inputs per the skill's parameter spec and get structured output
What is Headless OAuth?
Authorize any OAuth CLI on a headless server where the agent and the user are on separate machines. Use when a CLI tool requires OAuth login on a VPS or serv... It is an AI Agent Skill for Claude Code / OpenClaw, with 130 downloads so far.
How do I install Headless OAuth?
Run "/install headless-oauth" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Headless OAuth free?
Yes, Headless OAuth is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Headless OAuth support?
Headless OAuth is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Headless OAuth?
It is built and maintained by Igor Ivanter (@igorivanter); the current version is v1.3.1.