Agent skill

MCP OAuth Remote Gateway

by Luciole-Studio in Luciole-Studio/Misaka-Agent

Manual OAuth for remote MCP servers on headless gateways. An agent skill from Luciole-Studio/Misaka-Agent.

MITAuto-check: notesBackend & APIs

Install MCP OAuth Remote Gateway

skills CLI
$ npx skills add Luciole-Studio/Misaka-Agent --skill mcp-oauth-remote-gateway -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Luciole-Studio/Misaka-Agent mcp-oauth-remote-gateway --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Luciole-Studio/Misaka-Agent.git skills-src && mkdir -p .claude/skills && cp -r skills-src/misaka/core/skills/assets/optional/mcp/mcp-oauth-remote-gateway .claude/skills/mcp-oauth-remote-gateway && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
mcp-oauth-remote-gateway
GitHub stars
171
Used in
1 other repo
Token cost
~6k tokens
SKILL.md length
2,925 words
Files
3 (incl. scripts, references)
Skills in repo
77
Repo updated
First seen
Licence
MIT

At a glance

Manual OAuth for remote MCP servers on headless gateways. An agent skill from Luciole-Studio/Misaka-Agent.

  • Works in 11 steps: Confirm it's a remote gateway → Find HERMES_HOME and the config path → Discover OAuth metadata from the MCP… → …
  • Tasks that involve OAuth and OpenID Connect
  • SKILL.md covers Overview, When to Use, Why the Built-in OAuth Flow… and Cheap First Fallbacks: the…, plus 6 more sections
  • Runs Python scripts from its folder; calls curl, railway and python3; reaches github.com

What it does

MCP OAuth Remote Gateway is an agent skill from Luciole-Studio/Misaka-Agent. Manual OAuth for remote MCP servers on headless gateways.

Its SKILL.md is about 6k tokens, which your agent loads only when the skill is triggered. The skill folder holds 4 other files, including scripts and reference files (for example `references/stripe-mcp-oauth-revocation.md` and `scripts/diagnose-oauth-mcp.py`).

It sits in Backend & APIs, covering OAuth and OpenID Connect and MCP servers. It works with Model Context Protocol. The repository describes itself as: A multi-agent research system for the humanities and social sciences. The licence is MIT.

When your agent uses it

  • Tasks that involve OAuth and OpenID Connect
  • Tasks that involve MCP servers

Example prompts

  • “/mcp-oauth-remote-gateway”

Requirements

  • Python 3
  • Docker

Workflow steps

11 steps, taken from the step headings in SKILL.md.

  1. Confirm it's a remote gateway
  2. Find HERMES_HOME and the config path
  3. Discover OAuth metadata from the MCP server
  4. Dynamic Client Registration (RFC 7591)
  5. Build the authorize URL with PKCE
  6. Give the user the authorize URL
  7. Exchange the code for tokens
  8. Write tokens in Hermes' exact schema
  9. Add the server to config.yaml
  10. Smoke-test the token BEFORE asking the user to reload
  11. Tell the user to run /reload-mcp

What it can do on your machine

Read from SKILL.md and the folder at commit 3bcf7a3. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Python), which the agent can run.

    Shell commands in SKILL.md call:

    • curl
    • railway
    • python3
    • ssh

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • github.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

MCP OAuth Remote Gateway loads about 6k tokens when it runs, and up to ~6.8k if it reads all its reference files. Until then it costs about 21 tokens; SKILL.md has 2,925 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~21
When it runs · the whole SKILL.md, loaded when a task matches
~6k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~6.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:114
    g reading credentials from `$HERMES_HOME/.env`. Those

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from Luciole-Studio/Misaka-Agent at commit 3bcf7a3, republished under its MIT licence (© Luciole-Studio). 2,925 words, ~5,962 tokens.

Download SKILL.mdSave it as .claude/skills/mcp-oauth-remote-gateway/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.
name
mcp-oauth-remote-gateway
description
Manual OAuth for remote MCP servers on headless gateways.
version
1.0.0
author
Ben Barclay (benbarclay), Hermes Agent
license
MIT
platforms
linux, macos

