@battlegrid/mcp-server 31.2.64 → 31.2.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,8 +22,8 @@ step named beside it before doing anything else.
22
22
  verb that changes what the agent may do.* Every one of these has a reach the player cannot see
23
23
  from the verb: open positions that keep running, deployments that stop firing, materialized
24
24
  configuration that is replaced. State the reach from the reads BEFORE the confirm form. And a
25
- configuration change to an agent the player is mid-edit on is staged, not committed. → steps 3
26
- and 4.
25
+ configuration change is staged into the agent's draft and committed only on the player's
26
+ explicit pick. → steps 3 and 4.
27
27
  3. **Mis-lever'd halt recovery.** *Cue: "why is it stopped", "start it again", any halted agent.*
28
28
  The halt reason says why the agent stopped, not what clears it. Offering an exit the server's
29
29
  resume verdict does not offer is offering something that cannot work. → step 5.
@@ -33,16 +33,17 @@ step named beside it before doing anything else.
33
33
 
34
34
  ## Cross-skill rule: strategy changes are not yours
35
35
 
36
- `list_strategies` and `get_strategy` are yours — the binding lookup is part of commissioning.
37
- `compile_strategy_plan`, `apply_strategy_plan`, `fork_strategy`, `archive_strategy`,
38
- `restore_strategy` and `update_strategy_signal_rule` are **not**, even though activating this
39
- skill makes them visible in the conversation.
36
+ `list_strategies` and `get_strategy` are yours — the binding lookup is part of commissioning, and
37
+ which strategy an agent is bound to is the agent's own STRATEGY_BINDING axis (step 4).
38
+ `stage_strategy_draft`, `commit_strategy_draft`, `discard_strategy_draft`, `fork_strategy`,
39
+ `archive_strategy` and `restore_strategy` are **not**, even though activating this skill makes them
40
+ visible in the conversation.
40
41
 
41
42
  When the work is a strategy change, activate `strategy-authoring` and let its arc run — its
42
- evidence, spec-lock, compile-review and confirm rules bind from that point. Do not drive a
43
- strategy write from this arc's own steps. (Visibility is not authority: those tools keep their own
44
- server gates — plan token, schema confirm, ownership — and this rule is about which arc's
45
- discipline governs the change, not about what the server would accept.)
43
+ evidence, spec-lock, stage-review and confirm rules bind from that point. Do not drive a strategy
44
+ write from this arc's own steps. (Visibility is not authority: those tools keep their own server
45
+ fences — the draft version, the revision, ownership — and this rule is about which arc's discipline
46
+ governs the change, not about what the server would accept.)
46
47
 
47
48
  ## Sequence
48
49
 
@@ -53,8 +54,8 @@ discipline governs the change, not about what the server would accept.)
53
54
  currently-available models; a model you remember from another agent may be deprecated, which
54
55
  keeps serving agents already bound to it while refusing a new selection. Never name a model
55
56
  from memory. **Send the row's `modelId`** — the `provider/name` string, e.g. `z-ai/glm-5.3` —
56
- never its `id`. The `id` UUID identifies the catalogue row; `create_intelligence_agent` and
57
- `update_intelligence_agent` key on `modelId` and accept nothing else.
57
+ never its `id`. The `id` UUID identifies the catalogue row; the draft's MODEL axis,
58
+ `{ modelId }`, keys on `modelId` and accepts nothing else.
58
59
  - `list_strategies` — the binding candidates.
59
60
  - `list_agent_drafts` — what the player is already part-way through. **Mention an existing draft
60
61
  before starting new work** — "you have an unsaved <agent / new agent>, last touched from
@@ -63,7 +64,7 @@ discipline governs the change, not about what the server would accept.)
63
64
  Read each thing once. A roster or agent you already fetched in this conversation is still in front
64
65
  of you; re-fetching costs the player the same payload twice and it rides every later step.
65
66
 
