Skip to main content
Glama

MCP OAuth Proxy

A local, multi-upstream MCP router for Scout. It exposes one newline-delimited JSON-RPC MCP server on stdio and routes tools/list and tools/call to named HTTP MCP servers.

Distribution

The proxy follows the same versioned GitHub package model as the MSX MCP. Publish a release tag, then configure Scout to launch it with npx:

{
  "name": "MCP OAuth Proxy",
  "type": "command",
  "command": "npx",
  "args": [
    "-y",
    "github:aliyoussefi/mcp-oauth-proxy",
    "--config",
    "%USERPROFILE%\\mcp-oauth-proxy\\config.json"
  ],
  "timeout": 300000
}

The target machine needs Node.js 20 or later. The repository is also usable with a public npm package if one is published later.

The repository includes two Scout skills under skills/:

  • mcp-oauth-proxy-install prepares the package and local configuration.

  • mcp-oauth-proxy-add-server adds one MCP by URL, performs OAuth discovery, attempts Dynamic Client Registration, and configures a separate Scout entry.

Related MCP server: mcp-client-credentials-auth

Setup

cd .\mcp-oauth-proxy
npm install
Copy-Item config.example.json config.json
# Edit config.json; never put secrets in it.
npm test
npm start -- --config .\config.json

For non-developer setup, run the interactive wizard:

mcp-oauth-proxy.exe --setup --config "$env:USERPROFILE\mcp-oauth-proxy\config.json"

Scout can also launch the package directly:

npx -y github:aliyoussefi/mcp-oauth-proxy --config "%USERPROFILE%\mcp-oauth-proxy\config.json"

Run the same command with --setup once to create the configuration:

npx -y github:aliyoussefi/mcp-oauth-proxy --setup --config "%USERPROFILE%\mcp-oauth-proxy\config.json"

The wizard asks for the MCP URL and values that cannot be discovered automatically. It discovers OAuth metadata and attempts Dynamic Client Registration for a public PKCE client. If the authorization server does not support registration, it asks for a public OAuth client ID. It never asks for a password or token. Run it once for each server name, such as dataverse and salesforce. Choose auto to prefer device-code sign-in when available, browser for authorization-code plus PKCE, or device-code to require device-code sign-in.

Multiple upstreams

Each entry under servers points to one upstream MCP endpoint. Multiple entries can be configured in the same file, and their tools are exposed to Scout with names such as slack/search_messages, salesforce/query_records, and dataverse/list_records.

To register each upstream as a separate Scout MCP server while sharing one config file, pass the upstream name with --server:

npx -y github:aliyoussefi/mcp-oauth-proxy --config "%USERPROFILE%\mcp-oauth-proxy\config.json" --server dataverse
npx -y github:aliyoussefi/mcp-oauth-proxy --config "%USERPROFILE%\mcp-oauth-proxy\config.json" --server salesforce

--provider is accepted as an alias for --server. Omitting the selector keeps the multi-upstream behavior.

When --server selects one upstream, the proxy exposes that upstream's native tool names without a prefix. This lets Scout keep separate MCP identities and call each tool directly. In aggregate mode, tools remain namespaced as server/tool to avoid collisions.

Example with three named Scout MCP entries:

{
  "salesforce": {
    "builtin": false,
    "config": {
      "name": "Salesforce",
      "type": "command",
      "command": "npx",
      "args": ["-y", "github:aliyoussefi/mcp-oauth-proxy", "--config", "%USERPROFILE%\\mcp-oauth-proxy\\config.json", "--server", "salesforce"],
      "timeout": 300000
    },
    "tools": []
  },
  "slack": {
    "builtin": false,
    "config": {
      "name": "Slack",
      "type": "command",
      "command": "npx",
      "args": ["-y", "github:aliyoussefi/mcp-oauth-proxy", "--config", "%USERPROFILE%\\mcp-oauth-proxy\\config.json", "--server", "slack"],
      "timeout": 300000
    },
    "tools": []
  },
  "dataverse": {
    "builtin": false,
    "config": {
      "name": "Dataverse",
      "type": "command",
      "command": "npx",
      "args": ["-y", "github:aliyoussefi/mcp-oauth-proxy", "--config", "%USERPROFILE%\\mcp-oauth-proxy\\config.json", "--server", "dataverse"],
      "timeout": 300000
    },
    "tools": []
  }
}