MCP OAuth on a Remote Hermes Gateway

Overview

Hermes' built-in MCP OAuth client runs a one-shot HTTP listener on 127.0.0.1:<port> inside the Hermes process and registers that loopback address as the OAuth redirect_uri. That works perfectly for a local CLI on the user's own machine. It breaks completely when Hermes runs as a remote gateway (container, VPS, messaging bot), because the user's browser resolves 127.0.0.1 to the user's own laptop, not the remote container — so the authorization code never reaches Hermes.

This skill does the OAuth dance by hand and writes the resulting tokens into the exact files Hermes' token storage expects, so a subsequent /reload-mcp finds cached tokens and skips the browser flow entirely.

When to Use

Use this skill when all of the following are true:

  1. The user wants to add a remote HTTP MCP server that requires OAuth (not a static Bearer token).
  2. Hermes is running as a remote gateway (container, VPS, Docker, managed service) — NOT a local CLI on the user's laptop.
  3. The server supports OAuth 2.1 with PKCE and RFC 7591 Dynamic Client Registration (most modern MCP servers do — Better Stack, Linear, Cloudflare, Datadog, etc.). If it doesn't support DCR (GitHub is the notable exception), this skill does not apply — use a pre-registered OAuth App or a Personal Access Token instead.

Do NOT use this for:

  • Local CLI Hermes — just set auth: oauth in mcp_servers.<name> and /reload-mcp. The built-in flow opens a browser and captures the callback on localhost. Works perfectly.
  • Servers that accept a static Bearer token (API key) — always prefer headers.Authorization: "Bearer <token>" when the user is willing. Simpler, no refresh dance.
  • GitHub Copilot MCP (api.githubcopilot.com/mcp/) — GitHub does not expose DCR. Use a PAT or a pre-registered OAuth App (see pitfall 12).

Why the Built-in OAuth Flow Fails on a Remote Gateway

Hermes' native MCP OAuth client (tools/mcp_oauth.py):

  1. Picks a free local port P.
  2. Registers a dynamic OAuth client with the AS, sending redirect_uri = http://127.0.0.1:P/callback.
  3. Starts an HTTP server on 127.0.0.1:P inside the Hermes process.
  4. Prints the authorize URL and waits for the code at its local endpoint.

When Hermes runs remotely, the 127.0.0.1 in the redirect_uri is the remote container's loopback, not the user's. After authorizing, the user's browser 302s to http://127.0.0.1:P/callback?code=..., which resolves to the user's own laptop and fails to connect. The callback never reaches the Hermes process, the flow times out, and /reload-mcp returns "No MCP tools available" with no detail.

Symptoms to recognize: [xdg-open] <defunct> processes under the hermes user, an empty or missing tokens directory ($HERMES_HOME/mcp-tokens/), and a reload that responds without any "Added/Reconnected: X" line in change_detail.

Cheap First Fallbacks: the Built-in Flow's Own Escape Hatches

Before any manual token surgery, check whether the built-in flow's fallbacks already cover the deployment. When Hermes detects a remote session it prints two options alongside the authorize URL (tools/mcp_oauth.py):

  1. Paste-back — on an interactive TTY, a stdin reader races the HTTP listener. The user authorizes, the browser fails to connect to 127.0.0.1:<port>, and they paste the full address-bar URL (?code=...&state=...) back at the prompt. Works for SSH'd-in CLI sessions.
  2. SSH port-forward — ssh -N -L <port>:127.0.0.1:<port> <user>@<host> makes the redirect reach the remote listener normally.

Both require an interactive terminal to the Hermes host. The rest of this skill is for when there is NO interactive TTY — Hermes running purely as a messaging gateway/bot where /reload-mcp triggers the flow with nobody at a prompt.

Preferred Front Door: the Hermes Dashboard (try this BEFORE manual token surgery)

A remote Hermes gateway often also runs the dashboard web UI as a SEPARATE process (e.g. hermes dashboard --host 0.0.0.0 --port <port>; check with ps aux | grep 'hermes dashboard'). It exposes a connector/MCP console — endpoints like /api/mcp/servers, /api/mcp/status, and /connectors (all login-gated; a cookieless curl returning 401/302 confirms they exist).

