> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcphub.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment Variables

> Configure MCPHub using environment variables

MCPHub reads the following environment variables at startup. The authoritative list is whatever appears under `process.env.*` in `src/`; this page summarizes everything currently read by the code on `main`.

## Core application

| Variable                  | Default             | Description                                                                                                                                                                                     |
| ------------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PORT`                    | `3000`              | HTTP server port.                                                                                                                                                                               |
| `BASE_PATH`               | `''`                | Mount-point prefix when MCPHub is served under a sub-path (e.g. `/mcphub`).                                                                                                                     |
| `DEFAULT_REQUEST_TIMEOUT` | `60000`             | Default request timeout (ms) for upstream MCP server requests when a server does not set `options.timeout`.                                                                                     |
| `INIT_TIMEOUT`            | `300000`            | Initial timeout (ms) used when starting upstream MCP servers.                                                                                                                                   |
| `READONLY`                | `false`             | Reject mutating dashboard API requests. `GET` and `${basePath}/tools/*` remain allowed.                                                                                                         |
| `DISABLE_WEB`             | `false`             | Skip serving the bundled dashboard. The API and MCP transport routes still run.                                                                                                                 |
| `TRUST_PROXY`             | auto                | Express `trust proxy` setting. Accepts `true`, `false`, a hop count (`1`, `2`, …), or names like `loopback,linklocal,uniquelocal`. Defaults to `1` inside Docker/Kubernetes, `false` otherwise. |
| `MCPHUB_SETTING_PATH`     | `mcp_settings.json` | Override the path of the settings file used by file-mode storage.                                                                                                                               |
| `NODE_ENV`                | `development`       | `development` / `production` / `test`.                                                                                                                                                          |
| `DEBUG`                   | `false`             | Set to `true` to enable verbose startup logging for frontend-path discovery.                                                                                                                    |

## Authentication

| Variable         | Default            | Description                                                                                                                                            |
| ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ADMIN_PASSWORD` | random             | Password seeded for the bootstrap `admin` user when no users exist yet. If unset, a 24-character random password is generated and printed to the logs. |
| `JWT_SECRET`     | random per-process | Secret used to sign JWTs issued by `/api/auth/login`. See the warning below — this **must** be set explicitly in any non-development deployment.       |

<Warning>
  **`JWT_SECRET` must be set to a persistent, high-entropy value (≥ 32 random bytes) in staging and production.** If it is left unset, MCPHub generates a new random secret on every process start, which means: every restart invalidates all outstanding sessions and bearer tokens; horizontally-scaled instances cannot share sessions because each replica signs with its own secret; and CI / container restarts silently log everyone out. Generate one with `openssl rand -hex 32` and store it in your secret manager. Treat it like any other long-lived cryptographic key — rotation requires invalidating outstanding JWTs.
</Warning>

### Better Auth (optional social login)

Better Auth is initialized once at process startup in `src/betterAuth.ts`. Because of that, changing any Better Auth setting still requires a restart.

For non-secret Better Auth settings, MCPHub resolves values in this order:

1. `BETTER_AUTH_*` environment variables
2. `systemConfig.auth.betterAuth` (from `mcp_settings.json` or the database-backed system config)
3. Built-in defaults

Provider client credentials remain environment-variable only.

<Note>
  Better Auth currently requires PostgreSQL-backed storage in MCPHub. In practice that means `DB_URL` must be configured; file-only mode does not support Better Auth sessions.
</Note>

| Variable                                    | Description                                                                                                                                                                                                                                                   |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BETTER_AUTH_ENABLED`                       | Master switch for Better Auth. Better Auth is still disabled automatically when MCPHub is not in database mode or when no provider has the required credentials.                                                                                              |
| `BETTER_AUTH_URL`                           | Public base URL used to build Better Auth redirect URIs. This now takes precedence over `systemConfig.install.baseUrl`. Its origin is also auto-added to the trusted origin list.                                                                             |
| `BETTER_AUTH_BASE_PATH`                     | Mount path for the Better Auth handler. Defaults to `/api/auth/better`.                                                                                                                                                                                       |
| `BETTER_AUTH_TRUSTED_ORIGINS`               | Optional additional origins allowed to start Better Auth login flows. Accepts a comma-separated list, whitespace-separated list, or JSON array. When omitted, MCPHub still auto-trusts the origins from `BETTER_AUTH_URL` and `systemConfig.install.baseUrl`. |
| `BETTER_AUTH_GOOGLE_ENABLED`                | Enable or disable the Google provider after credentials are present. Defaults to `true`.                                                                                                                                                                      |
| `GOOGLE_CLIENT_ID` / `GOOGLE_CLIENT_SECRET` | Google OAuth app credentials.                                                                                                                                                                                                                                 |
| `BETTER_AUTH_GITHUB_ENABLED`                | Enable or disable the GitHub provider after credentials are present. Defaults to `true`.                                                                                                                                                                      |
| `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` | GitHub OAuth app credentials.                                                                                                                                                                                                                                 |
| `BETTER_AUTH_OIDC_ENABLED`                  | Enable or disable the generic OIDC provider. Defaults to `false`.                                                                                                                                                                                             |
| `BETTER_AUTH_OIDC_PROVIDER_ID`              | Provider identifier passed to Better Auth's generic OAuth plugin. Defaults to `oidc`.                                                                                                                                                                         |
| `BETTER_AUTH_OIDC_DISCOVERY_URL`            | Discovery URL for a local OIDC issuer (for example Keycloak, Authentik, or Dex).                                                                                                                                                                              |
| `OIDC_DISCOVERY_URL`                        | Legacy alias for `BETTER_AUTH_OIDC_DISCOVERY_URL`. It is also still useful for `${OIDC_DISCOVERY_URL}` interpolation inside `mcp_settings.json`.                                                                                                              |
| `BETTER_AUTH_OIDC_SCOPES`                   | Optional requested scopes for the local OIDC provider. Accepts a comma-separated list, whitespace-separated list, or JSON array. Defaults to `openid profile email`.                                                                                          |
| `BETTER_AUTH_OIDC_PKCE`                     | Enable or disable PKCE for the local OIDC provider. Defaults to `true`.                                                                                                                                                                                       |
| `BETTER_AUTH_OIDC_PROMPT`                   | Optional `prompt` parameter for the local OIDC provider (`login`, `consent`, `select_account`, etc.).                                                                                                                                                         |
| `OIDC_CLIENT_ID` / `OIDC_CLIENT_SECRET`     | Client credentials for a local OIDC provider such as Keycloak, Authentik, or Dex.                                                                                                                                                                             |

You can still store the non-secret Better Auth settings in `systemConfig.auth.betterAuth`, but `BETTER_AUTH_*` variables now override those values at startup. A full env-only local OIDC example looks like this:

```env theme={null}
BETTER_AUTH_ENABLED=true
BETTER_AUTH_URL=https://mcphub.example.com
BETTER_AUTH_BASE_PATH=/api/auth/better
BETTER_AUTH_TRUSTED_ORIGINS=https://dashboard.example.com,https://admin.example.com

BETTER_AUTH_OIDC_ENABLED=true
BETTER_AUTH_OIDC_PROVIDER_ID=local-oidc
BETTER_AUTH_OIDC_DISCOVERY_URL=https://auth.example.com/.well-known/openid-configuration
BETTER_AUTH_OIDC_SCOPES=openid,profile,email
BETTER_AUTH_OIDC_PKCE=true
BETTER_AUTH_OIDC_PROMPT=login
OIDC_CLIENT_ID=your-oidc-client-id
OIDC_CLIENT_SECRET=your-oidc-client-secret
```

## Storage

MCPHub picks file or database storage at boot:

```
useDatabase = (USE_DB === 'true') OR (USE_DB unset AND DB_URL is set)
```

| Variable                    | Default | Description                                                               |
| --------------------------- | ------- | ------------------------------------------------------------------------- |
| `USE_DB`                    | unset   | Force database mode (`true`) or file mode (`false`).                      |
| `DB_URL`                    | unset   | PostgreSQL connection URL. Required for database mode.                    |
| `USE_DAO_LAYER`             | unset   | Force the DAO layer on even in file mode (advanced; usually unnecessary). |
| `DB_POOL_SIZE`              | `10`    | Maximum TypeORM connection pool size.                                     |
| `DB_POOL_IDLE_TIMEOUT`      | `30000` | Idle pool connection timeout (ms).                                        |
| `DB_CONNECTION_TIMEOUT`     | `30000` | Initial connect timeout (ms).                                             |
| `DB_CONNECTION_RETRY_DELAY` | `2000`  | Base delay between connection retries (ms).                               |
| `DB_MAX_CONNECTION_RETRIES` | `5`     | Maximum connection retry attempts at startup.                             |
| `DB_ENABLE_HEALTH_CHECK`    | `true`  | Run periodic DB health probes (consumed by `/health`).                    |
| `DB_HEALTH_CHECK_INTERVAL`  | `30000` | Health-probe interval (ms).                                               |

See [Database Configuration](/configuration/database-configuration) for end-to-end setup.

## Smart Routing & embeddings

Smart Routing performs vector search over upstream tools to surface only the few most relevant tools for a given query. It requires Postgres + pgvector and an embedding endpoint.

| Variable                                  | Default                  | Description                                                                                                                                           |
| ----------------------------------------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SMART_ROUTING_ENABLED`                   | `false`                  | Master switch for smart routing.                                                                                                                      |
| `SMART_ROUTING_EMBEDDING_PROVIDER`        | `openai`                 | Embedding provider. Currently `openai` or `azure_openai`.                                                                                             |
| `SMART_ROUTING_EMBEDDING_ENCODING_FORMAT` | provider default         | Override the `encoding_format` passed to the embedding API.                                                                                           |
| `SMART_ROUTING_BASE_PACING_DELAY_MS`      | `0`                      | Base delay (ms) applied between embedding requests to avoid rate limits.                                                                              |
| `SMART_ROUTING_PROGRESSIVE_DISCLOSURE`    | unset                    | When set, expose progressively-disclosed tool metadata (see Smart Routing docs).                                                                      |
| `SMART_ROUTING_SERVER_DESCRIPTION_MODE`   | `names`                  | Control how `search_tools` lists available servers: `names` for server names only, `full` to include server descriptions/instructions when available. |
| `EMBEDDING_MODEL`                         | `text-embedding-3-small` | Embedding model name.                                                                                                                                 |
| `EMBEDDING_MAX_TOKENS`                    | per-model                | Override token truncation limit before embedding. Useful to match a local inference server's batch size.                                              |

### OpenAI

| Variable              | Description                                                                        |
| --------------------- | ---------------------------------------------------------------------------------- |
| `OPENAI_API_KEY`      | API key.                                                                           |
| `OPENAI_API_BASE_URL` | Override the base URL (set this for any OpenAI-compatible endpoint, e.g. LocalAI). |

### Azure OpenAI

| Variable                            | Description                                                                                                                 |
| ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `AZURE_OPENAI_API_KEY`              | API key.                                                                                                                    |
| `AZURE_OPENAI_ENDPOINT`             | Resource endpoint (e.g. `https://my-resource.openai.azure.com`).                                                            |
| `AZURE_OPENAI_API_VERSION`          | API version (e.g. `2024-02-01`).                                                                                            |
| `AZURE_OPENAI_EMBEDDING_DEPLOYMENT` | Deployment name.                                                                                                            |
| `AZURE_OPENAI_EMBEDDING_MODEL`      | The underlying OpenAI model the deployment maps to (e.g. `text-embedding-3-small`). Used for tokenizer and limit selection. |

## MCPRouter (optional upstream catalog)

| Variable             | Description                                                        |
| -------------------- | ------------------------------------------------------------------ |
| `MCPROUTER_API_KEY`  | API key for the MCPRouter cloud catalog.                           |
| `MCPROUTER_API_BASE` | Override the API base URL (default `https://api.mcprouter.to/v1`). |
| `MCPROUTER_REFERER`  | Optional `Referer` header sent on MCPRouter requests.              |
| `MCPROUTER_TITLE`    | Optional `Title` header sent on MCPRouter requests.                |

## Configuration examples

### Development

```env theme={null}
NODE_ENV=development
PORT=3000
JWT_SECRET=dev-secret-key
```

### Production with database + Smart Routing

```env theme={null}
NODE_ENV=production
PORT=3000
BASE_PATH=
JWT_SECRET=replace-with-32+-random-bytes

USE_DB=true
DB_URL=postgresql://mcphub:secret@db:5432/mcphub

SMART_ROUTING_ENABLED=true
OPENAI_API_KEY=sk-...
EMBEDDING_MODEL=text-embedding-3-small
```

## Loading order

MCPHub loads variables in this order; later sources override earlier ones:

1. System environment variables.
2. `.env.local` (gitignored).
3. `.env.{NODE_ENV}` (e.g. `.env.production`).
4. `.env`.

`dotenv-expand` is enabled, so `${VAR}` interpolation works inside `.env*` files.

## Security best practices

1. Never commit secrets — `.env*` files are gitignored by default; keep it that way.
2. Always set `JWT_SECRET` explicitly in production.
3. Rotate bearer keys (`/api/auth/keys`) and OAuth client secrets periodically.
4. Use Docker / Kubernetes secrets for container deployments instead of plain `-e`.
