@battlegrid/mcp-server 31.2.10 → 31.2.12

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,7 +24,7 @@ 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 — v37 → v52
27
+ ## Contract history — v37 → v53
28
28
 
29
29
  Eleven majors reached authors while this section stopped at v36. That gap is the mechanism, not an
30
30
  oversight: since v31 a contract move needs no release here, so nothing forced a note to be written —
@@ -112,6 +112,21 @@ refuse is now stored. Listed because a client that special-cased the refusal can
112
112
 
113
113
  ### Rejected input — something you author is no longer accepted
114
114
 
115
+ - **A condition naming a `swingHi` / `swingLo` header is refused — the indicator is a Donchian
116
+ channel** (53.0.0, `rename-donchian-channel`). The rolling-window extremes indicator computed the
117
+ highest high and lowest low of the trailing 20 closed bars — a Donchian channel — under a swing
118
+ point's name, and the name asserted a property the value does not have (a swing high survives being
119
+ broken; a channel edge re-anchors the instant it is). Every layer of the vocabulary moves at once,
120
+ with no alias: a clause on `compile_strategy_plan`, `apply_strategy_plan` or `fork_strategy` naming
121
+ a header on the old stems — `dist_swingLo`, `dist_swingHi_4h`, `dist_swingLo_rank_near`, any
122
+ timeframe- or rank-suffixed form — is refused as `CONDITION_COLUMN_UNKNOWN` where 52.0.0 accepted
123
+ it. The same shapes exist on the `donchianHi` / `donchianLo` stems, which
124
+ `get_strategy_column_contract` lists with the labels *20-bar high* / *20-bar low*. Every value is
125
+ the same number under its new name.
126
+
127
+ **Rename the stems** (`swingHi` → `donchianHi`, `swingLo` → `donchianLo`, suffixes unchanged) in
128
+ every condition and Market Read marker you author. That is the whole migration for what you send.
129
+
115
130
  - **`entry.levelSource` is refused — the level is derived, never authored** (52.0.0,
116
131
  `derive-entry-level`). The strict `entry` object on `compile_strategy_plan`, `apply_strategy_plan`
117
132
  and `fork_strategy` is six keys — `trigger`, `confirmTf`, `closes`, `bandAtrMultiple`,
@@ -258,6 +273,11 @@ refuse is now stored. Listed because a client that special-cased the refusal can
258
273
 
259
274
  ### Removed — no alias exists
260
275
 
276
+ - **`SWING_LOW` / `SWING_HIGH` leave the stop and take-profit method enums, and the four S/R
277
+ indicator keys leave the signal vocabulary** (53.0.0, `rename-donchian-channel`). `DONCHIAN_LOWER`
278
+ / `DONCHIAN_UPPER` and `donchian_upper` / `donchian_lower` / `prev_donchian_upper` /
279
+ `prev_donchian_lower` carry the same values; nothing answers to the old names.
280
+
261
281
  - **`get_coin_market_context` is REMOVED** (40.0.0, `retire-get-coin-market-context`). Calling it
262
282
  returns an unknown-tool error. There is deliberately **no alias**: a silent redirect would hide a
263
283
  payload shape change from a client that never asked for one. Use `get_market_context`.
@@ -271,6 +291,19 @@ refuse is now stored. Listed because a client that special-cased the refusal can
271
291
 
272
292
  ### Reshaped output — the same call returns a different shape
273
293
 
