@battlegrid/mcp-server 11.0.0 → 30.0.0
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 +161 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,6 +7,58 @@ MCP server for [BattleGrid](https://battlegrid.trade) — play crypto prediction
|
|
|
7
7
|
|
|
8
8
|
It is a thin, authenticated **stdio proxy** to BattleGrid's remote MCP server (Stripe `@stripe/mcp` pattern — no business logic). It discovers tools, prompts, and resources live from the server and re-exposes them to local MCP clients (Claude Desktop, Claude Code, Cursor). Capabilities are always **discovered live** — this package never hardcodes the tool catalog.
|
|
9
9
|
|
|
10
|
+
## v30 — breaking cutover (v12 → v30)
|
|
11
|
+
|
|
12
|
+
**v30 pairs with the BattleGrid server's MCP contract v30.x — currently v30.0.0.** The package version tracks the server's wire contract, because the proxy announces `battlegrid@<package version>` in its own stdio handshake — the number a client reads has to be the contract it will actually reach.
|
|
13
|
+
|
|
14
|
+
This release absorbs **eighteen** breaking contract majors at once. The published package went from `11.0.0` straight to `30.0.0`, so no `12.x` through `29.x` client exists to upgrade from — the breaks are grouped by **what you will observe**, with the contract version that introduced each.
|
|
15
|
+
|
|
16
|
+
**Why the gap happened, recorded so it does not repeat.** The pairing rule was documented and the publish gate enforced it, but nothing *noticed* when the server's contract advanced: `scripts/assert-deployed-contract.mjs` only runs when a publish is attempted, and none was between 2026-08-07 and this release. A stop sign cannot ring a doorbell. `.github/workflows/contract-drift.yml` now polls the deployed contract line daily and opens a bump PR when it diverges.
|
|
17
|
+
|
|
18
|
+
**The proxy itself is unchanged.** It embeds no schemas, pins no contract version, and forwards `{ request }` verbatim. Every break below lands on whatever *authors* the payload or *reads* the result, never on the proxy.
|
|
19
|
+
|
|
20
|
+
### Changed meaning, unchanged shape — the one to read first
|
|
21
|
+
|
|
22
|
+
- **Position-size presets are now a RISK BUDGET** (30.0.0, `split-stop-geometry-from-risk`). `smallPct` / `mediumPct` / `largePct` stop denoting a share of the ORDER (`notional = pct / 100 × headroom × leverage`) and start denoting the share of headroom placed **at risk** (`notional = headroom × riskPct / stopDistancePct`, capped at the margin headroom can post). Same keys, same types, same accepted range: **nothing in the payload tells you the meaning moved.** A client still sending `22.0` for MEDIUM is asking to risk 22% of its budget on one trade rather than roughly 2%. Typical risk budgets are `0.5`–`3`; the platform defaults moved to `1 / 2 / 3`. Leverage stops multiplying order size and becomes a constraint only.
|
|
23
|
+
|
|
24
|
+
### Rejected input — something you author is no longer accepted
|
|
25
|
+
|
|
26
|
+
- **The stop-loss ceiling changed unit** (30.0.0). `maxStopLossPct` (a percent of entry) becomes `maxStopLossAtrMultiple` (a multiple of ATR), and the accepted range narrows from `(0, 100]` to `(0, 3]`. It is a rename **and** a re-denomination — mapping the old value onto the new key sends a number one to two orders of magnitude too large. The objects are `.strict()`, so a 29.x client sending `maxStopLossPct` is rejected with an unknown-key error. A new cross-field rule comes with it: `minStopLossAtrMultiple < maxStopLossAtrMultiple` is now a real comparison and is enforced.
|
|
27
|
+
- **The grid-confidence and trade-conviction bars left the agent** (28.0.0, `remove-agent-rule-defaults`). `tradingConfig.gridMinConfidence` and `minTradeConviction` are removed from the shared `.strict()` config; a bar is declared on the arena slot or radar slot that fires.
|
|
28
|
+
- **Both entry-lifecycle guards left the agent** (26.0.0, `move-entry-guards-to-platform`). `tradingConfig.signalTimeoutMinutes` and `maxEntryDeviationAtrMultiple` are removed with no replacement key — both are platform values now.
|
|
29
|
+
- **The arena stopped granting trade authority** (25.0.0, `remove-arena-trade-permissions`). `upsert_deployment_policy` and `preview_deployment_resolution` stop accepting `tradingEnabled`, `minConviction` and `coinRules[]` on a slot.
|
|
30
|
+
- **Post-entry exit policy moved to the strategy** (24.0.0, `move-position-management-to-strategy`). The nested `positionManagement` object is removed from the agent config; the twelve dials are authored on the strategy.
|
|
31
|
+
- **The agent-level trading mode is retired** (23.0.0, `remove-agent-trading-mode`). `tradingConfig.tradingMode` is removed — trading on/off is scoped per deployment.
|
|
32
|
+
- **Trailing gained a required threshold** (22.0.0, `add-trailing-trigger-r`). `positionManagement` gains `trailingTriggerR` as REQUIRED (`0`–`2.0`, `0.01` precision, `0` = trail from entry); the object is `.strict()` all-required, so sending `positionManagement` without it is rejected.
|
|
33
|
+
- **The strategy regime timeframe became derived** (19.0.0, `remove-strategy-regime-override`). It stops being an authored axis anywhere on the contract and is served read-only.
|
|
34
|
+
- **Conditions gained a required `required`** (16.0.0, `add-condition-enforcement-gate`). A condition entry omitting the boolean is REJECTED rather than defaulted.
|
|
35
|
+
- **The trade-level policy moved to the strategy** (15.0.0, `move-trade-level-policy-to-strategy`). It leaves the agent authoring surface and joins the setup gates on the strategy.
|
|
36
|
+
- **The agent's ATR timeframe axis is gone** (14.0.0, `remove-agent-atr-timeframe-axis`). ATR is sampled on the strategy timeframe, always.
|
|
37
|
+
- **Radar's wall-clock condition changed shape** (12.0.0, `unify-deployment-hours-as-sets`).
|
|
38
|
+
|
|
39
|
+
### Moved or reshaped output — a field you read is somewhere else
|
|
40
|
+
|
|
41
|
+
- **`get_radar_activity` gained an `EDGE_REARM` variant** (29.0.0, `add-radar-anchor-rearm`), and every member gained five `rearm*` margin keys plus a `rearmReasons` discriminator. Breaking on both counts if you parse the union strictly.
|
|
42
|
+
- **The trade-defaults catalog dropped four seeds** (27.0.0, `retire-orphaned-trade-config-columns`) for fields no surface can author. Read the stop-loss band, ATR floor and risk-reward minimum from the bound STRATEGY.
|
|
43
|
+
- **`get_radar_activity` gained `blockReasonCode` on every member** (21.0.0, `fix-block-reason-attribution`) — non-null only on `BLOCKED_BEFORE_EVALUATION` rows written after 2026-08-17.
|
|
44
|
+
- **`signal_pipeline`'s decision became a discriminated union** (20.0.0, `add-decision-skip-attribution`). `ENTER`/`GATED` carry the seven level fields as REQUIRED; `SKIP` omits them entirely rather than sending nulls, so reading `entryPrice` without narrowing the verdict finds the key absent.
|
|
45
|
+
- **`get_radar_activity` gained an `EVALUATION_OUTCOME` member** (18.0.0, `add-radar-fire-outcome-journal`), and every existing member gained `evaluationOutcome` + `screenReason`.
|
|
46
|
+
- **Scalar families became placeable modules** (13.0.0, `add-scalar-family-modules`); six opt-in scalar headers moved off the shared `session-field` section key.
|
|
47
|
+
|
|
48
|
+
### Widened enum — new members your own copy rejects
|
|
49
|
+
|
|
50
|
+
- `TradeEvaluationAttemptReasonCode` gains `OPEN_POSITION_CHECK_UNAVAILABLE` (19.4.0), splitting a code that previously reported a platform fault as a fact about your account.
|
|
51
|
+
- `QualificationGateCode` gains `REQUIRED_CONDITION_FALSE` (19.3.0), from the SCAN-stage gate that now evaluates required conditions before a fire edge is spent.
|
|
52
|
+
- `TradingPipelineGateStage` gains `EVALUATION` and `TradeEvaluationAttemptReasonCode` gains `EVALUATION_FAULTED` (18.2.0).
|
|
53
|
+
|
|
54
|
+
### What you do NOT need to do
|
|
55
|
+
|
|
56
|
+
Nothing in the proxy changes. No configuration, no environment variable, no call-shape change on this package's own surface. If your client discovers tools live and reads results generically, `npm i @battlegrid/mcp-server@30` is the whole upgrade.
|
|
57
|
+
|
|
58
|
+
### Additive in the same span
|
|
59
|
+
|
|
60
|
+
`27.1.0` exit-policy authoring input on `compile_strategy_plan` · `19.2.0` `get_account_state` account identity · `19.1.0` Standing Orders marker authoring · `18.4.0` `list_gate_blocks` summary groups · `18.3.0` radar maintenance pause · `18.1.0` protection geometry · `17.2.0` break-even/trailing status · `17.1.0` `get_signal_log` condition evaluation · `13.1.0` four owner-scoped read tools · `12.1.0` cross-venue spot price metrics · `11.1.0` discoverable rate limit.
|
|
61
|
+
|
|
10
62
|
## v11 — breaking cutover (v6 → v11)
|
|
11
63
|
|
|
12
64
|
**v11 pairs with the BattleGrid server's MCP contract v11.x — currently v11.0.0.** The package version tracks the server's wire contract, because the proxy announces `battlegrid@<package version>` in its own stdio handshake — the number a client reads has to be the contract it will actually reach. Upgrade the package and the server together: the major carries the breaking cutover described below, and the minor tracks additive contract moves that leave every existing call working.
|
|
@@ -17,6 +69,35 @@ This release absorbs **six** breaking contract majors at once. The published pac
|
|
|
17
69
|
|
|
18
70
|
### Rejected input — something you author is no longer accepted
|
|
19
71
|
|
|
72
|
+
- **The agent no longer carries either entry guard** (26.0.0). `create_agent` and `update_agent` stop
|
|
73
|
+
accepting `tradingConfig.signalTimeoutMinutes` and `tradingConfig.maxEntryDeviationAtrMultiple`.
|
|
74
|
+
The schema is `.strict()`, so a client still sending either is **rejected**, not silently ignored.
|
|
75
|
+
Neither has a replacement key on any surface: unlike the strategy-owned fields below, these have no
|
|
76
|
+
owning surface at all beneath the platform. One `platform_config` value governs the entry-price
|
|
77
|
+
drift budget for every decision, read at evaluation time; one governs how long an entry may stay
|
|
78
|
+
unfilled, snapshotted onto the position at creation. **Remove both keys and send nothing in their
|
|
79
|
+
place.**
|
|
80
|
+
- **The agent no longer carries an exit policy** (24.0.0). `create_agent` and `update_agent` stop
|
|
81
|
+
accepting `tradingConfig.positionManagement`. The schema is `.strict()`, so a client still sending
|
|
82
|
+
it is **rejected**, not silently ignored. The twelve dials that decide how a stop MOVES after entry
|
|
83
|
+
— break-even arming, trailing engagement and giveback, time-decay tightening — are denominated in
|
|
84
|
+
the setup's own payoff shape (multiples of the trade's initial risk, fractions of take-profit
|
|
85
|
+
distance, minutes since entry) and read no balance, leverage or exposure, so they belong to the
|
|
86
|
+
thesis rather than to the account running it. **Author them on the strategy instead**, through
|
|
87
|
+
`compile_strategy_plan` / `apply_strategy_plan`: the post-state gains the same twelve keys beside
|
|
88
|
+
the trade-level trio, and the plan diff gains a `positionManagement` axis. An agent inherits the
|
|
89
|
+
policy from the strategy it binds. **The umbrella `enabled` flag is deleted rather than moved** —
|
|
90
|
+
each mechanism's toggle is now the whole truth for that mechanism, so "trailing on, management
|
|
91
|
+
off" is no longer expressible, a state the server's own monitor and boot recovery already
|
|
92
|
+
disagreed about.
|
|
93
|
+
- **The agent-level trading mode is gone** (23.0.0). `create_agent` and `update_agent` stop
|
|
94
|
+
accepting `tradingConfig.tradingMode`. The schema is `.strict()`, so a client still sending it is
|
|
95
|
+
**rejected**, not silently ignored. Trading on/off is now scoped per deployment — a radar policy's
|
|
96
|
+
`enabled`, an arena slot's `tradingEnabled`, a per-coin `tradeEnabled` — and approval-before-
|
|
97
|
+
execution is the conversational surface's own contract, so the account-level switch that sat above
|
|
98
|
+
both is removed rather than renamed. To stop an agent trading, turn its deployment off (or halt
|
|
99
|
+
the agent); to make one trade autonomously, arm a radar coin or switch trading on for an arena
|
|
100
|
+
slot. **A newly authored arena slot now starts with trading off.**
|
|
20
101
|
- **Challenge participation is no longer a field you set** (10.0.0). `create_agent` and `update_agent` stop accepting `arenaChallengeEnabled`, and a deployment policy's slot rules and per-coin rules stop accepting `challengeEnabled`. All four schemas are `.strict()`, so a client still sending any of them is **rejected**, not silently ignored. Challenge participation is now *identical* to effective trade permission, resolved per coin: to stop an agent taking challenges at a venue, turn that venue's trading off — at the slot, or per coin for finer grain — using fields you already have.
|
|
21
102
|
- **`VOLUME_RATIO` is retired and replaced by `RVOL`** (6.0.0). `MetricKeySchema` auto-derives from the server's metric catalog, so the published enum simply stops accepting the old key: a column authored with `metric: 'VOLUME_RATIO'` is rejected against the enum. **No alias exists** — deliberately. The catalog audit adjudicated the old name as a name-level lie (the value is current volume ÷ its 20-period average, a *multiple*), and the correction was made at the root rather than grandfathered. If you hit an enum rejection naming `VOLUME_RATIO`, this note is the match.
|
|
22
103
|
- **`BB_WIDTH` can no longer be ranked** (8.0.0). `{ metric: 'BB_WIDTH', transformId: 'rank' }` is now rejected. `BBwidth` is a price-unit spread (`upper − lower`) that had falsely declared `percent`, and that declaration was the only thing admitting it to exchange-wide ranking — the ordinal it produced sorted by token denomination rather than by compression. It re-declares `signedPrice` and leaves the ranked contract. **Rank `BB_WIDTH_PCT` (`bbWidthPct`) instead**, which ships in the same release: the capability moved, it was not removed.
|
|
@@ -40,6 +121,34 @@ This is the failure mode with no error attached to it. Nothing is rejected; your
|
|
|
40
121
|
|
|
41
122
|
Each mismatch also carries a **required** `data: CoverageDatum[]` — the `(metric, rung)` pairs the mismatch is about: every MISSING datum for the not-in-report code, the PRESENT data for the signal-off code, empty for `REQUIRED_SIGNAL_UNAVAILABLE`. A client switching exhaustively on the old code strings stops matching. Behaviourally, coverage is now decided by whether the report renders a signal's declared metrics at the **rung** that signal reads, not by whether its module appears anywhere — so expect warnings you never saw before, and the disappearance of warnings no composition could clear. Mismatches remain advisory and non-blocking; nothing about apply gates on them.
|
|
42
123
|
- **`IntelligenceAgentDTO` drops `arenaChallengeEnabled`** (10.0.0) — the read side of the input removal above. `ResolvedSlotRulesDTO.challengeEnabled` **stays and keeps its shape**; it is now derived server-side, carrying the same value and provenance as `tradingEnabled`, so a client reading the resolved bundle needs no change.
|
|
124
|
+
- **Both entry guards leave every agent-returning shape** (26.0.0) — the read side of the input
|
|
125
|
+
removal above. `AgentTradingConfigDTO` drops `signalTimeoutMinutes` and
|
|
126
|
+
`maxEntryDeviationAtrMultiple` on every tool that serves an agent, and the explorer trading spec
|
|
127
|
+
and the agent-review payload drop them too. `get_trading_config_catalog` drops
|
|
128
|
+
`defaultSignalTimeoutMinutes` from its defaults and the
|
|
129
|
+
`minimumMaxEntryDeviationAtrMultiple` / `maximumMaxEntryDeviationAtrMultiple` pair from its bounds —
|
|
130
|
+
a bound pair that constrained a per-agent field which no longer exists.
|
|
131
|
+
`defaultMaxEntryDeviationAtrMultiple` and `defaultTtlMinutes` **stay**, and are now the values that
|
|
132
|
+
actually govern rather than seeds a new agent copies. A client reading these objects strictly must
|
|
133
|
+
drop the removed keys.
|
|
134
|
+
- **`positionManagement` leaves every agent-returning shape** (24.0.0) — the read side of the input
|
|
135
|
+
removal above. `AgentTradingConfigDTO` drops the nested block on every tool that serves an agent,
|
|
136
|
+
and the explorer trading spec drops it too. A client reading these objects strictly must drop the
|
|
137
|
+
key; one that wants the policy reads it from the bound strategy.
|
|
138
|
+
- **`get_trading_config_catalog` drops `positionManagementPresets`** (24.0.0) — the pistol ladder
|
|
139
|
+
(COLT / WEBLEY / BERETTA / LUGER / WALTHER) is **retired, not renamed**. Once the values live on
|
|
140
|
+
the strategy, the strategy IS the named bundle, with its own name, description and revision
|
|
141
|
+
history; a parallel vocabulary of anonymous bundles beside it would be a second name for the same
|
|
142
|
+
thing. There is no replacement enum to migrate to — list strategies instead. The catalog's
|
|
143
|
+
`defaultPositionMgmt*` trading defaults go with it, for the same reason: nothing seeds an agent's
|
|
144
|
+
exit policy any more.
|
|
145
|
+
- **`tradingMode` leaves every agent-returning shape** (23.0.0) — the read side of the input
|
|
146
|
+
removal above. `AgentTradingConfigDTO` drops it on every tool that serves an agent, and so do the
|
|
147
|
+
agents-hub permission envelope, the explorer entry, and both public-profile shapes. A client
|
|
148
|
+
reading these objects strictly must drop the key.
|
|
149
|
+
- **`DeploymentResolvedResolutionDTO` drops `agentTradingMode`** (23.0.0) — the field 10.0.0 added,
|
|
150
|
+
now unnecessary: with no account layer to overlay, the resolved `tradingEnabled` is the whole
|
|
151
|
+
answer about whether the previewed deployment trades.
|
|
43
152
|
- **`range` is no longer a tuple** (11.0.0). The closed positional pair `[min, max]` becomes the half-open object **`{ min: number; max?: number }`**. It travels through `ScalarSchema`, so this lands on `list_strategy_vocabulary`, `query_report_catalog`, and `get_metric_construction_hints` alike.
|
|
44
153
|
|
|
45
154
|
**This one fails silently.** A client reading `range[0]` / `range[1]` gets `undefined` with no error raised — read `range.min` / `range.max` instead, and treat a missing `max` as unbounded above. The tuple could not state the truth about the volume/trade-count family, which is non-negative and unbounded above, and `Infinity` serializes to `null` on the wire. Those six metrics now declare `{ min: 0 }`, and as a consequence their **`far`/`near` rank orderings are no longer offered** — on a non-negative value that pair is a synonym pair under the magnitude gate's documented semantics.
|
|
@@ -59,7 +168,7 @@ Nothing here is a break, but a client that enumerates these vocabularies will wa
|
|
|
59
168
|
- **Four metric keys** join the catalog — `SPOT_CVD`, `PERP_SPOT_FLOW`, `PERP_SPOT_STRENGTH`, `PERP_SPOT_CONFIRMS` — and `includePerpSpotFlow` joins the context-source key set as its 23rd member, opt-in (5.2.0).
|
|
60
169
|
- **Two prompt-section `kind`s** join the union: `perp-spot-flow` (5.2.0) and `session-field` (5.1.0). Only a client that switches exhaustively on `kind` needs a default branch; one that renders `content` generically needs nothing.
|
|
61
170
|
- **The transform vocabulary grows 15 → 17** (11.0.0) — `efficiency` and `maxShare` join, and both join the chain-outer enum that `chainSuccessors` is served as. Only a client that switches exhaustively on `transformId` needs new branches; one that renders the served labels generically needs nothing.
|
|
62
|
-
-
|
|
171
|
+
- ~~**The deployment-policy resolution DTO gains `agentTradingMode`**~~ (10.0.0, **removed again in 23.0.0**) — it existed to tell "this rule permits the trade" from "this account can trade at all". The account-level trading mode is gone, so the second question no longer exists and the field was dropped; read the resolved `tradingEnabled` alone.
|
|
63
172
|
- **`PlatformSectionDTO` gains `columns`** (6.1.0) — a platform section's composition in the same wire shape a custom section's columns already travel in, empty for a registry-declared special. **Not a copy source**, which is where it differs from the identically-shaped `CustomSectionTemplateDTO.columns`: six platform columns pair a metric with `classifyState`, a deliberate composability exclusion that authoring rejects at construction. A client that round-trips these into a custom section will be refused, and that refusal is correct.
|
|
64
173
|
|
|
65
174
|
## v5 — breaking major (conditions/verdicts fusion)
|
|
@@ -328,6 +437,47 @@ Tools, prompts, and resources are **discovered live** from the connected server
|
|
|
328
437
|
| **9.0.0** | Server contract v9.0.0, **breaking**: `compile_strategy_plan`'s `approvedPlan.mismatches` changes on both axes. Both report-coverage codes are renamed off "module" (`ACTIVE_SIGNAL_MODULE_NOT_IN_REPORT` → `ACTIVE_SIGNAL_DATA_NOT_IN_REPORT`, `REPORT_MODULE_SIGNAL_OFF` → `REPORT_DATA_SIGNAL_OFF`), and each mismatch carries a required `data: CoverageDatum[]` — the `(metric, rung)` pairs it is about. A client switching exhaustively on the old code strings stops matching. Coverage is now decided by whether the report renders a signal's declared metrics at the rung that signal reads, so expect warnings never seen before and the disappearance of warnings no composition could clear; mismatches stay advisory and non-blocking. Never published as a package version |
|
|
329
438
|
| 10.0.0 | Server contract v10.0.0, **breaking**: challenge participation stops being a declared setting anywhere and becomes identical to effective trade permission, resolved per coin. `create_agent`/`update_agent` stop accepting `arenaChallengeEnabled`, and a deployment policy's slot and per-coin rule shapes stop accepting `challengeEnabled` — all four are `.strict()`, so a client still sending them is rejected rather than ignored, the same input-acceptance narrowing that made v4, v5, v6 and v8 majors. `IntelligenceAgentDTO` drops `arenaChallengeEnabled`; `ResolvedSlotRulesDTO.challengeEnabled` stays and keeps its shape, now derived server-side with the same value and provenance as `tradingEnabled`. The resolution DTO also gains `agentTradingMode` — the preview previously reported trade rules for an agent whose account-level trading was off. Never published as a package version |
|
|
330
439
|
| **11.0.0** | Server contract v11.0.0, **breaking**: a catalogued numeric output's `range` changes shape — the closed positional tuple `[min, max]` becomes the half-open object `{ min: number; max?: number }`, travelling through `ScalarSchema` into `list_strategy_vocabulary`, `query_report_catalog` and `get_metric_construction_hints`. A client reading `range[0]`/`range[1]` gets `undefined` **with no error**, which is the silent failure mode a version exists to prevent. The driver: the tuple could not state the truth about the volume/trade-count family — non-negative and unbounded above — and `Infinity` serializes to `null` on the wire; those six metrics now declare `{ min: 0 }` and no longer offer `far`/`near` rank orderings, which on a non-negative value are a synonym pair. Additive alongside it: the transform vocabulary grows 15 → 17 (`efficiency`, `maxShare`), both joining the chain-outer enum served as `chainSuccessors`. **This is the package version paired to the current server contract.** No proxy code change — the version is the client-facing signal, and the proxy's handshake carries it |
|
|
440
|
+
| 11.1.0 | Server contract v11.1.0, **additive**: the per-user request budget becomes discoverable rather than only enforceable |
|
|
441
|
+
| 12.0.0 | Server contract v12.0.0, **breaking**: radar's wall-clock condition changes shape (`unify-deployment-hours-as-sets`) |
|
|
442
|
+
| 12.1.0 | Server contract v12.1.0, **additive**: `SPOT_CLOSE_CB` / `SPOT_CLOSE_BN` join the metric catalog |
|
|
443
|
+
| 13.0.0 | Server contract v13.0.0, **breaking**: scalar families become placeable modules; six scalar headers leave the `session-field` key |
|
|
444
|
+
| 13.1.0 | Server contract v13.1.0, **additive**: four owner-scoped read tools join the catalog, closing web-client parity gaps |
|
|
445
|
+
| 14.0.0 | Server contract v14.0.0, **breaking**: the agent's ATR timeframe axis is removed — ATR samples on the strategy timeframe |
|
|
446
|
+
| 15.0.0 | Server contract v15.0.0, **breaking**: the trade-level policy moves off the agent onto the strategy |
|
|
447
|
+
| 16.0.0 | Server contract v16.0.0, **breaking**: a strategy condition gains a REQUIRED `required` boolean; omitting it is rejected |
|
|
448
|
+
| 17.1.0 | Server contract v17.1.0, **additive**: `get_signal_log` gains `log.conditionEvaluation` |
|
|
449
|
+
| 17.2.0 | Server contract v17.2.0, **additive**: position rows gain `breakEvenStatus` / `trailingStatus` |
|
|
450
|
+
| 18.0.0 | Server contract v18.0.0, **breaking**: `get_radar_activity` gains an `EVALUATION_OUTCOME` member and two keys on every member |
|
|
451
|
+
| 18.1.0 | Server contract v18.1.0, **additive**: protection geometry behind the v17.2.0 verdicts |
|
|
452
|
+
| 18.2.0 | Server contract v18.2.0, **additive**: `TradingPipelineGateStage` gains `EVALUATION`; reason codes gain `EVALUATION_FAULTED` |
|
|
453
|
+
| 18.3.0 | Server contract v18.3.0, **additive**: the platform maintenance pause reaches the radar surfaces |
|
|
454
|
+
| 18.4.0 | Server contract v18.4.0, **additive**: `list_gate_blocks` gains `summary` groups |
|
|
455
|
+
| 19.0.0 | Server contract v19.0.0, **breaking**: the strategy regime timeframe becomes derived and read-only |
|
|
456
|
+
| 19.1.0 | Server contract v19.1.0, **additive**: Standing Orders markers become authorable and resolvable before save |
|
|
457
|
+
| 19.2.0 | Server contract v19.2.0, **additive**: `get_account_state` gains account-identity fields |
|
|
458
|
+
| 19.3.0 | Server contract v19.3.0, **additive**: `QualificationGateCode` gains `REQUIRED_CONDITION_FALSE` |
|
|
459
|
+
| 19.4.0 | Server contract v19.4.0, **additive**: reason codes gain `OPEN_POSITION_CHECK_UNAVAILABLE` |
|
|
460
|
+
| 20.0.0 | Server contract v20.0.0, **breaking**: the `signal_pipeline` decision becomes a union discriminated on the verdict; `GATED` joins it |
|
|
461
|
+
| 21.0.0 | Server contract v21.0.0, **breaking**: `get_radar_activity` gains `blockReasonCode` on every member |
|
|
462
|
+
| 22.0.0 | Server contract v22.0.0, **breaking**: `positionManagement` gains REQUIRED `trailingTriggerR` |
|
|
463
|
+
| 23.0.0 | Server contract v23.0.0, **breaking**: `tradingConfig.tradingMode` is removed — trading is scoped per deployment |
|
|
464
|
+
| 24.0.0 | Server contract v24.0.0, **breaking**: `positionManagement` leaves the agent for the strategy |
|
|
465
|
+
| 25.0.0 | Server contract v25.0.0, **breaking**: the arena stops granting trade authority; slot trade fields are rejected |
|
|
466
|
+
| 26.0.0 | Server contract v26.0.0, **breaking**: both entry-lifecycle guards leave the agent for platform config |
|
|
467
|
+
| 27.0.0 | Server contract v27.0.0, **breaking**: the trade-defaults catalog drops four unauthorable seeds |
|
|
468
|
+
| 27.1.0 | Server contract v27.1.0, **additive**: `compile_strategy_plan` accepts the twelve exit-policy keys |
|
|
469
|
+
| 28.0.0 | Server contract v28.0.0, **breaking**: grid-confidence and trade-conviction bars become deployment declarations |
|
|
470
|
+
| 29.0.0 | Server contract v29.0.0, **breaking**: `get_radar_activity` gains an `EDGE_REARM` variant and six keys on every member |
|
|
471
|
+
| **30.0.0** | Server contract v30.0.0, **breaking**: the stop-loss ceiling changes unit (`maxStopLossPct` → `maxStopLossAtrMultiple`, range `(0,3]`), a `floor < ceiling` rule is enforced, and **the position-size presets change meaning without changing shape** — they denote a risk budget, not a share of the order |
|
|
472
|
+
| 23.0.0 | Server contract v23.0.0, **breaking**: the agent-level trading mode is retired. `create_agent`/`update_agent` stop accepting `tradingConfig.tradingMode` on the shared `.strict()` `TradingConfigSchema`, so a client still sending it is rejected rather than ignored — the same input-acceptance narrowing that made v4, v5, v6, v8 and v10 majors. On the read side `AgentTradingConfigDTO` drops `tradingMode` on every agent-returning tool, and so do the agents-hub permission envelope, the explorer entry and both public-profile shapes; `DeploymentResolvedResolutionDTO` drops `agentTradingMode`, the field v10.0.0 added, because with no account layer to overlay the resolved `tradingEnabled` is the whole answer. Trading on/off is now scoped per deployment (radar policy `enabled`, arena slot `tradingEnabled`, per-coin `tradeEnabled`) and a newly authored arena slot starts with trading **off**; approval-before-execution is the conversational surface's own contract, so `accept_entry_decision` / `cancel_entry_decision` / `list_pending_approvals` are unchanged on the wire but now carry conversational proposals exclusively — a deployed agent never queues for approval. Never published as a package version |
|
|
473
|
+
| 24.0.0 | Server contract v24.0.0, **breaking**: the post-entry exit policy moves from the agent to the strategy. `create_agent`/`update_agent` stop accepting `tradingConfig.positionManagement` on the shared `.strict()` `TradingConfigSchema`, so a client still sending it is rejected rather than ignored — the same input-acceptance narrowing that made v4, v5, v6, v8, v10 and v23 majors. On the read side `AgentTradingConfigDTO` drops the nested block on every agent-returning tool and the explorer trading spec drops it too; `get_trading_config_catalog` drops `positionManagementPresets` and the `defaultPositionMgmt*` trading defaults. The pistol-preset ladder (COLT / WEBLEY / BERETTA / LUGER / WALTHER) is **retired, not renamed** — once the values live on the strategy, the strategy is the named bundle. Additive on the authoring surface in the same bump: `compile_strategy_plan`/`apply_strategy_plan` post-state gains the twelve authored keys beside the trade-level trio, and the plan diff gains a `positionManagement` axis. Behaviourally the umbrella `enabled` flag is **deleted** rather than moved: each mechanism toggle is the whole truth for that mechanism, so a client can no longer express "trailing on, management off". Never published as a package version |
|
|
474
|
+
| 26.0.0 | Server contract v26.0.0, **breaking**: both entry-lifecycle guards stop being agent configuration. `create_agent`/`update_agent` stop accepting `tradingConfig.signalTimeoutMinutes` and `tradingConfig.maxEntryDeviationAtrMultiple` on the shared `.strict()` `TradingConfigSchema`, so a client still sending either is rejected rather than ignored — the same input-acceptance narrowing that made v4, v5, v6, v8, v10, v23 and v24 majors. Neither has a replacement key: one `platform_config` value governs the entry-price drift budget for every decision (read at evaluation time, so an admin edit applies to the next evaluation), and one governs how long an entry may stay unfilled (snapshotted onto the position at creation, so an edit can never cancel an order already resting on the book). On the read side `AgentTradingConfigDTO` drops both fields on every agent-returning tool, and so do the explorer trading spec and the agent-review payload; `get_trading_config_catalog` drops `defaultSignalTimeoutMinutes` and the `minimum_`/`maximum_maxEntryDeviationAtrMultiple` bound pair, while `defaultMaxEntryDeviationAtrMultiple` and `defaultTtlMinutes` stay and become the values that actually govern. Behaviourally a conversational entry and an autonomous entry on the same setup now receive the **identical** unfilled lifetime — the mode-selecting fallback that chose between a per-agent timeout and a hardcoded 15-minute resting window is gone, and the three-way timeout enum with it. Never published as a package version |
|
|
475
|
+
|
|
476
|
+
> **Gap: contract 25.0.0 is not recorded in this table.** It shipped server-side as
|
|
477
|
+
> `remove-arena-trade-permissions` (the arena stops granting trade authority; `upsert_deployment_policy`
|
|
478
|
+
> and `preview_deployment_resolution` stop accepting `tradingEnabled` / `minConviction` / `coinRules[]`
|
|
479
|
+
> on a slot, and `DeploymentSlotDTO` reshapes). Its row belongs to that change and is left for it to
|
|
480
|
+
> write rather than reconstructed here.
|
|
331
481
|
|
|
332
482
|
## Maintainer release procedure
|
|
333
483
|
|
|
@@ -358,6 +508,16 @@ Also confirm npm's Trusted Publisher for `@battlegrid/mcp-server` is GitHub Acti
|
|
|
358
508
|
- **Move all four values together** — `package.json`, both `package-lock.json` version fields (the root `version` and the self-referencing `packages[""].version`), and the exported `VERSION` in `src/index.ts`. The workflow compares all four against each other and fails closed on any disagreement.
|
|
359
509
|
- **Merge the version change only after the server is deployed.** The deploy assertion is a safety net, not a routine step: with the ordering right it never fires, and a red workflow on `main` means something is genuinely wrong rather than that you are waiting. Merging early blocks the publish until the deploy lands, then re-run the job — nothing was published and no tag exists to move.
|
|
360
510
|
|
|
511
|
+
### What tells you a pairing is owed
|
|
512
|
+
|
|
513
|
+
[`.github/workflows/contract-drift.yml`](.github/workflows/contract-drift.yml) runs daily, reads the same unauthenticated `GET /mcp/version` the deploy assertion reads, compares the same `MAJOR.MINOR` contract line, and **opens a bump PR when they diverge**. Merge it and the release follows, because a version change on `main` IS the release.
|
|
514
|
+
|
|
515
|
+
It exists because the deploy assertion could not do this job. `scripts/assert-deployed-contract.mjs` runs only when a publish is ATTEMPTED, so it can refuse a release someone started and cannot say one is owed. Between 2026-08-07 and 2026-08-23 no publish was attempted while the server advanced from contract `11.0` to `30.0`, and this package spent sixteen days announcing `battlegrid@11.0.0` to every client — the exact failure the pairing section above describes. It was also unpublishable for that whole period, since its own gate would have refused `11.0` against `30.0`.
|
|
516
|
+
|
|
517
|
+
Reading the DEPLOYED endpoint rather than the app repo's merged manifest is deliberate: it makes the watch fire only once the deploy has landed, which is the ordering *Preparing the version change* already requires.
|
|
518
|
+
|
|
519
|
+
The PR it opens moves all four version values, and its body says what a human still owes — the README release section describing what changed for clients. The bump is mechanical; the changelog is judgement, which is why this opens a PR instead of merging one.
|
|
520
|
+
|
|
361
521
|
### Which releases need a server deploy
|
|
362
522
|
|
|
363
523
|
The deploy assertion compares the **contract line** — `MAJOR.MINOR` — not the full version and not the major alone.
|
package/dist/index.d.ts
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
*/
|
|
33
33
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
34
34
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
35
|
-
export declare const VERSION = "
|
|
35
|
+
export declare const VERSION = "30.0.0";
|
|
36
36
|
export declare const DEFAULT_URL = "https://mcp.battlegrid.trade/mcp";
|
|
37
37
|
export interface EnvConfig {
|
|
38
38
|
apiKeys: string[];
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
36
36
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
37
37
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
38
38
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
39
|
-
export const VERSION = '
|
|
39
|
+
export const VERSION = '30.0.0';
|
|
40
40
|
export const DEFAULT_URL = 'https://mcp.battlegrid.trade/mcp';
|
|
41
41
|
const MAX_RETRIES = 3;
|
|
42
42
|
const RETRY_DELAYS_MS = [2000, 4000, 8000];
|