66
- ### 2. Commission: interview, restate, confirm, create
67
+ ### 2. Commission: interview, restate, draft, confirm, commit
67
68
 
68
69
  **No strategy, no agent.** If the player has no committed strategy they could bind, say so and
69
70
  offer the `strategy-authoring` arc first. Do not fabricate a binding, do not pick one on their
@@ -74,23 +75,29 @@ One interview with the player covering: **mandate** (what is this agent for), **
74
75
  scores and the strategy's own description, as the tools returned them.
75
76
 
76
77
  When the picks come back, restate in one line: *"Commissioning: <name>, bound to <strategy>, on
77
- <model>, <risk posture>."* Then one confirmation naming **the strategy, the model, and the
78
- budget posture** — the capital ceiling and stops the trading configuration will carry, or that it
79
- will take platform defaults.
78
+ <model>, <risk posture>."*
80
79
 
81
80
  **Build it in a create draft.** As the picks come back, stage them with `stage_agent_draft` —
82
- omit `agentId` and send `draftVersion: 0` on the first call, then reuse the id and the `version` it
83
- returns — each axis WHOLE: IDENTITY
84
- `{ displayName }`, BEHAVIOR `{ behavior: { risk, outlook, conviction } }`, MODEL `{ modelId }`,
85
- TRADING_CONFIG with every agent-owned field, and STRATEGY_BINDING `{ strategyId }`. The build then
86
- survives a refresh, lists in the Agents Hub as *not yet created*, and opens on the create screen,
87
- where **the player's Save creates it**. Staging creates nothing and spends no slot.
88
-
89
- Call `create_intelligence_agent` yourself only when the player asks you to create it from this
90
- conversation — on a surface with no create screen to save from — with an **`idempotencyKey`**
91
- derived from this conversation and this confirm turn. A create spends an agent slot against the player's rank quota; a retry after a
92
- dropped response would spend a second one. With the key, an ambiguous retry replays the original
93
- result instead.
81
+ omit `agentId` and send `draftVersion: 0` on the first call, then reuse the id it mints and the
82
+ `version` it returns — each axis WHOLE: IDENTITY `{ displayName }`, BEHAVIOR
83
+ `{ behavior: { risk, outlook, conviction } }`, MODEL `{ modelId }` and STRATEGY_BINDING
84
+ `{ strategyId }`, all four required to create, plus TRADING_CONFIG with every agent-owned field —
85
+ or no TRADING_CONFIG at all, to take the platform seed. The build then survives a refresh, lists in
86
+ the Agents Hub as *not yet created*, and opens on the create screen, where **the player's own
87
+ Create creates it**. Staging creates nothing and spends no slot.
88
+
89
+ **Then read it, confirm it, and commit it.** `get_agent_draft` serves the draft, its
90
+ `draftVersion`, a `committedRevision` of `null` and the diagnostics: a missing or invalid axis is
91
+ an error there, named, before anything is spent. A create draft has no impact. Then one
92
+ confirmation naming **the strategy, the model, and the budget posture** — the capital ceiling and
93
+ stops the trading configuration will carry, or that it will take the platform seed — and on the
94
+ player's explicit pick call `commit_agent_draft` with the `agentId`, that read's `draftVersion` and
95
+ `expectedRevision: null`. Where the player has the create screen open, their own Create is the
96
+ other way to commit it.
97
+
98
+ A create spends an agent slot against the player's rank quota, decided by the commit itself: a
99
+ full quota is refused there, with the draft unchanged. A retry of the same draft version after a
100
+ dropped response replays the original receipt, so an ambiguous retry never spends a second slot.
94
101
 
95
102
  **When the mandate names the arena, read `get_account_state` in the same breath.** The arena needs
96
103
  Agent Wagers: `mcpWagerEnabled: false` means every entry will be refused at the fee, so say the
@@ -100,39 +107,48 @@ Profile → Wallet tab path instead, because no control renders there. **Create
100
107
  way**: the consent gates entering a game, never commissioning one. A `true` flag is consent alone