294
+ - **Report headers, glosses and signal indicator keys are renamed for the Donchian channel**
295
+ (53.0.0, `rename-donchian-channel`). Every report surface — `preview_strategy_report`,
296
+ `get_strategy_section_template`, the agent prompt previews — renders `donchianHi` / `donchianLo`
297
+ and their `dist_…` / `…_rank_near` forms where it rendered `swingHi` / `swingLo`, with the labels
298
+ *20-bar high* / *20-bar low* and glosses that say what the number is (the highest high / lowest low
299
+ of the last 20 closed bars — the channel's edges). Signal definitions
300
+ (`get_strategy_signal_definition`, `list_strategy_signals`) and signal-log `indicatorValues`
301
+ carry `donchian_upper` / `donchian_lower` / `prev_donchian_upper` / `prev_donchian_lower` for the
302
+ four S/R signals. Signal ids, the `SUPPORT_RESISTANCE` module and its display names are unchanged.
303
+
304
+ **Read the new keys.** A reader keyed on `swing_high` / `swing_low` finds nothing; the values are
305
+ the same numbers under the new keys.
306
+
274
307
  - **The stored entry discipline no longer names a level source** (52.0.0, `derive-entry-level`).
275
308
  `StrategyDTO.entry` (`get_strategy`, `list_strategies`, the `fork_strategy` / `archive_strategy` /
276
309
  `restore_strategy` envelopes) and the apply envelope's `postState.entry` lose `levelSource`.
@@ -340,6 +373,11 @@ refuse is now stored. Listed because a client that special-cased the refusal can
340
373
 
341
374
  ### Widened enum — new members your own copy rejects
342
375
 
376
+ - **The stop and take-profit method enums gain `DONCHIAN_LOWER` / `DONCHIAN_UPPER`** (53.0.0,
377
+ `rename-donchian-channel`), replacing `SWING_LOW` / `SWING_HIGH` on the signal-pipeline detail
378
+ schemas — trade-setup options, R:R-rejected pairs and candidate levels. A copy of either enum that
379
+ rejects unknown members must add the two new ones; the two old ones never appear again.
380
+
343
381
  - **`TradeExecutionFailureReason` gains `LEVEL_NOT_RESTABLE`** (52.0.0, `derive-entry-level`): a
344
382
  level entry refused at placement because its resting price sat on the wrong side of the exchange
345
383
  mid — a buy stop at or below it, a buy limit at or above it, and the mirror for a sell. It appears
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.10";
52
+ export declare const PACKAGE_VERSION = "31.2.12";
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.10';
55
+ export const PACKAGE_VERSION = '31.2.12';
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.10",
3
+ "version": "31.2.12",
4
4
  "description": "BattleGrid MCP server — play crypto prediction games from AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
3
- "contractVersion": "52.0.0",
3
+ "contractVersion": "53.0.0",
4
4
  "files": {
5
5
  "battlegrid-agent-management/SKILL.md": "b6ea75b3d838c1dbaaf3984d7e99a11c81686de2c1a1910c35699ee7e70dafa5",
6
6
  "battlegrid-arena-play/SKILL.md": "03fa153bf82be18bf5ed01e3ba12e2cd9f99a81b08d903a77b52169e7519a182",
@@ -8,10 +8,11 @@
8
8
  "battlegrid-radar-deployment/SKILL.md": "d2a012b154e1e529db19529bd7c3d75d069f4e410d5804add51165f0f0902b2e",
9
9
  "battlegrid-strategy-authoring/SKILL.md": "2a973a9e52832ab1e0d9bf1b6d21b8bf898899bc3a455fde223646a01e914242",
10
10
  "battlegrid-strategy-doctor/SKILL.md": "9ab3f79128ec81d3e90167c3f1ea4bd6f6b570290e5ebe2bf855195263c58239",
11
- "battlegrid-strategy-examples/SKILL.md": "c986b9dfbf1a3dba083bd7f4fd0d06e187935d9c7e8bde175fafe592136b2f1d",
11
+ "battlegrid-strategy-examples/SKILL.md": "316c9635219c9a732e9c4bce9918a442be8b3ad9abac16c613224951e12887a1",
12
12
  "battlegrid-strategy-examples/references/playbooks.md": "35c543c090d00ba19e4bcf0a80502afac7a4954643fc535de0b24381c91ecbf4",
13
13
  "battlegrid-strategy-examples/references/recipes.md": "53887daece17995543e7d3fe1bf2577fc41a6254c291acacde48d7de63853641",
14
- "battlegrid-strategy-examples/references/tradingview-ports.md": "2f84758ba6ec015c7db3cf996f663971a7017eddbebe42d6ecba6386c7b78362",
15
- "battlegrid-trade-analysis/SKILL.md": "32573a67e55d735e6ee4e36b3b48c815694102704bc453c4d1c13db39551b3da"
14
+ "battlegrid-strategy-examples/references/tradingview-ports.md": "1ff63367de1f9a9fbbcd7ecd5367137800373df47aaeb1d61fb1298d3a1924f4",
15
+ "battlegrid-trade-analysis/SKILL.md": "32573a67e55d735e6ee4e36b3b48c815694102704bc453c4d1c13db39551b3da",
16
+ "battlegrid-trade-proposal/SKILL.md": "0a4586f660f605281c7775523c9e41422c6e52646ce52bf0688254af4619e46c"
16
17
  }
17
18
  }
@@ -145,7 +145,7 @@ level a level trigger rests at is DERIVED from the trigger and the trade's direc
145
145
  the tape, keeping the platform's flat wall-clock entry window. Today's behaviour.
146
146
  - `ON_CANDLE_CLOSE` — the flip ARMS the pair; the entry is taken only after a close on
147
147
  `confirmTf` that still reads the conditions true and has not displaced beyond the band.
148
- - `STOP_THROUGH_LEVEL` — a TRIGGER order rests past the swing channel's CURRENT edge in the
148
+ - `STOP_THROUGH_LEVEL` — a TRIGGER order rests past the Donchian channel's CURRENT edge in the
149
149
  trade's direction (the 20-bar high for a long, the 20-bar low for a short) by the offset, and
150
150
  the exchange book is the watcher; the entry is taken when price trades through, not when the
151
151
  platform notices.
@@ -60,10 +60,10 @@ rules about the columns themselves, not about porting — they live in the skill
60
60
  - **VWAP reversion** → `dist_VWAP` band + `dist_VWAP_rank_far lte 5` for board-relative
61
61
  stretch; required `NOT [ADX_state in ["trending","extreme"]]` veto; scalp geometry +
