@crush-protocol/mcp-client 0.3.0 → 0.3.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 +781 -96
- package/dist/cli.js +10 -14
- package/dist/setup/setupClients.d.ts +3 -2
- package/dist/setup/setupClients.js +113 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,200 +1,885 @@
|
|
|
1
1
|
# Crush Protocol MCP Client
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@crush-protocol/mcp-client)
|
|
4
|
+
[](./LICENSE)
|
|
4
5
|
|
|
5
6
|
`@crush-protocol/mcp-client` is the npm entrypoint for Crush Protocol MCP.
|
|
6
7
|
|
|
7
|
-
Crush Protocol is an AI-native quantitative trading product. It lets an MCP host connect to Crush and use trading-focused tools for
|
|
8
|
+
Crush Protocol is an AI-native quantitative trading product. It lets an MCP host connect to Crush and use trading-focused tools for strategy research, backtest creation, live strategy management, and market data discovery.
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
- backtest creation and result retrieval
|
|
11
|
-
- live strategy management
|
|
12
|
-
- market data and signal discovery
|
|
10
|
+
## Quick Setup
|
|
13
11
|
|
|
14
|
-
|
|
12
|
+
```sh
|
|
13
|
+
npx -y @crush-protocol/mcp-client setup --all
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This writes MCP config for all **9** supported hosts: Cursor, Claude Code, Codex, Gemini CLI, OpenCode, VS Code, Windsurf, Claude Desktop, Warp.
|
|
17
|
+
|
|
18
|
+
To target a single host: `npx -y @crush-protocol/mcp-client setup --cursor`
|
|
19
|
+
|
|
20
|
+
**[All Client Configurations →](#client-configuration)**
|
|
21
|
+
|
|
22
|
+
## Connection Modes
|
|
23
|
+
|
|
24
|
+
| Mode | Transport | Auth | Best For |
|
|
25
|
+
|------|-----------|------|----------|
|
|
26
|
+
| **Local** | stdio (npx) | OAuth — browser opens automatically | Most MCP clients |
|
|
27
|
+
| **Remote** | Streamable HTTP | OAuth — browser opens automatically | Clients with native HTTP support |
|
|
15
28
|
|
|
16
|
-
|
|
29
|
+
**Remote Server URL:** `https://crush-mcp-ats.dev.xexlab.com/mcp`
|
|
17
30
|
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
Authentication is automatic (OAuth 2.1 Authorization Code + PKCE). On first use, a browser window opens for login; tokens are cached locally for reuse.
|
|
32
|
+
|
|
33
|
+
For hosts that support URL-only MCP (Remote mode), the full flow is:
|
|
34
|
+
|
|
35
|
+
1. Host connects to the MCP URL
|
|
36
|
+
2. Server returns `401` with `WWW-Authenticate` header
|
|
37
|
+
3. Host performs OAuth discovery and dynamic client registration
|
|
38
|
+
4. Completes Authorization Code + PKCE via browser
|
|
39
|
+
5. Persists tokens locally and reconnects
|
|
40
|
+
|
|
41
|
+
If a host cannot complete OAuth automatically, pre-authorize with:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npx -y @crush-protocol/mcp-client login
|
|
20
45
|
```
|
|
21
46
|
|
|
22
|
-
##
|
|
47
|
+
## Available Tools
|
|
48
|
+
|
|
49
|
+
**Market Data** — `list_tables` · `list_tokens` · `list_indicators` · `list_timeframes` · `get_data_range` · `check_query_size` · `fetch_ohlcv` · `fetch_indicator` · `fetch_news` · `get_connection_config` · `save_custom_indicator` · `list_custom_indicators` · `get_custom_indicator` · `delete_custom_indicator`
|
|
50
|
+
|
|
51
|
+
**Backtest** — `get_backtest_config_schema` · `get_available_tokens` · `validate_expression` · `create_backtest` · `list_backtests`
|
|
52
|
+
|
|
53
|
+
**Strategy** — `create_strategy` · `list_strategies` · `get_strategy` · `update_strategy` · `delete_strategy` · `toggle_strategy` · `get_strategy_logs`
|
|
23
54
|
|
|
24
|
-
|
|
55
|
+
**Signal** — `get_signal_metadata` · `get_signals_by_category`
|
|
25
56
|
|
|
26
|
-
|
|
57
|
+
**Utilities** — `search_tokens` · `get_token_info` · `get_trending_tokens` · `get_alpha_feed` · `get_token_feed`
|
|
27
58
|
|
|
28
|
-
|
|
59
|
+
Detailed tool guidance is in [INSTRUCTIONS.md](./INSTRUCTIONS.md).
|
|
60
|
+
|
|
61
|
+
## Client Configuration
|
|
29
62
|
|
|
30
|
-
|
|
63
|
+
<details>
|
|
64
|
+
<summary><strong>Cursor</strong></summary>
|
|
31
65
|
|
|
32
|
-
[](https://cursor.com/install-mcp?name=crush-protocol&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjcnVzaC1wcm90b2NvbC9tY3AtY2xpZW50Il19)
|
|
33
67
|
|
|
34
|
-
|
|
68
|
+
[Cursor MCP docs](https://docs.cursor.com/context/model-context-protocol) · Go to: `Settings` → `Cursor Settings` → `MCP` → `Add new global MCP server`
|
|
69
|
+
|
|
70
|
+
**Local:**
|
|
35
71
|
|
|
36
72
|
```json
|
|
37
73
|
{
|
|
38
74
|
"mcpServers": {
|
|
39
75
|
"crush-protocol": {
|
|
40
76
|
"command": "npx",
|
|
41
|
-
"args": ["-y", "@crush-protocol/mcp-client"
|
|
77
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Remote:**
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"crush-protocol": {
|
|
89
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
42
90
|
}
|
|
43
91
|
}
|
|
44
92
|
}
|
|
45
93
|
```
|
|
46
94
|
|
|
47
|
-
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary><strong>Claude Code</strong></summary>
|
|
99
|
+
|
|
100
|
+
[Claude Code MCP docs](https://docs.anthropic.com/en/docs/claude-code/mcp)
|
|
101
|
+
|
|
102
|
+
**Local:**
|
|
48
103
|
|
|
49
104
|
```sh
|
|
50
|
-
claude mcp add --scope user crush-protocol
|
|
51
|
-
-- npx -y @crush-protocol/mcp-client \
|
|
52
|
-
--url https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
105
|
+
claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
53
106
|
```
|
|
54
107
|
|
|
55
|
-
|
|
108
|
+
**Remote:**
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
claude mcp add --scope user --transport http crush-protocol https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details>
|
|
117
|
+
<summary><strong>OpenCode</strong></summary>
|
|
118
|
+
|
|
119
|
+
[OpenCode MCP docs](https://opencode.ai/docs/mcp-servers) · Add to `~/.config/opencode/opencode.json`
|
|
120
|
+
|
|
121
|
+
**Local:**
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"$schema": "https://opencode.ai/config.json",
|
|
126
|
+
"mcp": {
|
|
127
|
+
"crush-protocol": {
|
|
128
|
+
"type": "local",
|
|
129
|
+
"command": ["npx", "-y", "@crush-protocol/mcp-client"],
|
|
130
|
+
"enabled": true
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Remote:**
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"$schema": "https://opencode.ai/config.json",
|
|
141
|
+
"mcp": {
|
|
142
|
+
"crush-protocol": {
|
|
143
|
+
"type": "remote",
|
|
144
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp",
|
|
145
|
+
"enabled": true
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
56
150
|
|
|
57
|
-
|
|
151
|
+
</details>
|
|
152
|
+
|
|
153
|
+
<details>
|
|
154
|
+
<summary><strong>OpenAI Codex</strong></summary>
|
|
155
|
+
|
|
156
|
+
[OpenAI Codex MCP docs](https://developers.openai.com/codex/mcp)
|
|
157
|
+
|
|
158
|
+
**CLI:** `codex mcp add crush-protocol -- npx -y @crush-protocol/mcp-client`
|
|
159
|
+
|
|
160
|
+
**Local** (add to `~/.codex/config.toml`):
|
|
58
161
|
|
|
59
162
|
```toml
|
|
60
163
|
[mcp_servers.crush-protocol]
|
|
61
164
|
command = "npx"
|
|
62
|
-
args = ["-y", "@crush-protocol/mcp-client"
|
|
165
|
+
args = ["-y", "@crush-protocol/mcp-client"]
|
|
63
166
|
startup_timeout_ms = 20000
|
|
64
167
|
```
|
|
65
168
|
|
|
66
|
-
|
|
169
|
+
**Remote:**
|
|
170
|
+
|
|
171
|
+
```toml
|
|
172
|
+
[mcp_servers.crush-protocol]
|
|
173
|
+
url = "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
</details>
|
|
177
|
+
|
|
178
|
+
<details>
|
|
179
|
+
<summary><strong>Google Gemini CLI</strong></summary>
|
|
67
180
|
|
|
68
|
-
Add to `~/.gemini/settings.json
|
|
181
|
+
[Gemini CLI Configuration](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html) · Add to `~/.gemini/settings.json`
|
|
182
|
+
|
|
183
|
+
**Remote:**
|
|
184
|
+
|
|
185
|
+
```json
|
|
186
|
+
{
|
|
187
|
+
"mcpServers": {
|
|
188
|
+
"crush-protocol": {
|
|
189
|
+
"httpUrl": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Local:**
|
|
69
196
|
|
|
70
197
|
```json
|
|
71
198
|
{
|
|
72
199
|
"mcpServers": {
|
|
73
200
|
"crush-protocol": {
|
|
74
201
|
"command": "npx",
|
|
75
|
-
"args": ["-y", "@crush-protocol/mcp-client"
|
|
202
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
76
203
|
}
|
|
77
204
|
}
|
|
78
205
|
}
|
|
79
206
|
```
|
|
80
207
|
|
|
81
|
-
|
|
208
|
+
</details>
|
|
209
|
+
|
|
210
|
+
<details>
|
|
211
|
+
<summary><strong>VS Code</strong></summary>
|
|
82
212
|
|
|
83
|
-
Add to
|
|
213
|
+
[VS Code MCP docs](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) · Add to `.vscode/mcp.json`
|
|
214
|
+
|
|
215
|
+
**Remote:**
|
|
84
216
|
|
|
85
217
|
```json
|
|
86
218
|
{
|
|
87
|
-
"
|
|
88
|
-
|
|
219
|
+
"servers": {
|
|
220
|
+
"crush-protocol": {
|
|
221
|
+
"type": "http",
|
|
222
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Local:**
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
{
|
|
232
|
+
"servers": {
|
|
233
|
+
"crush-protocol": {
|
|
234
|
+
"type": "stdio",
|
|
235
|
+
"command": "npx",
|
|
236
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
</details>
|
|
243
|
+
|
|
244
|
+
<details>
|
|
245
|
+
<summary><strong>Windsurf</strong></summary>
|
|
246
|
+
|
|
247
|
+
[Windsurf MCP docs](https://docs.windsurf.com/windsurf/cascade/mcp)
|
|
248
|
+
|
|
249
|
+
**Remote:**
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"mcpServers": {
|
|
254
|
+
"crush-protocol": {
|
|
255
|
+
"serverUrl": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Local:**
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"mcpServers": {
|
|
266
|
+
"crush-protocol": {
|
|
267
|
+
"command": "npx",
|
|
268
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
</details>
|
|
275
|
+
|
|
276
|
+
<details>
|
|
277
|
+
<summary><strong>Claude Desktop</strong></summary>
|
|
278
|
+
|
|
279
|
+
[Claude Desktop MCP docs](https://modelcontextprotocol.io/quickstart/user) · Edit `claude_desktop_config.json`
|
|
280
|
+
|
|
281
|
+
**Local:**
|
|
282
|
+
|
|
283
|
+
```json
|
|
284
|
+
{
|
|
285
|
+
"mcpServers": {
|
|
286
|
+
"crush-protocol": {
|
|
287
|
+
"command": "npx",
|
|
288
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
</details>
|
|
295
|
+
|
|
296
|
+
<details>
|
|
297
|
+
<summary><strong>Kiro</strong></summary>
|
|
298
|
+
|
|
299
|
+
[Kiro MCP docs](https://kiro.dev/docs/mcp/configuration/) · Navigate `Kiro` → `MCP Servers` → `+ Add`
|
|
300
|
+
|
|
301
|
+
**Remote:**
|
|
302
|
+
|
|
303
|
+
```json
|
|
304
|
+
{
|
|
305
|
+
"mcpServers": {
|
|
306
|
+
"crush-protocol": {
|
|
307
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**Local:**
|
|
314
|
+
|
|
315
|
+
```json
|
|
316
|
+
{
|
|
317
|
+
"mcpServers": {
|
|
318
|
+
"crush-protocol": {
|
|
319
|
+
"command": "npx",
|
|
320
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
</details>
|
|
327
|
+
|
|
328
|
+
<details>
|
|
329
|
+
<summary><strong>Roo Code</strong></summary>
|
|
330
|
+
|
|
331
|
+
[Roo Code MCP docs](https://docs.roocode.com/features/mcp/using-mcp-in-roo)
|
|
332
|
+
|
|
333
|
+
**Remote:**
|
|
334
|
+
|
|
335
|
+
```json
|
|
336
|
+
{
|
|
337
|
+
"mcpServers": {
|
|
338
|
+
"crush-protocol": {
|
|
339
|
+
"type": "streamable-http",
|
|
340
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
**Local:**
|
|
347
|
+
|
|
348
|
+
```json
|
|
349
|
+
{
|
|
350
|
+
"mcpServers": {
|
|
351
|
+
"crush-protocol": {
|
|
352
|
+
"command": "npx",
|
|
353
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
</details>
|
|
360
|
+
|
|
361
|
+
<details>
|
|
362
|
+
<summary><strong>Cline</strong></summary>
|
|
363
|
+
|
|
364
|
+
[Cline MCP Marketplace](https://cline.bot/mcp-marketplace)
|
|
365
|
+
|
|
366
|
+
**Remote:**
|
|
367
|
+
|
|
368
|
+
```json
|
|
369
|
+
{
|
|
370
|
+
"mcpServers": {
|
|
371
|
+
"crush-protocol": {
|
|
372
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp",
|
|
373
|
+
"type": "streamableHttp"
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
**Local:**
|
|
380
|
+
|
|
381
|
+
```json
|
|
382
|
+
{
|
|
383
|
+
"mcpServers": {
|
|
384
|
+
"crush-protocol": {
|
|
385
|
+
"command": "npx",
|
|
386
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
</details>
|
|
393
|
+
|
|
394
|
+
<details>
|
|
395
|
+
<summary><strong>Trae</strong></summary>
|
|
396
|
+
|
|
397
|
+
[Trae MCP docs](https://docs.trae.ai/ide/model-context-protocol?_lang=en)
|
|
398
|
+
|
|
399
|
+
**Remote:**
|
|
400
|
+
|
|
401
|
+
```json
|
|
402
|
+
{
|
|
403
|
+
"mcpServers": {
|
|
404
|
+
"crush-protocol": {
|
|
405
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
**Local:**
|
|
412
|
+
|
|
413
|
+
```json
|
|
414
|
+
{
|
|
415
|
+
"mcpServers": {
|
|
416
|
+
"crush-protocol": {
|
|
417
|
+
"command": "npx",
|
|
418
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
</details>
|
|
425
|
+
|
|
426
|
+
<details>
|
|
427
|
+
<summary><strong>Augment Code</strong></summary>
|
|
428
|
+
|
|
429
|
+
1. Click hamburger menu → Settings → Tools → `+ Add MCP`
|
|
430
|
+
2. Enter command: `npx -y @crush-protocol/mcp-client`
|
|
431
|
+
3. Name: `crush-protocol` → Click Add
|
|
432
|
+
|
|
433
|
+
Manual config in VS Code settings:
|
|
434
|
+
|
|
435
|
+
```json
|
|
436
|
+
"augment.advanced": {
|
|
437
|
+
"mcpServers": [
|
|
438
|
+
{
|
|
439
|
+
"name": "crush-protocol",
|
|
440
|
+
"command": "npx",
|
|
441
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
</details>
|
|
448
|
+
|
|
449
|
+
<details>
|
|
450
|
+
<summary><strong>Copilot Coding Agent</strong></summary>
|
|
451
|
+
|
|
452
|
+
[GitHub Copilot MCP docs](https://docs.github.com/en/enterprise-cloud@latest/copilot/how-tos/agents/copilot-coding-agent/extending-copilot-coding-agent-with-mcp)
|
|
453
|
+
|
|
454
|
+
**Remote:**
|
|
455
|
+
|
|
456
|
+
```json
|
|
457
|
+
{
|
|
458
|
+
"mcpServers": {
|
|
459
|
+
"crush-protocol": {
|
|
460
|
+
"type": "http",
|
|
461
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
**Local:**
|
|
468
|
+
|
|
469
|
+
```json
|
|
470
|
+
{
|
|
471
|
+
"mcpServers": {
|
|
89
472
|
"crush-protocol": {
|
|
90
473
|
"type": "local",
|
|
91
|
-
"command":
|
|
92
|
-
"
|
|
474
|
+
"command": "npx",
|
|
475
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
93
476
|
}
|
|
94
477
|
}
|
|
95
478
|
}
|
|
96
479
|
```
|
|
97
480
|
|
|
98
|
-
|
|
481
|
+
</details>
|
|
99
482
|
|
|
100
|
-
|
|
483
|
+
<details>
|
|
484
|
+
<summary><strong>Copilot CLI</strong></summary>
|
|
101
485
|
|
|
102
|
-
|
|
103
|
-
|
|
486
|
+
Add to `~/.copilot/mcp-config.json`:
|
|
487
|
+
|
|
488
|
+
**Remote:**
|
|
489
|
+
|
|
490
|
+
```json
|
|
491
|
+
{
|
|
492
|
+
"mcpServers": {
|
|
493
|
+
"crush-protocol": {
|
|
494
|
+
"type": "http",
|
|
495
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
**Local:**
|
|
502
|
+
|
|
503
|
+
```json
|
|
504
|
+
{
|
|
505
|
+
"mcpServers": {
|
|
506
|
+
"crush-protocol": {
|
|
507
|
+
"type": "local",
|
|
508
|
+
"command": "npx",
|
|
509
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
</details>
|
|
516
|
+
|
|
517
|
+
<details>
|
|
518
|
+
<summary><strong>Amazon Q Developer CLI</strong></summary>
|
|
519
|
+
|
|
520
|
+
[Amazon Q Developer CLI docs](https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-mcp-configuration.html)
|
|
521
|
+
|
|
522
|
+
```json
|
|
523
|
+
{
|
|
524
|
+
"mcpServers": {
|
|
525
|
+
"crush-protocol": {
|
|
526
|
+
"command": "npx",
|
|
527
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
</details>
|
|
534
|
+
|
|
535
|
+
<details>
|
|
536
|
+
<summary><strong>Warp</strong></summary>
|
|
537
|
+
|
|
538
|
+
[Warp MCP docs](https://docs.warp.dev/knowledge-and-collaboration/mcp#adding-an-mcp-server) · Navigate `Settings` → `AI` → `Manage MCP servers` → `+ Add`
|
|
539
|
+
|
|
540
|
+
```json
|
|
541
|
+
{
|
|
542
|
+
"crush-protocol": {
|
|
543
|
+
"command": "npx",
|
|
544
|
+
"args": ["-y", "@crush-protocol/mcp-client"],
|
|
545
|
+
"env": {},
|
|
546
|
+
"working_directory": null,
|
|
547
|
+
"start_on_launch": true
|
|
548
|
+
}
|
|
549
|
+
}
|
|
104
550
|
```
|
|
105
551
|
|
|
106
|
-
|
|
552
|
+
</details>
|
|
553
|
+
|
|
554
|
+
<details>
|
|
555
|
+
<summary><strong>Amp</strong></summary>
|
|
556
|
+
|
|
557
|
+
[Amp MCP docs](https://ampcode.com/manual#mcp)
|
|
107
558
|
|
|
108
559
|
```sh
|
|
109
|
-
|
|
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
|
|
560
|
+
amp mcp add crush-protocol https://crush-mcp-ats.dev.xexlab.com/mcp
|
|
114
561
|
```
|
|
115
562
|
|
|
116
|
-
|
|
563
|
+
</details>
|
|
117
564
|
|
|
118
|
-
|
|
565
|
+
<details>
|
|
566
|
+
<summary><strong>Zed</strong></summary>
|
|
119
567
|
|
|
120
|
-
- `
|
|
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`
|
|
568
|
+
[Zed Context Server docs](https://zed.dev/docs/assistant/context-servers) · Add to `settings.json`
|
|
129
569
|
|
|
130
|
-
|
|
570
|
+
```json
|
|
571
|
+
{
|
|
572
|
+
"context_servers": {
|
|
573
|
+
"crush-protocol": {
|
|
574
|
+
"source": "custom",
|
|
575
|
+
"command": "npx",
|
|
576
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
```
|
|
131
581
|
|
|
132
|
-
|
|
582
|
+
</details>
|
|
133
583
|
|
|
134
|
-
|
|
584
|
+
<details>
|
|
585
|
+
<summary><strong>JetBrains AI Assistant</strong></summary>
|
|
135
586
|
|
|
136
|
-
|
|
587
|
+
[JetBrains AI Assistant docs](https://www.jetbrains.com/help/ai-assistant/configure-an-mcp-server.html) · Go to `Settings` → `Tools` → `AI Assistant` → `Model Context Protocol (MCP)` → `+ Add`
|
|
137
588
|
|
|
138
|
-
|
|
139
|
-
- the client completes browser OAuth when needed
|
|
140
|
-
- tokens are stored locally for reuse
|
|
589
|
+
**Remote:**
|
|
141
590
|
|
|
142
|
-
|
|
591
|
+
```json
|
|
592
|
+
{
|
|
593
|
+
"mcpServers": {
|
|
594
|
+
"crush-protocol": {
|
|
595
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
```
|
|
143
600
|
|
|
144
|
-
|
|
145
|
-
- `CRUSH_OAUTH_ACCESS_TOKEN=<access-token>`
|
|
601
|
+
**Local:**
|
|
146
602
|
|
|
147
|
-
|
|
603
|
+
```json
|
|
604
|
+
{
|
|
605
|
+
"mcpServers": {
|
|
606
|
+
"crush-protocol": {
|
|
607
|
+
"command": "npx",
|
|
608
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
```
|
|
148
613
|
|
|
149
|
-
|
|
150
|
-
2. `CRUSH_OAUTH_ACCESS_TOKEN`
|
|
151
|
-
3. automatic OAuth with local token cache
|
|
614
|
+
</details>
|
|
152
615
|
|
|
153
|
-
|
|
616
|
+
<details>
|
|
617
|
+
<summary><strong>Qwen Code</strong></summary>
|
|
154
618
|
|
|
155
|
-
|
|
156
|
-
|
|
619
|
+
[Qwen Code MCP docs](https://qwenlm.github.io/qwen-code-docs/en/users/features/mcp/)
|
|
620
|
+
|
|
621
|
+
**CLI:** `qwen mcp add crush-protocol npx -y @crush-protocol/mcp-client`
|
|
622
|
+
|
|
623
|
+
**Remote** (add to `~/.qwen/settings.json`):
|
|
624
|
+
|
|
625
|
+
```json
|
|
626
|
+
{
|
|
627
|
+
"mcpServers": {
|
|
628
|
+
"crush-protocol": {
|
|
629
|
+
"httpUrl": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
157
633
|
```
|
|
158
634
|
|
|
159
|
-
|
|
635
|
+
**Local:**
|
|
160
636
|
|
|
161
|
-
|
|
637
|
+
```json
|
|
638
|
+
{
|
|
639
|
+
"mcpServers": {
|
|
640
|
+
"crush-protocol": {
|
|
641
|
+
"command": "npx",
|
|
642
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
```
|
|
162
647
|
|
|
163
|
-
|
|
648
|
+
</details>
|
|
164
649
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
650
|
+
<details>
|
|
651
|
+
<summary><strong>LM Studio</strong></summary>
|
|
652
|
+
|
|
653
|
+
[LM Studio MCP Support](https://lmstudio.ai/blog/lmstudio-v0.3.17) · Navigate `Program` → `Install` → `Edit mcp.json`
|
|
654
|
+
|
|
655
|
+
```json
|
|
656
|
+
{
|
|
657
|
+
"mcpServers": {
|
|
658
|
+
"crush-protocol": {
|
|
659
|
+
"command": "npx",
|
|
660
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
171
664
|
```
|
|
172
665
|
|
|
173
|
-
|
|
666
|
+
</details>
|
|
174
667
|
|
|
175
|
-
|
|
176
|
-
|
|
668
|
+
<details>
|
|
669
|
+
<summary><strong>Visual Studio 2022</strong></summary>
|
|
177
670
|
|
|
178
|
-
|
|
179
|
-
serverUrl: "https://crush-mcp-ats.dev.xexlab.com/mcp",
|
|
180
|
-
});
|
|
671
|
+
[Visual Studio MCP docs](https://learn.microsoft.com/visualstudio/ide/mcp-servers?view=vs-2022)
|
|
181
672
|
|
|
182
|
-
|
|
673
|
+
**Remote:**
|
|
183
674
|
|
|
184
|
-
|
|
185
|
-
|
|
675
|
+
```json
|
|
676
|
+
{
|
|
677
|
+
"inputs": [],
|
|
678
|
+
"servers": {
|
|
679
|
+
"crush-protocol": {
|
|
680
|
+
"type": "http",
|
|
681
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
**Local:**
|
|
688
|
+
|
|
689
|
+
```json
|
|
690
|
+
{
|
|
691
|
+
"mcp": {
|
|
692
|
+
"servers": {
|
|
693
|
+
"crush-protocol": {
|
|
694
|
+
"type": "stdio",
|
|
695
|
+
"command": "npx",
|
|
696
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
</details>
|
|
704
|
+
|
|
705
|
+
<details>
|
|
706
|
+
<summary><strong>BoltAI</strong></summary>
|
|
707
|
+
|
|
708
|
+
[BoltAI docs](https://docs.boltai.com/docs/plugins/mcp-servers)
|
|
709
|
+
|
|
710
|
+
```json
|
|
711
|
+
{
|
|
712
|
+
"mcpServers": {
|
|
713
|
+
"crush-protocol": {
|
|
714
|
+
"command": "npx",
|
|
715
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
</details>
|
|
722
|
+
|
|
723
|
+
<details>
|
|
724
|
+
<summary><strong>Perplexity Desktop</strong></summary>
|
|
725
|
+
|
|
726
|
+
[Perplexity MCP docs](https://www.perplexity.ai/help-center/en/articles/11502712-local-and-remote-mcps-for-perplexity) · Navigate `Perplexity` → `Settings` → `Connectors` → `Add Connector` → `Advanced` · Server Name: `crush-protocol`
|
|
727
|
+
|
|
728
|
+
```json
|
|
729
|
+
{
|
|
730
|
+
"args": ["-y", "@crush-protocol/mcp-client"],
|
|
731
|
+
"command": "npx",
|
|
732
|
+
"env": {}
|
|
733
|
+
}
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
</details>
|
|
737
|
+
|
|
738
|
+
<details>
|
|
739
|
+
<summary><strong>Kilo Code</strong></summary>
|
|
740
|
+
|
|
741
|
+
[Kilo Code docs](https://kilocode.ai)
|
|
742
|
+
|
|
743
|
+
**Remote:**
|
|
744
|
+
|
|
745
|
+
```json
|
|
746
|
+
{
|
|
747
|
+
"mcpServers": {
|
|
748
|
+
"crush-protocol": {
|
|
749
|
+
"type": "streamable-http",
|
|
750
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
**Local:**
|
|
757
|
+
|
|
758
|
+
```json
|
|
759
|
+
{
|
|
760
|
+
"mcpServers": {
|
|
761
|
+
"crush-protocol": {
|
|
762
|
+
"command": "npx",
|
|
763
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
</details>
|
|
770
|
+
|
|
771
|
+
<details>
|
|
772
|
+
<summary><strong>Zencoder</strong></summary>
|
|
773
|
+
|
|
774
|
+
Go to Zencoder menu → Agent tools → Add custom MCP, paste:
|
|
775
|
+
|
|
776
|
+
```json
|
|
777
|
+
{
|
|
778
|
+
"command": "npx",
|
|
779
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
780
|
+
}
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
</details>
|
|
784
|
+
|
|
785
|
+
<details>
|
|
786
|
+
<summary><strong>Qodo Gen</strong></summary>
|
|
787
|
+
|
|
788
|
+
[Qodo Gen docs](https://docs.qodo.ai/qodo-documentation/qodo-gen/qodo-gen-chat/agentic-mode/agentic-tools-mcps) · Open Qodo Gen chat → Connect more tools → `+ Add new MCP`
|
|
789
|
+
|
|
790
|
+
**Remote:**
|
|
791
|
+
|
|
792
|
+
```json
|
|
793
|
+
{
|
|
794
|
+
"mcpServers": {
|
|
795
|
+
"crush-protocol": {
|
|
796
|
+
"url": "https://crush-mcp-ats.dev.xexlab.com/mcp"
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
**Local:**
|
|
803
|
+
|
|
804
|
+
```json
|
|
805
|
+
{
|
|
806
|
+
"mcpServers": {
|
|
807
|
+
"crush-protocol": {
|
|
808
|
+
"command": "npx",
|
|
809
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
</details>
|
|
816
|
+
|
|
817
|
+
<details>
|
|
818
|
+
<summary><strong>Using Bun or Deno</strong></summary>
|
|
819
|
+
|
|
820
|
+
**Bun:**
|
|
186
821
|
|
|
187
|
-
|
|
822
|
+
```json
|
|
823
|
+
{
|
|
824
|
+
"mcpServers": {
|
|
825
|
+
"crush-protocol": {
|
|
826
|
+
"command": "bunx",
|
|
827
|
+
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
```
|
|
188
832
|
|
|
189
|
-
|
|
833
|
+
**Deno:**
|
|
834
|
+
|
|
835
|
+
```json
|
|
836
|
+
{
|
|
837
|
+
"mcpServers": {
|
|
838
|
+
"crush-protocol": {
|
|
839
|
+
"command": "deno",
|
|
840
|
+
"args": [
|
|
841
|
+
"run",
|
|
842
|
+
"--allow-env",
|
|
843
|
+
"--allow-net",
|
|
844
|
+
"--allow-read",
|
|
845
|
+
"--allow-write",
|
|
846
|
+
"npm:@crush-protocol/mcp-client"
|
|
847
|
+
]
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
190
851
|
```
|
|
191
852
|
|
|
192
|
-
|
|
853
|
+
</details>
|
|
193
854
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
855
|
+
<details>
|
|
856
|
+
<summary><strong>Windows</strong></summary>
|
|
857
|
+
|
|
858
|
+
Use `cmd` as the command wrapper:
|
|
859
|
+
|
|
860
|
+
```json
|
|
861
|
+
{
|
|
862
|
+
"mcpServers": {
|
|
863
|
+
"crush-protocol": {
|
|
864
|
+
"command": "cmd",
|
|
865
|
+
"args": ["/c", "npx", "-y", "@crush-protocol/mcp-client"]
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
</details>
|
|
872
|
+
|
|
873
|
+
## CLI Usage
|
|
874
|
+
|
|
875
|
+
```sh
|
|
876
|
+
npx -y @crush-protocol/mcp-client login # 预授权 OAuth(浏览器登录)
|
|
877
|
+
npx -y @crush-protocol/mcp-client setup --all # 写入所有客户端配置
|
|
878
|
+
npx -y @crush-protocol/mcp-client tools:list # 列出可用工具
|
|
879
|
+
npx -y @crush-protocol/mcp-client ping # 测试连通性
|
|
880
|
+
npx -y @crush-protocol/mcp-client backtest:schema # 获取回测配置 schema
|
|
881
|
+
npx -y @crush-protocol/mcp-client backtest:list --limit 10
|
|
882
|
+
```
|
|
198
883
|
|
|
199
884
|
## License
|
|
200
885
|
|
package/dist/cli.js
CHANGED
|
@@ -4,10 +4,10 @@ import { BacktestClient } from "./backtest/backtestClient.js";
|
|
|
4
4
|
import { ClickHouseDirectClient } from "./clickhouse/directClient.js";
|
|
5
5
|
import { OAuthRemoteMcpClient } from "./mcp/oauthRemoteClient.js";
|
|
6
6
|
import { RemoteMcpClient } from "./mcp/remoteClient.js";
|
|
7
|
-
import { installClientConfig } from "./setup/setupClients.js";
|
|
8
|
-
const
|
|
7
|
+
import { ALL_TARGETS, installClientConfig } from "./setup/setupClients.js";
|
|
8
|
+
const MCP_SERVER_URL = "https://crush-mcp-ats.dev.xexlab.com/mcp";
|
|
9
9
|
const printUsage = () => {
|
|
10
|
-
console.log(`\ncrush-mcp-client\n\nGeneral:\n login
|
|
10
|
+
console.log(`\ncrush-mcp-client\n\nGeneral:\n login\n setup [--cursor] [--claude] [--codex] [--gemini] [--opencode] [--all] [--scope user|project]\n tools:list [--token TOKEN]\n tool:call --name TOOL_NAME [--args JSON] [--token TOKEN]\n ping [--token TOKEN]\n\nBacktest:\n backtest:schema [--token TOKEN]\n backtest:tokens [--platform PLATFORM] [--token TOKEN]\n backtest:validate --expression JSON [--data-source kline|factors] [--token TOKEN]\n backtest:create --config JSON [--backtest-id ID] [--token TOKEN]\n backtest:list [--status STATUS] [--limit N] [--offset N] [--token TOKEN]\n\nClickHouse:\n clickhouse:list-tables [--ch-host HOST --ch-port PORT --ch-user USER --ch-password PASS --ch-database DB]\n clickhouse:query --sql SQL [--ch-host HOST --ch-port PORT --ch-user USER --ch-password PASS --ch-database DB --ch-row-cap N]\n\nAuth:\n --token TOKEN uses a provided OAuth access token.\n Without --token, OAuth runs automatically in the browser when needed.\n\nEnv:\n CRUSH_OAUTH_ACCESS_TOKEN\n CH_HOST, CH_PORT, CH_USER, CH_PASSWORD, CH_DATABASE, CH_ROW_CAP\n`);
|
|
11
11
|
};
|
|
12
12
|
const parseFlags = (args) => {
|
|
13
13
|
const flags = {};
|
|
@@ -32,15 +32,12 @@ const requireString = (value, message) => {
|
|
|
32
32
|
}
|
|
33
33
|
return value;
|
|
34
34
|
};
|
|
35
|
-
const getServerUrl = (
|
|
36
|
-
? flags.url
|
|
37
|
-
: (process.env.CRUSH_MCP_SERVER_URL ?? DEFAULT_MCP_SERVER_URL);
|
|
35
|
+
const getServerUrl = () => MCP_SERVER_URL;
|
|
38
36
|
const getSetupTargets = (flags) => {
|
|
39
|
-
const explicitTargets = ["cursor", "claude", "codex", "gemini", "opencode"].filter((target) => flags[target] === true);
|
|
40
37
|
if (flags.all === true) {
|
|
41
|
-
return [
|
|
38
|
+
return [...ALL_TARGETS];
|
|
42
39
|
}
|
|
43
|
-
return
|
|
40
|
+
return ALL_TARGETS.filter((target) => flags[target] === true);
|
|
44
41
|
};
|
|
45
42
|
/**
|
|
46
43
|
* 创建 MCP 客户端(统一认证入口)
|
|
@@ -54,7 +51,7 @@ const getSetupTargets = (flags) => {
|
|
|
54
51
|
* - 无 token → 自动拉起浏览器登录
|
|
55
52
|
*/
|
|
56
53
|
const createSmartClient = (flags) => {
|
|
57
|
-
const serverUrl = getServerUrl(
|
|
54
|
+
const serverUrl = getServerUrl();
|
|
58
55
|
// 显式传了 token → 用简单客户端
|
|
59
56
|
const explicitToken = typeof flags.token === "string" ? flags.token : process.env.CRUSH_OAUTH_ACCESS_TOKEN || "";
|
|
60
57
|
if (explicitToken) {
|
|
@@ -116,7 +113,7 @@ const run = async () => {
|
|
|
116
113
|
const flags = parseFlags(rest);
|
|
117
114
|
switch (command) {
|
|
118
115
|
case "login": {
|
|
119
|
-
const serverUrl = getServerUrl(
|
|
116
|
+
const serverUrl = getServerUrl();
|
|
120
117
|
const client = new OAuthRemoteMcpClient({ serverUrl });
|
|
121
118
|
try {
|
|
122
119
|
await client.ensureAuthorized();
|
|
@@ -130,16 +127,15 @@ const run = async () => {
|
|
|
130
127
|
case "setup": {
|
|
131
128
|
const targets = getSetupTargets(flags);
|
|
132
129
|
if (targets.length === 0) {
|
|
133
|
-
throw new Error(
|
|
130
|
+
throw new Error(`Specify at least one setup target: ${ALL_TARGETS.map((t) => "--" + t).join(", ")}, or --all`);
|
|
134
131
|
}
|
|
135
132
|
const rawScope = typeof flags.scope === "string" ? flags.scope : "user";
|
|
136
133
|
if (rawScope !== "user" && rawScope !== "project") {
|
|
137
134
|
throw new Error("Invalid --scope. Expected 'user' or 'project'.");
|
|
138
135
|
}
|
|
139
136
|
const scope = rawScope;
|
|
140
|
-
const serverUrl = getServerUrl(flags);
|
|
141
137
|
for (const target of targets) {
|
|
142
|
-
const location = installClientConfig(target,
|
|
138
|
+
const location = installClientConfig(target, scope);
|
|
143
139
|
console.log(`[setup] ${target}: configured (${location})`);
|
|
144
140
|
}
|
|
145
141
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type SetupTarget = "cursor" | "claude" | "codex" | "gemini" | "opencode";
|
|
1
|
+
export type SetupTarget = "cursor" | "claude" | "codex" | "gemini" | "opencode" | "vscode" | "windsurf" | "claude-desktop" | "warp";
|
|
2
2
|
export type SetupScope = "user" | "project";
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const ALL_TARGETS: readonly SetupTarget[];
|
|
4
|
+
export declare const installClientConfig: (target: SetupTarget, scope: SetupScope) => string;
|
|
@@ -4,6 +4,18 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
const SERVER_NAME = "crush-protocol";
|
|
6
6
|
const PACKAGE_NAME = "@crush-protocol/mcp-client";
|
|
7
|
+
const REMOTE_URL = "https://crush-mcp-ats.dev.xexlab.com/mcp";
|
|
8
|
+
export const ALL_TARGETS = [
|
|
9
|
+
"cursor",
|
|
10
|
+
"claude",
|
|
11
|
+
"codex",
|
|
12
|
+
"gemini",
|
|
13
|
+
"opencode",
|
|
14
|
+
"vscode",
|
|
15
|
+
"windsurf",
|
|
16
|
+
"claude-desktop",
|
|
17
|
+
"warp",
|
|
18
|
+
];
|
|
7
19
|
const ensureDir = (filePath) => {
|
|
8
20
|
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
9
21
|
};
|
|
@@ -21,37 +33,39 @@ const writeJson = (filePath, value) => {
|
|
|
21
33
|
ensureDir(filePath);
|
|
22
34
|
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
23
35
|
};
|
|
24
|
-
const createNpxConfig = (
|
|
36
|
+
const createNpxConfig = () => ({
|
|
25
37
|
command: "npx",
|
|
26
|
-
args: ["-y", PACKAGE_NAME
|
|
38
|
+
args: ["-y", PACKAGE_NAME],
|
|
27
39
|
});
|
|
40
|
+
// ─── Cursor ─────────────────────────────────────────────
|
|
28
41
|
const getCursorConfigPath = (scope) => scope === "project"
|
|
29
42
|
? path.join(process.cwd(), ".cursor", "mcp.json")
|
|
30
43
|
: path.join(os.homedir(), ".cursor", "mcp.json");
|
|
31
|
-
const
|
|
32
|
-
const getOpenCodeConfigPath = (scope) => scope === "project"
|
|
33
|
-
? path.join(process.cwd(), "opencode.json")
|
|
34
|
-
: path.join(os.homedir(), ".config", "opencode", "opencode.json");
|
|
35
|
-
const getCodexConfigPath = () => path.join(os.homedir(), ".codex", "config.toml");
|
|
36
|
-
const installCursor = (serverUrl, scope) => {
|
|
44
|
+
const installCursor = (scope) => {
|
|
37
45
|
const filePath = getCursorConfigPath(scope);
|
|
38
46
|
const config = readJson(filePath);
|
|
39
47
|
const mcpServers = (config.mcpServers ?? {});
|
|
40
|
-
mcpServers[SERVER_NAME] = createNpxConfig(
|
|
48
|
+
mcpServers[SERVER_NAME] = createNpxConfig();
|
|
41
49
|
config.mcpServers = mcpServers;
|
|
42
50
|
writeJson(filePath, config);
|
|
43
51
|
return filePath;
|
|
44
52
|
};
|
|
45
|
-
|
|
53
|
+
// ─── Gemini CLI ─────────────────────────────────────────
|
|
54
|
+
const getGeminiConfigPath = () => path.join(os.homedir(), ".gemini", "settings.json");
|
|
55
|
+
const installGemini = () => {
|
|
46
56
|
const filePath = getGeminiConfigPath();
|
|
47
57
|
const config = readJson(filePath);
|
|
48
58
|
const mcpServers = (config.mcpServers ?? {});
|
|
49
|
-
mcpServers[SERVER_NAME] = createNpxConfig(
|
|
59
|
+
mcpServers[SERVER_NAME] = createNpxConfig();
|
|
50
60
|
config.mcpServers = mcpServers;
|
|
51
61
|
writeJson(filePath, config);
|
|
52
62
|
return filePath;
|
|
53
63
|
};
|
|
54
|
-
|
|
64
|
+
// ─── OpenCode ───────────────────────────────────────────
|
|
65
|
+
const getOpenCodeConfigPath = (scope) => scope === "project"
|
|
66
|
+
? path.join(process.cwd(), "opencode.json")
|
|
67
|
+
: path.join(os.homedir(), ".config", "opencode", "opencode.json");
|
|
68
|
+
const installOpenCode = (scope) => {
|
|
55
69
|
const filePath = getOpenCodeConfigPath(scope);
|
|
56
70
|
const config = readJson(filePath);
|
|
57
71
|
const mcp = (config.mcp ?? {});
|
|
@@ -60,18 +74,20 @@ const installOpenCode = (serverUrl, scope) => {
|
|
|
60
74
|
}
|
|
61
75
|
mcp[SERVER_NAME] = {
|
|
62
76
|
type: "local",
|
|
63
|
-
command: ["npx", "-y", PACKAGE_NAME
|
|
77
|
+
command: ["npx", "-y", PACKAGE_NAME],
|
|
64
78
|
enabled: true,
|
|
65
79
|
};
|
|
66
80
|
config.mcp = mcp;
|
|
67
81
|
writeJson(filePath, config);
|
|
68
82
|
return filePath;
|
|
69
83
|
};
|
|
70
|
-
|
|
84
|
+
// ─── OpenAI Codex ───────────────────────────────────────
|
|
85
|
+
const getCodexConfigPath = () => path.join(os.homedir(), ".codex", "config.toml");
|
|
86
|
+
const installCodex = () => {
|
|
71
87
|
const filePath = getCodexConfigPath();
|
|
72
88
|
const section = `[mcp_servers.${SERVER_NAME}]
|
|
73
89
|
command = "npx"
|
|
74
|
-
args = ["-y", "${PACKAGE_NAME}"
|
|
90
|
+
args = ["-y", "${PACKAGE_NAME}"]
|
|
75
91
|
startup_timeout_ms = 20000
|
|
76
92
|
`;
|
|
77
93
|
ensureDir(filePath);
|
|
@@ -82,11 +98,12 @@ startup_timeout_ms = 20000
|
|
|
82
98
|
}
|
|
83
99
|
return filePath;
|
|
84
100
|
};
|
|
85
|
-
|
|
101
|
+
// ─── Claude Code CLI ────────────────────────────────────
|
|
102
|
+
const installClaude = (scope) => {
|
|
86
103
|
const configJson = JSON.stringify({
|
|
87
104
|
type: "stdio",
|
|
88
105
|
command: "npx",
|
|
89
|
-
args: ["-y", PACKAGE_NAME
|
|
106
|
+
args: ["-y", PACKAGE_NAME],
|
|
90
107
|
});
|
|
91
108
|
const result = spawnSync("claude", ["mcp", "add-json", "--scope", scope, SERVER_NAME, configJson], {
|
|
92
109
|
stdio: "pipe",
|
|
@@ -101,18 +118,91 @@ const installClaude = (serverUrl, scope) => {
|
|
|
101
118
|
}
|
|
102
119
|
return "claude-managed-config";
|
|
103
120
|
};
|
|
104
|
-
|
|
121
|
+
// ─── VS Code ────────────────────────────────────────────
|
|
122
|
+
const getVSCodeConfigPath = (scope) => scope === "project"
|
|
123
|
+
? path.join(process.cwd(), ".vscode", "mcp.json")
|
|
124
|
+
: path.join(os.homedir(), ".vscode", "mcp.json");
|
|
125
|
+
const installVSCode = (scope) => {
|
|
126
|
+
const filePath = getVSCodeConfigPath(scope);
|
|
127
|
+
const config = readJson(filePath);
|
|
128
|
+
const servers = (config.servers ?? {});
|
|
129
|
+
servers[SERVER_NAME] = {
|
|
130
|
+
type: "stdio",
|
|
131
|
+
command: "npx",
|
|
132
|
+
args: ["-y", PACKAGE_NAME],
|
|
133
|
+
};
|
|
134
|
+
config.servers = servers;
|
|
135
|
+
writeJson(filePath, config);
|
|
136
|
+
return filePath;
|
|
137
|
+
};
|
|
138
|
+
// ─── Windsurf ───────────────────────────────────────────
|
|
139
|
+
const getWindsurfConfigPath = () => path.join(os.homedir(), ".codeium", "windsurf", "mcp_config.json");
|
|
140
|
+
const installWindsurf = () => {
|
|
141
|
+
const filePath = getWindsurfConfigPath();
|
|
142
|
+
const config = readJson(filePath);
|
|
143
|
+
const mcpServers = (config.mcpServers ?? {});
|
|
144
|
+
mcpServers[SERVER_NAME] = createNpxConfig();
|
|
145
|
+
config.mcpServers = mcpServers;
|
|
146
|
+
writeJson(filePath, config);
|
|
147
|
+
return filePath;
|
|
148
|
+
};
|
|
149
|
+
// ─── Claude Desktop ─────────────────────────────────────
|
|
150
|
+
const getClaudeDesktopConfigPath = () => {
|
|
151
|
+
const platform = os.platform();
|
|
152
|
+
if (platform === "darwin") {
|
|
153
|
+
return path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
154
|
+
}
|
|
155
|
+
if (platform === "win32") {
|
|
156
|
+
return path.join(process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
157
|
+
}
|
|
158
|
+
// Linux
|
|
159
|
+
return path.join(os.homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
160
|
+
};
|
|
161
|
+
const installClaudeDesktop = () => {
|
|
162
|
+
const filePath = getClaudeDesktopConfigPath();
|
|
163
|
+
const config = readJson(filePath);
|
|
164
|
+
const mcpServers = (config.mcpServers ?? {});
|
|
165
|
+
mcpServers[SERVER_NAME] = createNpxConfig();
|
|
166
|
+
config.mcpServers = mcpServers;
|
|
167
|
+
writeJson(filePath, config);
|
|
168
|
+
return filePath;
|
|
169
|
+
};
|
|
170
|
+
// ─── Warp ───────────────────────────────────────────────
|
|
171
|
+
const getWarpConfigPath = () => path.join(os.homedir(), ".warp", "mcp_config.json");
|
|
172
|
+
const installWarp = () => {
|
|
173
|
+
const filePath = getWarpConfigPath();
|
|
174
|
+
const config = readJson(filePath);
|
|
175
|
+
config[SERVER_NAME] = {
|
|
176
|
+
command: "npx",
|
|
177
|
+
args: ["-y", PACKAGE_NAME],
|
|
178
|
+
env: {},
|
|
179
|
+
working_directory: null,
|
|
180
|
+
start_on_launch: true,
|
|
181
|
+
};
|
|
182
|
+
writeJson(filePath, config);
|
|
183
|
+
return filePath;
|
|
184
|
+
};
|
|
185
|
+
// ─── Router ─────────────────────────────────────────────
|
|
186
|
+
export const installClientConfig = (target, scope) => {
|
|
105
187
|
switch (target) {
|
|
106
188
|
case "cursor":
|
|
107
|
-
return installCursor(
|
|
189
|
+
return installCursor(scope);
|
|
108
190
|
case "claude":
|
|
109
|
-
return installClaude(
|
|
191
|
+
return installClaude(scope);
|
|
110
192
|
case "codex":
|
|
111
|
-
return installCodex(
|
|
193
|
+
return installCodex();
|
|
112
194
|
case "gemini":
|
|
113
|
-
return installGemini(
|
|
195
|
+
return installGemini();
|
|
114
196
|
case "opencode":
|
|
115
|
-
return installOpenCode(
|
|
197
|
+
return installOpenCode(scope);
|
|
198
|
+
case "vscode":
|
|
199
|
+
return installVSCode(scope);
|
|
200
|
+
case "windsurf":
|
|
201
|
+
return installWindsurf();
|
|
202
|
+
case "claude-desktop":
|
|
203
|
+
return installClaudeDesktop();
|
|
204
|
+
case "warp":
|
|
205
|
+
return installWarp();
|
|
116
206
|
default:
|
|
117
207
|
throw new Error(`Unsupported setup target: ${target}`);
|
|
118
208
|
}
|