mcp-oauth-remote-gateway – skill Agent & Tự động hóa cho agent AI
OAuth thủ công cho MCP server từ xa trên gateway không có giao diện (headless).
Cài skill mcp-oauth-remote-gateway bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/mcp-oauth-remote-gateway-875e7.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /mcp-oauth-remote-gateway – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/mcp-oauth-remote-gateway-875e7.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $mcp-oauth-remote-gateway – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/mcp-oauth-remote-gateway-875e7.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /mcp-oauth-remote-gateway – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/mcp-oauth-remote-gateway-875e7.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /mcp-oauth-remote-gateway – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
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: oauthinmcp_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:
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
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
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:
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:
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
doneFetch 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:
{
"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
… (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- mcporter – Liệt kê, xác thực và gọi MCP server/công cụ từ terminal.
- bash-scripting – Quy trình viết Bash script để tạo shell script sẵn sàng production, với các mẫu phòng…
- eval – Đánh giá và xếp hạng kết quả của agent theo chỉ số hoặc LLM judge cho một phiên…
- execute – /c-level-agents:execute [decision] — Tạo kế hoạch thực thi 90 ngày với các mốc hằng…
- bdi-mental-states – Dùng khi người dùng yêu cầu “mô hình hóa trạng thái tinh thần của agent”, “triển khai…
- extract – Biến một mẫu hoặc giải pháp gỡ lỗi đã được kiểm chứng thành một skill độc lập tái sử…
- bifrost-gateway – Chạy và cấu hình Bifrost, AI gateway mã nguồn mở: một API tương thích OpenAI cho hơn 20…
- bilig-workpaper – Dùng WorkPaper JSON có công thức và công cụ MCP cho các tác vụ bảng tính của agent…