@battlegrid/mcp-server 31.2.68 → 31.2.70

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.
package/README.md CHANGED
@@ -24,6 +24,98 @@ Seeing package `31.x` alongside handshake `battlegrid@33.x` — the package **be
24
24
 
25
25
  **What this changes for you:** nothing about how you call anything. Upgrading the package no longer waits on a server deploy, and a server deploy no longer strands you on a package that names the wrong contract — reconnect and the announcement follows. **Contract breaking-change notes are no longer keyed to package versions**, since a contract move is no longer a release here; the v11-and-earlier notes below are kept as history, and the live vocabulary is always discovery.
26
26
 
27
+ ## Contract history — v88.1 (an open position keeps the exit rules it opened under)
28
+
29
+ **Additive at v88.1: acceptance widens and one served value narrows; no input or output schema
30
+ changes.** v88.1 is the contract on top of v88.
31
+
32
+ ### Widened acceptance — `commit_strategy_draft`, `restore_strategy`, `commit_agent_draft`
33
+
34
+ - **An open position no longer refuses a strategy commit, a restore or a rebind.** At v88 a write that
35
+ would leave an exit rule unreadable on a coin a bound agent held an open position on was refused with
36
+ `CONDITION_UNREADABLE_BY_RADAR_SCAN` or `CONDITION_OPERAND_UNSERVED_IN_LANE`. At v88.1 it commits. A radar
37
+ slot's coin and a pending manual request's coin are still checked, and refused exactly as before.
38
+ - The three tools' descriptions now say this, so their description hashes move.
39
+
40
+ ### Narrowed served value — the readability refusal's `coinRole`
41
+
42
+ - The refusal's error context serves `coinRole` as `SLOT` or `MANUAL_REQUEST` only. `OPEN_POSITION` is no
43
+ longer emitted. A client switching on it loses a member it can no longer receive.
44
+
45
+ ### Behaviour behind unchanged schemas
46
+
47
+ - **An open position keeps what it opened with.** An agent position records the exit rules it opened
48
+ under, with the report and timeframes they read, and its exit rules are evaluated from that record for
49
+ the life of the trade. An exit-rule, exit-policy or level edit reaches only positions opened after it;
50
+ a revision, rebind, SYSTEM update or timeframe change after the open never reaches an open trade.
51
+
52
+ Nothing accepted at v88 is refused at v88.1.
53
+
54
+ ## Contract history — v88 (an exit rule names the side it closes)
55
+
56
+ **Breaking at v88: a condition body accepted at v87 is refused, and condition and chart output is
57
+ reshaped.** v88 is the contract on top of v87.
58
+
59
+ A condition is an entry condition or an exit rule, never both. An exit rule names the side it closes,
60
+ where `exit: true` read that side from the condition's verdict.
61
+
62
+ ### Rejected input — `stage_strategy_draft`, `preview_strategy_report`
63
+
64
+ - **A condition no longer carries `exit`.** A condition entry naming it is refused with the unknown-key
65
+ error, on the `CONDITIONS` axis of `stage_strategy_draft` and in the conditions of
66
+ `preview_strategy_report`'s `source: { kind: 'FIELDS', … }`.
67
+ - **Every condition requires `exitSide`**: `LONG`, `SHORT` or `BOTH` for an exit rule, `null` for an
68
+ entry condition. It is nullable, never optional; a condition without it is refused.
69
+ - **An exit rule carries `verdict: null` and `required: false`, and an entry condition cannot reference
70
+ an exit rule.** The builder refuses each with a typed remediation error —
71
+ `CONDITION_EXIT_RULE_CARRIES_VERDICT`, `CONDITION_EXIT_RULE_REQUIRED`,
72
+ `CONDITION_ENTRY_REFERENCES_EXIT_RULE` — in a staged draft's `diagnostics`, and as the refusal of its
73
+ `commit_strategy_draft`. An exit rule may reference anything: "exit when the entry setup stops holding"
74
+ is an exit rule whose definition is `NOT` a `conditionRef` to the entry condition.
75
+
76
+ ### Reshaped output
77
+
78
+ - **Every condition a strategy read or commit returns carries `exitSide` and no `exit`**:
79
+ `get_strategy`, `archive_strategy`, `restore_strategy` and `commit_strategy_draft`.
80
+ - **`get_agent_coin_qualification`'s chart names the side each exit rule closes.** Every served level
81
+ gains `referrers`, `{ conditionKey, conditionName, exitSide }` for each of its set's declared
82
+ conditions that reach it. Every series clause referrer and every `conditionsWithoutLevels` entry gains
83
+ `exitSide`, `null` on every entry-set referrer. The `ENTRY` set no longer lists exit rules; they are
84
+ listed under `EXIT`.
85
+
86
+ ### Widened enums
87
+
88
+ - **`CONDITION_EXIT_RULE_CLOSES_DIRECTION`** joins the qualification gate code, the trade evaluation
89
+ attempt reason, the trade gate reason and the trade screen reason. It can appear in the output of
90
+ `get_agent_coin_qualification`, `scan_agent_coins`, `scan_coin_agents`, `list_gate_blocks`,
91
+ `get_signal_log`, `get_public_agent_signal_log_detail`, `get_radar_activity`,
92
+ `get_radar_activity_summary`, `get_radar_close_decisions`, `get_radar_deployment`,
93
+ `list_radar_deployments`, `preview_radar_resolution`, `propose_entry_decision`,
94
+ `get_trade_conversation`, `get_agent_budget` and `reset_agent_drawdown_baseline`. A gate block under it
95
+ names the refusing exit rule in `decidedBy`.
96
+ - **`BLOCKED_BY_CONDITION_EXIT_RULE`** joins the radar evaluation outcome, on `get_radar_activity` and
97
+ `get_radar_activity_summary`.
98
+
99
+ A client switching exhaustively on any of them meets a member it has not seen.
100
+
101
+ ### Behaviour
102
+
103
+ - **An exit rule closes exactly the side it names.** A settled TRUE on a completed bar closes the
104
+ agent's open position on that side. No verdict chooses it; `exit: true` closed the side its verdict
105
+ opposed, and both sides for a `NEITHER` or `null` verdict.
106
+ - **While an exit rule reads TRUE, its side is not offered for entry.** Scan qualification and compose
107
+ refuse that side under `CONDITION_EXIT_RULE_CLOSES_DIRECTION`, after any verdict refusal of the same
108
+ side.
109
+ - **A stored `exit: true` condition is split and closes what it closed.** It keeps its verdict as an
110
+ entry condition, and its strategy gains an exit rule `CLOSE_ON_<conditionKey>`, a `conditionRef` to
111
+ it closing the side its verdict opposed (`UP` → `SHORT`, `DOWN` → `LONG`, `NEITHER` → `BOTH`). A
112
+ strategy read returns both.
113
+ - **Unchanged names keep their place.** `list_strategies`' `conditionTally.exit` now counts exit rules,
114
+ and a decision record's condition `declaration` keeps `exit: boolean`, true for an exit rule.
115
+
116
+ A strict client that rejects unknown keys fails to parse every condition and every chart level at v88;
117
+ list the tools again after the server deploys.
118
+
27
119
  ## Contract history — v87 (a fork's create resolves its source again)
