LABSCO SUMMARY
It has no tools of its own — it lends yours a login.
Everything the client sees comes from the upstream server; this only adds the token. Two details make it worth using over hand-rolled auth: endpoint discovery usually removes the OAuth configuration entirely, and the refresh token lands encrypted at mode 0600 rather than in plain text beside your config.
What it is
A Node proxy. Your client launches it over stdio; it forwards every JSON-RPC message to an OAuth2-protected HTTP MCP server with a bearer token attached, and handles login, caching and refresh on its own.
What you get
- An interactive
authorization_codelogin with PKCE and a built-in local browser callback listener, so no code is copied by hand - A refresh token cached on disk under AES-256-GCM with mode
0600, so the browser opens once per machine - A
client_credentialsgrant for headless and service-to-service use - OAuth endpoints discovered from the upstream through RFC 9728 and RFC 8414, which usually means no OAuth configuration at all
- Proactive token refresh with skew, in-flight de-duplication, and a 401 → invalidate → retry loop
- Streamable-HTTP upstreams handled properly: single-shot JSON, SSE
text/event-streamresponses, the optional server-notification channel, andMcp-Session-Id - Stderr-only logging with tokens, secrets and
Authorizationheaders redacted, leaving stdout a clean JSON-RPC channel
Requirements
Node.js 20+, an OAuth2-protected MCP server speaking the Streamable HTTP transport, and an OAuth2 client registered with your identity provider. For the interactive flow, register http://127.0.0.1:53682/callback as a redirect URI, or whatever you set OAUTH2_CALLBACK_PORT to. Launch with npx -y mcp-oauth2-proxy and configure through UPSTREAM_URL, OAUTH2_GRANT, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, OAUTH2_TOKEN_URL, OAUTH2_SCOPE, OAUTH2_RESOURCE and LOG_LEVEL, or with a JSON file named by MCP_PROXY_CONFIG. The package is mcp-oauth2-proxy 0.2.0.
Setup effort
One command plus credentials — npx -y mcp-oauth2-proxy, then supply credentials
USE CASES
01
Reaching a corporate MCP server from a desktop client
Let the proxy open the browser once, cache the refresh token, and keep the session alive from then on.
02
Running the same server headless in CI
Switch the grant to client_credentials with a service account, so no browser is involved.
03
Keeping tokens out of your logs
Logging goes to stderr with credentials redacted, which also keeps stdout usable as the JSON-RPC channel.
BEFORE YOU INSTALL
What to know first
Requires
- npx on PATH
- Node.js 20+
- UPSTREAM_URL: the address of the OAuth2-protected MCP server to proxy
- OAUTH2_CLIENT_ID: an OAuth2 client registered with your identity provider
Where it runs
All 4 documented clients run the server on your machine.
INSTALLATION
Connect your client
Server setup
TERMINAL
npx -y mcp-oauth2-proxyMCP Clients
Claude Desktop, Cursor, Other MCP clients
JSON
{
"mcpServers": {
"remote-oauth2-mcp": {
"command": "npx",
"args": [
"-y",
"mcp-oauth2-proxy"
],
"env": {
"UPSTREAM_URL": "<YOUR_SERVER_URL>/mcp",
"OAUTH2_GRANT": "authorization_code",
"OAUTH2_CLIENT_ID": "<YOUR_OAUTH2_CLIENT_ID>"
}
}
}
}<YOUR_SERVER_URL>/mcp is the address of the OAuth2-protected MCP server you want to reach, and <YOUR_OAUTH2_CLIENT_ID> the client ID you registered for it with your identity provider (redirect URI http://127.0.0.1:53682/callback).
Any MCP client — Windows
ANY MCP CLIENT — WINDOWS · JSON
{
"mcpServers": {
"remote-oauth2-mcp": {
"command": "cmd",
"args": [
"/c",
"npx",
"-y",
"mcp-oauth2-proxy"
],
"env": {
"UPSTREAM_URL": "<YOUR_SERVER_URL>/mcp",
"OAUTH2_GRANT": "authorization_code",
"OAUTH2_CLIENT_ID": "<YOUR_OAUTH2_CLIENT_ID>"
}
}
}
}Same entry as the other tabs with only command and args swapped — use it on Windows hosts where "command": "npx" fails to start. Set UPSTREAM_URL and OAUTH2_CLIENT_ID to your own server and client ID.