vike

The daemon and the app

Three clients of one trading node — the desktop app in observe mode, the CLI's REPL and read verb, and the MCP server — what each is best at, and what strategy-status actually reads.

The thing that trades is vike-tradehub: a headless daemon on a server, run as a systemd unit, holding the live core, the venue mounts and the risk gate. It survives an SSH disconnect because it is not attached to your login session. Everything on this page is a client of that daemon, and none of them holds any authority the daemon does not grant.

That is the frame worth carrying into the rest of the platform: the node is the trading process; the app, the CLI and the agent surface are three ways of looking at it and asking it for things.

One node, three clients

clienthow it attachesbest at
vike-desktop --observe <addr>the node's observe server, plus local keyless venue feedswatching. Charts, the DOM ladder, positions and the trade panel over a remote daemon's account plane
vike-cli trade --node <addr>observe and control, from a terminalacting, over SSH, on a box with no display — and being able to paste exactly what you did into an incident write-up
vike-cli strategy-status --node <addr>observe only, one short-lived connectionanswering what is that daemon actually running? in one line of shell
vike-cli mcp --node <addr>observe and control, exposed as MCP toolshanding the same vocabulary to an agent, behind a preview gate

The desktop app's remote mode is worth a sentence of its own, because it is not simply "the app, read-only". vike-desktop's split-plane model divides its data in two: the account plane — orders, positions, equity, bar history — belongs to the backend and arrives as wire snapshots over the observe bridge, while the market-data plane — books, the trade tape, order-flow series — belongs to the venue and is subscribed directly and keylessly. In --observe mode on a full build you get a remote daemon's account plane beside local feeds, with no local core and no execution engines at all. Observe mode is that page.

Two scopes, two keys

Every one of those attachments authenticates, and the protocol has exactly two scopes. VIKE_TRADEHUB_OBSERVE_KEY opens a read connection; VIKE_TRADEHUB_CONTROL_KEY opens a write one. The node verifies each scope against its own key, so a control key cannot stand in for an observe key — which is why strategy-status, a read verb, asks specifically for the observe half and reports the observe-specific absent-key message rather than a vaguer "no key" line.

Both keys are resolved once, by the dispatcher, for the three node-facing verbs only:

process environment  →  <project>/settings/secrets.env  →  nothing

The second rung is the same store the daemon itself loads them from, which is the whole point: before it existed, a box configured exactly as the daemon documents answered nothing to do. The first rung wins because an export is ephemeral, narrow and deliberate — it is what makes "point at a different node for one command" possible — while the store is the box's standing configuration. crates/vike-cli/src/cmd/nodekeys.rs carries that argument, including why this is not the policy.toml case: a node key is a credential, not a risk limit, and presenting a different key cannot widen what an authenticated peer may do. The worst an exported key achieves is failing the handshake.

Which keys this box holds is answered by vike-cli secrets, by name and never by value.

What strategy-status reads

strategy-status is the shell-level answer to what is that daemon running? It opens one short-lived observe connection, sends one request, and prints what came back (crates/vike-cli/src/cmd/trade_status.rs). Three things:

node hub-a — paper — build vike-tradehub 0.1.0 (abc1234, clean)
params: spread=0.01 size=20

  STRATEGY      MODE   PARAMS
  spread_maker  paper  venue=polymarket symbol=TOK-A spread=0.01
  np            LIVE   venue=polymarket symbol=TOK-B edge=0.02

The identity line names the node and the build it is running, down to the commit and whether that tree was dirty — the same provenance every --version in the workspace answers, asked remotely. The effective-params line is what the daemon resolved, not what a file says. And then one row per mounted strategy, with its mode and its parameters.

The mode cell is uppercase exactly when it matters: LIVE shouts, paper is the quiet default. Column widths come from the data, headers included, so a long strategy name cannot shear the params column. --json prints the wire payload verbatim instead — a machine consumer gets the protocol's own schema rather than a second hand-maintained shape that could drift from it.

Until this verb existed the only way to ask that question from a shell was to compile a throwaway probe, which is a thing people did.

A node too old to answer is refused on this side

The verb is feature-negotiated: against a node whose handshake advertises no strategy-verbs capability, the client sends nothing after the handshake and refuses locally. That is deliberate — an older node's deserializer cannot decode the frame, so sending it would produce an opaque decode error at the node instead of a diagnosis here. The message names the missing capability and the one action that fixes it: upgrade that node.

Choosing between them

They overlap on purpose, and the useful question is not which is most powerful but what does this moment need.

Take the app when the question is visual and the answer is a shape — is this fill where the chart says it is, is the book thinning out, does this indicator behave the way it did in the backtest. Nothing at a terminal replaces looking at a chart.

Take the CLI when the answer has to survive being written down. A strategy-status --json in a cron job, a trade session pasted into an incident review with the --reason you typed on each line, a deploy script that refuses to start a unit — none of those have a GUI shape. It is also the only one of the three that works over an SSH connection to a box with no display, which describes most trading servers.

Take the agent surface when the loop is author, compile, backtest, adjust and you would rather describe the change than type it. It speaks the same write vocabulary as the REPL — the same construction site, the same client-order-id mint, the same guardrail — so a verb added to one is visibly missing from the other rather than silently absent.

Whichever you take, the node's own control limits and risk gate are the enforcing backstop, and the per-venue arming ceiling in policy.toml sits above even the credential read. A client can only ever ask. See the control boundary, risk and arming and the node protocol for what the daemon does with what it is asked.

On this page