101
108
  and not readiness — the pipeline's own refusal at the fee is the authority.
102
109
 
103
- ### 3. Stage, review, commit — never commit around an open draft
110
+ ### 3. Stage, read, confirm, commit — every change goes through the draft
104
111
 
105
112
  Before proposing any change to an existing agent, `get_agent_draft`. **A draft means the player is
106
- mid-edit in their form.** Then:
107
-
108
- - **Stage** the change with `stage_agent_draft`, naming as `draftVersion` the `version` the read you
109
- proposed against returned (0 when `get_agent_draft` returned null): it lands in their open form,
110
- labelled as yours, and **their Save commits it** together with their own edits.
111
- `update_intelligence_agent` and `rebind_intelligence_agent` are REFUSED while the draft exists —
112
- that refusal is the server's, so do not retry them.
113
- - A staging call **refused naming an axis** means the player changed it after the version you name:
114
- read again and propose against what they now have — never re-send the same values. A call refused
115
- because that version is one the draft never reached means the draft you read is gone: read again.
116
- Never raise the number to get past either refusal.
117
- - **Rebinding is never staged.** While a draft is open, ask the player to save or discard it first.
118
- - `discard_agent_draft` only on the player's word: call it with `confirm:false` first, tell them
119
- when the draft was last written and from which surface, ask, then confirm.
113
+ mid-edit in their form**, and every change you make joins it. Then:
114
+
115
+ - **Stage** the change with `stage_agent_draft`, naming as `draftVersion` the `draftVersion` the
116
+ read you proposed against returned (0 when it found no draft): it lands in their open form,
117
+ labelled as yours. Each axis you send is written WHOLE — BEHAVIOR carries all three of risk,
118
+ outlook and conviction, TRADING_CONFIG the complete configuration (step 6) — and the axes you
119
+ omit keep their values.
120
+ - **Read the stage's diagnostics.** Its `errors` are the refusals the commit would raise, each
121
+ naming its field: fix the axis and stage again before you ask for anything.
122
+ - A staging call refused **`DRAFT_AXIS_CONTESTED`** names an axis the player changed after the
123
+ version you named: read again and propose against what they now have — never re-send the same
124
+ values. One refused **`DRAFT_VERSION_MOVED`** names a version the draft never reached, or a draft
125
+ that is gone: read again. Never raise the number to get past either refusal.
126
+ - **Commit** through step 4: read the draft with `get_agent_draft`, state the radius from its diff
127
+ and impact, confirm, and on the player's explicit pick call `commit_agent_draft` with the
128
+ `agentId` and exactly the `draftVersion` and, as `expectedRevision`, the `committedRevision` that
129
+ read returned. The commit publishes every axis the draft holds — the player's own unsaved edits
130
+ included — so the confirmation reads out the whole diff, not only your proposal. Where their form
131
+ is open, their own Save is the other way to commit it.
132
+ - **Discard** only on the player's word. `get_agent_draft` is the read of what a discard destroys:
133
+ tell them what the draft holds, when it was last written and from which surface, ask, and call
134
+ `discard_agent_draft` with the `agentId` and the `draftVersion` you read. There is no dry run and
135
+ no confirmation parameter: a draft written since your read is refused with `DRAFT_VERSION_MOVED`
136
+ and nothing is removed — read again and show them.
120
137
 
121
138
  **In a conversation the agent console hosts** — your context names the agent console and an agent
122
139
  id — the player's form is open on that agent whether or not a draft exists yet. Stage every change
123
140
  into that agent's draft, naming that id as `agentId`, create or edit alike: the create recipe's
124
141
  omitted id does not apply there, because the screen already holds the id the agent will be created
