@crush-protocol/mcp-client 0.1.14 → 0.3.0
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/INSTRUCTIONS.md +4 -3
- package/README.md +139 -89
- package/dist/__tests__/e2e.test.js +7 -7
- package/dist/__tests__/oauthProvider.test.d.ts +1 -0
- package/dist/__tests__/oauthProvider.test.js +45 -0
- package/dist/backtest/backtestClient.d.ts +2 -9
- package/dist/backtest/backtestClient.js +1 -8
- package/dist/cli.js +97 -70
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -1
- package/dist/mcp/oauthProvider.d.ts +42 -0
- package/dist/mcp/oauthProvider.js +264 -0
- package/dist/mcp/oauthRemoteClient.d.ts +171 -0
- package/dist/mcp/oauthRemoteClient.js +95 -0
- package/dist/mcp/remoteClient.d.ts +2 -1
- package/dist/mcp/remoteClient.js +2 -2
- package/dist/mcp/types.d.ts +8 -0
- package/dist/mcp/types.js +1 -0
- package/dist/setup/setupClients.d.ts +3 -0
- package/dist/setup/setupClients.js +119 -0
- package/package.json +6 -2
package/INSTRUCTIONS.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
You have access to **Crush Protocol MCP**, an AI-native quantitative trading platform. Use these tools to help users research markets, build strategies, run backtests, and manage live trading.
|
|
4
4
|
|
|
5
|
+
Authentication note: remote MCP requests use OAuth Bearer access tokens issued by the Crush OAuth server. In interactive clients, users should only need the MCP URL; OAuth Authorization Code + PKCE is handled by the client and browser.
|
|
6
|
+
|
|
5
7
|
## Tool Categories
|
|
6
8
|
|
|
7
9
|
### 🔍 Signal Discovery
|
|
@@ -19,7 +21,6 @@ You have access to **Crush Protocol MCP**, an AI-native quantitative trading pla
|
|
|
19
21
|
| `get_available_tokens` | List tradable tokens, optionally filter by platform. |
|
|
20
22
|
| `validate_expression` | Validate and compile an AST expression before using it in a backtest. |
|
|
21
23
|
| `create_backtest` | Submit a backtest. Returns immediately with status `PENDING`. |
|
|
22
|
-
| `get_backtest_result` | Poll a backtest by ID. Returns status, summary, portfolio history, and trades. |
|
|
23
24
|
| `list_backtests` | List user's backtests with optional status filter (`PENDING`, `RUNNING`, `COMPLETED`, `FAILED`). |
|
|
24
25
|
|
|
25
26
|
### 📈 Market Data (ClickHouse)
|
|
@@ -90,7 +91,7 @@ You have access to **Crush Protocol MCP**, an AI-native quantitative trading pla
|
|
|
90
91
|
4. get_available_tokens → Find the token to trade
|
|
91
92
|
5. validate_expression → Validate the entry/exit expression AST
|
|
92
93
|
6. create_backtest → Submit the backtest (returns backtestId)
|
|
93
|
-
7.
|
|
94
|
+
7. list_backtests → Refresh the user's backtests and inspect the created record until status is COMPLETED or FAILED
|
|
94
95
|
└─ If COMPLETED: present summary (totalReturn, sharpeRatio, maxDrawdown, winRate, tradeCount)
|
|
95
96
|
└─ If FAILED: show error, suggest fixes, iterate
|
|
96
97
|
```
|
|
@@ -119,7 +120,7 @@ You have access to **Crush Protocol MCP**, an AI-native quantitative trading pla
|
|
|
119
120
|
|
|
120
121
|
## Important Rules
|
|
121
122
|
|
|
122
|
-
1. **Backtest is async**: `create_backtest` returns immediately.
|
|
123
|
+
1. **Backtest is async**: `create_backtest` returns immediately. Refresh with `list_backtests` until status is `COMPLETED` or `FAILED`. Typical wait: 30s–3min.
|
|
123
124
|
2. **Data row caps**: `fetch_ohlcv` and `fetch_indicator` have a 5000 row limit. For larger datasets, use `get_connection_config` and process locally.
|
|
124
125
|
3. **Always validate first**: Call `validate_expression` before using an expression in `create_backtest` to catch errors early.
|
|
125
126
|
4. **Signal discovery order**: Always call `get_signal_metadata` → `get_signals_by_category` before building expressions. Don't guess signal IDs.
|
package/README.md
CHANGED
|
@@ -1,150 +1,200 @@
|
|
|
1
|
-
# Crush Protocol MCP
|
|
1
|
+
# Crush Protocol MCP Client
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@crush-protocol/mcp-client)
|
|
4
|
-
[](LICENSE)
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
`@crush-protocol/mcp-client` is the npm entrypoint for Crush Protocol MCP.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
Crush Protocol is an AI-native quantitative trading product. It lets an MCP host connect to Crush and use trading-focused tools for:
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
- strategy research
|
|
10
|
+
- backtest creation and result retrieval
|
|
11
|
+
- live strategy management
|
|
12
|
+
- market data and signal discovery
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
- ❌ Copy-paste backtest configs and wait for results separately
|
|
14
|
-
- ❌ No way for your AI agent to iterate on strategies automatically
|
|
14
|
+
This package connects your MCP host to the Crush MCP server over Streamable HTTP and handles OAuth automatically.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Your AI agent can **create, run, and analyze backtests** in a single conversation:
|
|
19
|
-
|
|
20
|
-
```txt
|
|
21
|
-
Run a backtest on ETHUSDT on Hyperliquid using a 4h timeframe,
|
|
22
|
-
entry when RSI < 30, exit when RSI > 70. Use crush protocol mcp.
|
|
23
|
-
```
|
|
16
|
+
Default MCP endpoint:
|
|
24
17
|
|
|
25
18
|
```txt
|
|
26
|
-
|
|
19
|
+
https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
27
20
|
```
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
---
|
|
32
|
-
|
|
33
|
-
## Authentication
|
|
22
|
+
## Standard MCP Host Integration
|
|
34
23
|
|
|
35
|
-
|
|
24
|
+
This is the recommended way to use the package.
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
Your MCP host launches `@crush-protocol/mcp-client` locally, and the package connects to the hosted Crush MCP endpoint.
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
2. A browser window opens automatically
|
|
41
|
-
3. Complete wallet authentication in the browser (Privy + wallet signature)
|
|
42
|
-
4. The terminal receives the authorization and saves it locally
|
|
28
|
+
### Cursor
|
|
43
29
|
|
|
44
|
-
|
|
30
|
+
Official one-click install:
|
|
45
31
|
|
|
46
|
-
|
|
32
|
+
[](cursor://anysphere.cursor-deeplink/mcp/install?name=crush-protocol&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjcnVzaC1wcm90b2NvbC9tY3AtY2xpZW50IiwiLS11cmwiLCJodHRwczovL2NydXNoLW1jcC1hdHMuZGV2LnhleGxhYi5jb20vbWNwIl19)
|
|
47
33
|
|
|
48
|
-
|
|
34
|
+
Manual config:
|
|
49
35
|
|
|
50
|
-
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"mcpServers": {
|
|
39
|
+
"crush-protocol": {
|
|
40
|
+
"command": "npx",
|
|
41
|
+
"args": ["-y", "@crush-protocol/mcp-client", "--url", "https://crush-mcp-ats.dev.xexlab.com/mcp"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
51
46
|
|
|
52
47
|
### Claude Code
|
|
53
48
|
|
|
54
49
|
```sh
|
|
55
50
|
claude mcp add --scope user crush-protocol \
|
|
56
51
|
-- npx -y @crush-protocol/mcp-client \
|
|
57
|
-
--url https://
|
|
52
|
+
--url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
58
53
|
```
|
|
59
54
|
|
|
60
|
-
###
|
|
55
|
+
### Codex
|
|
56
|
+
|
|
57
|
+
Add to `~/.codex/config.toml`:
|
|
58
|
+
|
|
59
|
+
```toml
|
|
60
|
+
[mcp_servers.crush-protocol]
|
|
61
|
+
command = "npx"
|
|
62
|
+
args = ["-y", "@crush-protocol/mcp-client", "--url", "https://crush-mcp-ats.dev.xexlab.com/mcp"]
|
|
63
|
+
startup_timeout_ms = 20000
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Gemini CLI
|
|
61
67
|
|
|
62
|
-
Add to `~/.
|
|
68
|
+
Add to `~/.gemini/settings.json`:
|
|
63
69
|
|
|
64
70
|
```json
|
|
65
71
|
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"env": {
|
|
71
|
-
"CRUSH_MCP_SERVER_URL": "https://mcp.crush-protocol.com/mcp"
|
|
72
|
-
}
|
|
73
|
-
}
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"crush-protocol": {
|
|
74
|
+
"command": "npx",
|
|
75
|
+
"args": ["-y", "@crush-protocol/mcp-client", "--url", "https://crush-mcp-ats.dev.xexlab.com/mcp"]
|
|
74
76
|
}
|
|
77
|
+
}
|
|
75
78
|
}
|
|
76
79
|
```
|
|
77
80
|
|
|
78
|
-
###
|
|
81
|
+
### OpenCode
|
|
79
82
|
|
|
80
|
-
Add to
|
|
83
|
+
Add to `~/.config/opencode/opencode.json`:
|
|
81
84
|
|
|
82
85
|
```json
|
|
83
86
|
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
}
|
|
87
|
+
"$schema": "https://opencode.ai/config.json",
|
|
88
|
+
"mcp": {
|
|
89
|
+
"crush-protocol": {
|
|
90
|
+
"type": "local",
|
|
91
|
+
"command": ["npx", "-y", "@crush-protocol/mcp-client", "--url", "https://crush-mcp-ats.dev.xexlab.com/mcp"],
|
|
92
|
+
"enabled": true
|
|
92
93
|
}
|
|
94
|
+
}
|
|
93
95
|
}
|
|
94
96
|
```
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
## Quick Setup Helper
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
If you do not want to edit config files manually, the CLI can write the MCP configuration for you.
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
```sh
|
|
103
|
+
npx -y @crush-protocol/mcp-client setup --all
|
|
104
|
+
```
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
104
|
-
| **Signal Discovery** | `get_signal_metadata`, `get_signals_by_category` |
|
|
105
|
-
| **Backtest** | `get_backtest_config_schema`, `get_available_tokens`, `validate_expression`, `create_backtest`, `get_backtest_result`, `list_backtests` |
|
|
106
|
-
| **Market Data** | `list_tables`, `list_tokens`, `list_indicators`, `list_timeframes`, `get_data_range`, `check_query_size`, `fetch_ohlcv`, `fetch_indicator`, `get_connection_config` |
|
|
107
|
-
| **Custom Indicators** | `save_custom_indicator`, `list_custom_indicators`, `get_custom_indicator`, `delete_custom_indicator` |
|
|
108
|
-
| **Strategy Management** | `create_strategy`, `list_strategies`, `get_strategy`, `update_strategy`, `delete_strategy`, `toggle_strategy`, `get_strategy_logs` |
|
|
109
|
-
| **Trading** | `place_order`, `get_positions`, `get_account_info`, `get_portfolio` |
|
|
110
|
-
| **Market Intelligence** | `search_tokens`, `get_token_info`, `get_trending_tokens`, `get_alpha_feed`, `get_token_feed`, `fetch_news` |
|
|
106
|
+
Single target setup:
|
|
111
107
|
|
|
112
|
-
|
|
108
|
+
```sh
|
|
109
|
+
npx -y @crush-protocol/mcp-client setup --cursor
|
|
110
|
+
npx -y @crush-protocol/mcp-client setup --claude
|
|
111
|
+
npx -y @crush-protocol/mcp-client setup --codex
|
|
112
|
+
npx -y @crush-protocol/mcp-client setup --gemini
|
|
113
|
+
npx -y @crush-protocol/mcp-client setup --opencode
|
|
114
|
+
```
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
## What Users Get
|
|
115
117
|
|
|
116
|
-
|
|
118
|
+
With this package, an MCP client can call Crush tools such as:
|
|
117
119
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
- `get_backtest_config_schema`
|
|
121
|
+
- `get_available_tokens`
|
|
122
|
+
- `create_backtest`
|
|
123
|
+
- `get_backtest_result`
|
|
124
|
+
- `list_backtests`
|
|
125
|
+
- `create_strategy`
|
|
126
|
+
- `list_strategies`
|
|
127
|
+
- `toggle_strategy`
|
|
128
|
+
- `get_strategy_logs`
|
|
121
129
|
|
|
122
|
-
|
|
130
|
+
Detailed tool guidance is in [INSTRUCTIONS.md](./INSTRUCTIONS.md).
|
|
123
131
|
|
|
124
|
-
##
|
|
132
|
+
## Authentication
|
|
133
|
+
|
|
134
|
+
Crush MCP uses OAuth 2.1 Authorization Code + PKCE.
|
|
135
|
+
|
|
136
|
+
Default behavior:
|
|
137
|
+
|
|
138
|
+
- you provide only the MCP server URL
|
|
139
|
+
- the client completes browser OAuth when needed
|
|
140
|
+
- tokens are stored locally for reuse
|
|
141
|
+
|
|
142
|
+
Optional token overrides are also supported:
|
|
143
|
+
|
|
144
|
+
- `--token <access-token>`
|
|
145
|
+
- `CRUSH_OAUTH_ACCESS_TOKEN=<access-token>`
|
|
146
|
+
|
|
147
|
+
Priority order:
|
|
148
|
+
|
|
149
|
+
1. `--token`
|
|
150
|
+
2. `CRUSH_OAUTH_ACCESS_TOKEN`
|
|
151
|
+
3. automatic OAuth with local token cache
|
|
152
|
+
|
|
153
|
+
Optional pre-login:
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
npx -y @crush-protocol/mcp-client login --url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## CLI / SDK Usage
|
|
160
|
+
|
|
161
|
+
Use this when you want to use Crush from Node.js directly.
|
|
125
162
|
|
|
126
|
-
|
|
163
|
+
CLI examples:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
npx -y @crush-protocol/mcp-client help
|
|
167
|
+
npx -y @crush-protocol/mcp-client tools:list --url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
168
|
+
npx -y @crush-protocol/mcp-client ping --url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
169
|
+
npx -y @crush-protocol/mcp-client backtest:schema --url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
170
|
+
npx -y @crush-protocol/mcp-client backtest:list --url https://crush-mcp-ats.dev.xexlab.com/mcp --limit 10
|
|
171
|
+
```
|
|
127
172
|
|
|
128
|
-
|
|
129
|
-
import { RemoteMcpClient, BacktestClient } from '@crush-protocol/mcp-client'
|
|
173
|
+
SDK example:
|
|
130
174
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
})
|
|
134
|
-
await mcp.connect()
|
|
175
|
+
```ts
|
|
176
|
+
import { OAuthRemoteMcpClient, BacktestClient } from "@crush-protocol/mcp-client";
|
|
135
177
|
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
/* ... */
|
|
140
|
-
},
|
|
141
|
-
})
|
|
142
|
-
const result = await backtest.getResult({ backtestId: bt.backtestId })
|
|
178
|
+
const mcp = new OAuthRemoteMcpClient({
|
|
179
|
+
serverUrl: "https://crush-mcp-ats.dev.xexlab.com/mcp",
|
|
180
|
+
});
|
|
143
181
|
|
|
144
|
-
await mcp.
|
|
182
|
+
await mcp.connect();
|
|
183
|
+
|
|
184
|
+
const backtests = new BacktestClient(mcp);
|
|
185
|
+
const result = await backtests.list({ limit: 10 });
|
|
186
|
+
|
|
187
|
+
console.log(result);
|
|
188
|
+
|
|
189
|
+
await mcp.close();
|
|
145
190
|
```
|
|
146
191
|
|
|
147
|
-
|
|
192
|
+
## Environment Variables
|
|
193
|
+
|
|
194
|
+
| Variable | Description |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| `CRUSH_MCP_SERVER_URL` | MCP server URL. Default: `https://crush-mcp-ats.dev.xexlab.com/mcp` |
|
|
197
|
+
| `CRUSH_OAUTH_ACCESS_TOKEN` | Optional OAuth access token override |
|
|
148
198
|
|
|
149
199
|
## License
|
|
150
200
|
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { RemoteMcpClient } from "../mcp/remoteClient.js";
|
|
1
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
3
2
|
import { BacktestClient } from "../backtest/backtestClient.js";
|
|
3
|
+
import { OAuthRemoteMcpClient } from "../mcp/oauthRemoteClient.js";
|
|
4
4
|
/**
|
|
5
5
|
* E2E 测试:验证 MCP client 能成功连接服务端并调用工具。
|
|
6
6
|
*
|
|
7
7
|
* 前置条件(通过环境变量或 .env.e2e 配置):
|
|
8
|
-
* CRUSH_MCP_SERVER_URL — 指向运行中的 MCP server(默认
|
|
9
|
-
*
|
|
8
|
+
* CRUSH_MCP_SERVER_URL — 指向运行中的 MCP server(默认 https://crush-mcp-ats.dev.xexlab.com/mcp)
|
|
9
|
+
* CRUSH_OAUTH_ACCESS_TOKEN — 有效的 OAuth access token
|
|
10
10
|
*/
|
|
11
|
-
const serverUrl = process.env.CRUSH_MCP_SERVER_URL ?? "
|
|
12
|
-
const token = process.env.
|
|
11
|
+
const serverUrl = process.env.CRUSH_MCP_SERVER_URL ?? "https://crush-mcp-ats.dev.xexlab.com/mcp";
|
|
12
|
+
const token = process.env.CRUSH_OAUTH_ACCESS_TOKEN ?? "";
|
|
13
13
|
// 没有 token 时跳过所有 e2e 测试
|
|
14
14
|
const describeE2E = token ? describe : describe.skip;
|
|
15
15
|
describeE2E("MCP Client E2E", () => {
|
|
16
16
|
let mcp;
|
|
17
17
|
let backtest;
|
|
18
18
|
beforeAll(async () => {
|
|
19
|
-
mcp = new
|
|
19
|
+
mcp = new OAuthRemoteMcpClient({ serverUrl, token, oauth: { openBrowser: false } });
|
|
20
20
|
await mcp.connect();
|
|
21
21
|
backtest = new BacktestClient(mcp);
|
|
22
22
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { mkdtemp, readFile } from "node:fs/promises";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { InteractiveOAuthProvider } from "../mcp/oauthProvider.js";
|
|
6
|
+
const tempDirs = [];
|
|
7
|
+
const createProvider = async () => {
|
|
8
|
+
const storageDir = await mkdtemp(path.join(os.tmpdir(), "crush-mcp-oauth-"));
|
|
9
|
+
tempDirs.push(storageDir);
|
|
10
|
+
const provider = new InteractiveOAuthProvider({
|
|
11
|
+
serverUrl: "https://example.com/mcp",
|
|
12
|
+
storageDir,
|
|
13
|
+
openBrowser: false,
|
|
14
|
+
});
|
|
15
|
+
return { provider, storageDir };
|
|
16
|
+
};
|
|
17
|
+
describe("InteractiveOAuthProvider", () => {
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
await Promise.all(tempDirs
|
|
20
|
+
.splice(0)
|
|
21
|
+
.map((dir) => import("node:fs/promises").then((fs) => fs.rm(dir, { recursive: true, force: true }))));
|
|
22
|
+
});
|
|
23
|
+
it("persists client info, tokens, and code verifier", async () => {
|
|
24
|
+
const { provider, storageDir } = await createProvider();
|
|
25
|
+
await provider.saveClientInformation({ client_id: "client_123" });
|
|
26
|
+
await provider.saveTokens({ access_token: "atk_123", token_type: "Bearer", refresh_token: "rt_123" });
|
|
27
|
+
await provider.saveCodeVerifier("verifier-123");
|
|
28
|
+
expect(await provider.clientInformation()).toEqual({ client_id: "client_123" });
|
|
29
|
+
expect(await provider.tokens()).toEqual({ access_token: "atk_123", token_type: "Bearer", refresh_token: "rt_123" });
|
|
30
|
+
expect(await provider.codeVerifier()).toBe("verifier-123");
|
|
31
|
+
const files = await import("node:fs/promises").then((fs) => fs.readdir(storageDir));
|
|
32
|
+
expect(files.length).toBe(1);
|
|
33
|
+
const raw = await readFile(path.join(storageDir, files[0]), "utf8");
|
|
34
|
+
expect(raw).toContain("client_123");
|
|
35
|
+
expect(raw).toContain("atk_123");
|
|
36
|
+
});
|
|
37
|
+
it("invalidates token state without removing client registration", async () => {
|
|
38
|
+
const { provider } = await createProvider();
|
|
39
|
+
await provider.saveClientInformation({ client_id: "client_123" });
|
|
40
|
+
await provider.saveTokens({ access_token: "atk_123", token_type: "Bearer", refresh_token: "rt_123" });
|
|
41
|
+
await provider.invalidateCredentials?.("tokens");
|
|
42
|
+
expect(await provider.clientInformation()).toEqual({ client_id: "client_123" });
|
|
43
|
+
expect(await provider.tokens()).toBeUndefined();
|
|
44
|
+
});
|
|
45
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type BacktestStatus, type Platform } from "@crush-protocol/mcp-contracts";
|
|
2
|
-
import type {
|
|
2
|
+
import type { McpClientLike } from "../mcp/types.js";
|
|
3
3
|
export type GetAvailableTokensInput = {
|
|
4
4
|
platform?: Platform;
|
|
5
5
|
};
|
|
@@ -11,9 +11,6 @@ export type CreateBacktestInput = {
|
|
|
11
11
|
config: Record<string, unknown>;
|
|
12
12
|
backtestId?: string;
|
|
13
13
|
};
|
|
14
|
-
export type GetBacktestResultInput = {
|
|
15
|
-
backtestId: string;
|
|
16
|
-
};
|
|
17
14
|
export type ListBacktestsInput = {
|
|
18
15
|
status?: BacktestStatus;
|
|
19
16
|
limit?: number;
|
|
@@ -81,7 +78,7 @@ export type ListBacktestsResult = {
|
|
|
81
78
|
*/
|
|
82
79
|
export declare class BacktestClient {
|
|
83
80
|
private readonly mcp;
|
|
84
|
-
constructor(mcp:
|
|
81
|
+
constructor(mcp: McpClientLike);
|
|
85
82
|
/**
|
|
86
83
|
* Return supported backtest configuration schema.
|
|
87
84
|
*/
|
|
@@ -103,10 +100,6 @@ export declare class BacktestClient {
|
|
|
103
100
|
* Create a new backtest or update an existing one.
|
|
104
101
|
*/
|
|
105
102
|
createBacktest(input: CreateBacktestInput): Promise<BacktestRecord>;
|
|
106
|
-
/**
|
|
107
|
-
* Get a backtest by ID with summary, portfolio history and trades.
|
|
108
|
-
*/
|
|
109
|
-
getResult(input: GetBacktestResultInput): Promise<BacktestRecord>;
|
|
110
103
|
/**
|
|
111
104
|
* List backtests for the current user with optional status filter and pagination.
|
|
112
105
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BacktestTools
|
|
1
|
+
import { BacktestTools } from "@crush-protocol/mcp-contracts";
|
|
2
2
|
const extractContent = (result) => {
|
|
3
3
|
// Compatibility path: some SDK result types expose `toolResult` directly.
|
|
4
4
|
if ("toolResult" in result && result.toolResult !== undefined) {
|
|
@@ -53,13 +53,6 @@ export class BacktestClient {
|
|
|
53
53
|
const result = await this.mcp.callTool(BacktestTools.CREATE_BACKTEST, input);
|
|
54
54
|
return extractContent(result);
|
|
55
55
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Get a backtest by ID with summary, portfolio history and trades.
|
|
58
|
-
*/
|
|
59
|
-
async getResult(input) {
|
|
60
|
-
const result = await this.mcp.callTool(BacktestTools.GET_BACKTEST_RESULT, input);
|
|
61
|
-
return extractContent(result);
|
|
62
|
-
}
|
|
63
56
|
/**
|
|
64
57
|
* List backtests for the current user with optional status filter and pagination.
|
|
65
58
|
*/
|