@battlegrid/mcp-server 32.0.0 → 32.0.2
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 +77 -0
- package/SKILL.md +3 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/skills/EXPORT.json +3 -3
- package/skills/battlegrid-radar-deployment/SKILL.md +22 -3
- package/skills/battlegrid-radar-deployment/references/radar-stage-examples.md +4 -1
package/README.md
CHANGED
|
@@ -38,6 +38,83 @@ Seeing package `31.x` alongside handshake `battlegrid@33.x` — the package **be
|
|
|
38
38
|
|
|
39
39
|
**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.
|
|
40
40
|
|
|
41
|
+
## Contract history — v118.1 (a server fault says whether repeating is safe)
|
|
42
|
+
|
|
43
|
+
**Nothing you send is refused that v118 accepted.** v118.1 is the contract on top of v118. No input schema moves.
|
|
44
|
+
Reconnect the proxy, or restart it, so discovery reads the new annotation below.
|
|
45
|
+
|
|
46
|
+
### Added fields
|
|
47
|
+
|
|
48
|
+
- **`details.correlationId`** is on every error envelope. The server mints it once per call and writes it on that
|
|
49
|
+
call's one log entry, so quote it when you report a failure.
|
|
50
|
+
- **`details.retryable`** is on a server fault: `SERVICE_UNAVAILABLE` from an unavailable dependency, and every
|
|
51
|
+
`INTERNAL_ERROR`. It says whether repeating the same call unchanged is safe, never that it will succeed:
|
|
52
|
+
- `true` means a repeat has no additional effect. If the repeat is then refused, follow that refusal;
|
|
53
|
+
- `false` on `SERVICE_UNAVAILABLE` means the call may have taken effect, so read the current state before
|
|
54
|
+
repeating it;
|
|
55
|
+
- `false` on `INTERNAL_ERROR` means repeating fails the same way;
|
|
56
|
+
- absent, on any typed refusal, means its message and `nextAct` say whether repeating helps.
|
|
57
|
+
|
|
58
|
+
### Reclassified
|
|
59
|
+
|
|
60
|
+
- **A dependency the server could not use answers `SERVICE_UNAVAILABLE`**, where it answered `INTERNAL_ERROR`. That
|
|
61
|
+
covers a dropped database or Redis connection, a serialization failure or deadlock, a network timeout, and the
|
|
62
|
+
exchange budget declining to admit a call. `retryable` is `true` for a tool that declares `readOnlyHint` or
|
|
63
|
+
`idempotentHint`.
|
|
64
|
+
- **`reset_agent_drawdown_baseline` declares `idempotentHint: false`.** Each call moves the drawdown baseline to now,
|
|
65
|
+
so a repeat forgives any loss realized in between.
|
|
66
|
+
|
|
67
|
+
## Contract history — v118 (a refused argument is the house error envelope)
|
|
68
|
+
|
|
69
|
+
**Breaking at v118: an argument refusal is JSON, and the scope check comes first.** v118 is the contract on top of
|
|
70
|
+
v117. No schema moves, so nothing you send is refused that v117 accepted. Code that read the SDK's refusal sentence
|
|
71
|
+
must read the envelope instead.
|
|
72
|
+
|
|
73
|
+
### Reshaped output — something you read has a new shape
|
|
74
|
+
|
|
75
|
+
- **A call whose arguments the tool's schema refuses** is an `isError` result whose text is the same JSON envelope
|
|
76
|
+
every other refusal uses: `{ "code": "VALIDATION_ERROR", "message", "details": { "issueCount", "issues" } }`. It
|
|
77
|
+
was the SDK's `Input validation error: …` sentence.
|
|
78
|
+
|
|
79
|
+
### Refusal vocabulary
|
|
80
|
+
|
|
81
|
+
- **`details.issues`** holds the first 20 issues in the order the parse found them. Each is `{ path, message }`:
|
|
82
|
+
- `path` is where the issue is, as segments within the arguments object, and `[]` is the arguments object itself;
|
|
83
|
+
- `message` is the schema's own text, so a remedy the schema appends to an issue reaches you unchanged.
|
|
84
|
+
- **`details.issueCount`** is how many issues the parse found. It exceeds the length of `issues` when more than 20
|
|
85
|
+
were found.
|
|
86
|
+
- **An unrecognised key** is reported at the path of the object it was sent on, by an issue whose message names the
|
|
87
|
+
key. A retired argument therefore shows up as an issue on its parent object, not as a path ending in its own name.
|
|
88
|
+
- **`message`** is the first issue's message.
|
|
89
|
+
- **The refusal carries no `details.nextAct`.** Recover by making the same call with corrected arguments. A refusal of
|
|
90
|
+
a draft's staged content still carries `nextAct: "stage"`, so the two are told apart by `details.issues`.
|
|
91
|
+
|
|
92
|
+
### Behaviour behind unchanged schemas
|
|
93
|
+
|
|
94
|
+
- **The required scope is checked before the arguments are parsed.** A credential without the tool's scope is refused
|
|
95
|
+
`FORBIDDEN` with `details.requiredScope` whatever it sends. Before, an argument object the schema refused was
|
|
96
|
+
answered by the parse first.
|
|
97
|
+
|
|
98
|
+
## Contract history — v117 (decided changes read at their horizon bar)
|
|
99
|
+
|
|
100
|
+
**Breaking at v117, behind unchanged schemas.** v117 is the contract on top of v116; no input or output schema moves.
|
|
101
|
+
|
|
102
|
+
### Rejected input — something you send is no longer accepted
|
|
103
|
+
|
|
104
|
+
- **A verdict carrier or hold that reads a change over a horizon above the strategy timeframe is refused.** That is
|
|
105
|
+
`chg4h` and `chg24h` on a `1h` strategy, and `oiRegime` (the `1h` change) below `1h`. Such a change is a developing
|
|
106
|
+
read whatever its selector.
|
|
107
|
+
- **Where it is refused:** a strategy save, draft stage or preview, refused `CONDITION_VERDICT_READ_ILLEGAL` or
|
|
108
|
+
`CONDITION_HOLD_ILLEGAL`. Restoring an archived strategy that holds one is refused the same way until it is
|
|
109
|
+
repaired.
|
|
110
|
+
- **What the refusal says:** it names the carrier and the column, with a remedy that reads a horizon at or below
|
|
111
|
+
the strategy timeframe.
|
|
112
|
+
|
|
113
|
+
### Behaviour behind unchanged schemas
|
|
114
|
+
|
|
115
|
+
- **A change is the frame's price against its horizon bar's open.** A decided frame reads it exactly where it read
|
|
116
|
+
UNRESOLVED, and a horizon whose bar was not read is UNRESOLVED where it read FALSE.
|
|
117
|
+
|
|
41
118
|
## Contract history — v116 (the server moves to MCP SDK v2 and protocol 2026-07-28)
|
|
42
119
|
|
|
43
120
|
**Breaking at v116: `test_generate_deployment_grid` takes its payload at the top level.** v116 is the contract on top
|
package/SKILL.md
CHANGED
|
@@ -72,8 +72,9 @@ than about authoring:
|
|
|
72
72
|
`expectedPolicyId` and `expectedRevision` a `COMMITTED` preview returned.
|
|
73
73
|
- **The proxy forwards numbers and `null` unchanged.** It never fills in a version, never retries a
|
|
74
74
|
refused call and never rebuilds a request. A `DRAFT_VERSION_MOVED` or `DRAFT_AXIS_CONTESTED` refusal
|
|
75
|
-
carries `details.nextAct` from every tool, and a revision `CONFLICT` or
|
|
76
|
-
from a stage or commit
|
|
75
|
+
carries `details.nextAct` from every tool, and a revision `CONFLICT` or a refusal of the staged content
|
|
76
|
+
carries it from a stage or commit. A refused argument (`VALIDATION_ERROR` with `details.issues`)
|
|
77
|
+
carries none: make the same call with the arguments corrected. The next act is the caller's.
|
|
77
78
|
|
|
78
79
|
`fork_strategy` copies a revision into a new create draft and creates nothing until that draft is
|
|
79
80
|
committed. An agent binds to a strategy through its draft's `STRATEGY_BINDING` axis, on a create or
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ import { Client, StreamableHTTPClientTransport } from '@modelcontextprotocol/cli
|
|
|
47
47
|
* being asked. Move it for a change to THIS package — a proxy fix, a dependency bump, a docs
|
|
48
48
|
* correction. Never move it to track the server.
|
|
49
49
|
*/
|
|
50
|
-
export declare const PACKAGE_VERSION = "32.0.
|
|
50
|
+
export declare const PACKAGE_VERSION = "32.0.2";
|
|
51
51
|
export declare const DEFAULT_URL = "https://mcp.battlegrid.trade/mcp";
|
|
52
52
|
export interface EnvConfig {
|
|
53
53
|
apiKeys: string[];
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,7 @@ import { Client, SdkHttpError, StreamableHTTPClientTransport } from '@modelconte
|
|
|
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 const PACKAGE_VERSION = '32.0.
|
|
52
|
+
export const PACKAGE_VERSION = '32.0.2';
|
|
53
53
|
export const DEFAULT_URL = 'https://mcp.battlegrid.trade/mcp';
|
|
54
54
|
const MAX_RETRIES = 3;
|
|
55
55
|
const RETRY_DELAYS_MS = [2000, 4000, 8000];
|
package/package.json
CHANGED
package/skills/EXPORT.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generator": "battlegrid-app/server/scripts/export-mcp-skills.mjs",
|
|
3
|
-
"contractVersion": "
|
|
3
|
+
"contractVersion": "116.0.0",
|
|
4
4
|
"files": {
|
|
5
5
|
"battlegrid-agent-management/SKILL.md": "9dc151c32c3578d06e8895c6752d7a64959bff6a6681a01d62ab65e1ea1590d1",
|
|
6
6
|
"battlegrid-agent-management/references/agent-stage-examples.md": "dffcc353d61dfc7b5bb6a2b3077fc6bf8c760a34c287cafb3b59b99306f24195",
|
|
7
7
|
"battlegrid-arena-play/SKILL.md": "2e37970a66b8738ffbc445a23da90651c1f41b56ce4eef551582ab123517ef74",
|
|
8
8
|
"battlegrid-arena-play/references/entry-stage-examples.md": "0223f3743171ff213e943789d27590b2f65648398e85e10cd24938d5eb6af665",
|
|
9
9
|
"battlegrid-market-analysis/SKILL.md": "fcbe98e30e1edce39bb170c224cdf20181934f62b5f3a26b293787c70eeb6229",
|
|
10
|
-
"battlegrid-radar-deployment/SKILL.md": "
|
|
10
|
+
"battlegrid-radar-deployment/SKILL.md": "cf6664f51f92d40acce21a46f4fb078d9afe46c99c4f4b603bf002e73d4c5a23",
|
|
11
11
|
"battlegrid-radar-deployment/references/arena-stage-examples.md": "d27cfed1f4663f267c4a7ecebe4a6e65a450fc74bd14ce8987fb61af5bbf2ca5",
|
|
12
|
-
"battlegrid-radar-deployment/references/radar-stage-examples.md": "
|
|
12
|
+
"battlegrid-radar-deployment/references/radar-stage-examples.md": "13fc3f55d91d3da9754e1ed7fb27493b7b7ba4d40a6a7e8d1ee0365f90ea10de",
|
|
13
13
|
"battlegrid-strategy-authoring/SKILL.md": "39cfa46b1f640e6800edb7e85a8f2c4b6b8786cddf71bb8244d172a44fc11d75",
|
|
14
14
|
"battlegrid-strategy-authoring/references/strategy-stage-examples.md": "f10ecdc91f3660a708eee7a7bacefce2acbb46c9cf7e0ac1454bd54f839f39fd",
|
|
15
15
|
"battlegrid-strategy-doctor/SKILL.md": "e34e055b0cc9b355bc1adeb5d49d464eaa0756ca3f48dc89ca2ccdda94e1311f",
|
|
@@ -107,7 +107,12 @@ is test-routing a regime. Never carry a fact from a radar conversation into it,
|
|
|
107
107
|
Do not confirm a draft whose diagnostics carry an error: stage a fix.
|
|
108
108
|
3. `preview_radar_resolution({ coinId, request: { kind: "DRAFT", draftVersion } })` at the version that
|
|
109
109
|
read returned. It composes the draft over the deployed policy **exactly as the commit will write it**,
|
|
110
|
-
and refuses a draft no longer at that version with `DRAFT_VERSION_MOVED`.
|
|
110
|
+
and refuses a draft no longer at that version with `DRAFT_VERSION_MOVED`. Its `ruleCloseCoverage`
|
|
111
|
+
counts, for each hours rule, the closes of its agent's `strategyTimeframe` bar the rule's hours let
|
|
112
|
+
it decide through `windowEndAt`. Before asking the player to commit, name every rule whose
|
|
113
|
+
`decidableCloses` is 0: its agent's timeframe, the served `windowEndAt`, and that it is this rule's
|
|
114
|
+
hours alone that hold no close — not the agent, which still decides closes it is on duty for through
|
|
115
|
+
another rule or the default. Never tell the player the agent will not trade.
|
|
111
116
|
|
|
112
117
|
To try a slot set without touching the draft, preview `{ kind: "SLOTS", slots }` — it resolves
|
|
113
118
|
explicit slots and nothing can commit it.
|
|
@@ -122,6 +127,19 @@ from what the player asked for:
|
|
|
122
127
|
| only in named hours and days | a rule with an hours condition |
|
|
123
128
|
| in named regimes during named hours | a rule with one hours condition and one regime condition |
|
|
124
129
|
|
|
130
|
+
When the player names an exchange session — New York, the New York open, London, the London open,
|
|
131
|
+
the London–New York overlap, Tokyo, the Tokyo open — call `get_radar_market_hours` and stage that session's `hours`
|
|
132
|
+
exactly as served, merged with any other session they name; never work session hours out yourself,
|
|
133
|
+
because New York and London shift with daylight saving on their own dates and the overlap changes
|
|
134
|
+
shape on each of those dates. The three opens are one hour wide, so they suit agents on 1h bars or
|
|
135
|
+
faster. The days stay the player's choice. Tell the player the staged hours are UTC, that an hour is
|
|
136
|
+
on duty from :00 through :59, and, when the session carries a `nextShift`, the date its hours change
|
|
137
|
+
and that the rule keeps the hours it was given.
|
|
138
|
+
|
|
139
|
+
Session closes are not presets. Asked for "the New York close" or any other session close, stage only
|
|
140
|
+
the hours the player names, or raise flattening before the session ends as a separate idea — never
|
|
141
|
+
work a close window out yourself.
|
|
142
|
+
|
|
125
143
|
When the ask maps to no single row, or a refusal rules out the construction the player asked for,
|
|
126
144
|
ask the player which construction they mean, naming the rows that fit — never stage one they did not
|
|
127
145
|
choose. Complete stage payloads for every row are in `references/radar-stage-examples.md`.
|
|
@@ -352,8 +370,9 @@ Four reads, cheapest first. Stop as soon as the player's question is answered.
|
|
|
352
370
|
refused it and nothing was traded. It is the only history of not-qualifying closes: the journal
|
|
353
371
|
writes no row for one, and `resolvesNow` keeps only each agent's last decision — the one
|
|
354
372
|
`reading.lastClose` (step 1) carries; this read holds every decision before it. Narrow with
|
|
355
|
-
`agentId
|
|
356
|
-
`
|
|
373
|
+
`agentId`. Each record carries its whole evidence, so keep `limit` small; page back by passing
|
|
374
|
+
the response's `nextCursor` as `cursor`, and stop when `nextCursor` is null — that is the end of
|
|
375
|
+
the history. A bar still
|
|
357
376
|
waiting inside its window has no record yet (`resolvesNow` shows its `closeDecision.state` as
|
|
358
377
|
`DEFERRED`), and records are kept 90 days.
|
|
359
378
|
4. **`get_radar_activity`** only for what steps 2 and 3 cannot do: more rows than its ten, a
|
|
@@ -56,7 +56,10 @@ regime condition is the regime-reading floor, and must be a level one of the sel
|
|
|
56
56
|
|
|
57
57
|
## On duty only in named hours and days
|
|
58
58
|
|
|
59
|
-
Hours are UTC, 0–23. Days run 0 (Sunday) to 6. Each is listed once.
|
|
59
|
+
Hours are UTC, 0–23. Days run 0 (Sunday) to 6. Each is listed once. For a named exchange session —
|
|
60
|
+
including the London and Tokyo opens and the London–New York overlap — stage the `hours` `get_radar_market_hours`
|
|
61
|
+
serves for it rather than a set of your own; the example below is a shape, not a session. No session
|
|
62
|
+
close is served: a close is staged only as hours the player names.
|
|
60
63
|
|
|
61
64
|
```json stage_radar_deployment_draft
|
|
62
65
|
{
|