125
- at. Create, update, rebind and discard are refused there — the player's own Create, Save or Discard
126
- is the act. On an existing agent a strategy change is a recommendation the player picks in the
127
- Strategy step. An axis their form rewrote after your proposal — typed over or undone — is their
128
- answer: propose it again only on their word.
129
-
130
- With **no draft open**, the update verb below stands, confirm and all — outside the agent console.
142
+ at. Their own Create or Save commits it; commit it yourself only when they explicitly confirm
143
+ through `ask_user`. On an existing agent a strategy change is staged into the draft's
144
+ STRATEGY_BINDING like any other axis, and lands in their Strategy step as a proposed binding. An
145
+ axis their form rewrote after your proposal — typed over or undone — is their answer: propose it
146
+ again only on their word.
131
147
 
132
148
  ### 4. Lifecycle verbs: read first, state the radius, then confirm
133
149
 
134
- Every one of update, rebind, halt, resume, activate and archive runs this shape. The reads
135
- (`get_agent_budget`, `get_agent_fund_allocation`, `get_agent_open_positions`,
150
+ Every one of a draft commit (an edit or a rebind), halt, resume, activate and archive runs this
151
+ shape. The reads (`get_agent_budget`, `get_agent_fund_allocation`, `get_agent_open_positions`,
136
152
  `get_agent_automation_status`, `get_agent_performance`, `get_agent_journal`) need no confirm and
137
153
  cost nothing but a call — do them first, always.
138
154
 
@@ -140,20 +156,32 @@ State the blast radius **from server fields, as numbers**, before the confirm fo
140
156
 
141
157
  - **Halt** — the open-position count (they keep running; halting opens no exit) and the deployment
142
158
  coverage that stops producing entries.
143
- - **Archive** — the same, plus that the agent stops entering games and signal evaluations, and
144
- that `activate_intelligence_agent` reverses it.
145
- - **Rebind** — that the target strategy's context modules, signal rules, prose and timeframe
146
- **replace** the ones materialized on the agent (this is not a merge), naming both strategies.
147
- Agent-owned settings are untouched.
148
- - **Update** — the concrete diff: each field, from what, to what.
159
+ - **Archive** — the same, plus that the agent stops entering games and signal evaluations, that
160
+ `activate_intelligence_agent` reverses it, and that the player's draft of it is kept.
161
+ - **Rebind** — a strategy change is the draft's STRATEGY_BINDING axis: stage `{ strategyId }`, read
162
+ `get_agent_draft`, and take both strategies from its `impact.rebind` — the strategy it replaces
163
+ (`fromStrategyName`) and the one it binds (`toStrategyName`, at `toStrategyRevision`). Say that
164
+ the target strategy's context modules, signal rules, prose and timeframe **replace** the ones
165
+ materialized on the agent (this is not a merge), naming both strategies. Agent-owned settings are
166
+ untouched. The commit checks the new strategy against the coins the radar acts on for this agent;
167
+ a refusal names the coin and the condition — surface it, never retry it unchanged.
168
+ - **Any other draft commit** — the concrete diff from the read: each field, from what, to what. And
169
+ the read's `impact`: the presets it is deployed to (`deployedPresetCount`), its open positions,
170
+ the coins its radar is armed on (`radarArmedCoinCount`), and the capital reading — its smallest
171
+ order (`smallestOrderUsd`) against the order floor (`orderFloorUsd`). `feasible: false` means the
172
+ agent could not place an order at those limits; say so before the form.
149
173
 
150
174
  Then one confirmation. Act only on an explicit pick — one of the options you offered. Free text
151
175
  while a confirmation is open is not consent, whether it arrives in chat or in the form's own
152
176
  answer-in-your-own-words box — answer what they said and re-present the same confirmation.
153
177
 
154
- **`expectedRevision` comes from the latest read.** A CONFLICT means the stored agent moved since
155
- you read it: re-read, re-state the radius against the NEW state, and re-confirm. Never retry with a
156
- bumped number — that is voting on a state you have not seen.
178
+ **The numbers a write names come from the latest read** — a commit's `draftVersion` and
179
+ `expectedRevision`, an archive's or activation's `expectedRevision`. A `CONFLICT` means the stored
180
+ agent moved since you read it, and a commit refused `DRAFT_VERSION_MOVED` means the draft did — the
181
+ player's form saved an edit, or another surface staged. Both carry `nextAct: get_draft`: re-read,
182
+ re-state the radius against the NEW state, and re-confirm. Never retry with a bumped number — that
183
+ is voting on a state you have not seen. A commit refused with `nextAct: stage` names the field the
184
+ diagnostics named: fix it in a stage, read, and confirm again.
157
185
 
158
186
  **A refused archive names its own blockers.** The refusal carries typed `archiveBlockers[]` —
159
187
  DEPLOYED / OPEN_TRADES / ACTIVE_SESSION, each with a count. Report each blocker and its count as
@@ -172,8 +200,10 @@ server's resume verdict. **The verdict decides the recovery**; the reason only e
172
200
  `resume_intelligence_agent`.
173
201
  - **`eligible: false`** — `breachedStop` names the stop still breached, with `breachingFigureUsd`
174
202
  against `limitUsd`. Present that stop and exactly the exits the verdict marks open:
175
- - `canRaiseTriggeringStop` — raise that stop above the figure through the update verb
176
- (`maxCumulativeDrawdownUsd` for the drawdown stop, `maxDailyLossUsd` for the daily loss limit);
203
+ - `canRaiseTriggeringStop` — raise that stop above the figure through the agent's draft (step 6:
204
+ `maxCumulativeDrawdownUsd` for the drawdown stop, `maxDailyLossUsd` for the daily loss limit).
205
+ The commit's receipt carries the new `haltResumeEligibility` when it moved a stop the resume
206
+ reads;
177
207
  - `canResetBaseline` — `reset_agent_drawdown_baseline`, which acknowledges the loss and re-arms
