@battlegrid/mcp-server 31.2.26 → 31.2.28
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 +56 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/EXPORT.json +4 -4
- package/skills/battlegrid-strategy-authoring/SKILL.md +3 -3
- package/skills/battlegrid-strategy-examples/SKILL.md +59 -33
- package/skills/battlegrid-trade-proposal/SKILL.md +16 -0
package/README.md
CHANGED
|
@@ -24,6 +24,62 @@ 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 — v61
|
|
28
|
+
|
|
29
|
+
One part to read first: **the per-condition evidence clock is gone**, and what replaced it is not a
|
|
30
|
+
rename. Which bar a condition reads is now decided by the surface asking — a decision reads completed
|
|
31
|
+
strategy bars, a display read shows the forming one — and by each candle column's own Confirmed /
|
|
32
|
+
Developing selector. `closes` survives and changes meaning. The canonical record for every contract
|
|
33
|
+
move is `docs/architecture/MCP_CONTRACT_HISTORY.md` in `battlegrid-app`; the served version is what
|
|
34
|
+
the handshake announces.
|
|
35
|
+
|
|
36
|
+
### Rejected input — something you author is no longer accepted
|
|
37
|
+
|
|
38
|
+
- **A condition entry carrying `clock` is REFUSED** (61.0.0, `read-higher-timeframes-per-column`).
|
|
39
|
+
The authoring schemas are `.strict()`, so `compile_strategy_plan`, `apply_strategy_plan`,
|
|
40
|
+
`fork_strategy` and the HTTP save alike fail the body with the unknown-key error. There is no
|
|
41
|
+
replacement key to send: the decision instant belongs to the caller, not to the condition. Two
|
|
42
|
+
input hashes move, `compile_strategy_plan`'s and `preview_strategy_report`'s — the two tools that
|
|
43
|
+
accept a condition entry.
|
|
44
|
+
|
|
45
|
+
- **`closes` stays mandatory and means something new.** It is now *held for N completed strategy
|
|
46
|
+
bars* (1–5). Above `1` it is legal only over a header a completed bar actually moves, at or above
|
|
47
|
+
the strategy timeframe, never over a developing read, and only where the condition carries a clause
|
|
48
|
+
of its own — a referenced condition resolves once and contributes the same answer to every bar, so
|
|
49
|
+
a hold reached only through a reference would count reads that never happened.
|
|
50
|
+
|
|
51
|
+
### Changed shape — what you receive moves
|
|
52
|
+
|
|
53
|
+
- **`ConditionOutcome.closeClock` becomes `hold`, and it is NON-NULL for every condition.** A
|
|
54
|
+
one-close condition reads `0 or 1 of 1` rather than serving an absence, so a client no longer
|
|
55
|
+
branches on whether the reading exists. The count is taken from completed strategy bars whatever
|
|
56
|
+
basis the surface evaluated on.
|
|
57
|
+
|
|
58
|
+
- **`ReportConditionColumnDTO.closeClockReadable` becomes `closesReadable`, beside a new
|
|
59
|
+
`developingRead`.** The first answers whether a condition addressing that header may hold more than
|
|
60
|
+
one completed bar; the second states whether the header reads the bar still in progress at the
|
|
61
|
+
decision instant. Both are server-supplied — derive neither. Eight output hashes move, covering
|
|
62
|
+
every tool that serves a strategy's conditions or a report's addressable columns.
|
|
63
|
+
|
|
64
|
+
### Wider input — nothing you send today breaks
|
|
65
|
+
|
|
66
|
+
- **The `bars` selector is declared on eleven candle-series transforms, not four.** `value`,
|
|
67
|
+
`classifyZone`, `classifyState`, `distance`, `spread`, `crossDetect` and `bandTouch` join
|
|
68
|
+
`trajectory`, `aggregate`, `efficiency` and `maxShare`. It carries **no default value**, because
|
|
69
|
+
the default is a rule rather than a constant: Confirmed (`"closed"`) above the strategy timeframe,
|
|
70
|
+
and at or below it the series as the frame carries it. The resolved answer is served per column on
|
|
71
|
+
`effectiveParameters.bars` — `null` where discovery has no anchor to resolve a rung against.
|
|
72
|
+
|
|
73
|
+
- **A higher-timeframe level is measured from the current strategy-bar price.** Distances and the
|
|
74
|
+
candle label classifiers compare against the frame's current price rather than the higher-timeframe
|
|
75
|
+
bar's own close, which could be a full higher-timeframe bar stale. A distance chained into a series
|
|
76
|
+
keeps every slot on its own bar's close.
|
|
77
|
+
|
|
78
|
+
### Vocabulary
|
|
79
|
+
|
|
80
|
+
`domains.conditionClock` is removed; `domains.columnBars: ["all", "closed"]` takes its place, and
|
|
81
|
+
`axes.condition` loses `clock`. `toolCount` stays 117.
|
|
82
|
+
|
|
27
83
|
## Contract history — v60
|
|
28
84
|
|
|
29
85
|
One release train, four numbers, and two parts to read first: **`propose_entry_decision` no longer
|
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.
|
|
52
|
+
export declare const PACKAGE_VERSION = "31.2.28";
|
|
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.
|
|
55
|
+
export const PACKAGE_VERSION = '31.2.28';
|
|
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
package/skills/EXPORT.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
|
|
3
|
-
"contractVersion": "
|
|
3
|
+
"contractVersion": "61.0.1",
|
|
4
4
|
"files": {
|
|
5
5
|
"battlegrid-agent-management/SKILL.md": "b6ea75b3d838c1dbaaf3984d7e99a11c81686de2c1a1910c35699ee7e70dafa5",
|
|
6
6
|
"battlegrid-arena-play/SKILL.md": "03fa153bf82be18bf5ed01e3ba12e2cd9f99a81b08d903a77b52169e7519a182",
|
|
7
7
|
"battlegrid-market-analysis/SKILL.md": "22fde9c4eac0261c89a8056ab8b20b66fcbe1fd58447fa0ac84fd410b4d134d7",
|
|
8
8
|
"battlegrid-radar-deployment/SKILL.md": "d2a012b154e1e529db19529bd7c3d75d069f4e410d5804add51165f0f0902b2e",
|
|
9
|
-
"battlegrid-strategy-authoring/SKILL.md": "
|
|
9
|
+
"battlegrid-strategy-authoring/SKILL.md": "93e1c9709079a4e9c968597ac572b4b62f5b0e68c01f9e9947db7e2ba304dcdf",
|
|
10
10
|
"battlegrid-strategy-doctor/SKILL.md": "9ab3f79128ec81d3e90167c3f1ea4bd6f6b570290e5ebe2bf855195263c58239",
|
|
11
|
-
"battlegrid-strategy-examples/SKILL.md": "
|
|
11
|
+
"battlegrid-strategy-examples/SKILL.md": "17e8cf8040813622bd5b82165c7af82e03287fee1f6aac974e0b6c584580dd27",
|
|
12
12
|
"battlegrid-strategy-examples/references/playbooks.md": "35c543c090d00ba19e4bcf0a80502afac7a4954643fc535de0b24381c91ecbf4",
|
|
13
13
|
"battlegrid-strategy-examples/references/recipes.md": "53887daece17995543e7d3fe1bf2577fc41a6254c291acacde48d7de63853641",
|
|
14
14
|
"battlegrid-strategy-examples/references/tradingview-ports.md": "2b13adbc137178955edcca31b6ab40c01c745a932a0750b91db8820c736700bb",
|
|
15
15
|
"battlegrid-trade-analysis/SKILL.md": "32573a67e55d735e6ee4e36b3b48c815694102704bc453c4d1c13db39551b3da",
|
|
16
|
-
"battlegrid-trade-proposal/SKILL.md": "
|
|
16
|
+
"battlegrid-trade-proposal/SKILL.md": "0d8ffecd493f7916d352cee3d22aee5812c3790592b100d3f9802c75ca1180c0"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -104,9 +104,9 @@ question you would otherwise guess — and a refusal you would otherwise earn:
|
|
|
104
104
|
`levelOffsetAtrMultiple`, `validForBars`. Every trigger is decided at the close of the strategy's
|
|
105
105
|
OWN bar, so there is no confirm-timeframe key; for the level triggers the level itself is derived
|
|
106
106
|
from the trigger and the trade's direction, never named. A multi-bar hold belongs to the condition
|
|
107
|
-
that needs it (
|
|
108
|
-
skill carries the vocabulary
|
|
109
|
-
refused outright.
|
|
107
|
+
that needs it (its own `closes`, counted in completed strategy bars), not to this axis. The
|
|
108
|
+
`strategy-examples` skill carries the vocabulary, the hold's legality and the per-column
|
|
109
|
+
Confirmed / Developing read; a CREATE without it is refused outright.
|
|
110
110
|
- `get_strategy_column_contract` → `outputs[].conditionOperators`. An empty array means that
|
|
111
111
|
rendered header has no comparison semantics and cannot appear in a condition clause at all.
|
|
112
112
|
Legality is per rendered header, not per column: a trajectory's slot header and its `_trend`
|
|
@@ -86,8 +86,9 @@ against a literal; neither of those shapes is what a previous-session level need
|
|
|
86
86
|
|
|
87
87
|
## Conditions
|
|
88
88
|
|
|
89
|
-
`{ conditionKey, name, definition, verdict, required, exit,
|
|
90
|
-
required, no defaults.
|
|
89
|
+
`{ conditionKey, name, definition, verdict, required, exit, closes }` — all seven
|
|
90
|
+
required, no defaults. A `clock` key is REFUSED: the per-condition evidence clock was retired in
|
|
91
|
+
contract `61.0.0`. Clauses: numeric/rank headers take `lt|lte|gte|gt|between`;
|
|
91
92
|
classification/direction headers take `is|in` with the served vocabulary. Groups:
|
|
92
93
|
`ALL | ANY | NOT | N_OF` (with `n`), depth ≤ 2. `conditionRef` composes named conditions (no
|
|
93
94
|
cycles; forward refs legal). `sectionKey: null` is sugar for a report-unique header only.
|
|
@@ -103,30 +104,53 @@ before billing. And the RESOLVED verdict binds entry DIRECTION: `UP` admits long
|
|
|
103
104
|
setups block and from the `decide_trade` contract, not merely discouraged in them. A strategy that
|
|
104
105
|
declares no verdict-carrying condition resolves `null` and constrains nothing.
|
|
105
106
|
|
|
106
|
-
A verdict carrier must read
|
|
107
|
-
|
|
108
|
-
plus everything reached through `conditionRef`,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
change
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
`
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
107
|
+
A verdict carrier must read no DEVELOPING bar. A verdict is refused over any closure that reads a
|
|
108
|
+
column selecting Developing above the strategy timeframe (`CONDITION_VERDICT_READ_ILLEGAL`). The
|
|
109
|
+
closure is what the condition reads directly plus everything reached through `conditionRef`,
|
|
110
|
+
transitively: a referenced condition contributes what IT reads, so moving the clause into a building
|
|
111
|
+
block does not launder it. A closure whose candle columns all read Confirmed — or whose operands no
|
|
112
|
+
bar moves at all, such as a published regime label, an open-interest regime or a published rolling
|
|
113
|
+
change — admits a verdict at every decision, because a decision reads the completed strategy bar and
|
|
114
|
+
a level is compared against that bar's close.
|
|
115
|
+
|
|
116
|
+
Evaluation is three-valued: UNRESOLVED never collapses to FALSE; a developing read is provisional,
|
|
117
|
+
and so is any reading taken on the display lane's forming bar.
|
|
118
|
+
|
|
119
|
+
**Every condition is decided at the strategy bar's close.** There is no per-condition clock. Which
|
|
120
|
+
bar a condition reads is decided by the surface asking — a decision (the radar's close decision, the
|
|
121
|
+
compose that takes the trade, the exit sweep) reads completed strategy bars; a display read shows the
|
|
122
|
+
forming one and decides nothing — and by each candle column's own Confirmed / Developing selector.
|
|
123
|
+
|
|
124
|
+
**The hold count.** `closes` is how many consecutive COMPLETED strategy bars must read TRUE (1–5). A
|
|
125
|
+
hold counts the same completed bars whichever surface asks, so a held condition reads them on the
|
|
126
|
+
display lane too. Above `1` it is legal **only** where a completed bar changes the reading: over a
|
|
127
|
+
header resolved from this coin's own candle series, at offset 0, at or above the strategy timeframe,
|
|
128
|
+
read Confirmed. Everything else is refused (`CONDITION_HOLD_OPERAND_ILLEGAL`) — perp-payload scalars,
|
|
129
|
+
published rolling changes, ranks, zone entities, MDS regime labels, enrichment metrics, session
|
|
130
|
+
scalars, a non-zero offset, a column BELOW the strategy timeframe (the retained lower series cannot
|
|
131
|
+
reach an earlier strategy close), and a developing read (the bar in progress exists on the newest
|
|
132
|
+
frame only). A hold also needs a clause of the condition's OWN
|
|
133
|
+
(`CONDITION_HOLD_ILLEGAL`): a referenced condition is resolved once and contributes the same answer
|
|
134
|
+
to every frame, so a hold that moves with the bar only through a reference would count reads that
|
|
135
|
+
never happened. **Worked liquidity floor:** `LIQUID_FLOOR` holds one close because `vol24hUsd` is a
|
|
136
|
+
bundle scalar. Reach for a split to keep a condition's MEANING separable, not to buy it a hold.
|
|
137
|
+
|
|
138
|
+
**Confirmed / Developing, per candle column.** Every transform whose home is the coin's candle series
|
|
139
|
+
carries `bars`: `"closed"` is Confirmed — the newest bar completed at the strategy close — and
|
|
140
|
+
`"all"` is Developing, the higher-timeframe bar still in progress at that close, which REPAINTS until
|
|
141
|
+
it completes. Left unset the default is a rule, not a value: Confirmed for a column ABOVE the
|
|
142
|
+
strategy timeframe, and at or below it the series as the frame carries it. At or below the strategy
|
|
143
|
+
timeframe the choice therefore sets only what the live lane shows — no bar is in progress at the
|
|
144
|
+
anchor's own close — so Developing there is legal and changes no decision. A condition reading a
|
|
145
|
+
developing bar is single-frame: it holds one close, carries no verdict and cannot take the `exit`
|
|
146
|
+
role. The resolved answer for a column is served on `effectiveParameters.bars`.
|
|
147
|
+
|
|
148
|
+
**A higher-timeframe level is measured from the current strategy-bar price.** The distance to a `4h`
|
|
149
|
+
Donchian band, and every candle label classifier (`MA_ALIGN`, `PRICE_ZONE`, `BB_TOUCH`), compares
|
|
150
|
+
against the frame's current price — the strategy bar's close under a decision, the live mark on
|
|
151
|
+
display — not against the higher-timeframe bar's own close, which is up to one higher-timeframe bar
|
|
152
|
+
stale. A distance CHAINED into a series transform keeps every slot on its own bar's close, so one
|
|
153
|
+
series carries one reference basis.
|
|
130
154
|
|
|
131
155
|
**The lane a strategy is deployed to.** Report-level scalars split by LANE, and the split is not a
|
|
132
156
|
quality of the header — it is which reader runs. Market breadth and the reference pairs are ordinary
|
|
@@ -138,10 +162,12 @@ can read instead. The refusal lands at DEPLOY rather than at save, because a str
|
|
|
138
162
|
of its own: the same strategy is legal, and reads those scalars correctly, on an arena agent.
|
|
139
163
|
|
|
140
164
|
**The exit role.** `exit: true` makes a settled TRUE reading close open positions its verdict
|
|
141
|
-
opposes — UP exits SHORTs, DOWN exits LONGs, a NEITHER or `null` verdict exits both. Legal only
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
165
|
+
opposes — UP exits SHORTs, DOWN exits LONGs, a NEITHER or `null` verdict exits both. Legal only over
|
|
166
|
+
a closure every operand of which a completed bar MOVES (`CONDITION_EXIT_READ_ILLEGAL`), which rules
|
|
167
|
+
out a developing read — a bar in progress is the forming bar, and an exit fired on one is an intrabar
|
|
168
|
+
exit — and rules out a frame-inert operand, which could never fire. Orthogonal to `required` — the
|
|
169
|
+
two act on disjoint lifecycles, pre-entry versus open — so a condition may carry both, either, or
|
|
170
|
+
neither.
|
|
145
171
|
|
|
146
172
|
**A state column is not a flip event.** `ST_DIR` reads the same on every bar of a trend, so
|
|
147
173
|
`ST_DIR is "bullish"` is a regime filter and never an entry signal. The flip needs an event column
|
|
@@ -163,7 +189,7 @@ is DERIVED from the trigger and the trade's direction, never named. There is no
|
|
|
163
189
|
key either: the bar whose close decides an entry is the strategy's OWN timeframe.
|
|
164
190
|
|
|
165
191
|
**Every trigger is decided at the close of the strategy's own bar — there are three, and the close
|
|
166
|
-
is the only entry clock.** The newest
|
|
192
|
+
is the only entry clock.** The newest completed bar is read on the closed basis — every one-close
|
|
167
193
|
condition resolves on that bar and the scorecard reads its close — and a reading that still qualifies
|
|
168
194
|
fires at that close. A bar that does not qualify decides nothing and is not revisited. The fill lands
|
|
169
195
|
at the next tick, and the platform refuses it if the market has already run past its own drift budget
|
|
@@ -180,8 +206,8 @@ and is REFUSED on every save; there is no live-reading entry to author.
|
|
|
180
206
|
short) by the offset, waiting for a return to it. Not filling is a correct outcome, not a
|
|
181
207
|
failure; no unrecovered break in memory means no setup, never a fallback level.
|
|
182
208
|
|
|
183
|
-
**A multi-bar hold belongs to the CONDITION that needs it.** Declare
|
|
184
|
-
|
|
209
|
+
**A multi-bar hold belongs to the CONDITION that needs it.** Declare that condition's own `closes` —
|
|
210
|
+
the entry axis counts no bars, and there is no displacement band: the
|
|
185
211
|
platform's entry-deviation gate measures the live mark against the decided close and refuses a fill
|
|
186
212
|
that drifted past the budget in either direction.
|
|
187
213
|
|
|
@@ -31,6 +31,15 @@ re-sorts a list, re-derives a verdict, or approves on the player's behalf.
|
|
|
31
31
|
|
|
32
32
|
## 2. Queue the request
|
|
33
33
|
|
|
34
|
+
**In a conversation the Agent Toolbox hosts, this section does not apply: name the coin and stop.**
|
|
35
|
+
The player presses **Request a trade** in the trade lane beside you and the same queued request is
|
|
36
|
+
registered from there, free and without a model turn; your job is to say which coin is worth
|
|
37
|
+
requesting and what the gates read, and to leave the press to them. `propose_entry_decision` and
|
|
38
|
+
`cancel_entry_request` are refused from such a conversation as tool errors, so calling one spends an
|
|
39
|
+
op of your budget and queues nothing. The refusal is **host-wide** — every tool that writes is
|
|
40
|
+
refused there, which is why no other skill carries a paragraph of its own — and every read in this
|
|
41
|
+
flow stays available.
|
|
42
|
+
|
|
34
43
|
- `propose_entry_decision` **only** on the coins the player named, or on the top qualifying row
|
|
35
44
|
when they asked for the best fit. One coin per call.
|
|
36
45
|
- **The call does not decide.** It registers a request against the agent's next strategy-bar close
|
|
@@ -62,6 +71,13 @@ re-sorts a list, re-derives a verdict, or approves on the player's behalf.
|
|
|
62
71
|
|
|
63
72
|
## 4. When the answer arrives — approve or decline only on the player's word
|
|
64
73
|
|
|
74
|
+
**In a conversation the Agent Toolbox hosts, the approval is not yours to send.** The decided close
|
|
75
|
+
lands on the trade card in the lane beside you, carrying the player's own Accept and Decline;
|
|
76
|
+
`accept_entry_decision` and `cancel_entry_decision` are refused there as tool errors, so calling one
|
|
77
|
+
spends an op and moves nothing. Read the card back to them — the direction, the levels, the
|
|
78
|
+
conviction, the expiry — and say what you would do, which is the whole of your part. What you have
|
|
79
|
+
to work from is whatever the player attaches from a card: its rendered readings, nothing more.
|
|
80
|
+
|
|
65
81
|
- A decided close produces one of: a PROPOSED decision awaiting approval; a no-trade with the
|
|
66
82
|
reason and the next coins worth asking about; a close that did not qualify; a window that passed
|
|
67
83
|
with no sweep; or a bar the agent's own radar deployment decided first and traded in full.
|