mcp-bridge / README.md
patdev's picture
Update mcp-bridge OAuth server
082d529 verified
|
Raw
History Blame Contribute Delete
3.81 kB
metadata
title: mcp-bridge
sdk: docker
app_port: 7860

mcp-bridge

Authenticated MCP-over-SSE bridge for Hugging Face Spaces, with OAuth support for ChatGPT remote MCP clients.

Public endpoints are intentionally quiet:

{"ok": true}

MCP endpoint:

https://patdev-mcp-bridge.hf.space/sse

Required Space secrets / variables

Secret:

MCP_API_KEY=<your-long-random-access-key>

Recommended variable:

PUBLIC_BASE_URL=https://patdev-mcp-bridge.hf.space

Optional secret to invalidate OAuth tokens independently from MCP_API_KEY:

MCP_OAUTH_SIGNING_KEY=<another-long-random-secret>

ChatGPT remote MCP

Use this URL in ChatGPT:

https://patdev-mcp-bridge.hf.space/sse

If ChatGPT can use Dynamic Client Registration, it should discover OAuth automatically. During the OAuth authorization page, enter your MCP_API_KEY once.

If ChatGPT says DCR/CIMD is unavailable, use manual OAuth:

OAuth client ID: chatgpt
OAuth client secret: leave empty
Token endpoint auth method: none
Scopes: mcp

No callback URL needs to be pasted by default. The bridge accepts ChatGPT callback URLs matching:

https://chatgpt.com/connector/oauth/*

Sync with:

python .\scripts\sync_hf.py --space-id patdev/mcp-bridge --api-key "YOUR_LONG_RANDOM_KEY" --restart

Using the PowerShell wrapper:

powershell -ExecutionPolicy Bypass -File .\scripts\sync_hf.ps1 -ApiKey "YOUR_LONG_RANDOM_KEY" -Restart

For stricter security, you may still force an exact redirect allowlist by setting:

python .\scripts\sync_hf.py --space-id patdev/mcp-bridge --api-key "YOUR_LONG_RANDOM_KEY" --chatgpt-callback-url "EXACT_CHATGPT_CALLBACK_URL" --restart

OAuth endpoints included

/.well-known/oauth-protected-resource
/.well-known/oauth-authorization-server
/oauth/register
/oauth/authorize
/oauth/token
/oauth/revoke
/oauth/jwks

Manual auth still works

For non-ChatGPT clients, these still work:

Authorization: Bearer <MCP_API_KEY>

or:

x-api-key: <MCP_API_KEY>

Generate a key

python -c "import secrets; print(secrets.token_urlsafe(48))"

Notes

  • / and /health reveal only {"ok": true}.
  • OAuth client registrations and pending authorization codes are in memory.
  • Manual ChatGPT OAuth accepts https://chatgpt.com/connector/oauth/* unless OAUTH_ALLOWED_REDIRECT_URIS is set.
  • OAuth access/refresh tokens are stateless signed tokens.
  • Rotate MCP_OAUTH_SIGNING_KEY or MCP_API_KEY to invalidate all OAuth tokens.
  • mcp_connect expects an HTTP(S) MCP URL such as https://example.com/sse or http://127.0.0.1:4000/mcp; bare remote hosts are normalized to https://..., while localhost/127.0.0.1 targets are normalized to http://....
  • mcp_connect now accepts optional bearer_token and x_api_key arguments for protected upstream MCP servers and verifies the remote endpoint by default during connect.
  • If you do not want to pass remote credentials on each call, set REMOTE_MCP_BEARER_TOKEN or REMOTE_MCP_X_API_KEY in the bridge environment and they will be applied automatically when explicit auth headers are absent.
  • FastMCP tool results are serialized as text-first when a tool returns mixed text plus image content, so the bridge emits image-only outputs whenever the upstream result includes images. This preserves screenshot rendering in hosts that otherwise hide the image behind the leading text item.
  • For Windows-MCP specifically, Snapshot only includes an actual screenshot when called with use_vision=true; plain Snapshot calls can legitimately return text-only desktop state.
  • Bridge sessions created by mcp_connect are in memory and reset when the Space restarts or sleeps.