Skip to content

Environment variables

mcp-test prefers YAML for configuration but every value can be overridden via an environment variable thanks to ${VAR} and ${VAR:-default} interpolation in the loaded config.

Convention

The convention is MCPTEST_<UPPER_SNAKE> for project-specific values, plus a few un-prefixed standard names (LOG_LEVEL).

Common overrides

LOG_LEVEL
used bybinary

debug, info (default), warn, error. Sets the slog log level for the whole process.

MCPTEST_PORT
maps toserver.address example8080

The live config interpolates as :${MCPTEST_PORT:-8080}.

MCPTEST_BASE_URL
maps toserver.base_url examplehttps://mcp-test.example.com

The public origin clients reach the server at. Used in OIDC redirect URIs and the protected-resource metadata document.

MCPTEST_DATABASE_URL
maps todatabase.url examplepostgres://mcp:mcp@localhost:5432/mcp_test?sslmode=disable

A pgx-compatible Postgres DSN.

MCPTEST_DEV_KEY
maps toapi_keys.file[0].key exampledevkey-please-change

The bootstrap file API key. Sent as X-API-Key.

MCPTEST_OIDC_ISSUER
maps tooidc.issuer examplehttp://localhost:8081/realms/mcp-test

Required when OIDC is enabled.

MCPTEST_OIDC_AUDIENCE
maps tooidc.audience examplemcp-test

Required aud claim value.

MCPTEST_OIDC_CLIENT_ID
maps tooidc.client_id examplemcp-test-portal

The OIDC client ID used by the browser PKCE login flow.

MCPTEST_OIDC_CLIENT_SECRET
maps tooidc.client_secret

Confidential clients only; public PKCE clients leave it empty.

MCPTEST_COOKIE_SECRET
maps toportal.cookie_secret example32+ bytes, base64

HMAC key for the portal session cookie. Generate with openssl rand -base64 32.

MCPTEST_INSECURE
used byOIDC skip-signature gate example1

Set to 1 to allow oidc.skip_signature_verification (refused otherwise).

Interpolation rules

  • ${VAR} is replaced with the env value, or empty string if unset.
  • ${VAR:-default} is replaced with the env value, or default if unset or empty.
  • Plain $VAR (no braces) is not interpolated. This is intentional so DSNs and other shell-shaped values round-trip.
  • The substitution happens on the raw YAML string before parsing, so it works for any field type.

Composing in compose

The bundled docker-compose.dev.yml shows the typical pattern: the binary container's environment: block sets the variables and the config file references them.

# docker-compose.dev.yml
mcp-test:
  environment:
    MCPTEST_DATABASE_URL: postgres://mcp:mcp@postgres:5432/mcp_test?sslmode=disable
    MCPTEST_BASE_URL: http://localhost:8080
    MCPTEST_OIDC_ISSUER: http://keycloak:8080/realms/mcp-test
    MCPTEST_OIDC_AUDIENCE: mcp-test
    MCPTEST_OIDC_CLIENT_ID: mcp-test-portal
    MCPTEST_COOKIE_SECRET: dev-cookie-secret-not-for-production-use-dev
    MCPTEST_DEV_KEY: devkey-please-change
  command: ["--config", "/app/configs/mcp-test.dev.yaml"]

Worth knowing

  • The binary doesn't read .env files. Use your shell, container runtime, or systemd unit to set variables.
  • Validation runs after interpolation, so a missing required variable surfaces as a config error rather than a YAML parse error.
  • Secrets in env vars show up in process listings on shared hosts. For production, prefer a config file mounted from a secret manager.