@battlegrid/mcp-server 31.2.13 → 31.2.15
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 +112 -54
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -413,6 +413,58 @@ refuse is now stored. Listed because a client that special-cased the refusal can
|
|
|
413
413
|
a stored result" and "the signal did not fire" are different states, and leaving the key off that
|
|
414
414
|
arm makes conflating them a type error rather than a convention.
|
|
415
415
|
|
|
416
|
+
### Additive in the same span
|
|
417
|
+
|
|
418
|
+
- **Two tools join the catalog for the agent trade flow** (52.1.0, `add-mcp-agent-trade-flow`).
|
|
419
|
+
`scan_agent_coins` evaluates every active coin against one of your agents in a single call and
|
|
420
|
+
returns them server-ranked, on the same use case, buckets and ranking the app's own TRADE-tab scan
|
|
421
|
+
serves. `propose_entry_decision` runs the conversational trade turn headlessly for one (agent,
|
|
422
|
+
coin) and returns its terminal in the stream's own vocabulary: `type: recommendation` carrying the
|
|
423
|
+
PROPOSED `TradingEntryDecisionDTO` row that `get_entry_decision` and `list_pending_approvals`
|
|
424
|
+
already publish, `type: no_trade`, or `type: error` carrying the turn's `TradeConvError` verbatim.
|
|
425
|
+
Nothing narrows and no existing schema hash moves; the 12-ticker `get_agent_coin_qualification`
|
|
426
|
+
stays as the spot-check probe.
|
|
427
|
+
|
|
428
|
+
**`idempotencyKey` is REQUIRED on `propose_entry_decision`** — it is the turn's own key, and a
|
|
429
|
+
same-key retry replays the recorded terminal rather than paying for a second inference. That
|
|
430
|
+
includes a post-billing `LLM_FAILURE`, which is returned as a value for precisely that reason.
|
|
431
|
+
Pre-engine faults are typed errors instead: `RATE_LIMITED`, `NOT_FOUND`, `CONFLICT` for a same-key
|
|
432
|
+
call still in flight, and `SERVICE_UNAVAILABLE` when the surface is switched off. Both tools
|
|
433
|
+
refuse with `RATE_LIMITED` carrying `retryAfterSeconds` under the same per-(user, agent) limit the
|
|
434
|
+
app itself enforces, so a scan is never served stale or partial.
|
|
435
|
+
|
|
436
|
+
- **`get_regime_snapshot` publishes the evidence behind the verdict** (47.1.0,
|
|
437
|
+
`publish-regime-classification-evidence`). The snapshot gains `evidence`: the quantities the
|
|
438
|
+
classifier read, the gates it tested them against, the signed margin to the gate deciding whether
|
|
439
|
+
the current label survives, and the two decision facts only the classifier holds — `gateState`
|
|
440
|
+
(`cleared` / `held` / `dropped`) and `directionSource` (`di` / `ema`). Nothing narrows; a client
|
|
441
|
+
that ignores the field is unaffected.
|
|
442
|
+
|
|
443
|
+
Read `gateState` before you trust a trend label: **`held` means the ADX hysteresis buffer is
|
|
444
|
+
carrying the PREVIOUS bar's label rather than this bar re-confirming it** — a materially weaker
|
|
445
|
+
claim wearing the same word, and one no client could previously detect. `directionSource: 'ema'`
|
|
446
|
+
is the same shape of warning: the direction came from the fallback that fires precisely when the
|
|
447
|
+
DI spread is indecisive. The margin is signed so **positive always means "the current label
|
|
448
|
+
survives by this much"**, in every gate state, so it is safe to branch on its sign.
|
|
449
|
+
|
|
450
|
+
`conviction` is a BRANCH DISCRIMINATOR, not a confidence: it encodes *which* rule in the priority
|
|
451
|
+
ladder matched, not how comfortably it matched. The margins carry comfort. A client reading
|
|
452
|
+
conviction as a strength score is reading it wrong, and always was — this release just makes the
|
|
453
|
+
alternative available.
|
|
454
|
+
|
|
455
|
+
- **Thirteen metric keys join the catalog** (47.1.0) — the `regime` family gains `REGIME_STATE`,
|
|
456
|
+
`REGIME_CONVICTION`, `REGIME_RUN_BARS`, `REGIME_TREND_GATE`, `REGIME_TREND_MARGIN`,
|
|
457
|
+
`REGIME_TREND_SOURCE`, `REGIME_DI_SPREAD`, `REGIME_VOL_ATR_RATIO`, `REGIME_VOL_BBW_RATIO`,
|
|
458
|
+
`REGIME_MOM_BULL_VOTES`, `REGIME_MOM_BEAR_VOTES`, `REGIME_CRASH_MARGIN` and `REGIME_CRASH_LATCH`,
|
|
459
|
+
making the composite regime and its evidence addressable in a report column or condition for the
|
|
460
|
+
first time. Only a client that switches exhaustively on `MetricKey` needs new branches.
|
|
461
|
+
|
|
462
|
+
Not a contract change, but worth knowing if you author conditions: the report grammar's regime
|
|
463
|
+
metrics now resolve from the **confirmed close** on every path. They previously resolved from the
|
|
464
|
+
forming bar when a report was rendered and the confirmed close when the scan swept, so the same
|
|
465
|
+
condition could read differently in preview than in production. Same wire shape; same bar
|
|
466
|
+
everywhere now.
|
|
467
|
+
|
|
416
468
|
## Contract history — v12 → v36
|
|
417
469
|
|
|
418
470
|
> **The number in this heading is a CONTRACT version, not this package's version.** The npm badge at the top
|
|
@@ -565,38 +617,6 @@ Nothing in the proxy changes. No configuration, no environment variable, no call
|
|
|
565
617
|
|
|
566
618
|
### Additive in the same span
|
|
567
619
|
|
|
568
|
-
- **`get_regime_snapshot` publishes the evidence behind the verdict** (47.1.0,
|
|
569
|
-
`publish-regime-classification-evidence`). The snapshot gains `evidence`: the quantities the
|
|
570
|
-
classifier read, the gates it tested them against, the signed margin to the gate deciding whether
|
|
571
|
-
the current label survives, and the two decision facts only the classifier holds — `gateState`
|
|
572
|
-
(`cleared` / `held` / `dropped`) and `directionSource` (`di` / `ema`). Nothing narrows; a client
|
|
573
|
-
that ignores the field is unaffected.
|
|
574
|
-
|
|
575
|
-
Read `gateState` before you trust a trend label: **`held` means the ADX hysteresis buffer is
|
|
576
|
-
carrying the PREVIOUS bar's label rather than this bar re-confirming it** — a materially weaker
|
|
577
|
-
claim wearing the same word, and one no client could previously detect. `directionSource: 'ema'`
|
|
578
|
-
is the same shape of warning: the direction came from the fallback that fires precisely when the
|
|
579
|
-
DI spread is indecisive. The margin is signed so **positive always means "the current label
|
|
580
|
-
survives by this much"**, in every gate state, so it is safe to branch on its sign.
|
|
581
|
-
|
|
582
|
-
`conviction` is a BRANCH DISCRIMINATOR, not a confidence: it encodes *which* rule in the priority
|
|
583
|
-
ladder matched, not how comfortably it matched. The margins carry comfort. A client reading
|
|
584
|
-
conviction as a strength score is reading it wrong, and always was — this release just makes the
|
|
585
|
-
alternative available.
|
|
586
|
-
|
|
587
|
-
- **Thirteen metric keys join the catalog** (47.1.0) — the `regime` family gains `REGIME_STATE`,
|
|
588
|
-
`REGIME_CONVICTION`, `REGIME_RUN_BARS`, `REGIME_TREND_GATE`, `REGIME_TREND_MARGIN`,
|
|
589
|
-
`REGIME_TREND_SOURCE`, `REGIME_DI_SPREAD`, `REGIME_VOL_ATR_RATIO`, `REGIME_VOL_BBW_RATIO`,
|
|
590
|
-
`REGIME_MOM_BULL_VOTES`, `REGIME_MOM_BEAR_VOTES`, `REGIME_CRASH_MARGIN` and `REGIME_CRASH_LATCH`,
|
|
591
|
-
making the composite regime and its evidence addressable in a report column or condition for the
|
|
592
|
-
first time. Only a client that switches exhaustively on `MetricKey` needs new branches.
|
|
593
|
-
|
|
594
|
-
Not a contract change, but worth knowing if you author conditions: the report grammar's regime
|
|
595
|
-
metrics now resolve from the **confirmed close** on every path. They previously resolved from the
|
|
596
|
-
forming bar when a report was rendered and the confirmed close when the scan swept, so the same
|
|
597
|
-
condition could read differently in preview than in production. Same wire shape; same bar
|
|
598
|
-
everywhere now.
|
|
599
|
-
|
|
600
620
|
`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.
|
|
601
621
|
|
|
602
622
|
## v11 and earlier — contract history (v6 → v11)
|
|
@@ -706,33 +726,45 @@ The v3 authoring contract below is unchanged and still current:
|
|
|
706
726
|
|
|
707
727
|
## Quick Start
|
|
708
728
|
|
|
709
|
-
###
|
|
729
|
+
### Remote server, OAuth — start here
|
|
710
730
|
|
|
711
|
-
```
|
|
712
|
-
|
|
731
|
+
```
|
|
732
|
+
https://mcp.battlegrid.trade/mcp
|
|
713
733
|
```
|
|
714
734
|
|
|
715
|
-
|
|
735
|
+
Give that URL to your MCP client over its streamable-http (remote) transport and authorize: the
|
|
736
|
+
client registers itself by Dynamic Client Registration, BattleGrid's consent page opens in your
|
|
737
|
+
browser, and you sign in and click **Authorize**. No npm install, no API key. The grant is listed —
|
|
738
|
+
and revocable — under **Profile → MCP → OAuth Sessions**.
|
|
716
739
|
|
|
717
|
-
|
|
718
|
-
BATTLEGRID_API_KEYS=bg_live_alice_key,bg_live_bob_key npx @battlegrid/mcp-server
|
|
719
|
-
```
|
|
740
|
+
### API key and the stdio proxy — the fallback
|
|
720
741
|
|
|
721
|
-
|
|
742
|
+
Reach for a key when your client has no remote transport at all, when your agent runs headless or in
|
|
743
|
+
CI and cannot open a browser to consent, or when one process drives several BattleGrid accounts. It
|
|
744
|
+
is fully supported for each of those, and nothing about it is deprecated.
|
|
722
745
|
|
|
723
|
-
|
|
746
|
+
**Single account (stdio transport):**
|
|
724
747
|
|
|
748
|
+
```bash
|
|
749
|
+
BATTLEGRID_API_KEY=bg_live_xxx npx @battlegrid/mcp-server
|
|
725
750
|
```
|
|
726
|
-
|
|
751
|
+
|
|
752
|
+
**Multiple accounts (stdio transport):**
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
BATTLEGRID_API_KEYS=bg_live_alice_key,bg_live_bob_key npx @battlegrid/mcp-server
|
|
727
756
|
```
|
|
728
757
|
|
|
729
|
-
|
|
758
|
+
When multiple keys are provided, the server discovers each account's identity and injects a required `account` parameter into every tool so the AI agent can choose which account to act as. OAuth has no equivalent — one grant authorizes one account.
|
|
730
759
|
|
|
731
760
|
## Configuration
|
|
732
761
|
|
|
733
762
|
### Claude Desktop
|
|
734
763
|
|
|
735
|
-
**
|
|
764
|
+
**OAuth (no key):** Settings → **Connectors** → **Add custom connector**. Paste
|
|
765
|
+
`https://mcp.battlegrid.trade/mcp`, save, and authorize on the consent page Claude opens.
|
|
766
|
+
|
|
767
|
+
**API key (fallback) — single account:**
|
|
736
768
|
|
|
737
769
|
```json
|
|
738
770
|
{
|
|
@@ -748,7 +780,7 @@ No npm install required — connect directly from any MCP client that supports s
|
|
|
748
780
|
}
|
|
749
781
|
```
|
|
750
782
|
|
|
751
|
-
**
|
|
783
|
+
**API key (fallback) — multiple accounts:**
|
|
752
784
|
|
|
753
785
|
```json
|
|
754
786
|
{
|
|
@@ -766,22 +798,44 @@ No npm install required — connect directly from any MCP client that supports s
|
|
|
766
798
|
|
|
767
799
|
### Claude Code
|
|
768
800
|
|
|
801
|
+
**OAuth (no key):**
|
|
802
|
+
|
|
769
803
|
```bash
|
|
770
|
-
claude mcp add
|
|
804
|
+
claude mcp add --transport http battlegrid https://mcp.battlegrid.trade/mcp
|
|
771
805
|
```
|
|
772
806
|
|
|
773
|
-
|
|
807
|
+
Then start `claude`, run `/mcp`, select **battlegrid** and choose **Authenticate** — the consent page
|
|
808
|
+
opens in your browser and the entry reads connected once you authorize.
|
|
809
|
+
|
|
810
|
+
**API key (fallback):**
|
|
774
811
|
|
|
775
812
|
```bash
|
|
776
813
|
# Single account
|
|
777
|
-
|
|
814
|
+
claude mcp add battlegrid -e BATTLEGRID_API_KEY=bg_live_xxx -- npx @battlegrid/mcp-server
|
|
778
815
|
|
|
779
816
|
# Multiple accounts
|
|
780
|
-
|
|
817
|
+
claude mcp add battlegrid -e BATTLEGRID_API_KEYS=bg_live_alice_key,bg_live_bob_key -- npx @battlegrid/mcp-server
|
|
781
818
|
```
|
|
782
819
|
|
|
783
820
|
### Cursor
|
|
784
821
|
|
|
822
|
+
**OAuth (no key):** Settings → **MCP** → **Add new global MCP server** opens `~/.cursor/mcp.json`.
|
|
823
|
+
|
|
824
|
+
```json
|
|
825
|
+
{
|
|
826
|
+
"mcpServers": {
|
|
827
|
+
"battlegrid": {
|
|
828
|
+
"url": "https://mcp.battlegrid.trade/mcp"
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
```
|
|
833
|
+
|
|
834
|
+
Back in Settings → MCP, click **Needs login** on `battlegrid` and authorize on BattleGrid's consent
|
|
835
|
+
page; the entry turns green once its tools load.
|
|
836
|
+
|
|
837
|
+
**API key (fallback):** the same file, with the stdio proxy in place of the remote entry.
|
|
838
|
+
|
|
785
839
|
```json
|
|
786
840
|
{
|
|
787
841
|
"mcpServers": {
|
|
@@ -808,12 +862,16 @@ ChatGPT Desktop connects via **OAuth 2.1** — no npm package or API key needed.
|
|
|
808
862
|
4. ChatGPT discovers OAuth endpoints, registers as a client (Dynamic Client Registration), and opens BattleGrid's consent page
|
|
809
863
|
5. Log in to BattleGrid and click **Authorize**
|
|
810
864
|
|
|
811
|
-
|
|
865
|
+
Authentication is a property of the **path**, not of the client — every client above reaches
|
|
866
|
+
BattleGrid either way, so pick the row that matches your runtime rather than your client:
|
|
867
|
+
|
|
868
|
+
| | Remote + OAuth | API key |
|
|
812
869
|
|---|---|---|
|
|
813
|
-
| **Transport** | stdio proxy (`@battlegrid/mcp-server`)
|
|
814
|
-
| **Auth** | API key (`bg_live_*`)
|
|
815
|
-
| **Setup** |
|
|
816
|
-
| **
|
|
870
|
+
| **Transport** | streamable-http, direct to `mcp.battlegrid.trade` | stdio proxy (`@battlegrid/mcp-server`), or the same URL with a Bearer header |
|
|
871
|
+
| **Auth** | OAuth 2.1 with Dynamic Client Registration | API key (`bg_live_*`) as a Bearer token |
|
|
872
|
+
| **Setup** | paste the URL, authorize in the browser | npm package + env vars |
|
|
873
|
+
| **Needs a browser** | yes, once, to consent | no — works headless and in CI |
|
|
874
|
+
| **Multi-account** | one grant per account | `BATTLEGRID_API_KEYS`, several accounts through one proxy |
|
|
817
875
|
|
|
818
876
|
## Account management
|
|
819
877
|
|
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.15";
|
|
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.15';
|
|
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];
|