@battlegrid/mcp-server 32.0.15 → 32.0.16

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/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.15";
50
+ export declare const PACKAGE_VERSION = "32.0.16";
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.15';
52
+ export const PACKAGE_VERSION = '32.0.16';
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@battlegrid/mcp-server",
3
- "version": "32.0.15",
3
+ "version": "32.0.16",
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": "121.0.0",
3
+ "contractVersion": "121.2.0",
4
4
  "files": {
5
5
  "battlegrid-agent-management/SKILL.md": "09e5cbf241e2ba8f672e8292d40b3a50ee875f9b838003b95ee51928c5dbdf2e",
6
6
  "battlegrid-agent-management/references/agent-stage-examples.md": "dffcc353d61dfc7b5bb6a2b3077fc6bf8c760a34c287cafb3b59b99306f24195",
@@ -14,13 +14,13 @@
14
14
  "battlegrid-strategy-authoring/SKILL.md": "39cfa46b1f640e6800edb7e85a8f2c4b6b8786cddf71bb8244d172a44fc11d75",
15
15
  "battlegrid-strategy-authoring/references/strategy-stage-examples.md": "f10ecdc91f3660a708eee7a7bacefce2acbb46c9cf7e0ac1454bd54f839f39fd",
16
16
  "battlegrid-strategy-doctor/SKILL.md": "e34e055b0cc9b355bc1adeb5d49d464eaa0756ca3f48dc89ca2ccdda94e1311f",
17
- "battlegrid-strategy-examples/SKILL.md": "82df6781b8dbb222407cc58f622f5fadb6f933aeb7efb855c26a9ae13620cca3",
17
+ "battlegrid-strategy-examples/SKILL.md": "5e0d3244ed0592b8af933c0925346b6bd3bbaeef6c7acb35329925a026e7cd05",
18
18
  "battlegrid-strategy-examples/references/playbooks.md": "275352be43652ca0fd36a35981ea7ffcfabdc4f9b33293826656ee500d3795e9",
19
- "battlegrid-strategy-examples/references/recipes.md": "635e03d163100f6de37cda1f6cc12928d5d36aa0ea883bf44fc72f17cbf3e98e",
19
+ "battlegrid-strategy-examples/references/recipes.md": "806aae0b4842408f6e6ed3e108293073f4f31d1c27fa419ad57df9e1134f23e7",
20
20
  "battlegrid-strategy-examples/references/tradingview-ports.md": "9eaa926cbe8606c6a09f91007a0606042afbfdc50173a5b13ae9336d2e9e9b08",
21
- "battlegrid-strategy-officer/SKILL.md": "b0b9643aa2b39315b93dd54384a6a4d09c1ac6389dc35d9acb420823e49d71f5",
21
+ "battlegrid-strategy-officer/SKILL.md": "2c28ec4afa632b0f69b84b6d309f77d811d0d7452c1dbebce011b22044563780",
22
22
  "battlegrid-strategy-officer/references/figures.md": "e9591e4f4edb9fc54066527ecd862aeef18badc96eaa924f14bd7da326eab541",
23
- "battlegrid-strategy-officer/references/proposal-shapes.md": "526e9d6873b71c3b8b96af199c79c0a26f8ed6396901d03bf6d11d707eeaada0",
23
+ "battlegrid-strategy-officer/references/proposal-shapes.md": "20c9acd2b20e7920ed7ac9aa096604d91625b1d5b6438aa1ded7f6b63ecc9a22",
24
24
  "battlegrid-trade-analysis/SKILL.md": "3f927b4f9796178526fa1673a2043c5f14358c39aa955de33192ea58641f18fb",
25
25
  "battlegrid-trade-proposal/SKILL.md": "e761fc6bddc0d1db79fcb90046d03a18439562c8658de726ec286830edd6369b"
26
26
  }
@@ -78,10 +78,10 @@ add. Either way you never invent one. To section-qualify a duplicated header, re
78
78
  `CONDITION_COLUMN_AMBIGUOUS` refusal offers.
79
79
 
80
80
  **Event columns print only on their event.** `MACDhist_cross` and `EMA5_13` (Bullish/Bearish) carry a
81
- value on the crossing bar and are null on every other one, which reads as UNRESOLVED. Use an event
81
+ value on the crossing bar and are null on every other one, and a null reads FALSE. Use an event
82
82
  column as a TRIGGER inside a carrier, and pair it with a persistent state — a spread sign,