Three-upstream example

The proxy can aggregate Salesforce, Slack, and Dataverse in one Scout process. The endpoint, client ID, scopes, and OAuth URLs are provider-specific and must be supplied by the administrator:

{
  "servers": {
    "salesforce": {
      "endpoint": "https://api.salesforce.com/platform/mcp/v1/platform/sobject-all",
      "transport": "streamable-http",
      "clientId": "<salesforce-public-client-id>",
      "scopes": ["api", "sfap_api", "refresh_token", "mcp_api"],
      "auth": {
        "flow": "browser",
        "authorizationEndpoint": "https://login.salesforce.com/services/oauth2/authorize?prompt=select_account",
        "tokenEndpoint": "https://login.salesforce.com/services/oauth2/token",
        "redirectUri": "http://localhost:8765/oauth/callback"
      },
      "tokens": {
        "file": "~/.mcp-oauth-proxy/salesforce-tokens.json"
      }
    },
    "slack": {
      "endpoint": "<slack-mcp-url>",
      "transport": "streamable-http",
      "clientId": "<slack-public-client-id>",
      "auth": {
        "flow": "browser",
        "authorizationEndpoint": "<slack-authorization-url>",
        "tokenEndpoint": "<slack-token-url>",
        "redirectUri": "http://localhost:8765/oauth/callback"
      },
      "tokens": {
        "file": "~/.mcp-oauth-proxy/slack-tokens.json"
      }
    },
    "dataverse": {
      "endpoint": "<dataverse-mcp-url>",
      "transport": "streamable-http",
      "clientId": "<dataverse-public-client-id>",
      "auth": {
        "flow": "browser",
        "authorizationEndpoint": "<dataverse-authorization-url>",
        "tokenEndpoint": "<dataverse-token-url>",
        "redirectUri": "http://localhost:8765/oauth/callback"
      },
      "tokens": {
        "file": "~/.mcp-oauth-proxy/dataverse-tokens.json"
      }
    }
  }
}

OAuth and token storage

Set MCP_OAUTH_PROXY_TOKEN_<SERVERNAME> for explicit access-token injection, with the server name uppercased and non-alphanumeric characters replaced by _. If clientId, authorizationEndpoint, and tokenEndpoint are configured, the first unauthenticated tool request opens browser OAuth using PKCE.

The provider must allow a loopback redirect under http://127.0.0.1:<port>/oauth/callback. Authorization servers that support OAuth Dynamic Client Registration can complete setup with only the MCP URL. Others require a pre-registered public client ID. Refresh tokens, access tokens, and client secrets are persisted encrypted. Windows uses DPAPI through PowerShell. On other platforms, set MCP_OAUTH_PROXY_KEY to a 32-byte base64 key. Persistence fails rather than writing plaintext.

Token files are user-specific credentials and must never be committed or shared. Client secrets are not stored in configuration files.

Tools are namespaced as server/tool. Calls may also specify { "server": "name", "name": "tool" }.

Metadata-only audit logging

Audit logging is disabled by default. Set MCP_PROXY_AUDIT_LOG to a local JSONL path to record tool-call metadata only:

MCP_PROXY_AUDIT_LOG=%USERPROFILE%\.mcp-oauth-proxy\audit.jsonl

Each event includes the timestamp, upstream server name, tool name, status, and duration. Tool arguments, results, headers, OAuth values, and business data are never written.

Portable executable

npm run build:exe

The resulting dist\mcp-oauth-proxy.exe is self-contained and does not require Node.js or npm. Copy it together with a user-edited config.json, then configure Scout with:

"C:\path\to\mcp-oauth-proxy.exe" --config "C:\path\to\config.json"

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Aggregates multiple MCP servers behind a single stdio interface, supporting stdio-based and HTTP SSE-based upstreams with OAuth.
    8 npm
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Bridge that lets stdio-only MCP clients connect to remote MCP servers with OAuth and other auth support, enabling local clients to use remote, authorized MCP servers.
    58 npm
    54
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables clients to access multiple backend MCP servers through a single endpoint, with OAuth 2.1 authorization, namespaced tools, and secure credential management.
    MIT