10, Configuration

Configuration

Every config file and knob in the Aelix repo, the MCP connection, the permission gate, the desk sub-agents, and where secrets must never live.

Aelix has no settings UI and no database, its entire configuration is a handful of plain files you can read, diff, and edit. The operating contract, the broker connection, the permission gate, the desk roles, and the risk caps are all text on disk. That is the point: every safeguard is something you can audit, not a setting hidden behind a toggle.

This page is the reference for each file and every knob inside it. The rules themselves are covered in Guardrails; how the broker connection is wired is covered in MCP; and the first-time OAuth walkthrough lives in Installation & Setup. Here we focus on the files: what each one is for, what a faithful copy looks like, and what you should and should not change.

Repo config map

Seven files (or file groups) hold the whole configuration surface. Everything else in the repo is application code, the dashboard, the backtester, and helper tools.

FilePurpose
CLAUDE.mdThe Portfolio Manager's operating contract, scope, hard guardrails, prompt-injection defense, and process. See Guardrails.
.mcp.jsonThe project-scoped Robinhood Trading MCP server (host + transport). See MCP.
.claude/settings.jsonPermissions (allow / ask / deny), enabled MCP servers, and the session-start hook.
.claude/agents/*.mdThe desk sub-agents, one file per role, each with a least-privilege tool list. See The Desk Team.
strategies/*.mdRisk caps and entry/exit rules the Risk Manager enforces. See Strategies.
ui/public/desk-state.jsonThe live snapshot the PM writes after each run. Gitignored; a sanitized desk-state.example.json ships instead. See Dashboard.
logs/*.jsonlAppend-only audit trail of desk decisions. See Logging.

Personal "allow always" choices are written to .claude/settings.local.json, which is gitignored, your local approvals never leak into the shared repo.

The broker connection, .mcp.json

.mcp.json declares the one MCP server the desk talks to. It is a project-scoped file: the connection lives with the repo, not in your global Claude Code config, so anyone who opens this folder gets the same broker wiring.

.mcp.json
{
  "mcpServers": {
    "robinhood-trading": {
      "type": "http",
      "url": "https://agent.robinhood.com/mcp/trading"
    }
  }
}
robinhood-trading
The server name the permission rules and sub-agent tool lists reference (tools appear as mcp__robinhood-trading__<tool>).
type: http
A remote HTTP MCP transport, Claude Code connects out to Robinhood's hosted endpoint; nothing runs locally.
url
https://agent.robinhood.com/mcp/trading, the Robinhood Agentic Trading endpoint (US, equities, beta).

Permissions & hooks, .claude/settings.json

.claude/settings.json is the permission gate. It sorts every tool call into one of three buckets, allow, ask, or deny, and it also enables the MCP server and registers a session-start hook. This is the file that makes "human approval for every order" structural rather than a hope.

The permissions object holds three arrays. Below is a trimmed but faithful excerpt, the real file lists every read tool the desk uses; these are representative entries from each bucket.

.claude/settings.json (excerpt)
{
  "permissions": {
    "allow": [
      "mcp__robinhood-trading__get_portfolio",
      "mcp__robinhood-trading__get_equity_positions",
      "mcp__robinhood-trading__get_equity_quotes",
      "mcp__robinhood-trading__run_scan",
      "mcp__robinhood-trading__review_equity_order"
    ],
    "ask": [
      "mcp__robinhood-trading__place_equity_order",
      "mcp__robinhood-trading__cancel_equity_order",
      "mcp__robinhood-trading__create_watchlist"
    ],
    "deny": [
      "mcp__robinhood-trading__place_option_order",
      "mcp__robinhood-trading__cancel_option_order"
    ]
  },
  "enabledMcpjsonServers": ["robinhood-trading"],
  "defaultMode": "default"
}

Rules are evaluated `deny` → `ask` → `allow`, first match wins. A tool named in deny is blocked outright and cannot be re-enabled by an allow entry; a tool in ask pauses for your confirmation even if it would otherwise be allowed; only tools matched by allow run silently. Anything not matched by any list falls back to the default mode.

allow
Runs with no prompt. Reserved for read-only market and account reads (get_portfolio, get_equity_quotes, …), scans (run_scan), the preview-only review_equity_order, plus WebSearch, a few whitelisted WebFetch news domains, and a handful of git and Skill commands.
ask
Claude Code pauses and asks you in-session before the call. This is where every order lives: place_equity_order and cancel_equity_order, alongside scan- and watchlist-mutating tools.
deny
Blocked outright, no prompt, no override. Holds place_option_order and cancel_option_order, options aren't supported in this equities-only beta, so they are hard-denied.

enabledMcpjsonServers

enabledMcpjsonServers pre-lists robinhood-trading, so the project's .mcp.json server is enabled for the desk rather than prompting to enable it on every session. Trust is still established the first time you open the folder.

The SessionStart hook

A hooks.SessionStart entry runs a shell script when a session starts or resumes, the desk uses it to check whether today's left-side (pre-market) scan has run.

.claude/settings.json, hooks
"hooks": {
  "SessionStart": [
    {
      "matcher": "startup|resume",
      "hooks": [
        {
          "type": "command",
          "command": "bash .claude/hooks/left-side-scan-gate.sh",
          "timeout": 15,
          "statusMessage": "Checking daily left-side scan…"
        }
      ]
    }
  ]
}
matcher: startup|resume
Fires both when a fresh session starts and when an existing one resumes.
type: command
Runs a shell command; here bash .claude/hooks/left-side-scan-gate.sh.
timeout: 15
The hook is given 15 seconds before it is cut off.
statusMessage
The line shown while the hook runs, Checking daily left-side scan….

defaultMode is default: tools follow the rules above and Claude Code prompts for anything not pre-allowed, no auto-accept or bypass mode.

Sub-agent definitions, .claude/agents/*.md

Each desk role is one Markdown file in .claude/agents/. A YAML frontmatter block at the top defines the role's identity and, critically, its tool allowlist, the sub-agent can call nothing outside that list. The body is the role's system prompt. The full roster is on The Desk Team.

FieldWhat it does
nameThe handle the PM dispatches (e.g. fundamental-analyst).
descriptionTells the PM when to call this role, and states plainly that it does not decide trades or place orders.
toolsA comma-separated, least-privilege allowlist. The sub-agent physically cannot call anything not listed, analysts have no order tools at all.
modelWhich model backs the role: sonnet for the three analysts, opus for the Risk Manager.

Here is the actual frontmatter for the Fundamental Analyst, note the tool list is read-only market and earnings data plus Read, with no order or mutation tools anywhere in it.

.claude/agents/fundamental-analyst.md
---
name: fundamental-analyst
description: Equity fundamental analyst on the trading desk. Use to assess valuation, earnings quality, growth, and balance-sheet health for one or more tickers before a trade decision. Returns a structured fundamental verdict, it does NOT decide trades or place orders.
tools: Read, mcp__robinhood-trading__get_equity_fundamentals, mcp__robinhood-trading__get_earnings_calendar, mcp__robinhood-trading__get_earnings_results, mcp__robinhood-trading__get_equity_quotes, mcp__robinhood-trading__search
model: sonnet
---

The Risk Manager follows the same shape but is deliberately different: model: opus (the last gate before a human sees a trade deserves the stronger model) and a tool list of Read, Grep, and read-only account/portfolio/order tools, enough to check a proposal against strategies/, and nothing that could place, cancel, or preview an order.

Account number & secrets

Your Agentic account number is recorded outside version control: copy .env.example to .env and put the number there. .env is gitignored. No secret, token, or credential belongs in this repo, the OAuth token that authorizes trading is issued and held by the broker connection, never written to a tracked file.

The .gitignore encodes those boundaries so a stray secret can't be committed by accident:

.gitignore (protections)
# Claude Code local/personal overrides (where "allow always" writes rules)
.claude/settings.local.json

# OAuth tokens and credentials, must never be committed
.claude.json
*.token
*.key
*.pem
.env
.env.*

# Secrets
secrets/
credentials/

# Live desk snapshot written by the PM (contains real account state)
ui/public/desk-state.json

# Runtime control file: the dashboard "Run desk" button writes it; the PM's /loop reads it.
desk-request.json
Lives in the repo
CLAUDE.md, the operating contract
.mcp.json, the broker host + transport (no token)
.claude/settings.json, the permission gate
.claude/agents/*.md, the desk roles
strategies/*.md, risk caps + rules
ui/public/desk-state.example.json, sanitized demo data
Never in the repo
The Robinhood OAuth token / credentials
.env, your Agentic account number
.claude/settings.local.json, personal approvals
ui/public/desk-state.json, real live account state
Anything under secrets/ or credentials/
*.token, *.key, *.pem files

Tightening permissions

The tool names shipped in .claude/settings.json are the desk's best guess at the server's surface. Once you've connected and authenticated, you can see the real tool names the robinhood-trading server exposes and refine the rules to match, narrowing allow and confirming every order path stays gated.

01

See the real tool names

After OAuth, run /mcp in-session to list what the server actually exposes. Names may differ from the placeholders shipped here. Full walkthrough in Setup and MCP.

02

Keep every order behind a gate

Leave place_equity_order and cancel_equity_order in ask (or deny). Never move an order tool into allow, that would remove the human approval step the whole desk is built around.

03

Allow only read tools

Add read-only tools (quotes, fundamentals, positions, scans, review_equity_order) to allow to cut prompt noise. When you're unsure what a tool does, leave it out so it prompts by default.

04

Deny what you'll never use

Keep place_option_order and cancel_option_order in deny. Options aren't supported in this beta, so hard-denying them means a mistaken call fails closed instead of prompting.

deny → ask → allowProject-scoped MCPLeast-privilege sub-agentsSecrets stay out of gitRestart to reload agentsBeta · equities only

Illustrative reference only, not investment advice, no track record, and any numbers shown elsewhere in these docs are demo data. See Safety & Disclaimer.