62
62
  aggressive timeDecay (VWAP anchors daily at 00:00 UTC).
63
- - **Donchian / Turtle breakout** → `zone is "breakout high"` + `dist_swingHi gte 0` +
63
+ - **Donchian / Turtle breakout** → `zone is "breakout high"` + `dist_donchianHi gte 0` +
64
64
  `RVOL gte 1.5`; `sr_resistance_break` 3 required; turtle exits = trend preset (trail from
65
65
  1R, giveback 50). Mirror with `"breakdown low"`. **Daily-breakout variant on any anchor:**
66
- pin the structure at 1d — `zone_1d is "breakout high"`, `dist_swingHi_1d gte 0` (validated).
66
+ pin the structure at 1d — `zone_1d is "breakout high"`, `dist_donchianHi_1d gte 0` (validated).
67
67
  **Literal previous-day levels are native**: `dist_PDH gte 0` composes directly. Their `{abs: '1d'}`
68
68
  binding is stated in `## Header grammar` in the skill body.
69
69
  - **ICT / SMC (FVG + order blocks)** → `STRUCT_ZONES` is the native zone engine:
@@ -0,0 +1,58 @@
1
+ ---
2
+ name: battlegrid-trade-proposal
3
+ description: Find and stage a trade for one of the player's agents, for the player to approve. Activate whenever the player asks which coins fit an agent right now, wants a trade found or proposed for an agent, asks the agent to evaluate a coin, or wants to approve or decline a proposal it made. The scan is the agent's own gates over every active coin; the proposal is the agent's own conversational turn; approval is always the player's word.
4
+ ---
5
+
6
+ # Trade Proposal
7
+
8
+ You are finding and staging a trade for an agent the player configured — never placing one. Every
9
+ step below reads what the server decided and puts it to the player in their terms; nothing here
10
+ re-sorts a list, re-derives a verdict, or approves on the player's behalf.
11
+
12
+ ## 0. What is already held — before anything else
13
+
14
+ - `list_pending_approvals` and `list_user_active_positions` first, every time.
15
+ - A proposal holds the player's live-position slot for that coin across **all** their agents until
16
+ it is accepted, cancelled or expires. **Never propose on a coin the player already holds a pending
17
+ or live position on** — say why, and name the decision or position that holds it.
18
+
19
+ ## 1. Which coins fit the agent right now
20
+
21
+ - `scan_agent_coins` for the agent. The rows arrive server-ranked: qualifying coins first by score,
22
+ then the rest with their first failing gate, then coins that could not be scored with the reason.
23
+ - Read the rows **as written**: the rank, the verdict, the first failing gate, the unscorable
24
+ label. Never re-sort them and never re-derive a verdict from its numbers — the server's ranking
25
+ is the answer.
26
+ - A refused scan (`RATE_LIMITED`) is a refusal: say the scan was refused and when it can be retried
27
+ (`retryAfterSeconds`). Never say "nothing fits".
28
+
29
+ ## 2. Propose
30
+
31
+ - `propose_entry_decision` **only** on the coins the player named, or on the top qualifying row
32
+ when they asked for the best fit. One coin per call.
33
+ - `userMessage` is the player's own words for the turn. Mint a **fresh UUID** `idempotencyKey` per
34
+ proposal; a retry with the same key replays the recorded result and never runs a second turn.
35
+ - The call is synchronous and may take the turn's full LLM latency. Do not retry while it is in
36
+ flight; a same-key call during that time is refused with `CONFLICT`.
37
+
38
+ ## 3. Report the outcome in the player's terms
39
+
40
+ - `type: "recommendation"` — the PROPOSED decision, awaiting approval. State the direction, the
41
+ entry, stop and take-profit levels, the position size, the **`convictionPercent`**, and the
42
+ expiry (`expiresAt`). No conviction floor was applied on this surface: the conviction is the
43
+ agent's own reading, and the player judges it.
44
+ - `type: "no_trade"` — the reason (`reasonCode`) and the next coins worth asking about.
45
+ - `type: "error"` — the engine's block or a post-billing failure, with its remedy:
46
+ `OPEN_POSITION_CONFLICT` means a position already holds the slot (see step 0);
47
+ `LLM_CREDITS_EXHAUSTED` means top up when `topupAvailable` is true; a `SURFACE` / `LLM_FAILURE`
48
+ means the model was billed and produced nothing usable — retry **with a new key**, since the
49
+ same key replays this failure.
50
+ - A refused proposal (`RATE_LIMITED`) is a refusal with its retry-after. Never "nothing to do".
51
+
52
+ ## 4. Approve or decline — only on the player's word
53
+
54
+ - Present the decision and **ask**. `accept_entry_decision` only after the player explicitly
55
+ approves; `cancel_entry_decision` only after they explicitly decline.
56
+ - Never accept because the conviction reads high, because the scan ranked the coin first, or
57
+ because the player asked you to "find a trade" — finding is not approving. `get_entry_decision`
58
+ re-reads the row if the conversation moved on before they answered.