83
- `MAalign` — for regime. A condition that treats an event column as a standing state is unresolved on
84
- nearly every bar, which is a gate that never gates.
83
+ `MAalign` — for regime. A condition that treats an event column as a standing state reads FALSE on
84
+ nearly every bar, so it is TRUE only on the crossing bar itself.
85
85
 
86
86
  **The previous-session levels are TIMELESS.** `PDH`, `PDL`, `PDO` and the seven floor pivots
87
87
  (`pivotP`, `pivotR1`–`R3`, `pivotS1`–`S3`) read the session profile, not a candle rung, so they take
@@ -46,7 +46,7 @@ and is null otherwise:
46
46
 
47
47
  An event column is a trigger inside a carrier, never a standing state; pair it with a persistent
48
48
  state for regime. The skill body's `## Header grammar` states that rule and is the authority on it —
49
- a condition that reads a `crossDetect` column as a state is UNRESOLVED on nearly every bar.
49
+ a condition that reads a `crossDetect` column as a state reads FALSE on nearly every bar, because a null reads FALSE.
50
50
 
51
51
  ## Board-relative rank recipes
52
52
 
@@ -125,19 +125,39 @@ the draft kind that applies it:
125
125
  | Break-even, trailing, time decay, invalidation exits | `strategy` | `POSITION_MANAGEMENT` |
126
126
  | A cited condition that confirms losers, a missing gate | `strategy` | `CONDITIONS` |
127
127
  | When an entry may be taken (confirmation, trigger) | `strategy` | `ENTRY` |
128
+ | The losing pattern needs data no report section carries; a section no condition or decision uses | `strategy` | `REPORT` |
128
129
  | Rail refusals, exposure, leverage, daily limits, drawdown | `agent` | `TRADING_CONFIG` |
130
+ | Win rate flat across conviction bands; a posture the drawdown record does not support | `agent` | `BEHAVIOR` |
131
+ | LLM spend outrunning realized net on the agent's model | `agent` | `MODEL` |
132
+ | Losses across regimes no condition change fixes; a strategy the owner did not author; another strategy that fits the market better | `agent` | `STRATEGY_BINDING` |
129
133
  | A regime or hours slice that loses while the others win | `radar-deployment` | `RULES` |
134
+ | Losses in hours or regimes no rule covers, routed by the catch-all | `radar-deployment` | `DEFAULT_SLOT` |
130
135
 
131
136
  A regime or hours finding routes to the agent's **Radar rule** — a `REGIME` condition excluding the losing
132
137
  regime, or an `HOURS` condition — never to the strategy. The second-best lever is recorded as a finding
133
138
  without a lever, never as a second proposal.
134
139
 
140
+ **A rail refusal is routed by the setting it names, never by its gate stage.** Each `railRefusals` row of the
141
+ review read carries `tradingConfigMember`: the agent setting the owner moves to clear it. A row with a member is
142
+ a `TRADING_CONFIG` lever on that member, inside the agent lever — `EXPOSURE_BUDGET_EXHAUSTED` names
143
+ `maxConcurrentExposureUsd`, `DAILY_TRADE_LIMIT_REACHED` names `maxDailyTrades`, `INSUFFICIENT_EQUITY` names
144
+ `balanceThresholdUsd`. Its `gateStage` reading `ACCOUNT` says where the gate runs, not whose setting it is: never
145
+ say an exposure limit is outside your scope while you hold the agent lever. Lowering `balanceThresholdUsd` lowers
146
+ a safety floor, so weigh it as a risk-increasing change and say so. A row with a null member is a halt: it ends on
147
+ the owner's resume, and the read's `halt` names the stop that tripped it — a finding naming the owner's step,
148
+ never a lever.
149
+
150
+ **Rebind or edit.** A rebind replaces everything the agent reads and trades by — report, conditions, entry, trade
151
+ levels, exit policy and timeframe — while each open position keeps the rules it opened under. Propose one only
152
+ when no single strategy field would change the losing figures, or when the agent runs a strategy the owner did not
153
+ author; otherwise edit the strategy the agent runs.
154
+
135
155
  - **A kind outside `scope.levers` is not yours.** Record the finding; if no in-scope lever is supported, submit
136
156
  lever `NONE`, reason `LEVER_NOT_ALLOWED`, and say which out-of-scope lever the figures pointed at.
