mcp-oauth-bridge
Verified@f12o/mcp-oauth-bridge Β· v0.1.1 Β· MIT
OAuth-capable MCP bridge for DSH: wraps mcp-remote over stdio and reuses @deepseek-ai/dsh-mcp-client.
Install
dsh plugin add @f12o/mcp-oauth-bridge Confirm the layer applied with dsh --profile default --dump-config β see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
@f12o/mcp-oauth-bridge
OAuth-capable MCP bridge for DeepSeek Harness (DSH).
DSH's built-in @deepseek-ai/dsh-mcp-client supports stdio and Streamable HTTP with static headers. It does not implement an OAuth flow. This bundle wraps the maintained mcp-remote proxy in the MCP client's stdio path, so an OAuth-protected remote MCP server becomes ordinary mcp__<serverName>__<tool> tools in DSH.
The bridge does not reimplement tool discovery, naming, resources, instructions, image projection, or reconnection. It builds the mcp-remote child configuration and hands it to @deepseek-ai/dsh-mcp-client, which remains the single owner of those behaviors. The built-in Streamable HTTP transport is unchanged; this package is a stdio bridge for servers that need OAuth.
Requirements
- DSH
>=0.2.1-rc.2 <0.3.0 - Node
>=22.19 - A browser that can reach the DSH host for the OAuth callback
- Network access from the DSH host to the MCP server and its authorization server
mcp-remote is installed as a dependency of this package.
Install
dsh plugin --profile web add @f12o/mcp-oauth-bridge
The package is a DSH bundle: installing it adds a disabled mcp-oauth-bridge row to the profile. Bundle membership changes take effect on the next profile start, so restart the host after installing.
Enable and configure the row in $DSH_HOME/profiles/web/cordis.patch.yml:
- id: mcp-oauth-bridge
disabled: false
config:
serverName: temote_remote
url: https://temote.f12o.com/mcp
A patch replaces the targeted row's complete config; this example relies on the plugin's defaults for every other field. Restart or hot-reload the profile after editing, then complete the OAuth flow described below.
First connection
- Start DSH in a terminal you can see (
dsh web,dsh --profile headless ..., etc.). - On the first connection,
mcp-remoteprints an authorization URL to stderr and tries to open the default browser. - Authorize the client. The browser redirects to the bridge's callback (
http://127.0.0.1:<port>/oauth/callbackby default). - The token is stored under
$DSH_HOME/mcp-auth/<serverName>(ortokenDir). Later starts reuse it and refresh it as needed.
If the browser does not open, copy the URL from the host's stderr. If the browser runs on a different machine from DSH, set callbackHost to an address the browser can reach and make sure the callback port is reachable; alternatively use an SSH tunnel.
DSH's MCP client applies its SDK initialize deadline (about 60 seconds). Complete the login promptly on first use. If the attempt times out, the client reconnects and starts a new proxy; retry the login.
Configuration
| Field | Default | Meaning |
|---|---|---|
serverName |
required | Tool namespace: mcp__<serverName>__<tool>; [A-Za-z0-9_-]{1,32} |
url |
required | HTTPS MCP endpoint. Loopback HTTP is accepted for local tests only |
callbackHost |
127.0.0.1 |
Host mcp-remote registers for the OAuth callback |
callbackPort |
derived | Fixed callback port; omission lets mcp-remote derive or choose one |
callbackPath |
/oauth/callback |
OAuth callback path; /wait-for-auth is reserved |
tokenDir |
$DSH_HOME/mcp-auth/<serverName> |
mcp-remote token cache directory |
authTimeoutSeconds |
300 |
How long mcp-remote waits for the browser callback |
transportStrategy |
http-only |
http-only, http-first, sse-only, or sse-first |
protocol |
auto |
auto enables the 2026 protocol probe; legacy skips it |
extraArgs |
[] |
Extra mcp-remote arguments appended last |
toolCallTimeoutMs |
MCP client default | Per-call timeout forwarded to the MCP client |
failOnStartupError |
false |
Reject plugin activation when the first connection fails |
reconnect |
MCP client defaults | Reconnect policy forwarded to the MCP client |
debug |
false |
Pass --debug to mcp-remote; detailed logs go to tokenDir |
Examples:
# Fixed redirect port and debug logging.
- id: mcp-oauth-bridge
disabled: false
config:
serverName: internal
url: https://mcp.example.com/mcp
callbackPort: 4444
debug: true
# A browser on another machine reaches the DSH host by LAN address.
- id: mcp-oauth-bridge
disabled: false
config:
serverName: internal
url: https://mcp.example.com/mcp
callbackHost: 192.168.0.71
Troubleshooting
mcp-remote is not installedβ reinstall the bundle (dsh plugin --profile <name> add @f12o/mcp-oauth-bridge). The proxy is resolved from this package's dependency tree.- No authorization URL visible β run DSH from a terminal; the URL is on the host's stderr. Set
debug: trueand inspecttokenDir/*_debug.log. - Cloudflare Access or another authorization server rejects registration β try a fixed
callbackPort; pass server-specific client metadata throughextraArgs, for example['--static-oauth-client-metadata', '{"client_name":"DeepSeek Harness"}']. Managed OAuth must allow the redirect URI and dynamic client registration. If the authorization server cannot support this flow, use a native OAuth client instead of this bridge. - Connection fails but DSH starts β the default
failOnStartupError: falsekeeps DSH usable and retries in the background. Check the host logs;npx -y mcp-remote-client <url>can test the endpoint and login independently. - Re-authentication needed β remove the server's directory under
tokenDirand reconnect, or wait for the refresh failure to surface in the logs.
Security
mcp-remoteruns as a child of the DSH host with your user permissions, outside the agent sandbox. Treat the installed version as trusted executable code and update it deliberately.- OAuth tokens are managed by
mcp-remoteundertokenDir(created with mode0700). Do not commit them or copy them into conversation text. - The bridge rejects non-loopback HTTP endpoints so tokens are not sent in clear text outside local testing.
- This is an independent third-party package, not an official DeepSeek package.
mcp-remoteis MIT-licensed; its authors own that code.
Development
pnpm install
pnpm build
pnpm typecheck
pnpm test
pnpm pack:check
The integration test mounts the published @deepseek-ai/dsh-system-prompt and @deepseek-ai/dsh-tools and uses a fixture stdio server in place of mcp-remote. The real OAuth flow against a live server is a manual check. After completing it once, the opt-in live test calls session_list through the real bridge:
MCP_OAUTH_LIVE=1 MCP_OAUTH_TOKEN_DIR=/path/to/token-dir pnpm exec vitest run tests/live.spec.ts
License
MIT