# Environment Variables

Device Agent reads workspace-root `.env` at startup for deployment, secrets, and environment-specific values. Supported fields are written into `.device_agent/config.json`; startup-only values such as HTTP binding, database, A2A identity, and extra IM channels are not.

```bash
cp .env.example .env
```

## MQTT

| Variable | Notes |
| --- | --- |
| `MQTT_BROKER_URL` | MQTT broker URL used by the gateway and device-side clients, such as `mqtt://localhost:1883`. |
| `VITE_MQTT_WS_URL` | MQTT broker WebSocket URL used by the browser, such as `ws://localhost:8083/mqtt`. |
| `MQTT_CLIENT_ID` | Client ID used by the gateway MQTT connection. |
| `MQTT_PROTOCOL_VERSION` | MQTT protocol version. Supports `4` and `5`. |
| `MQTT_KEEPALIVE_SECONDS` / `MQTT_KEEP_ALIVE_SECONDS` | Keep Alive interval. |
| `MQTT_CONNECT_TIMEOUT_MS` | Connection timeout. |
| `MQTT_AUTO_RECONNECT` | Whether to reconnect automatically. |
| `MQTT_RECONNECT_PERIOD_MS` | Reconnect interval. |
| `MQTT_CLEAN_START` | Whether to use Clean Start. |
| `MQTT_SESSION_EXPIRY_INTERVAL_SECONDS` | MQTT 5 session expiry interval. |
| `MQTT_USERNAME` / `MQTT_PASSWORD` | Common MQTT credentials for gateway and device-side clients. |
| `VITE_MQTT_USERNAME` / `VITE_MQTT_PASSWORD` | Browser-side MQTT credentials. Use only when the browser must connect directly to the broker. |

TLS variables:

| Variable | Notes |
| --- | --- |
| `MQTT_TLS_ENABLED` | Enable MQTT TLS. |
| `MQTT_TLS_INSECURE` | Set to `true` to disable server certificate verification. |
| `MQTT_TLS_REJECT_UNAUTHORIZED` | Whether to verify the server certificate. |
| `MQTT_TLS_CA_FILE` | CA certificate path. |
| `MQTT_TLS_CERT_FILE` | Client certificate path. |
| `MQTT_TLS_KEY_FILE` | Client private key path. |
| `MQTT_TLS_KEY_PASSPHRASE` | Client private key passphrase. |
| `MQTT_TLS_SERVER_NAME` | TLS Server Name. |

Topic template variables:

```bash
MQTT_TOPIC_PRODUCT_IN=device-agent/{productId}/in
MQTT_TOPIC_PRODUCT_OUT=device-agent/{productId}/out
MQTT_TOPIC_DEVICE_IN=device-agent/{productId}/device/{deviceId}/in
MQTT_TOPIC_DEVICE_OUT=device-agent/{productId}/device/{deviceId}/out
MQTT_TOPIC_DEVICE_COMMAND=device-agent/{productId}/device/{deviceId}/commands
MQTT_TOPIC_DEVICE_RESPONSE=device-agent/{productId}/device/{deviceId}/responses
MQTT_TOPIC_TELEMETRY=v1/{productId}/{deviceId}/telemetry
MQTT_TOPIC_EVENT=v1/{productId}/{deviceId}/event
MQTT_TOPIC_NTP_REQUEST=device-agent/{productId}/device/{deviceId}/ntp/request
MQTT_TOPIC_NTP_RESPONSE=device-agent/{productId}/device/{deviceId}/ntp/response
```

Topic templates must keep the `{productId}` and `{deviceId}` placeholders. See [MQTT Access](../../device-access/mqtt.md) for topics and payloads.

## Models and Vision