137
- - **A strategy the owner did not author is not a lever.** When `strategyOwnedByOwner` is false, record the
138
- finding, state that the strategy must be forked from the library before a strategy lever can be proposed —
139
- forking is the owner's step, never yours — and consider the agent and Radar levers within your scope
140
- instead. If none is supported, submit lever `NONE`, reason `TARGET_NOT_OWNED`.
157
+ - **A strategy the owner did not author is not a strategy lever.** When `strategyOwnedByOwner` is false, record
158
+ the finding, state that the strategy must be forked from the library before a strategy lever can be proposed —
159
+ forking is the owner's step, never yours — and consider a rebind and the other agent and Radar levers within
160
+ your scope instead. If none is supported, submit lever `NONE`, reason `TARGET_NOT_OWNED`.
141
161
  - **No ready figure, no lever.** When every figure a lever would rest on reads `INSUFFICIENT_DATA`, submit lever
142
162
  `NONE`, reason `INSUFFICIENT_DATA`, naming the figure and its sample.
143
163
  - **Nothing to change is an answer.** When the ready figures read as a playbook doing what it should, submit
@@ -148,11 +168,17 @@ without a lever, never as a second proposal.
148
168
  A proposal carries **exactly one axis, whole**, in the kind's own vocabulary — the complete current value of
149
169
  that axis with your one change in it. So read the current value first:
150
170
 
151
- - a strategy axis → `get_strategy` on the agent's `strategyId`;
171
+ - a strategy axis → `get_strategy` on the agent's `strategyId`; for `REPORT`, `list_strategy_categories` for the
172
+ platform sections a report may carry — the whole section list is sent, with your change in it;
152
173
  - `TRADING_CONFIG` → `get_intelligence_agent` for the agent's current `tradingConfig`, and
153
174
  `get_trading_config_catalog` for the bounds every member must sit inside;
154
- - `RULES` → `get_radar_deployment` on the coin the target names (`list_radar_deployments` shows which coins
155
- route this agent); every rule is sent, in priority order, with the one rule changed.
175
+ - `BEHAVIOR` → `get_intelligence_agent` for the current `behavior`; all three members are sent;
176
+ - `MODEL` → `list_approved_models` for the models the account may select now, by `modelId`;
177
+ - `STRATEGY_BINDING` → `list_strategies` (active strategies only) for the owner's own strategies and the
178
+ library's, by `strategyId`; a rebind carries no `TRADING_CONFIG`, since the timeframes follow the strategy;
179
+ - `RULES` and `DEFAULT_SLOT` → `get_radar_deployment` on the coin the target names (`list_radar_deployments`
180
+ shows which coins route this agent); every rule is sent, in priority order, with the one rule changed, and a
181
+ rule or the catch-all names only agents the coin already routes.
156
182
 
157
183
  The complete shape of every axis — which members it must carry and where each comes from — is in
158
184
  `references/proposal-shapes.md`. The proposal is `{ kind, targetId, axes, baseRevision }`, where `targetId` and
@@ -176,7 +202,7 @@ get past a `PROPOSAL_INVALID`: the record says what was refused, and the next re
176
202
  **The review is written in every case** — no new decisions, out of scope, not enough data, nothing to change.
177
203
 
178
204
  Close with the review, not a question. In a scheduled run that is the whole close. When the player is in the
179
- conversation, add one sentence: the change is proposed and waiting on their Agents Hub card, where Apply
205
+ conversation, add one sentence: the change is proposed and waiting on its card on the Officers page, where Apply
180
206
  publishes it, Push places it in the editor beside their own edits, and Dismiss closes it.
181
207
 
182
208
  ## Negatives
@@ -14,7 +14,7 @@ Every value below is a placeholder; replace it with what the reads served. Never
14
14
 
15
15
  ## Strategy — `kind: 'strategy'`, `targetId` the strategy id
16
16
 
17
- Read the current values with `get_strategy`. One of four axes:
17
+ Read the current values with `get_strategy`. One of five axes:
18
18
 
19
19
  ### `TRADE_LEVEL_POLICY`
20
20
 
