Skip to content

Environment Variables

All environment variables recognised by protoWorkstacean, their defaults, and which plugin or subsystem reads them.

VariableDefaultPluginDescription
WORKSTACEAN_HTTP_PORT3000HTTP serverPort the HTTP API listens on
WORKSTACEAN_API_KEY(none)HTTP serverAPI key required for authenticated endpoints. If unset, auth is skipped.
WORKSTACEAN_PUBLIC_URL(none)HTTP serverPublic base URL (used for webhook registration and self-links)
WORKSPACE_DIR./workspaceAll loadersPath to the workspace directory containing agent, goal, action, ceremony, and domain YAML files
PROTOLABS_AGENTS_JSON(none)SkillBrokerPluginIf set, overrides workspace/agents.yaml. Expected shape: { "agents": [ { name, url, auth, ... } ] }. Intended for Infisical-backed deployments where pushing a yaml file to every host is inconvenient — ship the whole registry through a single secret instead.
DATA_DIR./dataLoggerPlugin, SQLiteDirectory for the SQLite event log (events.db)
TZsystem defaultSchedulerPluginTimezone for cron schedule evaluation
DEBUG(none)AllSet to any value to enable verbose debug logging
DISABLE_EVENT_VIEWER(none)Event viewerSet to disable the live event viewer UI
VariableDefaultPluginDescription
LLM_GATEWAY_URLhttp://gateway:4000/v1AgentRuntimePlugin / ProtoSdkExecutorBase URL for the LiteLLM proxy gateway. All LLM calls route through this.
OPENAI_API_KEY(none)ProtoSdkExecutorAPI key sent as Bearer token to the LLM gateway.
OPENAI_BASE_URL(none)ProtoSdkExecutorAlternative base URL override (takes precedence over LLM_GATEWAY_URL if set).
ANTHROPIC_API_KEY(none)AgentRuntimePluginDirect Anthropic API key (used when running without a gateway).
ROUTER_DEFAULT_SKILL(none)RouterPluginFallback skill when no keyword match or skillHint found. If unset, unmatched messages are dropped.
ROUTER_DM_DEFAULT_AGENT(none)RouterPluginAgent to route Discord DMs to when no keyword matches. E.g. quinn. Required to enable natural DM conversations.
ROUTER_DM_DEFAULT_SKILLchatRouterPluginSkill used for DMs routed by ROUTER_DM_DEFAULT_AGENT. Defaults to chat.
DM_CONVERSATION_TIMEOUT_MS900000DiscordPlugin / RouterPluginIdle timeout (ms) before a DM conversation session expires. Default: 15 min.
DISABLE_ROUTER(none)RouterPluginSet to any non-empty value to skip RouterPlugin entirely.
VariableDefaultPluginDescription
LANGFUSE_PUBLIC_KEY(none)ProtoSdkExecutorLangFuse public key for tracing. If unset, tracing is disabled.
LANGFUSE_SECRET_KEY(none)ProtoSdkExecutorLangFuse secret key.
LANGFUSE_BASE_URL(none)ProtoSdkExecutorLangFuse base URL (e.g. https://cloud.langfuse.com).
LANGFUSE_HOST(none)ProtoSdkExecutorAlternative LangFuse host (overrides LANGFUSE_BASE_URL).

These env vars describe the HTTP server identity of the protoMaker team runtime (board ops, planning, feature lifecycle). The AVA_* prefix is historical and kept for backwards compatibility with infisical / homelab-iac; the logical agent slug in workspace/agents.yaml is protomaker.

VariableDefaultPluginDescription
AVA_BASE_URL(none)WorldStateEngine, SkillBrokerPluginBase URL of the protoMaker team server (e.g. http://ava:3008). Used for domain URL interpolation and A2A agent registration.
AVA_API_KEY(none)A2AExecutor, WorldStateEngineAPI key sent as X-API-Key when polling protoMaker team domain endpoints or calling its /a2a endpoint.
VariableDefaultPluginDescription
DISCORD_BOT_TOKEN(none)DiscordPluginDiscord bot token. If unset, DiscordPlugin is skipped.
DISCORD_GUILD_ID(none)DiscordPluginGuild (server) ID for slash command registration.
DISCORD_WELCOME_CHANNEL(none)DiscordPluginChannel ID for welcome/onboarding messages.
DISCORD_DIGEST_CHANNEL(none)DiscordPluginChannel ID for periodic digest posts.
DISCORD_OPS_WEBHOOK_URL(none)DiscordPluginWebhook URL for operational alerts.
DISCORD_GOALS_WEBHOOK_URL(none)WorldStateEngineWebhook URL for goal violation/resolution notifications.
DISCORD_CEREMONY_WEBHOOK_URL(none)CeremonyPluginWebhook URL for ceremony run notifications.
DISCORD_BUDGET_WEBHOOK_URL(none)BudgetPluginWebhook URL for budget threshold alerts.
DISCORD_WEBHOOK_ALERTS(none)VariousGeneral-purpose alert webhook URL (fallback for plugins without a dedicated webhook var).

Agents can declare their own Discord bot tokens via discordBotTokenEnvKey in either workspace/agents.yaml (A2A registry) or workspace/agents/*.yaml (in-process definitions). DiscordPlugin’s agent pool spins up a dedicated Client() per declared bot so users can DM each agent directly. The primary token (DISCORD_BOT_TOKEN) is the shared listener — protoBot — which handles guild messages, slash commands, HITL interactions, and DM fallback.

VariableDefaultPluginDescription
DISCORD_BOT_TOKEN(none)DiscordPluginPrimary shared client — protoBot. Guild messages, slash commands, HITL interactions, DM fallback. Should be a dedicated protoBot token, not a reuse of any agent-specific token.
DISCORD_BOT_TOKEN_PROTO(none)(homelab-iac)Source of truth for protoBot in infisical; DISCORD_BOT_TOKEN is interpolated from this in docker-compose.yml.
DISCORD_BOT_TOKEN_AVA(none)DiscordPluginIn-process Ava — conversational chat agent with no tools.
DISCORD_BOT_TOKEN_JON(none)DiscordPluginprotoContent — Jon persona for content/GTM dialogue.
DISCORD_BOT_TOKEN_FRANK(none)DiscordPluginFrank — personal chaos lab runtime (future).
DISCORD_BOT_TOKEN_QUINN(none)DiscordPluginQuinn — @protoquinn[bot]. Used by the pr-remediator + quinn’s own container for formal PR reviews.
VariableDefaultPluginDescription
GITHUB_TOKEN(none)GitHubPluginPersonal access token for GitHub API calls. If unset and GITHUB_APP_ID also unset, GitHubPlugin is skipped.
GITHUB_WEBHOOK_SECRET(none)GitHubPluginHMAC secret for verifying incoming webhook payloads.
GITHUB_WEBHOOK_PORT(none)GitHubPluginPort for the GitHub webhook receiver (if separate from main HTTP port).
GITHUB_APP_ID(none)GitHubPluginGitHub App ID (alternative to GITHUB_TOKEN).
GITHUB_APP_PRIVATE_KEY(none)GitHubPluginPEM-encoded private key for GitHub App authentication.
QUINN_APP_ID(none)GitHubPluginApp ID for Quinn’s dedicated GitHub App installation.
QUINN_APP_PRIVATE_KEY(none)GitHubPluginPEM private key for Quinn’s GitHub App.
VariableDefaultPluginDescription
PLANE_BASE_URL(none)PlanePluginBase URL of the Plane instance (e.g. https://plane.example.com). If unset, PlanePlugin is skipped.
PLANE_API_KEY(none)PlanePluginPlane API key for issue/project operations.
PLANE_WORKSPACE_SLUG(none)PlanePluginPlane workspace slug.
PLANE_WEBHOOK_SECRET(none)PlanePluginHMAC secret for verifying Plane webhook payloads.
PLANE_WEBHOOK_PORT(none)PlanePluginPort for the Plane webhook receiver.
VariableDefaultPluginDescription
GOOGLE_CLIENT_ID(none)GoogleWorkspacePluginOAuth2 client ID. If unset, GoogleWorkspacePlugin is skipped.
GOOGLE_CLIENT_SECRET(none)GoogleWorkspacePluginOAuth2 client secret.
GOOGLE_REFRESH_TOKEN(none)GoogleWorkspacePluginOAuth2 refresh token for long-lived access.
VariableDefaultPluginDescription
OLLAMA_URL(none)Quinn contextOllama base URL for local embedding generation.
OLLAMA_EMBED_MODEL(none)Quinn contextOllama model name for embeddings (e.g. nomic-embed-text).
QDRANT_URL(none)Quinn contextQdrant base URL for vector storage.
QDRANT_VECTOR_SIZE(none)Quinn contextEmbedding vector dimensions (must match the embed model).
REDIS_URL(none)Quinn contextRedis URL for caching embeddings or session state.
VariableDefaultPluginDescription
GRAPHITI_URLhttp://graphiti:8000SkillDispatcherPlugin, world-state memory domainBase URL of the Graphiti sidecar. If unreachable, memory enrichment is skipped silently (the message is still processed).

Graphiti itself (running as a sidecar) reads additional env vars — see User Memory (Graphiti) for the full list, including the required text-embedding-3-small and gpt-4.1-nano gateway aliases.

VariableDefaultPluginDescription
SIGNAL_URL(none)SignalPluginSignal API base URL. If unset, SignalPlugin is skipped.
SIGNAL_NUMBER(none)SignalPluginPhone number for sending Signal messages.
VariableDefaultPluginDescription
ENABLED_PLUGINS(none)Plugin loaderComma-separated list of optional plugin names to enable. Example: ENABLED_PLUGINS=echo

Any environment variable can be interpolated into domain URLs and headers in workspace/domains.yaml using the ${VAR_NAME} syntax:

domains:
- name: protomaker_board
url: "${AVA_BASE_URL}/api/world/board"
headers:
X-API-Key: "${AVA_API_KEY}"

This is resolved at poll time, not at startup, so changes to env vars take effect on the next poll cycle.