28
120
 
29
121
  **Breaking at v87: a fork's create can now be refused where it committed.** v87 is the contract on top of
package/dist/index.d.ts CHANGED
@@ -49,7 +49,7 @@ import { type Implementation, type Prompt, type Resource } from '@modelcontextpr
49
49
  * being asked. Move it for a change to THIS package — a proxy fix, a dependency bump, a docs
50
50
  * correction. Never move it to track the server.
51
51
  */
52
- export declare const PACKAGE_VERSION = "31.2.68";
52
+ export declare const PACKAGE_VERSION = "31.2.70";
53
53
  export declare const DEFAULT_URL = "https://mcp.battlegrid.trade/mcp";
54
54
  export interface EnvConfig {
55
55
  apiKeys: string[];
package/dist/index.js CHANGED
@@ -52,7 +52,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema
52
52
  * being asked. Move it for a change to THIS package — a proxy fix, a dependency bump, a docs
53
53
  * correction. Never move it to track the server.
54
54
  */
55
- export const PACKAGE_VERSION = '31.2.68';
55
+ export const PACKAGE_VERSION = '31.2.70';
56
56
  export const DEFAULT_URL = 'https://mcp.battlegrid.trade/mcp';
57
57
  const MAX_RETRIES = 3;
58
58
  const RETRY_DELAYS_MS = [2000, 4000, 8000];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@battlegrid/mcp-server",
3
- "version": "31.2.68",
4
- "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
3
+ "version": "31.2.70",
4
+ "description": "BattleGrid MCP server \u2014 play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "87.0.0",
3
+ "contractVersion": "88.1.0",
4
4
  "files": {
5
5
  "battlegrid-agent-management/SKILL.md": "b2f04d76480de2f9fdbd00f8cb25610d2b72fcaa4f87ca57a09bd9ffc78fdbba",
6
6
  "battlegrid-arena-play/SKILL.md": "4cfaa92a8d0dcaf477b227abd774e7aa8642c185d72108dfd401be0cf8aecd7f",
7
7
  "battlegrid-market-analysis/SKILL.md": "3a9943de9f482a8230fb2983efd2f2d8b8c17d49c242e49b68e7243c20c3aa7b",
8
- "battlegrid-radar-deployment/SKILL.md": "17301fa66f4b128154435462ffa967efcb3d016df671b03c485d0f8b840fc891",
8
+ "battlegrid-radar-deployment/SKILL.md": "a624807c9d1f0e1fa650592bfbbdab228d75098d66a9c2d4d3cd3f85e5d3796c",
9
9
  "battlegrid-strategy-authoring/SKILL.md": "a5066740d7d57f095545fd812b0228a8eef6e3b08c87047596a0e1639ae4971d",
10
10
  "battlegrid-strategy-doctor/SKILL.md": "14f20bff9e2b5a59d11634fe3615b1298d672d5e2eba06d3dc8698b571b3bee3",
11
- "battlegrid-strategy-examples/SKILL.md": "3c11942f7327e00208d48a7a256faf83d80faf568bd0181b707657bace3c1ef9",
11
+ "battlegrid-strategy-examples/SKILL.md": "7ec80099efe3a923e1a701703eba5edbbe3ce044628273c806dfd688f2fd715c",
12
12
  "battlegrid-strategy-examples/references/playbooks.md": "63aa07f3d55f97e53b2bf6401528807ab23bd093a4bbc37e598158249db24a59",
13
13
  "battlegrid-strategy-examples/references/recipes.md": "61382acdd295fa159f055b787ba501f1c015f383f59a6714a973057f10de611f",
14
14
  "battlegrid-strategy-examples/references/tradingview-ports.md": "2b13adbc137178955edcca31b6ab40c01c745a932a0750b91db8820c736700bb",
@@ -122,7 +122,7 @@ resolve.
122
122
 
123
123
  **A Radar preview refuses an agent the scan cannot read on the coin.** Every slot agent, on duty now
124
124
  or not, must have every condition the radar acts on — its required conditions, the ones carrying a
125
- verdict, its exit conditions, and every condition they reference — readable by the radar scan on this
125
+ verdict, its exit rules, and every condition they reference — readable by the radar scan on this
126
126
  coin. When one is not, the preview itself is refused, issues no certificate, and nothing can be
127
127
  committed: `CONDITION_UNREADABLE_BY_RADAR_SCAN`, whose `details.context.reachReason` says why
128
128
  (`INSTRUMENT` — the market-data profile of the coin, or of a benchmark section's own instrument, carries
@@ -88,10 +88,11 @@ against a literal; neither of those shapes is what a previous-session level need
88
88
 
89
89
  ## Conditions
90
90
 
91
- `{ conditionKey, name, definition, verdict, required, exit }` — all six
91
+ `{ conditionKey, name, definition, verdict, required, exitSide }` — all six
92
92
  required, no defaults. A `clock` key is REFUSED (the per-condition evidence clock was retired in
93
- contract `61.0.0`), and so is a condition-level `closes` key: the hold lives on each clause and each
94
- group (contract `84.0.0`). Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
93
+ contract `61.0.0`), so is a condition-level `closes` key — the hold lives on each clause and each
94
+ group (contract `84.0.0`) — and so is a boolean `exit` key: the side an exit closes is its own
95
+ `exitSide` (contract `88.0.0`). Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
95
96
  classification/direction headers take `is|in` with the served vocabulary. Groups:
96
97
  `ALL | ANY | NOT | N_OF` (with `n`), depth ≤ 2. Every clause and every group carries a required
97
98
  `hold: { atLeast, of }` — `{ "atLeast": 1, "of": 1 }` is a single read; a clause or group without
@@ -184,7 +185,7 @@ strategy timeframe, and at or below it the series as the frame carries it. At or
184
185
  timeframe the choice therefore sets only what the live lane shows — no bar is in progress at the
185
186
  anchor's own close — so Developing there is legal and changes no decision. A condition reading a
186
187
  developing bar is single-frame: its clause holds Once (a Developing column cannot be held), it
187
- carries no verdict and it cannot take the `exit` role. One exception overrides both the stored value and the default: a column reading a metric with
188
+ carries no verdict and it cannot be an exit rule. One exception overrides both the stored value and the default: a column reading a metric with
188
189
  no live value (itself, or a `spread` operand) reads completed bars at every rung, because the forming
189
190
  bar publishes nothing for it. The resolved answer for a column is served on
190
191
  `effectiveParameters.bars`, and it states that exception.
@@ -205,7 +206,7 @@ strategy reads one is refused outright (`CONDITION_OPERAND_UNSERVED_IN_LANE`), n
205
206
  can read instead.
206
207
 
207
208
  **What the radar scan can read on a coin.** Beyond the lane, a condition the radar acts on — a
208
- required one, one carrying a verdict, an exit one, and every condition they reference — must be
209
+ required one, one carrying a verdict, an exit rule, and every condition they reference — must be
209
210
  readable by the radar scan on each coin the radar acts on for the agent, or it would be decided unread.
210
211
  What a coin can be read for is its market-data profile: the kinds of data the market-data service
211
212
  publishes that it serves for that coin, never the coin's asset class. A refusal carries
@@ -216,12 +217,12 @@ column on a ticker with no catalog row), `AGENT_TIMEFRAME` when the agent has no
216
217
  enabled ladder, and `FEED` when the radar scan never reads that data for the agent (crowd reads:
217
218
  compose reads them, but only for a coin the scan has already admitted). An `INSTRUMENT` refusal names
218
219
  the kind of data the profile lacks, or says the coin has no profile. The fixes it names: take the
219
- condition's radar role away (neither required nor a verdict, or no exit role), read a column the radar
220
+ condition's radar role away (neither required nor a verdict, or, for an exit rule, its exit role), read a column the radar
220
221
  scan has on that coin, or free the coin.
221
222
 
222
223
  **The refusal lands where an agent meets a coin**: at the radar deploy (its preview, the builder's
223
224
  Save and the draft commit); at a manual entry request, as `CONDITION_UNREADABLE_ON_COIN`;
224
- and, for an agent already deployed or holding an open position or a pending manual request, at a
225
+ and, for an agent already deployed or holding a pending manual request, at a
225
226
  strategy commit (`commit_strategy_draft`, the builder's Save, `restore_strategy`) or a rebind (the
226
227
  agent draft's STRATEGY_BINDING commit). A commit is checked only on behalf of those agents: a
227
228
  strategy carries no lane of its own, so one with no agent the radar acts on is never checked, and
@@ -229,13 +230,22 @@ the same strategy is legal, and reads session-field scalars correctly, on an are
229
230
  may hold such content — staging never refuses a draft for being invalid — but its commit is
230
231
  refused, so it never reaches the agents.
231
232
 
232
- **The exit role.** `exit: true` makes a settled TRUE reading close open positions its verdict
233
- opposes — UP exits SHORTs, DOWN exits LONGs, a NEITHER or `null` verdict exits both. Legal only over
234
- a closure every operand of which a completed bar MOVES (`CONDITION_EXIT_READ_ILLEGAL`), which rules
235
- out a developing read — a bar in progress is the forming bar, and an exit fired on one is an intrabar
236
- exit — and rules out a frame-inert operand, which could never fire. Orthogonal to `required` — the
237
- two act on disjoint lifecycles, pre-entry versus open — so a condition may carry both, either, or
238
- neither.
233
+ **Exit rules.** A condition is an entry condition (`exitSide: null`) or an exit rule, never both.
234
+ An exit rule's `exitSide` names the side it closes — `LONG`, `SHORT` or `BOTH` — and it has two
235
+ effects: a settled TRUE on a completed bar closes the agent's open position on that side, and while it
236
+ reads TRUE that side is not offered for entry (a scan qualification or a compose refusal under
237
+ `CONDITION_EXIT_RULE_CLOSES_DIRECTION`, after any verdict refusal of the same side). No verdict chooses
238
+ the side: an exit rule carries `verdict: null` and `required: false` (`CONDITION_EXIT_RULE_CARRIES_VERDICT`,
239
+ `CONDITION_EXIT_RULE_REQUIRED`). An entry condition cannot reference an exit rule
240
+ (`CONDITION_ENTRY_REFERENCES_EXIT_RULE`), so editing an exit rule never changes what the agent enters;
241
+ an exit rule may reference anything, so "exit when the entry setup stops holding" is an exit rule
242
+ whose definition is `NOT` a `conditionRef` to the entry condition. An exit rule is legal only over a
243
+ closure every operand of which a completed bar MOVES (`CONDITION_EXIT_READ_ILLEGAL`), which rules out
244
+ a developing read — a bar in progress is the forming bar, and an exit fired on one is an intrabar
245
+ exit — and rules out a frame-inert operand, which could never fire. A position stamps the exit rules
246
+ it opened under, with the report and timeframes they read: an exit-rule edit applies to positions
247
+ opened after it, and an open position keeps the exit rules it opened with, so an open position never
248
+ refuses a commit or a rebind.
239
249
 
240
250
  **A state column is not a flip event.** `ST_DIR` reads the same on every bar of a trend, so
241
251
  `ST_DIR is "bullish"` is a regime filter and never an entry signal. The flip needs an event column