Spaces:
Running
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/healthreveal only{"ok": true}.- OAuth client registrations and pending authorization codes are in memory.
- Manual ChatGPT OAuth accepts
https://chatgpt.com/connector/oauth/*unlessOAUTH_ALLOWED_REDIRECT_URISis set. - OAuth access/refresh tokens are stateless signed tokens.
- Rotate
MCP_OAUTH_SIGNING_KEYorMCP_API_KEYto invalidate all OAuth tokens. mcp_connectexpects an HTTP(S) MCP URL such ashttps://example.com/sseorhttp://127.0.0.1:4000/mcp; bare remote hosts are normalized tohttps://..., whilelocalhost/127.0.0.1targets are normalized tohttp://....mcp_connectnow accepts optionalbearer_tokenandx_api_keyarguments 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_TOKENorREMOTE_MCP_X_API_KEYin 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,
Snapshotonly includes an actual screenshot when called withuse_vision=true; plainSnapshotcalls can legitimately return text-only desktop state. - Bridge sessions created by
mcp_connectare in memory and reset when the Space restarts or sleeps.