# How to Set Up OIDC Authentication with Supported Providers in MetaMCP

> Easily set up OIDC authentication in MetaMCP by configuring three essential environment variables in your .env file. Securely sign in with your preferred OIDC provider today.

- Repository: [metatool-ai/metamcp](https://github.com/metatool-ai/metamcp)
- Tags: how-to-guide
- Published: 2026-03-07

---

**Configure OIDC in MetaMCP by setting three required environment variables (`OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_DISCOVERY_URL`) in your `.env` file, then restart the application to enable the "Sign in with OIDC" button on the login page.**

MetaMCP uses **Better-Auth** as its authentication layer, with built-in OIDC support via the generic OAuth plugin. When you configure the required environment variables, MetaMCP automatically registers your identity provider in [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts), enabling secure single sign-on through the Authorization Code flow with PKCE. This guide covers the complete setup process for Auth0, Keycloak, Azure AD, Google, Okta, and any other OIDC-compliant provider.

## Prerequisites

Before configuring OIDC, ensure you have the following values from your identity provider:

- **Client ID** – Public identifier for your MetaMCP application
- **Client Secret** – Confidential secret for server-side authentication
- **Discovery URL** – The `.well-known/openid-configuration` endpoint of your provider

You will also need access to your MetaMCP deployment environment to modify the `.env` file and restart services.

## Step-by-Step Configuration

### 1. Configure Environment Variables

Add the required OIDC variables to your `.env` file (copy from `example.env` if needed):

```bash

# Required - Replace with values from your IdP

OIDC_CLIENT_ID=your-oidc-client-id
OIDC_CLIENT_SECRET=your-oidc-client-secret
OIDC_DISCOVERY_URL=https://your-provider.com/.well-known/openid-configuration

```

### 2. Optional Customizations

MetaMCP supports additional environment variables for advanced configurations:

```bash

# Optional - Change only if you need custom settings

OIDC_PROVIDER_ID=oidc                # Internal identifier (default: "oidc")

OIDC_SCOPES=openid email profile    # Space-separated scopes

OIDC_PKCE=true                      # PKCE enabled by default

OIDC_AUTHORIZATION_URL=https://your-provider.com/oauth/authorize  # Only needed for specific IdP bugs

```

The `OIDC_AUTHORIZATION_URL` is specifically required only when working around a Better-Auth bug with certain identity providers, as noted in the source code comments.

### 3. Restart MetaMCP

Restart your MetaMCP containers to load the new environment variables:

```bash
docker compose up -d

```

The backend in [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) automatically detects the OIDC configuration and registers the provider with Better-Auth during startup.

### 4. Verify the Login Interface

Navigate to your MetaMCP login page. You should now see a **"Sign in with OIDC"** button alongside the standard email/password form. Clicking this button initiates the Authorization Code flow with PKCE.

### 5. Control User Registration

Administrators can control whether new users can register via OIDC through the **Settings → Authentication Settings** page in the admin UI. Toggle the **"Disable SSO Registration"** setting to restrict automatic account creation. This setting is enforced by the `configService` checks in the user-creation hook within [`auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/auth.ts).

## Supported Identity Providers

MetaMCP works with any OIDC-compliant identity provider. The following providers have been tested and verified:

| Provider | Example Discovery URL |
|----------|----------------------|
| **Auth0** | `https://your-domain.auth0.com/.well-known/openid-configuration` |
| **Keycloak** | `https://your-keycloak.com/realms/your-realm/.well-known/openid-configuration` |
| **Azure AD** | `https://login.microsoftonline.com/your-tenant-id/v2.0/.well-known/openid-configuration` |
| **Google** | `https://accounts.google.com/.well-known/openid-configuration` |
| **Okta** | `https://your-domain.okta.com/.well-known/openid-configuration` |

Copy the appropriate discovery URL into your `OIDC_DISCOVERY_URL` environment variable. MetaMCP automatically discovers the authorization, token, and user-info endpoints from this configuration document.

## Security Features

MetaMCP implements several security best practices for OIDC authentication:

- **PKCE (Proof Key for Code Exchange)** is enabled by default to prevent authorization code interception attacks
- **Authorization Code Flow** is used exclusively; implicit flows are not supported
- **Auto-discovery** of endpoints via the `.well-known/openid-configuration` document eliminates manual URL configuration errors
- **Cross-subdomain cookies** are configured for session management across MetaMCP services

These features are implemented in the Better-Auth configuration within [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts).

## Code Implementation Details

The following excerpt from [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) demonstrates how MetaMCP constructs the OIDC provider configuration:

```typescript
import { genericOAuth, GenericOAuthConfig } from "better-auth/plugins";

const oidcProviders: GenericOAuthConfig[] = [];

// Add OIDC provider if env vars are present
if (process.env.OIDC_CLIENT_ID && process.env.OIDC_CLIENT_SECRET) {
  const oidcConfig: GenericOAuthConfig = {
    providerId: process.env.OIDC_PROVIDER_ID || "oidc",
    clientId: process.env.OIDC_CLIENT_ID,
    clientSecret: process.env.OIDC_CLIENT_SECRET,
    scopes: (process.env.OIDC_SCOPES || "openid email profile").split(" "),
    pkce: process.env.OIDC_PKCE !== "false",
    discoveryUrl: process.env.OIDC_DISCOVERY_URL,
    // Only needed for a specific Better-Auth bug
    authorizationUrl: process.env.OIDC_AUTHORIZATION_URL,
  };
  oidcProviders.push(oidcConfig);
}

// Register the plugin with Better-Auth
export const auth = betterAuth({
  // ... other configuration ...
  plugins: [
    ...(oidcProviders.length > 0
      ? [genericOAuth({ config: oidcProviders })]
      : []),
  ],
});

```

To add multiple OIDC providers, create distinct configurations with unique `providerId` values and append them to the `oidcProviders` array.

## Key Files Reference

| File | Role | Location |
|------|------|----------|
| [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) | Creates the Better-Auth instance, registers OIDC providers, and defines authentication middleware | [View on GitHub](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) |
| [`apps/backend/src/lib/config.service.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/config.service.ts) | Provides `getAuthProviders()` to report OIDC availability to the frontend UI | [View on GitHub](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/lib/config.service.ts) |
| `example.env` | Template file containing placeholder OIDC environment variables | [View on GitHub](https://github.com/metatool-ai/metamcp/blob/main/example.env) |
| [`README.md`](https://github.com/metatool-ai/metamcp/blob/main/README.md) | User-facing documentation of OIDC support and required variables | [View on GitHub](https://github.com/metatool-ai/metamcp/blob/main/README.md) |

## Summary

- **MetaMCP uses Better-Auth** with the generic OAuth plugin to enable OIDC authentication through environment variable configuration.
- **Three required variables** (`OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, `OIDC_DISCOVERY_URL`) activate the feature automatically on startup.
- **PKCE is enabled by default** for security, with optional customization of scopes, provider IDs, and authorization URLs.
- **Supported providers** include Auth0, Keycloak, Azure AD, Google, and Okta, or any OIDC-compliant identity provider.
- **Registration control** is available through the admin UI settings to disable automatic user creation via SSO.

## Frequently Asked Questions

### What happens if I only set some of the OIDC environment variables?

MetaMCP requires all three core variables (`OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, and `OIDC_DISCOVERY_URL`) to be present simultaneously. If any are missing, the backend in [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) skips OIDC registration entirely, and the login page will not display the SSO button. Check your container logs for the message confirming OIDC configuration status.

### Can I configure multiple OIDC providers simultaneously?

Yes, though the default environment-based configuration supports one provider out of the box. To add multiple providers, you must modify [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts) to construct additional `GenericOAuthConfig` objects with unique `providerId` values (e.g., `oidc-azure`, `oidc-okta`) and append them to the `oidcProviders` array before passing it to the `genericOAuth` plugin.

### Why is my identity provider requiring an explicit authorization URL?

Some identity providers trigger a known Better-Auth bug where the discovery document parsing fails for the authorization endpoint. If you encounter redirect errors during login, set the `OIDC_AUTHORIZATION_URL` environment variable to your provider's explicit OAuth authorization endpoint (e.g., `https://your-provider.com/oauth/authorize`). This bypasses the discovery mechanism for that specific endpoint while still using discovery for tokens and user info.

### How do I prevent automatic user creation for OIDC logins?

Administrators can disable automatic account provisioning through the **Settings → Authentication Settings** page in the MetaMCP admin UI. Toggle the **"Disable SSO Registration"** option to block new user creation via OIDC while still allowing existing users to authenticate. This setting is enforced by the `configService` checks in the user-creation hook within [`apps/backend/src/auth.ts`](https://github.com/metatool-ai/metamcp/blob/main/apps/backend/src/auth.ts).