@@ -58,15 +58,71 @@ record the finding and name the authoring flow as the owner's step.
58
58
  validForBars } }` for a level trigger — the trigger the strategy read serves, or the one you propose, with every dial
59
59
  it honours and none it does not.
60
60
 
61
+ ### `REPORT`
62
+
63
+ `{ sections: [...] }` — **every** section of the strategy's report, in the order `get_strategy` serves them, with
64
+ your one change: a platform section added or removed. Each section is a reference: a platform section is
65
+ `{ kind: 'platform', sectionKey }`, its key one `list_strategy_categories` serves; a custom section is
66
+ `{ kind: 'custom', sectionKey }`, its `custom:<uuid>` key as `get_strategy` serves it, and nothing else — the submit
67
+ takes its title, columns, benchmark and note from the committed report, so a review never edits one. A custom key the
68
+ report does not carry is refused. A report that drops a section a condition reads is refused by the assessment: keep
69
+ it, or propose the condition change first. Composing a new custom section is authoring work, outside a review.
70
+
71
+ ```json
72
+ {
73
+ "kind": "strategy",
74
+ "targetId": "<STRATEGY_ID>",
75
+ "baseRevision": 12,
76
+ "axes": {
77
+ "REPORT": {
78
+ "sections": [
79
+ { "kind": "platform", "sectionKey": "includePriceAction" },
80
+ { "kind": "custom", "sectionKey": "custom:<SECTION_UUID>" },
81
+ { "kind": "platform", "sectionKey": "includeVolume" }
82
+ ]
83
+ }
84
+ }
85
+ }
86
+ ```
87
+
61
88
  ## Agent — `kind: 'agent'`, `targetId` the agent id
62
89
 
90
+ Read the current values with `get_intelligence_agent`. One of four axes:
91
+
63
92
  ### `TRADING_CONFIG`
64
93
 
65
94
  `{ tradingConfig: { ... } }` — the agent's complete trading configuration from `get_intelligence_agent`, less the two
66
95
  members the server derives (`strategyTimeframe`, `regimeTimeframe`): `minAllocationUsd`, `maxDailyTrades`,
67
96
  `balanceThresholdUsd`, `maxLeverage`, `maxSlippageBps`, `maxConcurrentExposureUsd`, `maxCumulativeDrawdownUsd`,
68
97
  `maxDailyLossUsd` and `positionSizePresets` (the whole preset ladder), each inside the bounds
69
- `get_trading_config_catalog` serves. Change the one rail the finding names; send the rest as read.
98
+ `get_trading_config_catalog` serves. Change the one rail the finding names; send the rest as read. A rail refusal
99
+ names its rail as `tradingConfigMember` on the review read.
100
+
101
+ ### `BEHAVIOR`
102
+
103
+ `{ behavior: { risk, outlook, conviction } }` — all three members, the ones you do not change as read: `risk` one of
104
+ `CONSERVATIVE`, `MODERATE`, `AGGRESSIVE`; `outlook` one of `OPTIMIST`, `REALIST`, `PESSIMIST`; `conviction` one of
105
+ `CAUTIOUS`, `MEASURED`, `BOLD`.
106
+
107
+ ### `MODEL`
108
+
109
+ `{ modelId }` — a `modelId` `list_approved_models` serves now. The model sets what each decision costs: cite the
110
+ agent's LLM spend against its net as the finding.
111
+
112
+ ### `STRATEGY_BINDING`
113
+
114
+ `{ strategyId }` — an active strategy `list_strategies` serves: one the owner authored, or a library strategy. Never
115
+ another user's, never an archived one. A rebind carries nothing else: the strategy and regime timeframes follow the
116
+ new strategy, and each open position keeps the rules it opened under.
117
+
118
+ ```json
119
+ {
120
+ "kind": "agent",
121
+ "targetId": "<AGENT_ID>",
122
+ "baseRevision": 14,
123
+ "axes": { "STRATEGY_BINDING": { "strategyId": "<STRATEGY_ID>" } }
124
+ }
125
+ ```
70
126
 
71
127
  ## Radar deployment — `kind: 'radar-deployment'`, `targetId` the coin id
72
128
 
@@ -109,4 +165,10 @@ with the one rule that routes this agent changed. A rule's conditions are a non-
109
165
  }
110
166
  ```
111
167
 
112
- The catch-all default is a different axis and is never part of a Radar proposal.
168
+ Every agent a rule names is an agent the coin already routes: placing an agent on a coin is the owner's step, and the
169
+ submit refuses a proposal naming any other.
170
+
171
+ ### `DEFAULT_SLOT`
172
+
173
+ `{ defaultSlot: { agentId, minConviction } }` — the catch-all that takes the coin when no rule is on duty, its agent one
174
+ the coin already routes; or `{ defaultSlot: null }` to remove the catch-all. Read it with `get_radar_deployment`.