Configuration reference
Complete reference for every key in desk.toml — workspace settings, account options, guards, data sources, agent behaviour, and schedules.
desk.toml is the single configuration file for a Qoc workspace — it controls everything from the service port and risk guards to which data sources the agent queries and how scheduled runs behave.
File location and format
desk.toml lives at the root of your workspace directory, alongside the entities/, orders/, and research/ directories. It is a standard TOML file — human-readable, comment-friendly, and safe to commit to version control (exclude any secrets by using environment-variable references instead of literal values).
Run qoc init to generate a starter file with sensible defaults. Use qoc status to validate the current file — it reports any missing required keys or type mismatches.
Reference environment variables
Any string value in desk.toml can reference an environment variable using the syntax env:VAR_NAME. For example, api_key = "env:QOC_BROKER_KEY" reads the key from the shell environment at startup, so secrets never touch the file.
[workspace] section
| Key | Type | Default | Description |
|---|---|---|---|
| name | string | "my-desk" | Human-readable name shown in qoc status and the dashboard. |
| port | integer | 7070 | TCP port the local MCP and REST service binds to. |
| log_level | string | "info" | Log verbosity. One of error, warn, info, debug, trace. |
| log_dir | string | "~/.qoc/logs" | Directory where service log files are written. |
| history_enabled | boolean | true | When true, the workspace tracks file history using built-in versioning. |
| history_max_snapshots | integer | 90 | Number of daily snapshots to retain before pruning the oldest. |
| timezone | string | "America/New_York" | IANA timezone used for schedule expressions and market-hours guards. |
[account] section
| Key | Type | Default | Description |
|---|---|---|---|
| currency | string | "USD" | Base currency of the Unified Trading Account. |
| nav_method | string | "last_snapshot" | How NAV is computed for guard percentage calculations. Options: last_snapshot, live. |
| margin_enabled | boolean | false | Allow margin usage across connected venues when true. |
| day_trade_mode | string | "pattern_check" | Controls pattern-day-trader checks. Options: off, pattern_check, block. |
[guards] section
| Key | Type | Default | Description |
|---|---|---|---|
| max_order_nav_pct | float | 0.02 | Maximum single-order size as a fraction of NAV (0.02 = 2%). |
| max_position_nav_pct | float | 0.10 | Maximum total position size in any single symbol as a fraction of NAV. |
| day_loss_limit_pct | float | 0.05 | Halt new orders if realised + unrealised day loss exceeds this fraction of NAV. |
| allow_symbols | string[] | [] | If non-empty, only symbols in this list can be traded. An empty list means no allowlist filter. |
| deny_symbols | string[] | [] | Symbols that can never be traded, regardless of any other setting. |
| market_hours_only | boolean | true | When true, block orders outside regular market hours for the asset class. |
| require_approval | boolean | true | When true (the default), every proposal must be explicitly approved before routing. Set to false only for fully automated schedules where you have reviewed the guard parameters carefully. |
| max_open_proposals | integer | 5 | Maximum number of unapproved proposals allowed at once before the agent pauses new proposal generation. |
[data] section
| Key | Type | Default | Description |
|---|---|---|---|
| quote_source | string | "hub" | Quote feed source. hub uses the built-in Data Hub aggregator; venue uses the primary connected venue's feed directly. |
| fundamentals_enabled | boolean | true | Pull earnings, revenue, and ratio data into entity files. |
| news_enabled | boolean | true | Fetch news and RSS feeds for tracked entities. |
| news_max_age_hours | integer | 48 | Discard news items older than this many hours when updating entity files. |
| technicals_enabled | boolean | true | Compute and store technical indicators (RSI, MACD, Bollinger Bands) in entity files. |
| technicals_lookback_days | integer | 90 | Number of calendar days of price history used for technical calculations. |
| entity_refresh_cron | string | "0 7 * * 1-5" | Cron expression (workspace timezone) for automatic entity data refresh. Defaults to weekdays at 07:00. |
[agent] section
| Key | Type | Default | Description |
|---|---|---|---|
| mcp_host | string | "127.0.0.1" | Host the MCP server listens on. Change to 0.0.0.0 only if the agent runs on a separate host. |
| mcp_port | integer | 7070 | Port the MCP server listens on. Must match port in [workspace] unless running with a reverse proxy. |
| max_concurrent_tasks | integer | 1 | Maximum number of agent tasks allowed to run in parallel. Increase only if you have validated your guards handle concurrent proposals correctly. |
| task_timeout_minutes | integer | 30 | Agent tasks that exceed this duration are cancelled and an error is written to the task's issue file. |
| research_depth | string | "standard" | Controls how many data sources the agent queries per entity. Options: quick, standard, deep. |
| write_research_files | boolean | true | When true, the agent writes a markdown thesis file to research/ for every completed task. |
[schedule] section
| Key | Type | Default | Description |
|---|---|---|---|
| enabled | boolean | false | Enable scheduled runs defined in schedules/. When false, schedules are parsed but not executed. |
| max_runs_per_day | integer | 10 | Hard ceiling on total scheduled executions per calendar day regardless of individual schedule frequency. |
| run_log_dir | string | "schedules/.logs" | Directory where per-run logs are written for scheduled tasks. |
| notify_on_complete | boolean | false | Write a completion notice to inbox/ after each scheduled run finishes. |
| notify_on_error | boolean | true | Write an error notice to inbox/ if a scheduled run fails or times out. |
Complete desk.toml example
# desk.toml — Qoc workspace configuration
# Generated by qoc init, edited for production use.
[workspace]
name = "main-desk"
port = 7070
log_level = "info"
log_dir = "~/.qoc/logs"
history_enabled = true
history_max_snapshots = 90
timezone = "America/Chicago"
[account]
currency = "USD"
nav_method = "live"
margin_enabled = false
day_trade_mode = "pattern_check"
[guards]
max_order_nav_pct = 0.02 # 2% of NAV per order
max_position_nav_pct = 0.08 # 8% of NAV per symbol
day_loss_limit_pct = 0.03 # halt at -3% day loss
allow_symbols = [] # empty = no allowlist filter
deny_symbols = ["GME", "AMC"]
market_hours_only = true
require_approval = true
max_open_proposals = 3
[data]
quote_source = "hub"
fundamentals_enabled = true
news_enabled = true
news_max_age_hours = 24
technicals_enabled = true
technicals_lookback_days = 60
entity_refresh_cron = "0 7 * * 1-5"
[agent]
mcp_host = "127.0.0.1"
mcp_port = 7070
max_concurrent_tasks = 1
task_timeout_minutes = 20
research_depth = "standard"
write_research_files = true
[schedule]
enabled = true
max_runs_per_day = 6
run_log_dir = "schedules/.logs"
notify_on_complete = false
notify_on_error = true
# Connector blocks are written by `qoc connect <venue>`
# and should not be edited by hand unless you know the connector schema.
# Example (do not copy verbatim — run `qoc connect` to generate):
#
# [connector.paper]
# venue_type = "equities"
# mode = "paper"require_approval = false is irreversible per run
Setting require_approval = false allows the desk to route orders without a human review step. Once an order is sent to a live venue it cannot be unsent. Only disable approval for fully automated schedules where you have explicitly verified that your guard configuration — including max_order_nav_pct, day_loss_limit_pct, and deny_symbols — prevents any outcome you are not willing to accept.
Connector blocks
Connector configuration blocks ([connector.<name>]) are appended to desk.toml by qoc connect <venue>. Each connector block contains the venue type, credentials (referenced via env: variables), and venue-specific settings such as account IDs or sub-account routing.
Do not edit connector blocks by hand unless you understand the connector's TOML schema — an invalid block causes qoc up to refuse to start. If a connector block becomes corrupted, remove it and re-run qoc connect to regenerate it.
Validation and troubleshooting
- Run
qoc statusafter every edit to validate the file — it prints the first error it finds and the offending key. - TOML is whitespace-tolerant but key names are case-sensitive —
Log_Levelis not the same aslog_level. - Float values for guard percentages must be written as decimals (
0.02), not percentages (2%). - Cron expressions in
entity_refresh_cronand schedule files use five-field standard cron syntax evaluated in thetimezoneset in[workspace]. - If
qoc upexits immediately after a config change, check~/.qoc/logs/service.logfor a parse error with a line number.