Environment variables
CLI variables
These variables configure mcp behavior:
MCP_SERVERS_CONFIG
—
Inline JSON config (entire servers.json content). Highest priority — skips file read entirely.
MCP_CONFIG_PATH
~/.config/mcp/servers.json
Path to the config file
MCP_CONFIG_DIR
~/.config/mcp
Config directory. Falls back to /tmp/mcp when HOME is not set.
MCP_TIMEOUT
60
Timeout in seconds for server responses (stdio, CLI, and HTTP transports)
MCP_MAX_OUTPUT
1048576
Maximum output bytes from CLI server commands
MCP_PROXY_REQUEST_TIMEOUT
120
(proxy mode) Hard upper bound, in seconds, that any single client request can spend inside mcp serve before the proxy returns a JSON-RPC error. Acts as a belt-and-suspenders boundary on top of the per-transport MCP_TIMEOUT.
MCP_CLASSIFIER_CACHE
~/.config/mcp/tool-classification.json
Path to the persistent tool read/write classification cache (see mcp acl classify). Override this in CI/containers that cannot write to $HOME.
MCP_DISCOVERY_CONCURRENCY
10
Max parallel --help calls during CLI subcommand discovery (see CLI as MCP)
MCP_AUDIT_OUTPUT
unset (→ file for CLI, file+stdout for serve --http, file+stderr for serve stdio)
Audit output destination: file (ChronDB, queryable via mcp logs), stdout, stderr (JSON lines for container log drivers), file+stdout, file+stderr (ChronDB and JSON lines for both mcp logs and a log driver), or none (disable). Setting this env var marks the value as explicit and skips the per-context auto-promotion (so MCP_AUDIT_OUTPUT=file reliably forces chrondb-only output, including in mcp serve). Leaving it unset (and the config field absent) lets each context pick its safe default — file for CLI to keep stdout clean for command output, dual-sink for mcp serve so audit shows up in docker logs/kubectl logs.
MCP_AUDIT_ENABLED
true
Set to false or 0 to disable audit logging and database initialization. Overrides audit.enabled in the config file.
MCP_AUDIT_PATH
~/.config/mcp/db/data
Override the ChronDB data directory. Overrides audit.path in the config file.
MCP_AUDIT_INDEX_PATH
~/.config/mcp/db/index
Override the ChronDB index directory. Overrides audit.index_path in the config file.
MCP_LOG_LEVEL
info
Log verbosity: trace, debug, info, warn, error. Uses tracing EnvFilter syntax — you can also set per-module levels like mcp=debug,hyper=warn.
MCP_LOG_FORMAT
text
Log output format: text (human-readable) or json (structured, for container log drivers).
MCP_OAUTH_CALLBACK_PORT
8085-8099
Port or range for the OAuth callback listener. Single port (9000), range (9000-9010), or 0 for OS-assigned.
MCP_AUTH_CONFIG
—
Inline JSON content of auth.json (read-only). Highest priority for auth — skips file read. Writes are no-ops with a single warn log. Intended for k8s/Docker Secrets.
MCP_AUTH_PATH
~/.config/mcp/auth.json
Override the OAuth token storage location (file path)
MCP_AUTH_SERVER_CONFIG
—
Inline JSON of the OAuth Authorization Server state (auth_server.json). Same precedence model as MCP_AUTH_CONFIG: read-only on disk, mutable in memory. Used when serverAuth.providers includes "oauth_as".
MCP_AUTH_SERVER_PATH
~/.config/mcp/auth_server.json
File path for AS state (registered DCR clients + refresh tokens). Used when serverAuth.providers includes "oauth_as".
MCP_OAUTH_AS_JWT_SECRET
—
HMAC-SHA256 signing key for issued JWTs when running the OAuth Authorization Server. Must be ≥ 32 bytes. Typically referenced from serverAuth.oauthAs.jwtSecret via ${MCP_OAUTH_AS_JWT_SECRET}. Rotation invalidates every previously issued token.
Config loading priority
mcp resolves its configuration in this order:
MCP_SERVERS_CONFIG— inline JSON string, parsed directly (no file read)MCP_CONFIG_PATH— path to a config fileMCP_CONFIG_DIR/servers.json — config directory override~/.config/mcp/servers.json— default file location/tmp/mcp/servers.json— last-resort fallback whenHOMEis not set
Environment variable substitution (${VAR_NAME}) works in all cases, including inline config.
MCP_SERVERS_CONFIG
MCP_SERVERS_CONFIGProvide the entire config as a JSON string. This is the recommended approach for containers — no file mounts required:
Load from an existing file with $(cat ...):
MCP_SERVERS_CONFIG takes priority over MCP_CONFIG_PATH. If both are set, the inline config wins.
MCP_CONFIG_PATH
MCP_CONFIG_PATHOverride the default config file location. Useful for maintaining multiple configs or testing.
MCP_CONFIG_DIR
MCP_CONFIG_DIROverride the base config directory (default ~/.config/mcp). All default paths (servers.json, auth.json, db/, tool-classification.json) resolve relative to this directory.
When HOME is not set (common in scratch and distroless containers), mcp falls back to /tmp/mcp with a warning.
MCP_TIMEOUT
MCP_TIMEOUTHow long to wait for a server to respond, in seconds. Applies to all transports: stdio, CLI, and HTTP. Increase this for servers that take a long time to initialize (like some npm packages on first run) or slow HTTP backends.
MCP_MAX_OUTPUT
MCP_MAX_OUTPUTMaximum number of bytes to capture from a CLI server's stdout. Commands that exceed this limit have their output truncated. Default is 1 MB.
MCP_PROXY_REQUEST_TIMEOUT
MCP_PROXY_REQUEST_TIMEOUTOnly applies to mcp serve. Bounds how long the proxy will wait for any single client JSON-RPC request to complete end-to-end (auth + routing + backend I/O). If the bound is hit, the client receives a JSON-RPC error with code -32000 and the in-flight request is dropped — other concurrent clients are unaffected. Set lower for tighter SLAs, higher for backends that legitimately take a long time.
MCP_CLASSIFIER_CACHE
MCP_CLASSIFIER_CACHEOverride the path of the tool read/write classification cache. The cache is a JSON file populated lazily by mcp serve and mcp acl classify, keyed by (server, tool, hash(description)). If the description changes, that tool's entry is transparently invalidated.
Useful when $HOME is read-only (CI workers, containers) — point the cache at an ephemeral path:
Corrupt or unreadable cache files are non-fatal: a warning is logged and the process proceeds with fresh in-memory classifications.
MCP_DISCOVERY_CONCURRENCY
MCP_DISCOVERY_CONCURRENCYOnly applies to CLI servers (cli: true). Limits how many --help calls run in parallel during subcommand discovery. Lower this if your machine struggles with many concurrent child processes, or raise it to speed up discovery for deeply nested CLIs.
MCP_AUDIT_ENABLED
MCP_AUDIT_ENABLEDDisable audit logging entirely. When set to false or 0, the database is not initialized and no filesystem writes occur. This overrides "enabled": true in the config file's audit section.
The default Docker image sets MCP_AUDIT_ENABLED=false because scratch images have no writable filesystem. Override it when you mount a volume:
MCP_AUDIT_PATH / MCP_AUDIT_INDEX_PATH
MCP_AUDIT_PATH / MCP_AUDIT_INDEX_PATHOverride the ChronDB data and index directories. These take priority over the audit.path and audit.index_path fields in the config file.
MCP_LOG_LEVEL
MCP_LOG_LEVELControls verbosity of tracing events emitted by the proxy and CLI. Output goes to stderr (so stdout stays clean for mcp logs --json, MCP_AUDIT_OUTPUT=stdout, and stdio JSON-RPC).
Accepts the full tracing EnvFilter syntax — not just a single level:
The per-module pattern is the one to reach for in containers. A bare debug floods logs with HTTP framing noise from hyper/h2/reqwest — scoping mcp to debug and the rest to warn keeps the signal-to-noise ratio usable.
Invalid filter strings fall back silently to info.
MCP_LOG_FORMAT
MCP_LOG_FORMATSelects between human-readable and structured logging. Defaults to text (color, indented multiline events). Set to json for newline-delimited JSON — one complete event per line, drop-in for any log driver:
Each event is a self-contained JSON object:
Combined with MCP_AUDIT_OUTPUT=stdout, every byte the container emits is JSON: tracing on stderr, audit on stdout. No mixed formats, no parse rules to maintain.
MCP_AUTH_CONFIG
MCP_AUTH_CONFIGInline JSON content of auth.json, equivalent to MCP_SERVERS_CONFIG but for OAuth tokens and dynamic-client registrations. Highest priority — when set, the file at MCP_AUTH_PATH (or the default location) is not read.
${VAR} placeholders are expanded the same way as in MCP_SERVERS_CONFIG, so you can split tokens across multiple Secret keys.
Read-only on disk; mutable in memory. When MCP_AUTH_CONFIG is set, the env var seeds an in-memory auth store on first load. Subsequent OAuth flows — token refresh, dynamic-client registration — update the cache so refreshed tokens are visible to later calls within the same process. Nothing is ever written back to disk (the source of truth is the Secret), and a single warn log is emitted on the first save attempt. On pod restart, the Secret is read again — any in-memory mutations are discarded.
Use cases:
Kubernetes deployments where the pod has a read-only filesystem and OAuth tokens come from a Secret (see Deploying on Kubernetes)
Docker containers where mounting a writable
auth.jsonis undesirableCI environments that need pre-provisioned tokens for ephemeral runs
Not recommended for:
Local development on a workstation — use the default
auth.jsonand letmcp addhandle the OAuth flow.Any environment where you expect
mcp add <server>to register a new client and persist the result. That flow requires a writable file.
MCP_AUTH_CONFIG takes priority over MCP_AUTH_PATH. If both are set, the inline content wins. An empty or whitespace-only value falls through to the file path.
MCP_AUTH_PATH
MCP_AUTH_PATHOverride the OAuth token storage location (file path). Default is ~/.config/mcp/auth.json. Useful in containers where $HOME doesn't exist, or to share an auth store across multiple mcp invocations.
For container deployments where the filesystem is read-only or you want tokens injected from a secret manager, use MCP_AUTH_CONFIG instead.
Auth loading priority
mcp resolves the auth store in this order:
MCP_AUTH_CONFIG— inline JSON (read-only, no file I/O)MCP_AUTH_PATH— file path overrideMCP_CONFIG_DIR/auth.json — config directory override~/.config/mcp/auth.json— default file location
MCP_AUTH_SERVER_CONFIG
MCP_AUTH_SERVER_CONFIGInline JSON for the OAuth Authorization Server state — registered clients (Dynamic Client Registration / RFC 7591) and persisted refresh tokens. Equivalent to MCP_AUTH_CONFIG but for the server-side AS state file (auth_server.json), used only when serverAuth.providers contains "oauth_as".
Same precedence model: inline content takes priority, writes during runtime stay in memory only (the on-disk source is treated as read-only, matching how Kubernetes Secrets behave).
Authorization codes are intentionally not persisted — restart drops them, which is the safer default than letting captured codes resume post-restart.
MCP_AUTH_SERVER_PATH
MCP_AUTH_SERVER_PATHOverride the file location for AS state. Default is ~/.config/mcp/auth_server.json. The file is rewritten atomically via tempfile-then-rename, so a crash mid-write cannot leave a partial JSON behind.
MCP_AUTH_SERVER_CONFIG takes priority over MCP_AUTH_SERVER_PATH. Both apply only when oauth_as is in serverAuth.providers; otherwise they're ignored.
MCP_OAUTH_AS_JWT_SECRET
MCP_OAUTH_AS_JWT_SECRETHMAC-SHA256 signing key for the JWTs issued by the OAuth Authorization Server. Must be at least 32 bytes — boot fails otherwise. Generate with:
Reference it from serverAuth.oauthAs.jwtSecret via ${MCP_OAUTH_AS_JWT_SECRET} so the secret never lives in the config file.
Rotation invalidates every previously issued access and refresh token. v1 has no in-place rotation — plan for a forced re-login when changing the secret.
Config variables
Environment variables referenced in servers.json with ${VAR_NAME} syntax. These are user-defined and depend on which servers you've configured.
Common examples:
GITHUB_TOKEN
GitHub
Personal access token
SLACK_TOKEN
Slack
Bot or user OAuth token (xoxb- or xoxp-)
SENTRY_TOKEN
Sentry
Auth token
GRAFANA_TOKEN
Grafana
Service account token
ROAM_TOKEN
Roam Research
Graph API token
Set them in your shell profile (~/.bashrc, ~/.zshrc, etc.):
Or pass them inline:
Last updated
Was this helpful?