Vizier - the decision-making brain of an agentic-trading stack. A Claude Code skill that researches, decides, remembers and orchestrates trades across US stocks/ETFs (IBKR) and crypto spot (CCXT), driving the Scout and Valet MCP servers it never modifies. Hybrid skill + deterministic safety core; paper-first.
FAQ
vizier-trading-skill is a Claude Code plugin with 1 hand-picked skill for automation work, indexed on Flowy. Install it with the command on its page. It includes vizier-trading-skill. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.
$ npx -y skills add pedrobraiti/vizier-trading-skill --agent claude-code
Repo: pedrobraiti/vizier-trading-skill
Not financial advice. Vizier is a research-and-orchestration tool, not a guarantee of returns. It is paper-first / shadow-mode by default: out of the box it journals decisions or trades against a paper account / exchange testnet. Real-money autonomy is the last rung of a deliberate ladder (shadow โ paper โ live read-only โ real money), gated behind a forward-test and a live read-only validation. Use at your own risk.
Vizier is the brain of a three-part split โ a single, natural-language-driven Claude Code skill
(/vizier) that turns a request like "research the market and make 3 investments totaling $100" into
researched, risk-checked, journaled trades. It is the one component that touches both MCP servers:
| Layer | Project | Role |
|---|---|---|
| Senses | Scout | Gathers & structures market data โ stateless, data-not-verdict, keyless (60+ tools). |
| Hands | Valet | Executes orders on IBKR (stocks/ETFs, 20 tools) and crypto exchanges (spot, CCXT, 16 tools). |
| Brain | Vizier (this repo) | Researches, decides, remembers, orchestrates. The only thing that touches both MCPs. |
The inviolable boundary. The MCPs are deliberately dumb (I/O without judgment). Vizier consumes them exactly as they are and never modifies, adds to, or plugs logic into them. All intelligence, glue, state and decision lives in the skill. No MCP calls another; no MCP concludes.
/analyze vs /invest. Behavior is read from intent:
an empty/vague call โ a read-only market sweep; "research MU" โ a thesis, no execution; "buy $3 of
AAPL" โ an order it just executes. It pauses to ask only on real ambiguity ("invest a little"), never
double-confirms the obvious, and treats "I think I should sell" as deliberation, not an order.core vs tactical tag so anti-churn applies correctly per horizon.ibkr server) and crypto spot (the crypto server), routed by
the asset; risk limits and NAV are kept strictly per-account / per-venue.Vizier is a hybrid: the judgment lives in the skill (SKILL.md + references/, loaded on demand),
while every money-sensitive calculation lives in a deterministic Python core the skill calls and reads
back as a {"ok": bool, "data": ...} envelope. Code does the math that must not be re-derived by an LLM
"in its head" between rounds โ that is exactly the forget-between-rounds failure the split prevents.
flowchart LR
U["User request<br/>(natural language)"] --> V["VIZIER skill<br/>(judgment, orchestration)"]
V -->|reads data| S["Scout MCP<br/>(senses)"]
V -->|money-math, state| C["Deterministic core<br/>python -m vizier"]
V -->|places orders| X["Valet MCP<br/>(hands: ibkr / crypto)"]
C --> M["Private memory<br/>theses ยท decision log ยท NAV"]
The reasoning runs as a fan-out of subagents, adapting depth to the request:
flowchart LR
A["Analysts (parallel)<br/>Fundamental ยท Technical ยท News ยท Macro"] --> BB["Bull x Bear<br/>debate"]
BB --> T["Trader<br/>proposes thesis + trade<br/>(horizon tag, conviction 1-5)"]
T --> DS["Data-sufficiency gate<br/>proceed | downsize | abstain"]
DS --> R["Risk gate + PM<br/>sizing within limits"]
R --> PM["Pre-mortem / red-team<br/>why is THIS trade, NOW, wrong?"]
PM --> E["Execute via Valet"]
Research mode stops at "Trader proposes"; execution mode continues through the gates to Valet, then journals the thesis and the fills.
MODE: PAPER ยท venue: ibkr
TL;DR โ Buy $60 NVDA (core) + $40 XLE (tactical); breaker clear, book has room in both.
By horizon
โข Long โ NVDA: datacenter capex still accelerating; quality metrics intact
โข Short โ NVDA: RSI 71, extended โ divergence flagged: scale-in, don't chase
Action
โข NVDA โ ibkr, BUY $60, market (liquid large-cap) [EXECUTED โ order id 1247]
โข XLE โ ibkr, BUY $40, limit 92.10 [EXECUTED โ order id 1248]
Conviction โ NVDA 4/5 (secular + earnings momentum) ยท XLE 3/5 (honest: a hedge, not a hero)
Scenarios + price target (NVDA)
โข Bear $95 ยท Base $128 (analyst consensus relay, n=42) ยท Bull $150
(crude multiple cross-check flagged as crude โ no independent valuation claimed)
Risks & caveats โ news feed may be incomplete for corporate events (8-K check run: clean);
data-sufficiency on XLE: thin positioning data โ annotated, amount honored
Pre-mortem โ buying an extended name near an earnings window (checked: 24 days out)
Post-trade portfolio โ NVDA 8.2% ยท XLE 5.5% ยท cash 22% ยท 6 positions
Sources โ SEC filings (as_of 2026-05-28), FRED, IBKR quotes 14:31 ET
The full format (mandatory MODE banner, per-name [RECOMMENDATION]/[EXECUTED] tags, honest-caveat
rules) is specified in references/output-template.md.
"Is this actually working?" is answered by a deterministic scorecard, not by vibes. The skill
feeds it current prices and a benchmark price history (SPY for equities, BTC/USDT for crypto) and the
core computes, over every thesis (open marked-to-market + closed on recorded outcomes):
days_held reported so a 3-day tactical and a 6-month
core are weighed by the reader โ no annualization (annualizing both into one number is nonsense).The honesty rules are the point: a thesis that can't be scored is named in skipped (never guessed),
an aggregate with no sample is null, not a fake zero, and a benchmark that doesn't cover the window
yields a null or annotated alpha with the reason attached. If the ideas are not beating the benchmark,
the scorecard says exactly that โ that verdict is what the paper-first ladder exists to produce.
The money-safety rules are not prose the model is asked to remember โ they are deterministic checks with
exact, self-latching arithmetic. A precise word on bindingness: these checks are advisory/bookkeeping
that bind when the skill calls them each candidate with an honest live NAV โ Vizier holds no order pipe of
its own, so the one hard, code-enforced dollar backstop is the Valet's MAX_DAILY_VALUE (enforced at
the executor no matter what the skill does), which is why arming autonomy is forbidden until it is set. The
dangerous mode (autonomy) is guarded by four composed legs plus a re-arm guard โ a backstop for the robot
running unattended, never a clamp on a human's confirmed explicit order:
/loops. A shrinking account never re-authorizes fresh slices โ this is the
drain fix (a per-round cap alone does not stop a loop from emptying the account).arm-autonomy refuses while a window is still active (re-arming would reset the
baseline and wipe the day's spend โ a drain vector); a legitimate re-arm requires an explicit disarm or
window expiry. No force-override.account_type before every order, re-check the circuit
breaker, reconcile against your own sent-order log โช broker positions (never lagged positions alone),
and run a mandatory data-sufficiency gate that downsizes or abstains when the evidence isn't there โ even
under an explicit order.The Valet's own per-order guards (MAX_ORDER_VALUE, MAX_DAILY_VALUE, DUPLICATE_WINDOW_SECONDS) are set
as an independent second line when arming. Live execution is venue-specific and gated; real-money
autonomy is the last rung:
shadow (journal / dry-run) -> paper / testnet -> live read-only -> real-money autonomy
First time? The three repos have a dependency order โ set them up in this sequence:
market-research-mcp.
Gives you research immediately, no accounts or keys.agentic-trading-mcp.
For stocks it needs the Interactive Brokers Client Portal Gateway running plus a manual 2FA login;
for crypto it needs exchange API keys. Skip this until you actually want to execute.Two facts that decide what works without each piece: a read-only market sweep ("what's happening in the market?") requires the Scout MCP registered โ without it the skill has no data tools and degrades to nothing useful; execution requires the Valet MCP registered. Research-only needs just Scout + Vizier.
Vizier has two pieces that both need to be in place: the skill (so /vizier is discoverable) and the
deterministic core (so the skill can call python -m vizier ...).
# 1. Clone
git clone https://github.com/pedrobraiti/vizier-trading-skill vizier && cd vizier
# 2. Install the deterministic core into the environment your agent uses.
# The `vizier` package MUST be importable for `python -m vizier` to work.
python -m venv .venv
# Windows (PowerShell): & ".venv\Scripts\Activate.ps1" (on a policy error: Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass)
# Linux/macOS: source .venv/bin/activate
pip install -e ".[dev]"
# 3. Make the skill discoverable by Claude Code at ~/.claude/skills/vizier
# Windows (junction, no admin needed):
cmd /c mklink /J "%USERPROFILE%\.claude\skills\vizier" "%CD%"
# Linux/macOS (symlink):
ln -s "$(pwd)" ~/.claude/skills/vizier
In a new Claude Code session the skill is available โ invoke it in natural language (the trigger is the intent, e.g. "research NVDA", "is my book healthy?", "buy $50 of BTC", "invest $100 across 3 ideas", or the breadth sweep "analyze the market and bring me recommendations" / "find the best opportunities"). For execution you also need the two MCP servers registered (Scout, Valet); for research-only the skill degrades gracefully.
To remove the deployed skill, delete the link: Windows
rmdir "%USERPROFILE%\.claude\skills\vizier"(removing the junction, not its target); Linux/macOSrm ~/.claude/skills/vizier.
The skill is global, so register Scout and Valet at user scope (-s user) โ that makes them reachable
from /vizier in any directory. The default claude mcp add is project-scoped, which silently limits a
server to one folder (a common gotcha: the skill "works here but not there"). Point each command at the
venv python from that repo's own README:
# Scout (research) โ one server
claude mcp add scout -s user -- "/path/to/market-research-mcp/.venv/bin/python" -m scout.server.app
# Valet (execution) โ two servers from the same repo
claude mcp add ibkr -s user -- "/path/to/agentic-trading/.venv/bin/python" -m ibkr_agent.server.app
claude mcp add crypto -s user -- "/path/to/agentic-trading/.venv/bin/python" -m crypto_agent.server.app
Open a new Claude Code session afterward so the servers are picked up (claude mcp list to confirm).
Research-only needs just Scout; execution also needs Valet (with its IBKR gateway / exchange keys). On
Windows use the .venv\Scripts\python.exe path instead of .venv/bin/python.
Breadth-discovery (manager mode) fans out research-only envoy subagents. By default that boundary is held by dispatch discipline (the envoy is given only Scout tools). For a hard firewall โ an envoy that cannot even see the execution tools โ install the bundled agent type so the envoys are spawned with the Valet servers withheld:
# copy the agent type into your user agents dir (active next session)
mkdir -p ~/.claude/agents && cp agents/vizier-research-envoy.md ~/.claude/agents/
The agent's frontmatter is a default-deny tools: allowlist (Read, Grep, Glob, mcp__scout): the
envoy holds ONLY the Scout research server plus read tools and can never see an execution tool โ no
Valet re-registration or new tool can leak in. If you registered Scout under a different server name,
substitute it there (see the maintainer note inside the file). Without this agent installed, the soft
dispatch boundary still applies and only the main thread ever executes.
Every money-sensitive helper is a subcommand; args go in --json, the result comes back as {ok, data}:
python -m vizier profile # show the active risk profile
python -m vizier allocate --json '{"total_amount":100,"nav":10000,"explicit_order":true,"candidates":[{"ticker":"AAA","conviction":5},{"ticker":"BBB","conviction":3}]}'
python -m vizier autonomy-gate --json '{"candidate_value":200,"current_nav":990}' # composed ยงB verdict
python -m vizier trim-qty --json '{"current_qty":2.0,"pct":30,"step":0.001}' # %/$ -> sell qty, rounds down
python -m vizier exit-qty --json '{"position_qty":0.0063,"filled_quantity":2.0,"is_cash_quantity":true}' # stop/exit qty, capped at the holding
Units are never implicit. qty/quantity/position_qty = shares or crypto base units;
cash_amount/cash_qty/filled_cash = USD. Every exit (protective stop, sell, trim) is sized from
the venue's positions through exit-qty, which cannot return more than you hold โ because IBKR
reports a cash-quantity (US$) order's fill in dollars: a real buy(AAPL, cash_amount=2) came back as
filled_quantity = 2.0 for a position of 0.0063 shares, and a stop sized off that number would have
been a naked short. (Crypto/CCXT reports base units correctly; the hazard is IBKR-specific, the
positions-first rule is universal.)
Risk posture is one editable file โ config/risk_profile.yaml: flip active_profile
(conservative | moderate | aggressive) or tweak a single number. Every limit is a percent of NAV, so it
works the same on a $100 account or a $100k one.
Environment overrides. Two optional env vars relocate the core's inputs without passing flags every
call: VIZIER_PROFILE_PATH (the risk-profile YAML, same as --profile-path) and VIZIER_MEMORY_DIR
(the private memory/ dir, same as --memory-dir). Vizier holds no secrets, so there's nothing to put
in a .env.
Vizier remembers what the stateless Scout and point-in-time Valet cannot โ why you bought, the entry date, the horizon, the quantitative baseline to diff against. That state is private:
memory/theses/*.yaml), the decision log,
NAV snapshots and autonomy state are written under memory/ and never committed โ only EXAMPLE_*
templates and .gitkeep are. This mirrors how the MCPs gitignore their .env.--commit).pytest -q # 153 offline tests (deterministic, no network, no real git)
ruff check . # lint
The core is pure, deterministic functions (injectable clock and memory dir) so the money-safety guarantees are tested in isolation โ including the adversarial ยงB scenarios (loop drain, re-arm drain, drawdown kill, double-buy lag, data-starvation).
MIT โ see LICENSE.
.editorconfig
.gitattributes
.github/
dependabot.yml
workflows/
ci.yml
.gitignore
agents/
vizier-research-envoy.md
CHANGELOG.md
CLAUDE.md
config/
risk_profile.yaml
CONTRIBUTING.md
LICENSE
memory/
EXAMPLE_decision_log.jsonl
README.md
theses/
.gitkeep
EXAMPLE_thesis.yaml
pyproject.toml
README.md
references/
anchor-example.md
autonomy-and-safety.md
execution-mechanics.md
output-template.md
pipeline.md
SECURITY.md
SKILL.md
tests/
conftest.py
test_autonomy.py
test_cli.py
test_config.py
test_data_sufficiency.py
test_memory.py
test_reconcile.py
test_risk.py
test_scorecard.py
vizier/
__init__.py
__main__.py
autonomy.py
cli.py
constants.py
data_sufficiency.py
memory.py
reconcile.py
risk.py
scorecard.pyยฉ 2026 Flowy ยท Free and open source
Built for Claude Code ยท Not affiliated with Anthropic