178
208
  the drawdown stop from today (it erases no history and journals the acknowledgement);
179
209
  - a `breachedStop` of `DAILY_LOSS` also clears at the UTC-day rollover.
@@ -191,13 +221,15 @@ read the verdict again rather than assuming it cleared.
191
221
 
192
222
  ### 6. Risk limits are a whole object
193
223
 
194
- `update_intelligence_agent`'s `tradingConfig` is a **complete** configuration: what you send
195
- replaces what is stored, and every field in that schema is required when the object is present.
224
+ The draft's TRADING_CONFIG axis is `{ tradingConfig }`, a **complete** configuration: what you
225
+ stage replaces the drafted one whole, and every agent-owned field is required in it.
196
226
 
197
- So: **read the current configuration, write the complete object with your change applied**, and
198
- name **every changed value** in the confirm — from what, to what. Never assemble a partial config
199
- and never echo a read config back unchanged: the read shape is wider than the write shape
200
- (`strategyTimeframe` and `regimeTimeframe` are strategy-derived and rejected as unknown keys).
227
+ So: **read the current configuration — the draft's TRADING_CONFIG when it holds one, otherwise the
228
+ agent's — and stage the complete object with your change applied**, then name **every changed
229
+ value** in the confirm, from what to what, as the draft read's diff serves it. Never assemble a
230
+ partial config and never echo a read config back unchanged: the agent's read shape is wider than
231
+ the axis (`strategyTimeframe` and `regimeTimeframe` are strategy-derived and refused as unknown
232
+ keys). The commit holds the configuration to the same risk rules the agent form's Save applies.
201
233
 
202
234
  ### 7. Live positions: present the served state, name the bypass
203
235
 
@@ -221,15 +253,23 @@ never describe it as a permission check, and never add one of your own.
221
253
 
222
254
  ## When a write's outcome is unknown
223
255
 