| Variable | Notes |
| --- | --- |
| `LLM_PROVIDER` | Primary agent model provider. |
| `LLM_MODEL` | Primary agent model name. |
| `LLM_BASE_URL` | Custom model service URL, commonly used for OpenAI-compatible endpoints or local model services. |
| `LLM_API_KEY` | Generic model API key. |
| `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `KIMI_API_KEY` / `QWEN_API_KEY` | Provider-specific API keys. |
| `OPENAI_CODEX_AUTH_FILE` | Codex auth file path for the `openai-codex` provider. |
| `OPENAI_CODEX_ACCESS_TOKEN` | Access token for the `openai-codex` provider. |
| `AGENT_MAX_ITERATIONS` | Maximum iterations for one agent task. |
| `VISION_ENABLED` | Whether vision is enabled. |
| `VISION_PROVIDER` | Vision provider. Supports `auto` and `dashscope`. |
| `VISION_MODEL` | Vision model name. |
| `VISION_API_KEY` | Vision model API key. |
| `VISION_TIMEOUT_MS` | Vision analysis timeout. |

With `VISION_PROVIDER=auto`, Device Agent tries to reuse the primary agent model when it supports image input. To use a separate vision model, set `VISION_PROVIDER=dashscope`, `VISION_MODEL`, and `VISION_API_KEY`.

## HTTP, Frontend, and Data Storage

| Variable | Notes |
| --- | --- |
| `AGENT_GATEWAY_HTTP_HOST` | Console and HTTP API bind address. Defaults to `127.0.0.1`. Use `0.0.0.0` for server IP or LAN access. |
| `AGENT_GATEWAY_HTTP_PORT` | Console and HTTP API port. Defaults to `3000`. |
| `VITE_API_BASE_URL` | Frontend API base URL. Usually not needed when same-origin proxying is used. |
| `VITE_DEVICE_AGENT_PENDING_TIMEOUT_MS` | Timeout for console Device Agent creation or pending responses. |
| `VITE_FF_A2A_MARKETPLACE_ENABLE` | Whether to show A2A Marketplace entry points. |
| `VITE_DEVICE_ACCESS_CONTROL_BASE_URL` | Device Access Control service URL for miniapp and external access-control scenarios. |
| `DATABASE_DRIVER` | Data storage driver. The default uses local storage; set `postgres` to use PostgreSQL. |
| `DATABASE_URL` | PostgreSQL connection URL. Required only when `DATABASE_DRIVER=postgres`. |

Frontend variables are read by the frontend dev server or build process. Restart the frontend service or rebuild after changing them.

## Voice

| Variable | Notes |
| --- | --- |
| `VOICE_ENABLED` | Whether the voice channel is enabled. |
| `VOICE_HOST` | Voice service bind address. |
| `VOICE_PORT` | Voice service bind port. Defaults to `3001`. |
| `VITE_ASR_SAMPLE_RATE` | ASR sample rate used by browser audio capture. |
| `VOICE_REGION` | Voice region. Supports `cn`, `us`, `eu`, and `global`. |
| `VOICE_TLS_ENABLED` | Whether voice service TLS is enabled. |
| `VOICE_TLS_CERT_FILE` / `VOICE_TLS_KEY_FILE` | Voice service TLS certificate and private key paths. |
| `VOICE_TLS_PASSPHRASE` | Voice service TLS private key passphrase. |

Speech provider variables:

| Provider | Variables |
| --- | --- |
| Volcengine | `VOLCENGINE_SPEECH_APP_ID`, `VOLCENGINE_SPEECH_ACCESS_KEY`, `VOLCENGINE_ASR_RESOURCE_ID`, `VOLCENGINE_ASR_LANGUAGE`, `VOLCENGINE_TTS_RESOURCE_ID`, `VOLCENGINE_TTS_VOICE`, `VOLCENGINE_TTS_VOICES`, `VOLCENGINE_TTS_EXPLICIT_LANGUAGE`, `VOLCENGINE_TTS_SAMPLE_RATE` |
| Alibaba Cloud DashScope | `ALIYUN_DASHSCOPE_API_KEY`, `ALIYUN_ASR_MODEL`, `ALIYUN_ASR_LANGUAGE`, `ALIYUN_TTS_MODEL`, `ALIYUN_TTS_VOICE`, `ALIYUN_TTS_VOICES`, `ALIYUN_TTS_SAMPLE_RATE` |
| AWS | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_REGION`, `AWS_TRANSCRIBE_LANGUAGE_CODE`, `AWS_POLLY_VOICE`, `AWS_POLLY_SAMPLE_RATE` |
| ElevenLabs | `ELEVENLABS_API_KEY`, `ELEVENLABS_API_ENDPOINT`, `ELEVENLABS_ASR_MODEL_ID`, `ELEVENLABS_ASR_LANGUAGE`, `ELEVENLABS_TTS_MODEL_ID`, `ELEVENLABS_TTS_VOICE`, `ELEVENLABS_TTS_VOICES`, `ELEVENLABS_TTS_SAMPLE_RATE` |

