This app functions as an MCP auth proxy within your Heroku app and enables you to use a remote MCP server. Alternatively, you can run this code as a separate free-standing proxy app.
This repo is based on a node-oidc-provider Express.js example.
This app uses the Heroku Buildpack MCP Auth Proxy to install the server on your Heroku app.
Configure a new Heroku app you created in a Private Space for an MCP Server that requires authorization for MCP clients.
Heroku Key-Value Store (KVS) with Redis is required for client and authorization storage. To provision KVS, run:
heroku addons:create heroku-redis:private-3 --as=MCP_AUTH_PROXY_REDIS
Set the base URL for the auth proxy to the public-facing HTTPS hostname of the Heroku app. The base URL is self-referential in auth flow redirect URIs. If you plan to deploy the app, use a custom domain name.
heroku config:set \
BASE_URL=https://<app-subdomain>.herokuapp.com
The auth proxy uses embedded JavaScript templates (EJS) for interaction views. Currently, there are two required templates: confirm-login.ejs
and _layout.ejs
.
To use the templates, their directory path must be absolute and start with /
.
For example, to use the directory /support/auth-views
committed along with the MCP Server source code and running on Heroku:
heroku config:set \
OIDC_PROVIDER_VIEWS_PATH=/app/mcp-auth-proxy/mcp-auth-proxy/support/auth-views
The auth proxy automatically detects and applies branding based on the Identity Provider (IdP) URL. You can also customize the branding appearance with the following environment variables.
Use BRANDING_TITLE
to customize the page title displayed in the browser tab and page header.
- Default:
"Login for Model Context Protocol"
- Example:
heroku config:set BRANDING_TITLE="My Custom Auth Service"
Use BRANDING_FAVICON
to customize the favicon URL for authentication pages.
- Default:
undefined
(no favicon) - Example:
heroku config:set BRANDING_FAVICON="https://example.com/custom-favicon.ico"
Edit the default brand color scheme in branding-config.js
:
colors: {
primary: '#a7bcd9',
secondary: '#718096',
background: 'linear-gradient(135deg, #f7fafc 0%, #e2e8f0 100%)',
text: '#2d3748',
textMuted: '#718096',
border: '#bbc2c9'
}
Set the internal, local URL for the proxy to reach the MCP Server, and the command to start it, by overriding the PORT
set by Heroku runtime. For example:
heroku config:set \
MCP_SERVER_URL=http://localhost:3000/mcp \
MCP_SERVER_RUN_COMMAND="pnpm" \
MCP_SERVER_RUN_ARGS_JSON='["start"]' \
MCP_SERVER_RUN_DIR="/app" \
MCP_SERVER_RUN_ENV_JSON='{"PORT":3000,"BACKEND_API_URL":"https://mcp.example.com"}'
Generate the JSON Web Key Set (jwks) for auth proxy cryptographic material with the JSON Web Key Generator:
heroku config:set \
OIDC_PROVIDER_JWKS="[$(jwkgen --jwk)]"
Generate a new static OAuth client for the identity provider. This client's redirect URI origin must match the Auth Proxy Base URL (BASE_URL
) origin.
Each identity provider has its own process and interface to create OAuth clients. See their documentation for instructions.
After creating it, set the client ID, secret, Identity Provider URL, and OAuth scope to be granted with config vars:
heroku config:set \
IDENTITY_SERVER_URL=https://identity.example.com \
IDENTITY_CLIENT_ID=yyyyy \
IDENTITY_CLIENT_SECRET=zzzzz \
IDENTITY_SCOPE=global
Optionally, for identity providers that don't support OIDC discovery,
reference a ServerMetadata JSON file that contains the "issuer"
, "authorization_endpoint"
, "token_endpoint"
, and "scopes_supported"
fields.
Your Heroku app is now ready to deploy. Start a new deployment for the app in your Heroku Dashboard.
Install the Remote MCP Auth Proxy Buildpack to deploy this repository as a buildpack alongside a remote MCP server.
- Use the JSON Web Key Generator to generate jwks.
- Key-Value Store with Redis is required, which you can set in
MCP_AUTH_PROXY_REDIS_URL
pnpm install
cp .env-example .env
echo "OIDC_PROVIDER_JWKS='[$(jwkgen --jwk)]'" >> .env
Inspect .env
to fill in missing values:
- Set the
IDENTITY_SERVER_URL
,IDENTITY_CLIENT_ID
,IDENTITY_CLIENT_SECRET
, andIDENTITY_SCOPE
fields in the upstream/primary identity OAuth provider, like a Heroku OAuth client, or Salesforce External Client App. These fields provide the API access required by the MCP server's tools. - The redirect URL for the identity OAuth client must use the path
/interaction/identity/callback
, such ashttp://localhost:3001/interaction/identity/callback
for local development.
Start via pnpm
:
pnpm start
Run MCP Inspector pointed at the proxy:
rm -rf ~/.mcp-auth && npx -y @modelcontextprotocol/inspector npx -y mcp-remote@next http://localhost:3001/mcp
Run the MCP server itself at http://localhost:3000
.
When you visit MCP Inspector at http://localhost:6274
and click Connect
, you should be redirected to the identity OAuth flow, as configured by the IDENTITY_*
env variables.
Some third-party packages require patches to support the quirks of the emerging MCP Clients. We use patch-package for patches.
Patching is configured with:
package.json
postinstall
script- Code diffs in
patches/
- Create or update a patch
pnpm exec patch-package MODULE_NAME
This project uses pnpm for package management and includes comprehensive code quality tools to maintain high standards.
# Run the full Mocha test suite with c8 coverage reporting using the `.env-test` environment configuration
pnpm test
# Check code quality with ESLint
pnpm lint
# Automatically fix linting issues and format code with Prettier
pnpm format
# Run TypeScript type checks on enabled JS files with JSDoc tag annotations
# Note: Add @ts-check at the top of the file to enable type checking
# Full instrucitons here: https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html
pnpm type-check
# All code quality checks and tests
pnpm check
# Run the continuous integration checks (linting, type checking, and tests)
pnpm ci
For the best development experience:
- Before starting work: Ensure dependencies are installed with
pnpm install
- During development: Run
pnpm type-check
periodically to catch type errors early - Before committing: Run
pnpm check
to ensure all quality standards are met - Fix issues quickly: Use
pnpm format
to auto-fix formatting and linting issues
Tests require:
- Redis instance running (local or configured via
MCP_AUTH_PROXY_REDIS_URL
in.env-test
) - Valid test configuration in
.env-test
file - All identity provider settings configured for test scenarios
Enable verbose logging for the proxy middleware:
DEBUG=express-http-proxy pnpm start