224
- An interrupted or timed-out write may have landed. **Read current state first** — the agent
225
- (`get_intelligence_agent`), the budget, the positions — and report the committed outcome. If it
226
- committed, that is a success, not a failure to retry. Never re-issue a state-changing call over an
227
- unverified outcome, and never re-create over an unread roster.
256
+ An interrupted or timed-out write may have landed.
257
+
258
+ **A draft commit recovers by being sent again.** `commit_agent_draft` replays the original receipt
259
+ for the same draft version, so a create that landed is reported once and spends one slot. If the
260
+ retry is refused as moved, read the agent — or the roster, for a create — and reconcile with the
261
+ player before anything else.
262
+
263
+ For every other write, **read current state first** — the agent (`get_intelligence_agent`), the
264
+ budget, the positions — and report the committed outcome. If it committed, that is a success, not a
265
+ failure to retry. Never re-issue a state-changing call over an unverified outcome, and never
266
+ re-create over an unread roster.
228
267
 
229
268
  ## Reporting discipline
230
269
 
231
270
  - Report numbers exactly as the tools return them. Never recompute, re-derive, or round.
232
- - Reads are free of confirms; every write has one, and the radius is stated before the form.
271
+ - Reads and stages are free of confirms — a stage changes only the draft. Every commit and every
272
+ state verb has one, and the radius is stated before the form.
233
273
  - A tool that fails is reported as failed, with what could not be checked. Never convert a failed
234
274
  read into "no issue".
235
275
  - Be concise. Every write on this surface points real capital somewhere, or takes it away.
@@ -30,18 +30,22 @@ Run these in order. Skip a step only when the player's question makes it irrelev
30
30
  indicator modules ACROSS a set of coins (comparing RSI, funding or volatility over the leaders,
31
31
  over a category, over the session pool), use `preview_strategy_report`: one table per module with
32
32
  coins as rows, the schema preamble emitted once instead of per coin, and a server-reported token
33
- budget. Ask `list_strategy_categories` for the section catalogue and pass the sections you want as
34
- `{ "kind": "platform", "sectionKey": "includeRsi" }` — no authoring vocabulary is needed. Use
35
- `{ "mode": "ranked", "limit": N }` as the coin selection when you have no explicit list.
36
- Looping a per-coin tool over N coins costs several times this and returns the same values.
33
+ budget. Ask `list_strategy_categories` for the section catalogue and pass the sections you want,
34
+ each as `{ "kind": "platform", "sectionKey": "includeRsi" }`, inside
35
+ `source: { "kind": "FIELDS", "timeframe": …, "sections": [ … ] }` — no authoring vocabulary is
36
+ needed. Use `{ "mode": "ranked", "limit": N }` as the coin selection when you have no explicit
37
+ list. Looping a per-coin tool over N coins costs several times this and returns the same values.
37
38
  4. **Coin deep-dive**, when the player named a coin or when one dominates the read: the SAME
38
- `preview_strategy_report` call as step 3, with `{ "kind": "tickers", "tickers": ["SOL"] }` as the
39
+ `preview_strategy_report` call as step 3, with `{ "mode": "explicit", "tickers": ["SOL"] }` as the
39
40
  coin selection and the funding / open-interest / positioning sections chosen — one coin is a
40
41
  one-row report, not a different tool. Then `get_coin_candles` for the price action. For momentum
41
42
  across timeframes, add the Relative Strength section — it carries the PPO trajectory and its
42
43
  zero-crossing — or author `PPO` columns at the intervals you want pinned; that is the same read
43
44
  at the precision the catalog declares, in the call you are already making. Use
44
45
  `get_coin_performance_history` when the question is about how it has behaved, not where it is.
46
+ Coin symbols are case-insensitive and exchange symbols are accepted (`btc`, `kPEPE`,
47
+ `xyz:BRENTOIL`); a symbol that names no tracked coin is rejected with an error naming the field,
48
+ never answered as an empty read — say the coin is not tracked rather than retrying it.
45
49
  4b. **How much of the FIELD is moving, not just this coin.** Add the Market Breadth module
46
50
  (`{ "kind": "platform", "sectionKey": "includeMarketBreadth" }`) for the two-axis read: how much
47
51
  of the tracked universe closed up, and how much of it carries positive momentum. It reports per