See [Voice Interaction](../../usage/voice.md) for voice setup.

## IM

These channels can also be configured from the console settings page:

| Channel | Variables |
| --- | --- |
| Feishu | `FEISHU_ENABLED`, `FEISHU_APP_ID`, `FEISHU_APP_SECRET`, `FEISHU_ENCRYPT_KEY`, `FEISHU_VERIFICATION_TOKEN`, `FEISHU_ALLOW_FROM` |
| DingTalk | `DINGTALK_ENABLED`, `DINGTALK_CLIENT_ID`, `DINGTALK_CLIENT_SECRET`, `DINGTALK_ALLOW_FROM` |
| Discord | `DISCORD_ENABLED`, `DISCORD_BOT_TOKEN`, `DISCORD_ALLOW_FROM` |
| Telegram | `TELEGRAM_ENABLED`, `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOW_FROM` |
| Slack | `SLACK_ENABLED`, `SLACK_BOT_TOKEN`, `SLACK_APP_TOKEN`, `SLACK_SIGNING_SECRET`, `SLACK_ALLOW_FROM`, `SLACK_CHANNEL_DIRECT_ENABLED` |

Additional IM channels are env-only and do not appear in the console settings page:

| Channel | Variables |
| --- | --- |
| WhatsApp | `WHATSAPP_ENABLED`, `WHATSAPP_BRIDGE_URL`, `WHATSAPP_BRIDGE_TOKEN`, `WHATSAPP_ALLOW_FROM` |
| QQ | `QQ_ENABLED`, `QQ_APP_ID`, `QQ_APP_SECRET`, `QQ_TOKEN`, `QQ_SANDBOX`, `QQ_ALLOW_FROM` |
| Matrix | `MATRIX_ENABLED`, `MATRIX_HOMESERVER_URL`, `MATRIX_ACCESS_TOKEN`, `MATRIX_AUTOJOIN`, `MATRIX_ALLOW_FROM` |
| MoChat | `MOCHAT_ENABLED`, `MOCHAT_SERVER_URL`, `MOCHAT_TOKEN`, `MOCHAT_BOT_NAME`, `MOCHAT_ALLOW_FROM` |
| Email | `EMAIL_ENABLED`, `EMAIL_IMAP_HOST`, `EMAIL_IMAP_PORT`, `EMAIL_IMAP_USER`, `EMAIL_IMAP_PASSWORD`, `EMAIL_IMAP_TLS`, `EMAIL_SMTP_HOST`, `EMAIL_SMTP_PORT`, `EMAIL_SMTP_USER`, `EMAIL_SMTP_PASSWORD`, `EMAIL_SMTP_TLS`, `EMAIL_FROM_ADDRESS`, `EMAIL_POLL_INTERVAL_MS`, `EMAIL_ALLOW_FROM` |

See [IM Access](../../integrations/im.md) for platform-specific setup.

## Logging

| Variable | Notes |
| --- | --- |
| `LOG_LEVEL` | Log level. Supports `debug`, `info`, `warn`, and `error`. |
| `LOG_CONSOLE_ENABLED` | Whether to write logs to the console. |
| `LOG_FILE_ENABLED` | Whether to write logs to files. |
| `LOG_DIR` | Log directory. Relative paths resolve under the runtime home. |
| `LOG_MAX_SIZE_MB` | Maximum size of one log file. |
| `LOG_RETENTION_DAYS` | Log retention days. |
| `LOG_MAX_TOTAL_SIZE_MB` | Maximum total log file size. |
| `LOG_TIMEZONE` | File log timestamp timezone: `system` or `utc`. |

See [Logs](../logs.md) for logging usage.

## Tool Permissions

| Variable | Notes |
| --- | --- |
| `ENABLE_TOOL_EDITOR_MUTATIONS` | Seeds the tool editor save/delete permission. |
| `ENABLE_FILE_WRITE_TOOL` | Seeds the `write_file` tool permission. |
| `ENABLE_EXECUTE_COMMAND_TOOL` | Seeds the `execute_command` tool permission. |
| `ALLOWED_EXEC_COMMAND_PREFIXES` | Seeds allowed command prefixes. |

## A2A

| Variable | Notes |
| --- | --- |
| `A2A_ORG_ID` / `A2A_UNIT_ID` | Organization and unit identity used for A2A registration and discovery. Both default to `default`. |

See [A2A](../../usage/a2a.md) for A2A usage.