Why the dashboard solves the core problem: when the user drives OAuth from the dashboard in their own browser, the redirect lands in a context the dashboard can capture — sidestepping the 127.0.0.1-callback failure that breaks the CLI/manual flow. So the correct escalation order for "add or re-auth an OAuth MCP server on a remote gateway" is:

  1. Dashboard, in the user's browser — the intended front door. Add servers, run OAuth, reload, all authenticated as the user. No copy-paste-callback dance, no hand-writing token files.
  2. Manual token surgery (the rest of this skill) — the FALLBACK for when there's no browser session to the dashboard (pure-chat/headless context).

Finding the dashboard's PUBLIC URL. The dashboard binds internally to 0.0.0.0:<port>, but the user needs the externally-reachable URL. Most deploy platforms inject it into the environment — grep for it rather than making the user hunt:

bash
env | grep -iE "HERMES_DASHBOARD_PUBLIC_URL|RAILWAY_PUBLIC_DOMAIN|RAILWAY_STATIC_URL|RAILWAY_SERVICE_.*_URL|PUBLIC_URL|BASE_URL|DOMAIN" \
  | sed -E 's/(TOKEN|SECRET|KEY|PASSWORD)=.*/\1=***REDACTED***/I'

HERMES_DASHBOARD_PUBLIC_URL is authoritative when present. On Railway also check RAILWAY_PUBLIC_DOMAIN / RAILWAY_STATIC_URL (the *.up.railway.app host) and RAILWAY_SERVICE_*_URL vars, which sometimes carry a friendlier custom domain. Hand the user the full https:// URL and point them at the Connectors/MCP section. ALWAYS pipe through the sed redaction above — these env greps sit next to *_TOKEN/*_SECRET vars.

What the dashboard does NOT fix (still host-side / shell): stdio servers that need shell auth state (a CLI login command whose credentials may not persist across restarts) and anything reading credentials from $HERMES_HOME/.env. Those are out of the dashboard's scope regardless.

The Workaround

Do the OAuth dance manually, then write the resulting tokens into the exact files Hermes' HermesTokenStorage would have written, so on /reload-mcp Hermes finds cached tokens and skips the browser flow entirely.

Run the shell commands below through the terminal tool on the gateway host and do the Python steps (PKCE generation, token exchange, file writes) via execute_code or a terminal python3 invocation — file writes must happen in the SAME code block as the token exchange (see pitfall 16).

1. Confirm it's a remote gateway
bash
env | grep -iE "HERMES|RAILWAY|CONTAINER"
echo "$DISPLAY $WAYLAND_DISPLAY $SSH_CLIENT"

No display + a remote indicator = remote gateway. tools/mcp_oauth.py::_can_open_browser() uses these same env vars, so if Hermes' own auto-detect says "headless", the built-in flow won't work.

2. Find HERMES_HOME and the config path
bash
HERMES_HOME=$(python3 -c 'from hermes_constants import get_hermes_home; print(get_hermes_home())')
echo "config: $HERMES_HOME/config.yaml"
echo "tokens: $HERMES_HOME/mcp-tokens/"
3. Discover OAuth metadata from the MCP server

MCP servers advertise their OAuth setup via RFC 9728 (OAuth 2.0 Protected Resource Metadata). The WWW-Authenticate header on a 401 tells you where to look:

bash
curl -sI https://mcp.example.com | grep -i www-authenticate
# → Bearer realm="mcp", resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"

Not every server returns WWW-Authenticate. Some return a bare {"errors":["Unauthorized"]} 401 with no auth-discovery hint. When that happens, probe well-known paths directly:

bash
for p in \
  /.well-known/oauth-protected-resource \
  /.well-known/oauth-authorization-server \
  /.well-known/openid-configuration ; do
  echo "=== $p ==="
  curl -s -A "python-httpx/0.27" "https://mcp.example.com$p" | head -c 400; echo
done

Fetch the resource metadata to get authorization_servers, then fetch the AS's /.well-known/oauth-authorization-server to get authorization_endpoint, token_endpoint, and registration_endpoint.

