@battlegrid/mcp-server 31.2.67 → 31.2.69

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,94 @@ 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 (an exit rule names the side it closes)
28
+
29
+ **Breaking at v88: a condition body accepted at v87 is refused, and condition and chart output is
30
+ reshaped.** v88 is the contract on top of v87.
31
+
32
+ A condition is an entry condition or an exit rule, never both. An exit rule names the side it closes,
33
+ where `exit: true` read that side from the condition's verdict.
34
+
35
+ ### Rejected input — `stage_strategy_draft`, `preview_strategy_report`
36
+
37
+ - **A condition no longer carries `exit`.** A condition entry naming it is refused with the unknown-key
38
+ error, on the `CONDITIONS` axis of `stage_strategy_draft` and in the conditions of
39
+ `preview_strategy_report`'s `source: { kind: 'FIELDS', … }`.
40
+ - **Every condition requires `exitSide`**: `LONG`, `SHORT` or `BOTH` for an exit rule, `null` for an
41
+ entry condition. It is nullable, never optional; a condition without it is refused.
42
+ - **An exit rule carries `verdict: null` and `required: false`, and an entry condition cannot reference
43
+ an exit rule.** The builder refuses each with a typed remediation error —
44
+ `CONDITION_EXIT_RULE_CARRIES_VERDICT`, `CONDITION_EXIT_RULE_REQUIRED`,
45
+ `CONDITION_ENTRY_REFERENCES_EXIT_RULE` — in a staged draft's `diagnostics`, and as the refusal of its
46
+ `commit_strategy_draft`. An exit rule may reference anything: "exit when the entry setup stops holding"
47
+ is an exit rule whose definition is `NOT` a `conditionRef` to the entry condition.
48
+
49
+ ### Reshaped output
50
+
51
+ - **Every condition a strategy read or commit returns carries `exitSide` and no `exit`**:
52
+ `get_strategy`, `archive_strategy`, `restore_strategy` and `commit_strategy_draft`.
53
+ - **`get_agent_coin_qualification`'s chart names the side each exit rule closes.** Every served level
54
+ gains `referrers`, `{ conditionKey, conditionName, exitSide }` for each of its set's declared
55
+ conditions that reach it. Every series clause referrer and every `conditionsWithoutLevels` entry gains
56
+ `exitSide`, `null` on every entry-set referrer. The `ENTRY` set no longer lists exit rules; they are
57
+ listed under `EXIT`.
58
+
59
+ ### Widened enums
60
+
61
+ - **`CONDITION_EXIT_RULE_CLOSES_DIRECTION`** joins the qualification gate code, the trade evaluation
62
+ attempt reason, the trade gate reason and the trade screen reason. It can appear in the output of
63
+ `get_agent_coin_qualification`, `scan_agent_coins`, `scan_coin_agents`, `list_gate_blocks`,
64
+ `get_signal_log`, `get_public_agent_signal_log_detail`, `get_radar_activity`,
65
+ `get_radar_activity_summary`, `get_radar_close_decisions`, `get_radar_deployment`,
66
+ `list_radar_deployments`, `preview_radar_resolution`, `propose_entry_decision`,
67
+ `get_trade_conversation`, `get_agent_budget` and `reset_agent_drawdown_baseline`. A gate block under it
68
+ names the refusing exit rule in `decidedBy`.
69
+ - **`BLOCKED_BY_CONDITION_EXIT_RULE`** joins the radar evaluation outcome, on `get_radar_activity` and
70
+ `get_radar_activity_summary`.
71
+
72
+ A client switching exhaustively on any of them meets a member it has not seen.
73
+
74
+ ### Behaviour
75
+
76
+ - **An exit rule closes exactly the side it names.** A settled TRUE on a completed bar closes the
77
+ agent's open position on that side. No verdict chooses it; `exit: true` closed the side its verdict
78
+ opposed, and both sides for a `NEITHER` or `null` verdict.
79
+ - **While an exit rule reads TRUE, its side is not offered for entry.** Scan qualification and compose
80
+ refuse that side under `CONDITION_EXIT_RULE_CLOSES_DIRECTION`, after any verdict refusal of the same
81
+ side.
82
+ - **A stored `exit: true` condition is split and closes what it closed.** It keeps its verdict as an
83
+ entry condition, and its strategy gains an exit rule `CLOSE_ON_<conditionKey>`, a `conditionRef` to
84
+ it closing the side its verdict opposed (`UP` → `SHORT`, `DOWN` → `LONG`, `NEITHER` → `BOTH`). A
85
+ strategy read returns both.
86
+ - **Unchanged names keep their place.** `list_strategies`' `conditionTally.exit` now counts exit rules,
87
+ and a decision record's condition `declaration` keeps `exit: boolean`, true for an exit rule.
88
+
89
+ A strict client that rejects unknown keys fails to parse every condition and every chart level at v88;
90
+ list the tools again after the server deploys.
91
+
92
+ ## Contract history — v87 (a fork's create resolves its source again)
93
+
94
+ **Breaking at v87: a fork's create can now be refused where it committed.** v87 is the contract on top of
95
+ v86. No schema, description or tool changes.
96
+
97
+ ### Narrowed acceptance
98
+
99
+ A create draft that `fork_strategy` opened is committed by `commit_strategy_draft` with
100
+ `expectedRevision: null`, or by the builder's Create. That create now resolves the strategy it copied
101
+ again. It uses only the source id and revision in the draft's `ORIGIN`, by the same rule the fork applied:
102
+
103
+ - **A source that moved past the forked revision** refuses the create with `CONFLICT` and **no
104
+ `details.nextAct`**. Reading the draft again cannot cure it; the message says to discard the draft and
105
+ fork again. `get_strategy_draft` and `stage_strategy_draft` report the same refusal in the draft's
106
+ diagnostics.
107
+ - **A source you can no longer see** — archived, or neither yours nor SYSTEM — answers `NOT_FOUND`.
108
+
109
+ ### Widened acceptance
110
+
111
+ - **Neither `fork_strategy` nor the create reads the source's stored revision snapshot.** A strategy whose
112
+ stored snapshot predates the current shape — every SYSTEM template among them — now forks and creates
113
+ from its live state, where both were refused.
114
+
27
115
  ## Contract history — v86 (a refusal hint belongs to the operation that can act on it)
28
116
 
29
117
  **Breaking at v86: refusals on most tools lose `details.nextAct`, two refusals change code, and one
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.67";
52
+ export declare const PACKAGE_VERSION = "31.2.69";
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.67';
55
+ export const PACKAGE_VERSION = '31.2.69';
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@battlegrid/mcp-server",
3
- "version": "31.2.67",
3
+ "version": "31.2.69",
4
4
  "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "86.0.0",
3
+ "contractVersion": "88.0.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": "5c3d9b484569c62f0c340620ca1ec2b1dfb9b950662558d07b7ae9c40d682979",
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,7 +217,7 @@ 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
@@ -229,13 +230,19 @@ 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.
239
246
 
240
247
  **A state column is not a flip event.** `ST_DIR` reads the same on every bar of a trend, so
241
248
  `ST_DIR is "bullish"` is a regime filter and never an entry signal. The flip needs an event column