Skip to content

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

  1. Start DSH in a terminal you can see (dsh web, dsh --profile headless ..., etc.).
  2. On the first connection, mcp-remote prints an authorization URL to stderr and tries to open the default browser.
  3. Authorize the client. The browser redirects to the bridge's callback (http://127.0.0.1:<port>/oauth/callback by default).
  4. The token is stored under $DSH_HOME/mcp-auth/<serverName> (or tokenDir). 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: true and inspect tokenDir/*_debug.log.
  • Cloudflare Access or another authorization server rejects registration β€” try a fixed callbackPort; pass server-specific client metadata through extraArgs, 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: false keeps 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 tokenDir and reconnect, or wait for the refresh failure to surface in the logs.

Security

  • mcp-remote runs 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-remote under tokenDir (created with mode 0700). 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-remote is 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