Pitfall: many servers sit behind Cloudflare and 403 bare urllib user agents. Always set User-Agent: python-httpx/0.27 (or similar) on requests in this flow.

4. Dynamic Client Registration (RFC 7591)

POST to the registration_endpoint with:

json
{
  "client_name": "Hermes Agent (manual OAuth)",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "<scopes_from_resource_metadata>"
}

Omit scope entirely if the AS's scopes_supported is empty — see step 5 pitfall. Use port 8765 (or any port — nothing will listen). token_endpoint_auth_method: none marks this as a public PKCE client. Save the returned client_id.

5. Build the authorize URL with PKCE

Generate:

  • code_verifier: secrets.token_urlsafe(64)[:128]
  • code_challenge: base64url(sha256(code_verifier)) (no padding)
  • state: secrets.token_urlsafe(24)

Query params: response_type=code, client_id, redirect_uri, code_challenge, code_challenge_method=S256, state, plus resource=<mcp_server_url> (RFC 8707 — many servers require this to bind the token to the specific MCP resource). Include scope=<space-separated> ONLY if the AS metadata's scopes_supported is a non-empty array AND/OR the resource metadata declares specific scopes. If scopes_supported: [], omit the scope parameter — the server grants its full default set on its own. Fabricating scope strings against an empty scopes_supported can cause invalid_scope errors on some ASes.

Stash code_verifier and state to disk (e.g. /tmp/.mcp-oauth-work/<server>.json, 0600 perms). You need them for step 7, possibly across multiple chat turns.

6. Give the user the authorize URL
Open this URL in your browser:
<authorize_url>

After approving, your browser will try to load http://127.0.0.1:8765/callback
and fail to connect — THAT'S EXPECTED. Just copy the entire URL from the
address bar (it will contain ?code=...&state=...) and paste it back here.
7. Exchange the code for tokens

When the user pastes the callback URL:

  1. Parse code and state from the query string.
  2. Verify state matches the stashed value (CSRF check — do not skip).
  3. POST application/x-www-form-urlencoded to the token_endpoint:
    • grant_type=authorization_code
    • code=<from callback>
    • redirect_uri=<same as step 4>
    • client_id=<from step 4>
    • code_verifier=<stashed>
    • resource=<mcp_server_url> (if the AS required it in step 5, include here too)
  4. Response contains access_token, refresh_token, token_type, expires_in, scope.
8. Write tokens in Hermes' exact schema

tools/mcp_oauth.py::HermesTokenStorage expects two files under $HERMES_HOME/mcp-tokens/ (create dir with 0o700, files with 0o600):

<server_name>.json — the OAuthToken pydantic model:

json
{
  "access_token": "...",
  "token_type": "Bearer",
  "expires_in": 7200,
  "refresh_token": "...",
  "scope": "read write"
}

<server_name>.client.json — the OAuthClientInformationFull model:

json
{
  "client_id": "...",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "none",
  "scope": "read write",
  "client_name": "..."
}

Write each file via json.dumps(..., indent=2). Sanitize the filename with re.sub(r'[^\w\-]', '_', server_name)[:128] — this matches _safe_filename() in Hermes' token storage.

9. Add the server to config.yaml
yaml
mcp_servers:
  <name>:
    url: "https://mcp.example.com"
    auth: oauth
    timeout: 180
    connect_timeout: 60
10. Smoke-test the token BEFORE asking the user to reload

Manually POST an MCP initialize request to confirm the token works end-to-end — this catches scope misconfigurations, wrong resource values, and CF blocks before the user is confused by another "No MCP tools available" reload:

python
body = json.dumps({
    "jsonrpc": "2.0", "id": 1, "method": "initialize",
    "params": {
        "protocolVersion": "2025-06-18",
        "capabilities": {},
        "clientInfo": {"name": "hermes-debug", "version": "1.0"},
    },
}).encode()
# POST to the MCP URL with:
#   Authorization: Bearer <access_token>
#   Accept: application/json, text/event-stream
#   Content-Type: application/json
#   MCP-Protocol-Version: 2025-06-18
#   User-Agent: python-httpx/0.27

