Command Environment Requirements
Explain required command environment, files, and env-variable priority for all city command groups
Command Environment Requirements
This page answers one question: what environment each city command group needs to run correctly.
0) Top-level command boundary
Top-level command groups are:
city consolecity agentcity servicecity plugin
Commands like city chat, city task, city memory, city skill, city asr, and city tts are action commands under service/plugin systems, not top-level commands.
1) Environment by command group
| Command Group | Required Environment | Optional Environment | Notes |
|---|---|---|---|
city init | Writable ~/.downcity/ | None | Writes ~/.downcity/downcity.db (sensitive fields encrypted) |
city start/stop/restart/status | Writable ~/.downcity/console/ | None | Manages global console process and registry |
city console | Console is running; browser can reach UI port | --host, --port | Single UI instance can switch across multiple running agents |
city agent create | Writable target directory | None | Generates downcity.json, PROFILE.md, .downcity/ |
city agent start | Console is running; project has downcity.json + PROFILE.md | --host | Agent port is always allocated by console and then registered into console registry |
city agent restart/status/doctor | Target agent is registered in console registry | None | Operates through registry resolution, not arbitrary path only |
city config ... | Valid downcity.json exists under target path | --path | Reads/writes project config; does not call agent API |
city config alias | Writable ~/.zshrc or ~/.bashrc | `--shell zsh | bash` |
city service list/status | None | --json | Static console-level service catalog; does not resolve any agent |
city service start/stop/restart/command | Target agent is running; project is registered; project has downcity.json + PROFILE.md | --agent, --path, --host, --port | Advanced targeting form; prefer city <service> ... for daily usage |
city plugin list/status | None | --json | Static console-level plugin catalog; does not resolve any agent |
city plugin action ... | Project has downcity.json | --path | Advanced local execution form; prefer city <plugin> ... for daily usage |
city <service> <action> (e.g. city chat ...) | Target agent is running | --path, --host, --port | Forwarded through local IPC by default; explicit remote mode uses /api/services/command |
city <plugin> <action> (e.g. city asr ...) | Project has downcity.json | --path | Executes locally against the selected project |
Additional notes:
city service list/statusandcity plugin list/statusare static console catalog reads.- Local
city service start/stop/restart/command,city task,city chat, and similar runtime commands use local IPC by default instead of HTTP. - Local
city plugin actionandcity <plugin> <action>commands read the selected project and execute directly in the CLI process. - A call only enters remote HTTP mode when you explicitly pass
--hostor--port. - In remote HTTP mode, token resolution order is:
--token>DC_AUTH_TOKEN. sessionIdandchatKeyare execution context, not authentication tokens.
1.1) DC_AUTH_TOKEN
The most important rule first:
- For most users, you do not need to care about auth env vars for normal local
city ...usage.
That is because local calls now use IPC by default. These variables only matter when a call is explicitly made through remote HTTP.
| Variable | Primary Purpose | Who Sets It | Typical Use |
|---|---|---|---|
DC_AUTH_TOKEN | explicit user override for a CLI/API call | user, script, CI | you want this specific city ... invocation to authenticate as a specific token |
Recommended rule:
- When you explicitly make a remote HTTP call from your terminal, CI, or a script, prefer
--tokenorDC_AUTH_TOKEN - Do not treat
sessionIdorchatKeyas auth tokens; they only define execution context
Unified priority order
When a city ... invocation is explicitly using remote HTTP, the final auth resolution order is:
- explicit
--token DC_AUTH_TOKEN
That means:
--tokenalways overrides everything elseDC_AUTH_TOKENis the only env-level auth source used for remote HTTP- without either one, explicit remote HTTP calls fail with
Missing bearer token
Common mistakes
- Mistake 1: using
sessionIdas a token Not valid.sessionIdonly decides where execution belongs. - Mistake 2: assuming local
city taskorcity chatalways needs a token first Not true anymore. Normal local calls now use IPC and do not need a Bearer token. - Mistake 3: assuming agent shell/script subprocesses automatically inherit a usable token Not anymore. Generic subprocesses do not inherit Bearer tokens by default; if you intentionally call remote HTTP, pass a token explicitly.
- Mistake 4: treating local IPC commands and remote HTTP commands as the same auth model
They are different. Local defaults to IPC; only explicit remote HTTP uses
DC_AUTH_TOKEN.
How to read Missing bearer token
If an explicit remote HTTP call such as:
city service list --host 127.0.0.1 --port 5314city task create --host 127.0.0.1 --port 5314 ...
returns:
Missing bearer token
check in this order:
- did you pass
--token - is
DC_AUTH_TOKENset in the current shell - does this invocation actually need remote HTTP, or should it be using local IPC instead
2) Context env requirements for common commands
city chat ...
- If
--chat-keyis omitted, it triesDC_CTX_CHAT_KEY - If
--session-idis omitted, it first triesDC_SESSION_ID - In agent shell, these
DC_CTX_*variables are usually injected automatically
city task ...
- Task creation/run needs
sessionId - You can pass
--session-idexplicitly - Or first fallback to
DC_SESSION_ID - Local calls use IPC by default and do not need a Bearer token
- Only explicit remote HTTP calls resolve auth through
--token/DC_AUTH_TOKEN
Chat channel credentials
- The only path is binding
services.chat.channels.<channel>.channelAccountIdindowncity.json. - Real credentials (
botToken/appId/appSecret) are stored in global~/.downcity/downcity.db(channel_accounts). downcity.jsonand agent.envno longer carry these credentials.
3) city service target agent resolution order
For city service start/stop/restart/command:
- explicit
--agent <name>(highest priority) - if
--agentomitted and--pathis default., tryDC_AGENT_NAMEfirst - fallback to
--pathor default. - if default
.andDC_AGENT_PATHexists, resolve.to it first
Still must satisfy:
- resolved path is registered in console registry
- resolved path contains
downcity.jsonandPROFILE.md
4) Runtime transport and endpoint resolution (host/port)
Default rule:
- no
--host/--port: use local IPC --hostor--portprovided: use remote HTTP
Only after a command enters remote HTTP mode does the endpoint resolution below apply.
For agent API calls (service/plugin/action commands):
- explicit CLI args:
--host/--port - env vars:
DC_SERVER_HOST/PORT - env vars:
DC_CTX_SERVER_HOST/PORT - daemon meta args (
.downcity/.debug/downcity.daemon.json) - default:
127.0.0.1:5314
Normalization rule:
0.0.0.0and::are normalized to127.0.0.1
5) Variable injection sources
Injected after agent startup
DC_AGENT_PATHDC_AGENT_NAMEDC_SERVER_HOSTDC_SERVER_PORT
Injected into agent shell subprocess
DC_SESSION_IDDC_CTX_REQUEST_IDDC_CTX_SERVER_HOSTDC_CTX_SERVER_PORT
6) Recommended usage
For multi-agent workflows, prefer explicit target on advanced commands:
city service restart task --agent my-agent
# or
city service restart task --path /abs/path/to/agentFor catalog inspection, no target is required:
city service list
city plugin listExample Output (Based on Current Implementation)
The examples below are aligned with current command implementations in packages/downcity/src (including default output mode and field structure). Placeholder values are used for environment-specific fields.
$ city service list --json
{
"success": true,
"count": 4,
"services": []
}$ city chat send --text "hi"
{
"success": false,
"error": "Failed to parse command input: <error>"
}