Expect HTTP 200 with Content-Type: text/event-stream and a JSON-RPC result containing serverInfo and capabilities. Do not use urllib with its default UA — Cloudflare will 403 you even though Hermes (which uses httpx) will succeed. scripts/diagnose-oauth-mcp.py automates this smoke test.

11. Tell the user to run /reload-mcp

On reload, Hermes sees auth: oauth, calls HermesTokenStorage.get_tokens(), finds your cached tokens, skips the browser flow, and registers mcp_<name>_* tools. Refresh happens automatically before expires_in elapses.

Show full SKILL.md (1,437 more words)Show less

Pitfalls & Lessons Learned

  1. Do not assume "headless" means "OAuth impossible." The built-in flow works fine for local CLI; the issue is strictly remote deployments where the user's browser and the Hermes process are on different machines. Check the execution environment before claiming OAuth isn't an option.

  2. Read the source, not just the skill docs. tools/mcp_oauth.py and the MCP config reference in website/docs/ are the authoritative references. Grep the tree before telling the user a feature "doesn't exist."

  3. Cloudflare UA filter. Many MCP/OAuth providers front their infra with Cloudflare, which 403s python-urllib/* user agents on metadata endpoints even though those endpoints are public. Set User-Agent: python-httpx/0.27 (or any browser-like string) on every request in this flow. Hermes itself uses httpx, so this is never a problem in the real connection path.

  4. Include resource in both authorize and token requests. RFC 8707 resource indicators are not optional for most modern MCP servers — they bind the issued token to the specific MCP resource URL. Leaving it out sometimes still works but may yield a token that later fails at the MCP server with a scope/audience error.

  5. Trailing slash matters. Some servers advertise the resource as https://mcp.example.com/ with a trailing slash and reject tokens issued against the no-slash variant. Copy the resource value verbatim from the .well-known/oauth-protected-resource response.

  6. /reload-mcp is silent on failure. If the reload shows "No MCP tools available" with no change_detail line, a server is in config but failed to connect and no error bubbled up. Tail the error log, smoke-test the token directly with a manual initialize POST, and — if everything looks good — ask for a full process restart.

  7. Circuit breaker can survive /reload-mcp. tools/mcp_tool.py keeps a module-level error-count dict with a small threshold. Once tripped (e.g. after token expiry produces several consecutive failures), the tool handler can short-circuit before calling the server, so no successful call resets the counter. Symptom: reload says "Reconnected: X" but subsequent calls still fail with "server unreachable" in the same conversation. Recovery order: try /reload-mcp FIRST (cheap, no chat-process blip) — on current builds it can clear the counter; only escalate to a full gateway process restart if a live call STILL short-circuits after reload. Do not lead with "you must restart."

  8. Refresh on an expired access_token + a tripped breaker is a deadlock. The auto-refresh logic runs inside the MCP call path, which the breaker short-circuits once tripped. Manually refreshing the token on disk does not help by itself — pair a manual token refresh with a full restart, not a /reload-mcp.

  9. invalid_grant on a manual refresh means the refresh token is DEAD — re-auth is the only fix, do not loop. When the access_token has been expired long enough, the refresh_token can also be revoked/expired server-side. A grant_type=refresh_token POST then returns HTTP 400 {"error":"invalid_grant",...} (wording varies: "Grant not found", "Token expired", "refresh token is invalid"). There is NO recovery from the gateway side. Hand back to the user with two options: (a) re-run the full manual OAuth dance (steps 3–10), or (b) if the provider offers a static personal API key, switch to that — no refresh/expiry cycle, more durable for an unattended remote gateway. Detect early: before any create/update operation against an OAuth MCP, check expires_at vs time.time(); if already expired, attempt the refresh first and surface invalid_grant immediately rather than failing mid-task.

  10. A successful refresh that STILL yields a rejected token = server-side SESSION revocation; only a fresh authorization_code flow fixes it. Distinct from pitfall 9. The stored token file can look healthy (expires_at well out, refresh_token present), yet a live initialize POST returns 401 invalid_token with a JSON-RPC body like {"error":{"code":-32002,"message":"Session expired. Please re-authenticate."}}. The grant_type=refresh_token POST may succeed (HTTP 200, new access_token) — yet the brand-new token gets the SAME -32002. The provider revoked the underlying MCP session server-side; the OAuth refresh chain re-mints credentials but cannot re-establish a revoked session. Decision rule when an OAuth MCP reports "not connected": (1) smoke-test the stored access_token with a manual initialize POST; (2) if 401 invalid_token, attempt a refresh and smoke-test the NEW token; (3a) new token works → write it + restart to clear the breaker; (3b) new token STILL gets -32002/"Session expired" → stop, this is session revocation, hand the user the authorize URL for a full re-auth. scripts/diagnose-oauth-mcp.py automates steps 1–2 and prints which branch you're in. For an unattended gateway whose session keeps getting revoked, prefer a static Personal API key. See references/stripe-mcp-oauth-revocation.md for a worked example of a provider that revokes weekly.

  11. Client info file is NOT optional. Hermes needs <server>.client.json to know the client_id for refresh grants. Skipping it means the first refresh fails and the user has to re-auth — writing both files is the whole point of this skill.

  12. Never hand-type the redirect URL for the user to open. Generate the authorize URL programmatically with urllib.parse.urlencode(). Spaces in scopes and special chars in state break string-concatenated URLs.

  13. Security: the stash file contains the code_verifier. Delete /tmp/.mcp-oauth-work/<server>.json immediately after successful token exchange. There's no reason to keep a proof-of-identity secret around once it's consumed.

  14. Write what the token endpoint actually returned. The AS may grant a narrower (or wider) scope than requested. Write the scope from the token-exchange response to <server>.json, not what you asked for in step 5. When scopes_supported: [], the explicit scope list you send IS authoritative both ways: some servers grant exactly what you list (pass narrow scopes for least-privilege, or enumerate the full set if the user needs everything), and some won't echo the granted scope back at registration time — only the token-exchange response is authoritative.

  15. OAuth tokens often double as Bearer tokens against the provider's public REST API. The access_token in <server>.json is frequently not "MCP-only" — Authorization: Bearer <token> against the provider's documented REST API succeeds whenever the corresponding resource scope was granted. This is the OAuth 2.0 spec, not a provider quirk. When the MCP server is read-only but you need a write operation, check whether the OAuth token can hit the provider's REST API directly before suggesting a separate API key.

  16. Secret redaction can mask tokens in tool output. If secret redaction is enabled, tokens and long opaque strings render as *** in tool-result output, so you cannot print(response) to keep the access_token visible across turns. Combined with single-use code values from authorization_code grants: if you print the token-exchange response, you may lose the token AND consume the code, forcing a restart with a fresh authorize URL. Always write the access_token directly to its final destination file in the SAME code block that performs the token exchange. If you must print for debugging, print only len(access_token), token_type, scope, expires_in — never the secret.

  17. GitHub MCP (api.githubcopilot.com/mcp/) uses a pre-registered confidential OAuth App, not DCR + PKCE-public. Its client info ships with a real client_secret and token_endpoint_auth_method: client_secret_post. The token-exchange POST to https://github.com/login/oauth/access_token must include client_secret as a form field alongside client_id, code, code_verifier, and redirect_uri (PKCE is still honored on top of the secret). The redirect URI is fixed in the OAuth App config — you cannot change it, so the manual listener-port trick doesn't apply; the user just lets the browser fail to connect on that port and pastes the address-bar URL back.

What NOT to do

  • Don't use mcp-remote as a fallback. It runs an npx subprocess whose OAuth callback server ALSO sits on the remote container's localhost — same problem. mcp-remote only helps when the MCP client doesn't speak remote HTTP at all (Hermes does natively).
  • Don't push "paste your API token and I'll add headers" if the user explicitly asked for OAuth. Offer the static-token shortcut only after explaining why the native OAuth flow fails in remote deployments. Respect the user's choice to do the extra legwork for rotation-free, scope-limited access.
  • Don't claim Hermes doesn't support a feature without reading the source. Grep the source tree before making capability claims.

Quick Reference Files

  • scripts/diagnose-oauth-mcp.py — re-runnable, read-only-by-default diagnostic. Given a server name, it smoke-tests the stored access_token, attempts a refresh, smoke-tests the new token, and prints exactly which recovery branch you're in (TOKEN_OK = breaker/restart, REFRESH_FIXED = persist+restart, SESSION_REVOKED = full re-auth, REFRESH_DEAD = full re-auth/API key). Pass --write to persist a working refreshed token atomically. Never prints secret values. Run this FIRST when an OAuth MCP server reports "not connected" — it encodes the pitfall 7/9/10 decision tree.
  • references/stripe-mcp-oauth-revocation.md — a worked example (Stripe) of a provider that revokes its OAuth session on a recurring basis, and the durable fix: switch to a static restricted API key.
  • native-mcp — general guide to configuring MCP in Hermes. Authoritative config reference lives there.
  • mcporter — the external CLI bridge, for ad-hoc MCP calls outside of Hermes' config.

© Luciole-Studio, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 2 other files (scripts, references) in misaka/core/skills/assets/optional/mcp/mcp-oauth-remote-gateway of Luciole-Studio/Misaka-Agent.

  • SKILL.md
  • references/stripe-mcp-oauth-revocation.md
  • scripts/diagnose-oauth-mcp.py

Open the folder on GitHubat commit 3bcf7a3

Used in 1 other repository

We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in Luciole-Studio/Misaka-Agent, which our catalogue first saw on October 7, 2026.

Compare with similar skills

MCP OAuth Remote Gateway next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

MCP OAuth Remote Gateway compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
MCP OAuth Remote Gateway this skillLuciole-Studio/Misaka-Agent1711 repos~6kAutomated safety check: NotesMIT
Xquik MCPXquik-dev/x-twitter-scraper2111 repos~997Automated safety check: PassMIT
MCP Dart Streamable HTTPleehack/mcp_dart116—~2kAutomated safety check: PassMIT
Unifapiunifapi-agent/agents589—~741Automated safety check: PassMIT
E2a Setuptokencanopy/e2a193—~820Automated safety check: PassApache-2.0
Vercel Connectvercel/vercel-plugin301—~5.3kAutomated safety check: PassCustom licence

Similar skills

  • Xquik MCP

    Xquik-dev/x-twitter-scraper

    Connect, verify, and troubleshoot Xquik's remote MCP server.

    211 GitHub starsUsed in 1 repo~997 tokens
    Backend & APIsAuto-check passed
  • MCP Dart Streamable HTTP

    leehack/mcp_dart

    A skill your agent uses when serving an MCP server over HTTP with mcpdart or connecting to a remote one: StreamableMcpServer setup, Host and Origin allowlists (DNS rebinding protection), CORS for…

    116 GitHub stars~2k tokensUpdated 5 days ago
    Backend & APIsAuto-check passed
  • Unifapi

    unifapi-agent/agents

    A skill your agent uses when working with UnifAPI public-data APIs or the UnifAPI MCP server: connecting OAuth MCP clients, discovering operations, calling social/search/scrape/news APIs…

    589 GitHub stars~741 tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • E2a Setup

    tokencanopy/e2a

    A skill your agent uses when a user wants to connect or authorize the e2a MCP server, select or create an agent inbox, verify first-run readiness, or set up a custom email domain.

    193 GitHub stars~820 tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Vercel Connect

    vercel/vercel-plugin

    Official

    Vercel Connect expert guidance for securely obtaining scoped credentials for third-party services on behalf of apps or users.

    301 GitHub stars~5.3k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Robinhood MCP

    aeonfun/aeon

    Read your Robinhood Agentic brokerage account via the Robinhood Trading MCP - portfolio, buying power, positions, and order history - and place a single operator-instructed trade.

    770 GitHub stars~1.3k tokensUpdated yesterday
    Backend & APIsAuto-check passed

More from Luciole-Studio/Misaka-Agent

All 77 skills in this repo
  • Kanban Video Orchestrator

    Luciole-Studio/Misaka-Agent

    Plan and run multi-agent video production pipelines. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 2 repos~2.4k tokens
    Auto-check: notes
  • Ast Grep

    Luciole-Studio/Misaka-Agent

    AST-aware structural code search and rewrite via ast-grep. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 1 repo~3.2k tokens
    Auto-check passed
  • Drug Discovery

    Luciole-Studio/Misaka-Agent

    Drug discovery: ChEMBL search, drug-likeness, interactions. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed
  • Fitness Nutrition

    Luciole-Studio/Misaka-Agent

    Workout planning, macros, and body metrics via wger/USDA. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 1 repo~2.4k tokens
    Auto-check passed
  • Hyperframes

    Luciole-Studio/Misaka-Agent

    Render MP4/WebM videos from HTML compositions. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 1 repo~3.9k tokens
    Auto-check passed
  • Osint Investigation

    Luciole-Studio/Misaka-Agent

    Follow the money via public records and sanctions data. An agent skill from Luciole-Studio/Misaka-Agent.

    171 GitHub starsUsed in 1 repo~2.9k tokens
    Auto-check passed

Questions about MCP OAuth Remote Gateway

What does MCP OAuth Remote Gateway do?

Manual OAuth for remote MCP servers on headless gateways. An agent skill from Luciole-Studio/Misaka-Agent. MCP OAuth Remote Gateway is an agent skill from Luciole-Studio/Misaka-Agent. Manual OAuth for remote MCP servers on headless gateways.

When should I use MCP OAuth Remote Gateway?

MCP OAuth Remote Gateway fits situations like: tasks that involve OAuth and OpenID Connect; tasks that involve MCP servers.

How do I install MCP OAuth Remote Gateway in Claude Code?

Run `npx skills add Luciole-Studio/Misaka-Agent --skill mcp-oauth-remote-gateway -a claude-code`. Or copy the skill folder (misaka/core/skills/assets/optional/mcp/mcp-oauth-remote-gateway in Luciole-Studio/Misaka-Agent) into .claude/skills/mcp-oauth-remote-gateway in your project. Claude Code loads it when a task matches its description.

How do I install MCP OAuth Remote Gateway in Codex?

Run `npx skills add Luciole-Studio/Misaka-Agent --skill mcp-oauth-remote-gateway -a codex`. Or copy the skill folder (misaka/core/skills/assets/optional/mcp/mcp-oauth-remote-gateway in Luciole-Studio/Misaka-Agent) into .agents/skills/mcp-oauth-remote-gateway in your project. Codex loads it when a task matches its description.

Can I use MCP OAuth Remote Gateway in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Luciole-Studio/Misaka-Agent --skill mcp-oauth-remote-gateway -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/mcp-oauth-remote-gateway, .gemini/skills/mcp-oauth-remote-gateway, .github/skills/mcp-oauth-remote-gateway and .opencode/skills/mcp-oauth-remote-gateway in your project.

What does MCP OAuth Remote Gateway need to run?

Going by SKILL.md and its folder, MCP OAuth Remote Gateway needs Python for the scripts in its folder and the command-line tools its instructions call (curl, railway, python3 and ssh). Our summary lists: Python 3; Docker.

Does MCP OAuth Remote Gateway access the network?

SKILL.md names 1 domain. In commands or code: github.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.

Is MCP OAuth Remote Gateway safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does MCP OAuth Remote Gateway use?

MCP OAuth Remote Gateway is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does MCP OAuth Remote Gateway use?

About 6k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 826 tokens, read only when the agent opens those files.

What are the alternatives to MCP OAuth Remote Gateway?

Skills that share tags, products or a category with MCP OAuth Remote Gateway: Xquik MCP (Xquik-dev/x-twitter-scraper, 211 stars), MCP Dart Streamable HTTP (leehack/mcp_dart, 116 stars), Unifapi (unifapi-agent/agents, 589 stars) and E2a Setup (tokencanopy/e2a, 193 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains MCP OAuth Remote Gateway?

Luciole-Studio (a GitHub organization) maintains it in Luciole-Studio/Misaka-Agent, which has 171 GitHub stars. The repository holds 77 skills in this directory. The repository was last updated on October 8, 2026.

Source: Luciole-Studio/Misaka-Agent on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.