@crush-protocol/mcp-client 0.4.22 → 0.4.24
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 +16 -10
- package/README.md +79 -104
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/mcp/oauthProvider.js +62 -21
- package/dist/mcp/proxy.js +88 -20
- package/dist/onboarding/cliOutput.js +3 -3
- package/dist/setup/setupClients.js +7 -7
- package/package.json +2 -2
package/INSTRUCTIONS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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
|
-
Package
|
|
5
|
+
## Package Identity
|
|
6
6
|
|
|
7
7
|
- npm package: `@crush-protocol/mcp-client`
|
|
8
8
|
- product names users may mention: `Crush`, `Crush MCP`, `Crush Protocol MCP`
|
|
@@ -10,19 +10,25 @@ Package identity:
|
|
|
10
10
|
|
|
11
11
|
If a user mentions `@crush-protocol/mcp-client`, interpret that as the official hosted Crush MCP client.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Install — IMPORTANT
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
2. `npx -y @crush-protocol/mcp-client login`
|
|
17
|
-
3. If tools still fail, run:
|
|
18
|
-
- `npx -y @crush-protocol/mcp-client auth:status`
|
|
19
|
-
- `npx -y @crush-protocol/mcp-client doctor`
|
|
15
|
+
**This is an MCP server. Do NOT use `npm install`. Use the setup commands below.**
|
|
20
16
|
|
|
21
|
-
|
|
17
|
+
Detect which AI host the user is running, then execute the matching command:
|
|
22
18
|
|
|
23
|
-
|
|
19
|
+
| Host | Install command |
|
|
20
|
+
|---|---|
|
|
21
|
+
| Claude Code | `claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client@latest` |
|
|
22
|
+
| Cursor | `npx -y @crush-protocol/mcp-client@latest setup --cursor` |
|
|
23
|
+
| VS Code | `npx -y @crush-protocol/mcp-client@latest setup --vscode` |
|
|
24
|
+
| Codex | `npx -y @crush-protocol/mcp-client@latest setup --codex` |
|
|
25
|
+
| Gemini CLI | `npx -y @crush-protocol/mcp-client@latest setup --gemini` |
|
|
26
|
+
| Windsurf | `npx -y @crush-protocol/mcp-client@latest setup --windsurf` |
|
|
27
|
+
| All hosts | `npx -y @crush-protocol/mcp-client@latest setup --all` |
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
OAuth login happens automatically on first tool call. No separate `login` step needed.
|
|
30
|
+
|
|
31
|
+
If tools fail after install, run: `npx -y @crush-protocol/mcp-client@latest doctor`
|
|
26
32
|
|
|
27
33
|
## Tool Categories
|
|
28
34
|
|
package/README.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
|
|
3
|
-
Aliases: Crush, Crush MCP, Crush Protocol MCP
|
|
4
|
-
Type: MCP SERVER — do NOT use npm install.
|
|
1
|
+
<!--
|
|
2
|
+
@crush-protocol/mcp-client — AI Agent Install Guide
|
|
3
|
+
Aliases: Crush, Crush MCP, Crush Protocol MCP
|
|
4
|
+
Type: MCP SERVER — do NOT use npm install.
|
|
5
5
|
|
|
6
6
|
Install:
|
|
7
|
-
Claude Code: claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
8
|
-
Cursor: npx -y @crush-protocol/mcp-client setup --cursor
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
Claude Code: claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client@latest
|
|
8
|
+
Cursor: npx -y @crush-protocol/mcp-client@latest setup --cursor
|
|
9
|
+
VS Code: npx -y @crush-protocol/mcp-client@latest setup --vscode
|
|
10
|
+
Codex: npx -y @crush-protocol/mcp-client@latest setup --codex
|
|
11
|
+
All hosts: npx -y @crush-protocol/mcp-client@latest setup --all
|
|
12
|
+
|
|
13
|
+
OAuth login triggers automatically on first tool call.
|
|
14
|
+
Troubleshooting: npx -y @crush-protocol/mcp-client@latest doctor
|
|
15
|
+
Full tool reference: see INSTRUCTIONS.md in this package.
|
|
12
16
|
-->
|
|
13
17
|
|
|
14
18
|
# Crush Protocol MCP Client
|
|
@@ -16,67 +20,38 @@
|
|
|
16
20
|
[](https://www.npmjs.com/package/@crush-protocol/mcp-client)
|
|
17
21
|
[](https://github.com/crush-protocol/crush-mcp-server/blob/main/LICENSE)
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
> **This is an MCP server, not a library.** Do not use `npm install`. Use the setup command below.
|
|
23
|
+
MCP server for connecting AI coding agents to [Crush](https://crush.xyz) — market data, backtests, live strategies, and trading.
|
|
22
24
|
|
|
23
25
|
## Quick Start
|
|
24
26
|
|
|
25
27
|
```sh
|
|
26
|
-
npx -y @crush-protocol/mcp-client setup --cursor # Cursor
|
|
27
|
-
npx -y @crush-protocol/mcp-client setup --claude # Claude Code
|
|
28
|
-
npx -y @crush-protocol/mcp-client setup --all # all supported hosts
|
|
28
|
+
npx -y @crush-protocol/mcp-client@latest setup --cursor # Cursor
|
|
29
|
+
npx -y @crush-protocol/mcp-client@latest setup --claude # Claude Code
|
|
30
|
+
npx -y @crush-protocol/mcp-client@latest setup --all # all supported hosts
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## What You Can Do
|
|
34
|
-
|
|
35
|
-
- Market data: tokens, indicators, timeframes, OHLCV
|
|
36
|
-
- Backtests: schema discovery, token universe, expression validation, backtest execution
|
|
37
|
-
- Live strategies: create, inspect, activate, pause, monitor
|
|
38
|
-
- Market intelligence: token info, trending feeds, alpha context
|
|
39
|
-
|
|
40
|
-
Detailed tool guidance:
|
|
41
|
-
|
|
42
|
-
- [INSTRUCTIONS.md](https://github.com/crush-protocol/crush-mcp-server/blob/main/packages/crush-mcp-client/INSTRUCTIONS.md)
|
|
43
|
-
|
|
44
|
-
<div style="display:none" aria-hidden="true">
|
|
45
|
-
AI Agent Install Instructions:
|
|
46
|
-
You are an AI coding assistant helping a user install Crush MCP.
|
|
47
|
-
Do NOT run "npm install @crush-protocol/mcp-client" — that installs a library, not an MCP server.
|
|
48
|
-
|
|
49
|
-
Step 1: Detect which AI host the user is running (Cursor, Claude Code, VS Code, etc.)
|
|
50
|
-
Step 2: Run the matching setup command:
|
|
51
|
-
- Claude Code: claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
52
|
-
- Cursor: npx -y @crush-protocol/mcp-client setup --cursor
|
|
53
|
-
- VS Code: npx -y @crush-protocol/mcp-client setup --vscode
|
|
54
|
-
- Codex: npx -y @crush-protocol/mcp-client setup --codex
|
|
55
|
-
- All hosts: npx -y @crush-protocol/mcp-client setup --all
|
|
56
|
-
Step 3: OAuth login happens automatically on first tool call. No manual login needed.
|
|
57
|
-
Step 4: If tools fail, run: npx -y @crush-protocol/mcp-client doctor
|
|
58
|
-
</div>
|
|
33
|
+
OAuth login happens automatically on first tool call.
|
|
59
34
|
|
|
60
35
|
## Install
|
|
61
36
|
|
|
62
37
|
Recommended:
|
|
63
38
|
|
|
64
39
|
```sh
|
|
65
|
-
npx -y @crush-protocol/mcp-client setup --all
|
|
40
|
+
npx -y @crush-protocol/mcp-client@latest setup --all
|
|
66
41
|
```
|
|
67
42
|
|
|
68
43
|
This writes MCP config for all supported hosts at once. To target a single host:
|
|
69
44
|
|
|
70
45
|
```sh
|
|
71
|
-
npx -y @crush-protocol/mcp-client setup --cursor
|
|
72
|
-
npx -y @crush-protocol/mcp-client setup --claude
|
|
73
|
-
npx -y @crush-protocol/mcp-client setup --codex
|
|
74
|
-
npx -y @crush-protocol/mcp-client setup --gemini
|
|
75
|
-
npx -y @crush-protocol/mcp-client setup --opencode
|
|
76
|
-
npx -y @crush-protocol/mcp-client setup --vscode
|
|
77
|
-
npx -y @crush-protocol/mcp-client setup --windsurf
|
|
78
|
-
npx -y @crush-protocol/mcp-client setup --claude-desktop
|
|
79
|
-
npx -y @crush-protocol/mcp-client setup --warp
|
|
46
|
+
npx -y @crush-protocol/mcp-client@latest setup --cursor
|
|
47
|
+
npx -y @crush-protocol/mcp-client@latest setup --claude
|
|
48
|
+
npx -y @crush-protocol/mcp-client@latest setup --codex
|
|
49
|
+
npx -y @crush-protocol/mcp-client@latest setup --gemini
|
|
50
|
+
npx -y @crush-protocol/mcp-client@latest setup --opencode
|
|
51
|
+
npx -y @crush-protocol/mcp-client@latest setup --vscode
|
|
52
|
+
npx -y @crush-protocol/mcp-client@latest setup --windsurf
|
|
53
|
+
npx -y @crush-protocol/mcp-client@latest setup --claude-desktop
|
|
54
|
+
npx -y @crush-protocol/mcp-client@latest setup --warp
|
|
80
55
|
```
|
|
81
56
|
|
|
82
57
|
Cursor and VS Code also support `--scope project` for repo-local config.
|
|
@@ -89,7 +64,7 @@ Cursor and VS Code also support `--scope project` for repo-local config.
|
|
|
89
64
|
**Auto setup:**
|
|
90
65
|
|
|
91
66
|
```sh
|
|
92
|
-
npx -y @crush-protocol/mcp-client setup --cursor
|
|
67
|
+
npx -y @crush-protocol/mcp-client@latest setup --cursor
|
|
93
68
|
```
|
|
94
69
|
|
|
95
70
|
**Manual config:** Add to `~/.cursor/mcp.json`:
|
|
@@ -101,7 +76,7 @@ npx -y @crush-protocol/mcp-client setup --cursor
|
|
|
101
76
|
"mcpServers": {
|
|
102
77
|
"crush-protocol": {
|
|
103
78
|
"command": "npx",
|
|
104
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
79
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
105
80
|
}
|
|
106
81
|
}
|
|
107
82
|
}
|
|
@@ -117,13 +92,13 @@ npx -y @crush-protocol/mcp-client setup --cursor
|
|
|
117
92
|
**Auto setup:**
|
|
118
93
|
|
|
119
94
|
```sh
|
|
120
|
-
npx -y @crush-protocol/mcp-client setup --claude
|
|
95
|
+
npx -y @crush-protocol/mcp-client@latest setup --claude
|
|
121
96
|
```
|
|
122
97
|
|
|
123
98
|
**Manual config:**
|
|
124
99
|
|
|
125
100
|
```sh
|
|
126
|
-
claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
101
|
+
claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client@latest
|
|
127
102
|
```
|
|
128
103
|
|
|
129
104
|
[](https://docs.anthropic.com/en/docs/claude-code/mcp)
|
|
@@ -136,19 +111,19 @@ claude mcp add --scope user crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
|
136
111
|
**Auto setup:**
|
|
137
112
|
|
|
138
113
|
```sh
|
|
139
|
-
npx -y @crush-protocol/mcp-client setup --codex
|
|
114
|
+
npx -y @crush-protocol/mcp-client@latest setup --codex
|
|
140
115
|
```
|
|
141
116
|
|
|
142
117
|
**Manual config:**
|
|
143
118
|
|
|
144
|
-
**CLI:** `codex mcp add crush-protocol -- npx -y @crush-protocol/mcp-client`
|
|
119
|
+
**CLI:** `codex mcp add crush-protocol -- npx -y @crush-protocol/mcp-client@latest`
|
|
145
120
|
|
|
146
121
|
**File:** Add to `~/.codex/config.toml`:
|
|
147
122
|
|
|
148
123
|
```toml
|
|
149
124
|
[mcp_servers.crush-protocol]
|
|
150
125
|
command = "npx"
|
|
151
|
-
args = ["-y", "@crush-protocol/mcp-client"]
|
|
126
|
+
args = ["-y", "@crush-protocol/mcp-client@latest"]
|
|
152
127
|
startup_timeout_ms = 20000
|
|
153
128
|
```
|
|
154
129
|
|
|
@@ -162,7 +137,7 @@ startup_timeout_ms = 20000
|
|
|
162
137
|
**Auto setup:**
|
|
163
138
|
|
|
164
139
|
```sh
|
|
165
|
-
npx -y @crush-protocol/mcp-client setup --gemini
|
|
140
|
+
npx -y @crush-protocol/mcp-client@latest setup --gemini
|
|
166
141
|
```
|
|
167
142
|
|
|
168
143
|
**Manual config:** Add to `~/.gemini/settings.json`:
|
|
@@ -172,7 +147,7 @@ npx -y @crush-protocol/mcp-client setup --gemini
|
|
|
172
147
|
"mcpServers": {
|
|
173
148
|
"crush-protocol": {
|
|
174
149
|
"command": "npx",
|
|
175
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
150
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
176
151
|
}
|
|
177
152
|
}
|
|
178
153
|
}
|
|
@@ -188,7 +163,7 @@ npx -y @crush-protocol/mcp-client setup --gemini
|
|
|
188
163
|
**Auto setup:**
|
|
189
164
|
|
|
190
165
|
```sh
|
|
191
|
-
npx -y @crush-protocol/mcp-client setup --vscode
|
|
166
|
+
npx -y @crush-protocol/mcp-client@latest setup --vscode
|
|
192
167
|
```
|
|
193
168
|
|
|
194
169
|
**Manual config:** Add to `.vscode/mcp.json` (project) or `~/.vscode/mcp.json` (global):
|
|
@@ -199,7 +174,7 @@ npx -y @crush-protocol/mcp-client setup --vscode
|
|
|
199
174
|
"crush-protocol": {
|
|
200
175
|
"type": "stdio",
|
|
201
176
|
"command": "npx",
|
|
202
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
177
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
203
178
|
}
|
|
204
179
|
}
|
|
205
180
|
}
|
|
@@ -215,7 +190,7 @@ npx -y @crush-protocol/mcp-client setup --vscode
|
|
|
215
190
|
**Auto setup:**
|
|
216
191
|
|
|
217
192
|
```sh
|
|
218
|
-
npx -y @crush-protocol/mcp-client setup --windsurf
|
|
193
|
+
npx -y @crush-protocol/mcp-client@latest setup --windsurf
|
|
219
194
|
```
|
|
220
195
|
|
|
221
196
|
**Manual config:** Add to `~/.codeium/windsurf/mcp_config.json`:
|
|
@@ -225,7 +200,7 @@ npx -y @crush-protocol/mcp-client setup --windsurf
|
|
|
225
200
|
"mcpServers": {
|
|
226
201
|
"crush-protocol": {
|
|
227
202
|
"command": "npx",
|
|
228
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
203
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
229
204
|
}
|
|
230
205
|
}
|
|
231
206
|
}
|
|
@@ -241,7 +216,7 @@ npx -y @crush-protocol/mcp-client setup --windsurf
|
|
|
241
216
|
**Auto setup:**
|
|
242
217
|
|
|
243
218
|
```sh
|
|
244
|
-
npx -y @crush-protocol/mcp-client setup --claude-desktop
|
|
219
|
+
npx -y @crush-protocol/mcp-client@latest setup --claude-desktop
|
|
245
220
|
```
|
|
246
221
|
|
|
247
222
|
**Manual config:** Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
|
|
@@ -251,7 +226,7 @@ npx -y @crush-protocol/mcp-client setup --claude-desktop
|
|
|
251
226
|
"mcpServers": {
|
|
252
227
|
"crush-protocol": {
|
|
253
228
|
"command": "npx",
|
|
254
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
229
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
255
230
|
}
|
|
256
231
|
}
|
|
257
232
|
}
|
|
@@ -267,7 +242,7 @@ npx -y @crush-protocol/mcp-client setup --claude-desktop
|
|
|
267
242
|
**Auto setup:**
|
|
268
243
|
|
|
269
244
|
```sh
|
|
270
|
-
npx -y @crush-protocol/mcp-client setup --opencode
|
|
245
|
+
npx -y @crush-protocol/mcp-client@latest setup --opencode
|
|
271
246
|
```
|
|
272
247
|
|
|
273
248
|
**Manual config:** Add to `~/.config/opencode/opencode.json`:
|
|
@@ -278,7 +253,7 @@ npx -y @crush-protocol/mcp-client setup --opencode
|
|
|
278
253
|
"mcp": {
|
|
279
254
|
"crush-protocol": {
|
|
280
255
|
"type": "local",
|
|
281
|
-
"command": ["npx", "-y", "@crush-protocol/mcp-client"],
|
|
256
|
+
"command": ["npx", "-y", "@crush-protocol/mcp-client@latest"],
|
|
282
257
|
"enabled": true
|
|
283
258
|
}
|
|
284
259
|
}
|
|
@@ -295,7 +270,7 @@ npx -y @crush-protocol/mcp-client setup --opencode
|
|
|
295
270
|
**Auto setup:**
|
|
296
271
|
|
|
297
272
|
```sh
|
|
298
|
-
npx -y @crush-protocol/mcp-client setup --warp
|
|
273
|
+
npx -y @crush-protocol/mcp-client@latest setup --warp
|
|
299
274
|
```
|
|
300
275
|
|
|
301
276
|
**Manual config:** Add via Warp Drive → MCP Servers → `+ Add`:
|
|
@@ -304,7 +279,7 @@ npx -y @crush-protocol/mcp-client setup --warp
|
|
|
304
279
|
{
|
|
305
280
|
"crush-protocol": {
|
|
306
281
|
"command": "npx",
|
|
307
|
-
"args": ["-y", "@crush-protocol/mcp-client"],
|
|
282
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"],
|
|
308
283
|
"env": {},
|
|
309
284
|
"working_directory": null,
|
|
310
285
|
"start_on_launch": true
|
|
@@ -326,7 +301,7 @@ Add to `~/.kiro/settings/mcp.json` (global) or `.kiro/settings/mcp.json` (worksp
|
|
|
326
301
|
"mcpServers": {
|
|
327
302
|
"crush-protocol": {
|
|
328
303
|
"command": "npx",
|
|
329
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
304
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
330
305
|
}
|
|
331
306
|
}
|
|
332
307
|
}
|
|
@@ -346,7 +321,7 @@ Add to `.roo/mcp.json` (project) or open Roo Code settings → Edit Global MCP:
|
|
|
346
321
|
"mcpServers": {
|
|
347
322
|
"crush-protocol": {
|
|
348
323
|
"command": "npx",
|
|
349
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
324
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
350
325
|
}
|
|
351
326
|
}
|
|
352
327
|
}
|
|
@@ -366,7 +341,7 @@ Add to `cline_mcp_settings.json` (open via Cline panel → MCP Servers → Confi
|
|
|
366
341
|
"mcpServers": {
|
|
367
342
|
"crush-protocol": {
|
|
368
343
|
"command": "npx",
|
|
369
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
344
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
370
345
|
}
|
|
371
346
|
}
|
|
372
347
|
}
|
|
@@ -386,7 +361,7 @@ Add via Trae → Settings → MCP → Add MCP Server:
|
|
|
386
361
|
"mcpServers": {
|
|
387
362
|
"crush-protocol": {
|
|
388
363
|
"command": "npx",
|
|
389
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
364
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
390
365
|
}
|
|
391
366
|
}
|
|
392
367
|
}
|
|
@@ -399,7 +374,7 @@ Add via Trae → Settings → MCP → Add MCP Server:
|
|
|
399
374
|
<details>
|
|
400
375
|
<summary><strong>Augment Code</strong></summary>
|
|
401
376
|
|
|
402
|
-
Add via Settings → Tools → `+ Add MCP` → Command: `npx -y @crush-protocol/mcp-client`
|
|
377
|
+
Add via Settings → Tools → `+ Add MCP` → Command: `npx -y @crush-protocol/mcp-client@latest`
|
|
403
378
|
|
|
404
379
|
```json
|
|
405
380
|
"augment.advanced": {
|
|
@@ -407,7 +382,7 @@ Add via Settings → Tools → `+ Add MCP` → Command: `npx -y @crush-protocol/
|
|
|
407
382
|
{
|
|
408
383
|
"name": "crush-protocol",
|
|
409
384
|
"command": "npx",
|
|
410
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
385
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
411
386
|
}
|
|
412
387
|
]
|
|
413
388
|
}
|
|
@@ -428,7 +403,7 @@ Add to `.github/copilot/mcp.json` in your repository:
|
|
|
428
403
|
"crush-protocol": {
|
|
429
404
|
"type": "local",
|
|
430
405
|
"command": "npx",
|
|
431
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
406
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
432
407
|
}
|
|
433
408
|
}
|
|
434
409
|
}
|
|
@@ -449,7 +424,7 @@ Add to `~/.copilot/mcp-config.json`:
|
|
|
449
424
|
"crush-protocol": {
|
|
450
425
|
"type": "local",
|
|
451
426
|
"command": "npx",
|
|
452
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
427
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
453
428
|
}
|
|
454
429
|
}
|
|
455
430
|
}
|
|
@@ -469,7 +444,7 @@ Add to `~/.aws/amazonq/mcp.json`:
|
|
|
469
444
|
"mcpServers": {
|
|
470
445
|
"crush-protocol": {
|
|
471
446
|
"command": "npx",
|
|
472
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
447
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
473
448
|
}
|
|
474
449
|
}
|
|
475
450
|
}
|
|
@@ -483,7 +458,7 @@ Add to `~/.aws/amazonq/mcp.json`:
|
|
|
483
458
|
<summary><strong>Amp</strong></summary>
|
|
484
459
|
|
|
485
460
|
```sh
|
|
486
|
-
amp mcp add crush-protocol -- npx -y @crush-protocol/mcp-client
|
|
461
|
+
amp mcp add crush-protocol -- npx -y @crush-protocol/mcp-client@latest
|
|
487
462
|
```
|
|
488
463
|
|
|
489
464
|
[](https://ampcode.com/manual#mcp)
|
|
@@ -501,7 +476,7 @@ Add to `~/.config/zed/settings.json`:
|
|
|
501
476
|
"crush-protocol": {
|
|
502
477
|
"source": "custom",
|
|
503
478
|
"command": "npx",
|
|
504
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
479
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
505
480
|
}
|
|
506
481
|
}
|
|
507
482
|
}
|
|
@@ -521,7 +496,7 @@ Add via Settings → Tools → AI Assistant → Model Context Protocol (MCP) →
|
|
|
521
496
|
"mcpServers": {
|
|
522
497
|
"crush-protocol": {
|
|
523
498
|
"command": "npx",
|
|
524
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
499
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
525
500
|
}
|
|
526
501
|
}
|
|
527
502
|
}
|
|
@@ -534,14 +509,14 @@ Add via Settings → Tools → AI Assistant → Model Context Protocol (MCP) →
|
|
|
534
509
|
<details>
|
|
535
510
|
<summary><strong>Qwen Code</strong></summary>
|
|
536
511
|
|
|
537
|
-
**CLI:** `qwen mcp add crush-protocol npx -y @crush-protocol/mcp-client`
|
|
512
|
+
**CLI:** `qwen mcp add crush-protocol npx -y @crush-protocol/mcp-client@latest`
|
|
538
513
|
|
|
539
514
|
```json
|
|
540
515
|
{
|
|
541
516
|
"mcpServers": {
|
|
542
517
|
"crush-protocol": {
|
|
543
518
|
"command": "npx",
|
|
544
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
519
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
545
520
|
}
|
|
546
521
|
}
|
|
547
522
|
}
|
|
@@ -561,7 +536,7 @@ Add to `mcp.json` (open via Program → Install → Edit mcp.json):
|
|
|
561
536
|
"mcpServers": {
|
|
562
537
|
"crush-protocol": {
|
|
563
538
|
"command": "npx",
|
|
564
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
539
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
565
540
|
}
|
|
566
541
|
}
|
|
567
542
|
}
|
|
@@ -583,7 +558,7 @@ Add to `.mcp/mcp.json` in your solution directory:
|
|
|
583
558
|
"crush-protocol": {
|
|
584
559
|
"type": "stdio",
|
|
585
560
|
"command": "npx",
|
|
586
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
561
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
587
562
|
}
|
|
588
563
|
}
|
|
589
564
|
}
|
|
@@ -602,7 +577,7 @@ Add to `.mcp/mcp.json` in your solution directory:
|
|
|
602
577
|
"mcpServers": {
|
|
603
578
|
"crush-protocol": {
|
|
604
579
|
"command": "npx",
|
|
605
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
580
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
606
581
|
}
|
|
607
582
|
}
|
|
608
583
|
}
|
|
@@ -619,7 +594,7 @@ Add via Perplexity → Settings → Connectors → Add Connector → Advanced. S
|
|
|
619
594
|
|
|
620
595
|
```json
|
|
621
596
|
{
|
|
622
|
-
"args": ["-y", "@crush-protocol/mcp-client"],
|
|
597
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"],
|
|
623
598
|
"command": "npx",
|
|
624
599
|
"env": {}
|
|
625
600
|
}
|
|
@@ -637,7 +612,7 @@ Add via Perplexity → Settings → Connectors → Add Connector → Advanced. S
|
|
|
637
612
|
"mcpServers": {
|
|
638
613
|
"crush-protocol": {
|
|
639
614
|
"command": "npx",
|
|
640
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
615
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
641
616
|
}
|
|
642
617
|
}
|
|
643
618
|
}
|
|
@@ -655,7 +630,7 @@ Add via Zencoder menu → Agent tools → Add custom MCP:
|
|
|
655
630
|
```json
|
|
656
631
|
{
|
|
657
632
|
"command": "npx",
|
|
658
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
633
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
659
634
|
}
|
|
660
635
|
```
|
|
661
636
|
|
|
@@ -673,7 +648,7 @@ Qodo Gen chat → Connect more tools → `+ Add new MCP`
|
|
|
673
648
|
"mcpServers": {
|
|
674
649
|
"crush-protocol": {
|
|
675
650
|
"command": "npx",
|
|
676
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
651
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
677
652
|
}
|
|
678
653
|
}
|
|
679
654
|
}
|
|
@@ -693,7 +668,7 @@ Qodo Gen chat → Connect more tools → `+ Add new MCP`
|
|
|
693
668
|
"mcpServers": {
|
|
694
669
|
"crush-protocol": {
|
|
695
670
|
"command": "bunx",
|
|
696
|
-
"args": ["-y", "@crush-protocol/mcp-client"]
|
|
671
|
+
"args": ["-y", "@crush-protocol/mcp-client@latest"]
|
|
697
672
|
}
|
|
698
673
|
}
|
|
699
674
|
}
|
|
@@ -729,7 +704,7 @@ Qodo Gen chat → Connect more tools → `+ Add new MCP`
|
|
|
729
704
|
"mcpServers": {
|
|
730
705
|
"crush-protocol": {
|
|
731
706
|
"command": "cmd",
|
|
732
|
-
"args": ["/c", "npx", "-y", "@crush-protocol/mcp-client"]
|
|
707
|
+
"args": ["/c", "npx", "-y", "@crush-protocol/mcp-client@latest"]
|
|
733
708
|
}
|
|
734
709
|
}
|
|
735
710
|
}
|
|
@@ -740,12 +715,12 @@ Qodo Gen chat → Connect more tools → `+ Add new MCP`
|
|
|
740
715
|
## Common Commands
|
|
741
716
|
|
|
742
717
|
```sh
|
|
743
|
-
npx -y @crush-protocol/mcp-client setup --all
|
|
744
|
-
npx -y @crush-protocol/mcp-client login
|
|
745
|
-
npx -y @crush-protocol/mcp-client auth:status
|
|
746
|
-
npx -y @crush-protocol/mcp-client doctor
|
|
747
|
-
npx -y @crush-protocol/mcp-client ping
|
|
748
|
-
npx -y @crush-protocol/mcp-client tools:list
|
|
718
|
+
npx -y @crush-protocol/mcp-client@latest setup --all
|
|
719
|
+
npx -y @crush-protocol/mcp-client@latest login
|
|
720
|
+
npx -y @crush-protocol/mcp-client@latest auth:status
|
|
721
|
+
npx -y @crush-protocol/mcp-client@latest doctor
|
|
722
|
+
npx -y @crush-protocol/mcp-client@latest ping
|
|
723
|
+
npx -y @crush-protocol/mcp-client@latest tools:list
|
|
749
724
|
```
|
|
750
725
|
|
|
751
726
|
## Troubleshooting
|
|
@@ -753,9 +728,9 @@ npx -y @crush-protocol/mcp-client tools:list
|
|
|
753
728
|
| Problem | What to do |
|
|
754
729
|
| --- | --- |
|
|
755
730
|
| Tools do not appear after install | Restart the MCP host after `setup` |
|
|
756
|
-
| Tools appear but fail with auth errors | Run `npx -y @crush-protocol/mcp-client login` |
|
|
757
|
-
| Crush was working before but now fails | Run `npx -y @crush-protocol/mcp-client doctor` |
|
|
758
|
-
| You want to confirm local auth state | Run `npx -y @crush-protocol/mcp-client auth:status` |
|
|
731
|
+
| Tools appear but fail with auth errors | Run `npx -y @crush-protocol/mcp-client@latest login` |
|
|
732
|
+
| Crush was working before but now fails | Run `npx -y @crush-protocol/mcp-client@latest doctor` |
|
|
733
|
+
| You want to confirm local auth state | Run `npx -y @crush-protocol/mcp-client@latest auth:status` |
|
|
759
734
|
|
|
760
735
|
## License
|
|
761
736
|
|
package/dist/config.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const PACKAGE_NAME = "@crush-protocol/mcp-client";
|
|
2
|
+
export declare const PACKAGE_NAME_LATEST = "@crush-protocol/mcp-client@latest";
|
|
2
3
|
export declare const SERVER_NAME = "crush-protocol";
|
|
3
4
|
export declare const DEFAULT_MCP_SERVER_URL = "https://crush-mcp-omni.dev.xexlab.com/mcp";
|
|
4
5
|
export declare const DEFAULT_OAUTH_SCOPE = "mcp:tools";
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export const PACKAGE_NAME = "@crush-protocol/mcp-client";
|
|
2
|
+
export const PACKAGE_NAME_LATEST = "@crush-protocol/mcp-client@latest";
|
|
2
3
|
export const SERVER_NAME = "crush-protocol";
|
|
3
4
|
export const DEFAULT_MCP_SERVER_URL = "https://crush-mcp-omni.dev.xexlab.com/mcp";
|
|
4
5
|
export const DEFAULT_OAUTH_SCOPE = "mcp:tools";
|
|
@@ -8,48 +8,89 @@ import { defaultStorageDir, getStorageFileForServer } from "./oauthStorage.js";
|
|
|
8
8
|
const DEFAULT_REDIRECT_PORT = 8787;
|
|
9
9
|
const DEFAULT_REDIRECT_PATH = "/oauth/callback";
|
|
10
10
|
const escapeHtml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
11
|
-
const
|
|
11
|
+
const CRUSH_LOGO_SVG = `<svg width="150" height="78" viewBox="0 0 399 78" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
12
|
+
<path d="M6.09178 25.7399C11.0178 10.3981 25.2316 0 41.2772 0H120.647L111.405 28.7857H5.11381L6.09178 25.7399Z" fill="#FF1850"/>
|
|
13
|
+
<path d="M1.38577 50.1428C-3.76778 63.563 6.09066 78 20.4083 78H69.7897L80.4873 50.1428H1.38577Z" fill="#FF1850"/>
|
|
14
|
+
<path d="M175.128 73.96C170.008 73.96 165.24 73.128 160.824 71.464C156.472 69.736 152.664 67.336 149.4 64.264C146.2 61.128 143.704 57.448 141.912 53.224C140.12 49 139.224 44.392 139.224 39.4C139.224 34.408 140.12 29.8 141.912 25.576C143.704 21.352 146.232 17.704 149.496 14.632C152.76 11.496 156.568 9.096 160.92 7.432C165.272 5.704 170.04 4.84 175.224 4.84C180.728 4.84 185.752 5.8 190.296 7.72C194.84 9.576 198.68 12.36 201.816 16.072L193.752 23.656C191.32 21.032 188.6 19.08 185.592 17.8C182.584 16.456 179.32 15.784 175.8 15.784C172.28 15.784 169.048 16.36 166.104 17.512C163.224 18.664 160.696 20.296 158.52 22.408C156.408 24.52 154.744 27.016 153.528 29.896C152.376 32.776 151.8 35.944 151.8 39.4C151.8 42.856 152.376 46.024 153.528 48.904C154.744 51.784 156.408 54.28 158.52 56.392C160.696 58.504 163.224 60.136 166.104 61.288C169.048 62.44 172.28 63.016 175.8 63.016C179.32 63.016 182.584 62.376 185.592 61.096C188.6 59.752 191.32 57.736 193.752 55.048L201.816 62.728C198.68 66.376 194.84 69.16 190.296 71.08C185.752 73 180.696 73.96 175.128 73.96Z" fill="white"/>
|
|
15
|
+
<path d="M207.822 73V21.736H219.246V35.848L217.902 31.72C219.438 28.264 221.838 25.64 225.102 23.848C228.43 22.056 232.558 21.16 237.486 21.16V32.584C236.974 32.456 236.494 32.392 236.046 32.392C235.598 32.328 235.15 32.296 234.702 32.296C230.158 32.296 226.542 33.64 223.854 36.328C221.166 38.952 219.822 42.888 219.822 48.136V73H207.822Z" fill="white"/>
|
|
16
|
+
<path d="M265.031 73.672C260.679 73.672 256.838 72.872 253.51 71.272C250.182 69.608 247.59 67.112 245.734 63.784C243.878 60.392 242.951 56.136 242.951 51.016V21.736H254.951V49.384C254.951 53.992 255.974 57.448 258.022 59.752C260.134 61.992 263.111 63.112 266.951 63.112C269.767 63.112 272.198 62.536 274.246 61.384C276.358 60.232 277.991 58.504 279.143 56.2C280.359 53.896 280.966 51.048 280.966 47.656V21.736H292.966V73H281.543V59.176L283.559 63.4C281.831 66.728 279.303 69.288 275.975 71.08C272.647 72.808 268.999 73.672 265.031 73.672Z" fill="white"/>
|
|
17
|
+
<path d="M319.718 73.672C315.43 73.672 311.302 73.128 307.334 72.04C303.43 70.888 300.326 69.512 298.022 67.912L302.63 58.792C304.934 60.264 307.686 61.48 310.886 62.44C314.086 63.4 317.286 63.88 320.486 63.88C324.262 63.88 326.982 63.368 328.646 62.344C330.374 61.32 331.238 59.944 331.238 58.216C331.238 56.808 330.662 55.752 329.51 55.048C328.358 54.28 326.854 53.704 324.998 53.32C323.142 52.936 321.062 52.584 318.758 52.264C316.518 51.944 314.246 51.528 311.942 51.016C309.702 50.44 307.654 49.64 305.798 48.616C303.942 47.528 302.438 46.088 301.286 44.296C300.134 42.504 299.558 40.136 299.558 37.192C299.558 33.928 300.486 31.112 302.342 28.744C304.198 26.312 306.79 24.456 310.118 23.176C313.51 21.832 317.51 21.16 322.118 21.16C325.574 21.16 329.062 21.544 332.582 22.312C336.102 23.08 339.014 24.168 341.318 25.576L336.71 34.696C334.278 33.224 331.814 32.232 329.318 31.72C326.886 31.144 324.454 30.856 322.022 30.856C318.374 30.856 315.654 31.4 313.862 32.488C312.134 33.576 311.27 34.952 311.27 36.616C311.27 38.152 311.846 39.304 312.998 40.072C314.15 40.84 315.654 41.448 317.51 41.896C319.366 42.344 321.414 42.728 323.654 43.048C325.958 43.304 328.23 43.72 330.47 44.296C332.71 44.872 334.758 45.672 336.614 46.696C338.534 47.656 340.07 49.032 341.222 50.824C342.374 52.616 342.95 54.952 342.95 57.832C342.95 61.032 341.99 63.816 340.07 66.184C338.214 68.552 335.558 70.408 332.102 71.752C328.646 73.032 324.518 73.672 319.718 73.672Z" fill="white"/>
|
|
18
|
+
<path d="M377.573 21.16C381.669 21.16 385.317 21.96 388.517 23.56C391.781 25.16 394.34 27.624 396.197 30.952C398.053 34.216 398.98 38.44 398.98 43.624V73H386.98V45.16C386.98 40.616 385.892 37.224 383.716 34.984C381.604 32.744 378.629 31.624 374.789 31.624C371.973 31.624 369.477 32.2 367.301 33.352C365.125 34.504 363.428 36.232 362.212 38.536C361.06 40.776 360.484 43.624 360.484 47.08V73H348.484V1.768H360.484V35.56L357.893 31.336C359.685 28.072 362.277 25.576 365.669 23.848C369.125 22.056 373.093 21.16 377.573 21.16Z" fill="white"/>
|
|
19
|
+
</svg>`;
|
|
20
|
+
const renderCallbackHtml = (title, message) => {
|
|
21
|
+
const isSuccess = title.toLowerCase().includes("complete");
|
|
22
|
+
const statusColor = isSuccess ? "var(--green)" : "var(--red)";
|
|
23
|
+
const statusBg = isSuccess ? "var(--green-bg)" : "var(--red-bg)";
|
|
24
|
+
return `<!DOCTYPE html>
|
|
12
25
|
<html lang="en">
|
|
13
26
|
<head>
|
|
14
27
|
<meta charset="UTF-8">
|
|
15
28
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
16
|
-
<title>${title}</title>
|
|
29
|
+
<title>${escapeHtml(title)}</title>
|
|
17
30
|
<style>
|
|
31
|
+
:root {
|
|
32
|
+
--bg: #000;
|
|
33
|
+
--card: #0D0D0D;
|
|
34
|
+
--border: rgba(255, 255, 255, 0.1);
|
|
35
|
+
--text: #fff;
|
|
36
|
+
--text-muted: rgba(255, 255, 255, 0.7);
|
|
37
|
+
--green: #15f364;
|
|
38
|
+
--green-bg: rgba(34, 197, 94, 0.1);
|
|
39
|
+
--red: #f3154c;
|
|
40
|
+
--red-bg: rgba(239, 68, 68, 0.1);
|
|
41
|
+
}
|
|
42
|
+
* { box-sizing: border-box; }
|
|
18
43
|
body {
|
|
19
44
|
margin: 0;
|
|
20
45
|
min-height: 100vh;
|
|
21
|
-
display:
|
|
22
|
-
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: center;
|
|
48
|
+
justify-content: center;
|
|
49
|
+
background: var(--bg);
|
|
23
50
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
24
|
-
|
|
25
|
-
|
|
51
|
+
color: var(--text);
|
|
52
|
+
}
|
|
53
|
+
.card {
|
|
54
|
+
width: 100%;
|
|
55
|
+
max-width: 380px;
|
|
56
|
+
border-radius: 12px;
|
|
57
|
+
border: 1px solid var(--border);
|
|
58
|
+
background: var(--card);
|
|
59
|
+
backdrop-filter: blur(20px);
|
|
60
|
+
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.5);
|
|
61
|
+
overflow: hidden;
|
|
26
62
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
padding: 32px;
|
|
30
|
-
border-radius: 20px;
|
|
31
|
-
background: rgba(255, 255, 255, 0.96);
|
|
32
|
-
box-shadow: 0 20px 45px rgba(15, 23, 42, 0.14);
|
|
63
|
+
.header {
|
|
64
|
+
padding: 32px 24px;
|
|
33
65
|
text-align: center;
|
|
34
66
|
}
|
|
67
|
+
.logo { margin-bottom: 20px; }
|
|
35
68
|
h1 {
|
|
36
|
-
margin: 0 0
|
|
37
|
-
font-size:
|
|
69
|
+
margin: 0 0 8px;
|
|
70
|
+
font-size: 18px;
|
|
71
|
+
font-weight: 600;
|
|
72
|
+
color: ${statusColor};
|
|
38
73
|
}
|
|
39
|
-
|
|
74
|
+
.desc {
|
|
40
75
|
margin: 0;
|
|
41
|
-
|
|
42
|
-
color:
|
|
76
|
+
font-size: 13px;
|
|
77
|
+
color: var(--text-muted);
|
|
78
|
+
line-height: 1.5;
|
|
43
79
|
}
|
|
44
80
|
</style>
|
|
45
81
|
</head>
|
|
46
82
|
<body>
|
|
47
|
-
<
|
|
48
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
83
|
+
<div class="card">
|
|
84
|
+
<div class="header">
|
|
85
|
+
<div class="logo">${CRUSH_LOGO_SVG}</div>
|
|
86
|
+
<h1>${escapeHtml(title)}</h1>
|
|
87
|
+
<p class="desc">${escapeHtml(message)}</p>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
<script>setTimeout(() => window.close(), 3000);</script>
|
|
51
91
|
</body>
|
|
52
92
|
</html>`;
|
|
93
|
+
};
|
|
53
94
|
const openBrowser = async (authorizationUrl) => {
|
|
54
95
|
const url = authorizationUrl.toString();
|
|
55
96
|
if (process.env.BROWSER) {
|
package/dist/mcp/proxy.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* MCP Proxy — stdio ↔ Streamable HTTP
|
|
2
|
+
* MCP Proxy — stdio ↔ Streamable HTTP bridge
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* proxy 将请求转发到远程 MCP Server(Streamable HTTP)。
|
|
4
|
+
* AI hosts (Cursor / Claude Code / Codex / Antigravity) connect via stdio.
|
|
5
|
+
* The proxy forwards tool calls to the remote Crush MCP over authenticated HTTP.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
7
|
+
* Auth is handled transparently:
|
|
8
|
+
* - On startup: attempts to connect with cached tokens.
|
|
9
|
+
* - On 401 during a tool call: triggers OAuth, returns auth URL as tool result
|
|
10
|
+
* so the user sees it in the AI host UI, then retries after authorization.
|
|
12
11
|
*/
|
|
13
12
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
14
13
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -16,6 +15,43 @@ import { CallToolRequestSchema, ListToolsRequestSchema, PingRequestSchema } from
|
|
|
16
15
|
import { OAuthRemoteMcpClient } from "./oauthRemoteClient.js";
|
|
17
16
|
import { getCachedAuthStatus } from "./oauthStorage.js";
|
|
18
17
|
import { CLIENT_NAME, CLIENT_VERSION } from "./version.js";
|
|
18
|
+
/** Attempt OAuth and return a user-visible auth message with the authorization URL. */
|
|
19
|
+
async function authorizeWithVisiblePrompt(remoteClient) {
|
|
20
|
+
let authUrl = "";
|
|
21
|
+
const origProvider = remoteClient.authProvider;
|
|
22
|
+
const origCallback = origProvider?.onAuthorizationUrl;
|
|
23
|
+
// Capture the authorization URL so we can return it in tool results.
|
|
24
|
+
if (origProvider) {
|
|
25
|
+
origProvider.onAuthorizationUrl = async (url) => {
|
|
26
|
+
authUrl = url.toString();
|
|
27
|
+
if (origCallback)
|
|
28
|
+
await origCallback(url);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
await remoteClient.ensureAuthorized();
|
|
32
|
+
// Restore original callback.
|
|
33
|
+
if (origProvider) {
|
|
34
|
+
origProvider.onAuthorizationUrl = origCallback;
|
|
35
|
+
}
|
|
36
|
+
return authUrl;
|
|
37
|
+
}
|
|
38
|
+
function authRequiredMessage(authUrl) {
|
|
39
|
+
const lines = [
|
|
40
|
+
"🔐 **Crush MCP requires authorization**",
|
|
41
|
+
"",
|
|
42
|
+
"This MCP server provides access to trading tools and market data.",
|
|
43
|
+
"You need to authorize in your browser to continue.",
|
|
44
|
+
"",
|
|
45
|
+
];
|
|
46
|
+
if (authUrl) {
|
|
47
|
+
lines.push("**Authorization URL:**", authUrl, "");
|
|
48
|
+
}
|
|
49
|
+
lines.push("✅ Authorization complete. Please retry your request.");
|
|
50
|
+
return {
|
|
51
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
52
|
+
isError: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
19
55
|
export async function runProxy(serverUrl) {
|
|
20
56
|
const remoteClient = new OAuthRemoteMcpClient({
|
|
21
57
|
serverUrl,
|
|
@@ -23,18 +59,17 @@ export async function runProxy(serverUrl) {
|
|
|
23
59
|
authorizationOutput: "stderr",
|
|
24
60
|
},
|
|
25
61
|
});
|
|
62
|
+
// Try to connect with cached credentials. If none exist, defer auth to first tool call.
|
|
26
63
|
const authStatus = await getCachedAuthStatus(serverUrl);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
64
|
+
let needsAuth = authStatus.status === "not_authenticated";
|
|
65
|
+
if (!needsAuth) {
|
|
66
|
+
try {
|
|
67
|
+
await remoteClient.connect();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
needsAuth = true;
|
|
71
|
+
}
|
|
35
72
|
}
|
|
36
|
-
await remoteClient.connect();
|
|
37
|
-
const remoteTools = await remoteClient.listTools();
|
|
38
73
|
const localServer = new Server({
|
|
39
74
|
name: `${CLIENT_NAME}-proxy`,
|
|
40
75
|
version: CLIENT_VERSION,
|
|
@@ -48,14 +83,47 @@ export async function runProxy(serverUrl) {
|
|
|
48
83
|
return await remoteClient.listTools();
|
|
49
84
|
}
|
|
50
85
|
catch {
|
|
51
|
-
return { tools:
|
|
86
|
+
return { tools: [] };
|
|
52
87
|
}
|
|
53
88
|
});
|
|
54
89
|
localServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
55
90
|
const { name, arguments: args } = request.params;
|
|
56
|
-
|
|
91
|
+
// If auth is needed, trigger OAuth and show the URL to the user.
|
|
92
|
+
if (needsAuth) {
|
|
93
|
+
const authUrl = await authorizeWithVisiblePrompt(remoteClient);
|
|
94
|
+
await remoteClient.connect();
|
|
95
|
+
needsAuth = false;
|
|
96
|
+
// Retry the original tool call after successful auth.
|
|
97
|
+
try {
|
|
98
|
+
return await remoteClient.callTool(name, (args ?? {}));
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return authRequiredMessage(authUrl);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
return await remoteClient.callTool(name, (args ?? {}));
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
// If we get a 401 mid-session (token expired), re-authorize.
|
|
109
|
+
if (String(error).includes("Unauthorized") || String(error).includes("401")) {
|
|
110
|
+
const authUrl = await authorizeWithVisiblePrompt(remoteClient);
|
|
111
|
+
try {
|
|
112
|
+
return await remoteClient.callTool(name, (args ?? {}));
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return authRequiredMessage(authUrl);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
57
120
|
});
|
|
58
121
|
localServer.setRequestHandler(PingRequestSchema, async () => {
|
|
122
|
+
if (needsAuth) {
|
|
123
|
+
await authorizeWithVisiblePrompt(remoteClient);
|
|
124
|
+
await remoteClient.connect();
|
|
125
|
+
needsAuth = false;
|
|
126
|
+
}
|
|
59
127
|
await remoteClient.ping();
|
|
60
128
|
return {};
|
|
61
129
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_MCP_SERVER_URL,
|
|
1
|
+
import { DEFAULT_MCP_SERVER_URL, PACKAGE_NAME_LATEST } from "../config.js";
|
|
2
2
|
const TARGET_LABELS = {
|
|
3
3
|
cursor: "Cursor",
|
|
4
4
|
claude: "Claude Code",
|
|
@@ -12,8 +12,8 @@ const TARGET_LABELS = {
|
|
|
12
12
|
};
|
|
13
13
|
export const getTargetLabel = (target) => TARGET_LABELS[target];
|
|
14
14
|
export const getLoginCommand = (serverUrl) => serverUrl === DEFAULT_MCP_SERVER_URL
|
|
15
|
-
? `npx -y ${
|
|
16
|
-
: `CRUSH_MCP_SERVER_URL=\"${serverUrl}\" npx -y ${
|
|
15
|
+
? `npx -y ${PACKAGE_NAME_LATEST} login`
|
|
16
|
+
: `CRUSH_MCP_SERVER_URL=\"${serverUrl}\" npx -y ${PACKAGE_NAME_LATEST} login`;
|
|
17
17
|
export const formatLoginRequiredMessage = (serverUrl) => [
|
|
18
18
|
"Crush needs sign-in on this machine.",
|
|
19
19
|
"",
|
|
@@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import {
|
|
5
|
+
import { PACKAGE_NAME_LATEST, SERVER_NAME } from "../config.js";
|
|
6
6
|
export const ALL_TARGETS = [
|
|
7
7
|
"cursor",
|
|
8
8
|
"claude",
|
|
@@ -42,7 +42,7 @@ const writeJson = (filePath, value) => {
|
|
|
42
42
|
};
|
|
43
43
|
const createNpxConfig = () => ({
|
|
44
44
|
command: "npx",
|
|
45
|
-
args: ["-y",
|
|
45
|
+
args: ["-y", PACKAGE_NAME_LATEST],
|
|
46
46
|
});
|
|
47
47
|
// ─── Cursor ─────────────────────────────────────────────
|
|
48
48
|
const getCursorConfigPath = (scope) => scope === "project"
|
|
@@ -79,7 +79,7 @@ const installOpenCode = (scope) => {
|
|
|
79
79
|
}
|
|
80
80
|
mcp[SERVER_NAME] = {
|
|
81
81
|
type: "local",
|
|
82
|
-
command: ["npx", "-y",
|
|
82
|
+
command: ["npx", "-y", PACKAGE_NAME_LATEST],
|
|
83
83
|
enabled: true,
|
|
84
84
|
};
|
|
85
85
|
config.mcp = mcp;
|
|
@@ -91,7 +91,7 @@ const installCodex = () => {
|
|
|
91
91
|
const filePath = getCodexConfigPath();
|
|
92
92
|
const section = `[mcp_servers.${SERVER_NAME}]
|
|
93
93
|
command = "npx"
|
|
94
|
-
args = ["-y", "${
|
|
94
|
+
args = ["-y", "${PACKAGE_NAME_LATEST}"]
|
|
95
95
|
startup_timeout_ms = 20000
|
|
96
96
|
`;
|
|
97
97
|
ensureDir(filePath);
|
|
@@ -110,7 +110,7 @@ const installClaude = (scope) => {
|
|
|
110
110
|
const configJson = JSON.stringify({
|
|
111
111
|
type: "stdio",
|
|
112
112
|
command: "npx",
|
|
113
|
-
args: ["-y",
|
|
113
|
+
args: ["-y", PACKAGE_NAME_LATEST],
|
|
114
114
|
});
|
|
115
115
|
const result = spawnSync("claude", ["mcp", "add-json", "--scope", scope, SERVER_NAME, configJson], {
|
|
116
116
|
stdio: "pipe",
|
|
@@ -136,7 +136,7 @@ const installVSCode = (scope) => {
|
|
|
136
136
|
servers[SERVER_NAME] = {
|
|
137
137
|
type: "stdio",
|
|
138
138
|
command: "npx",
|
|
139
|
-
args: ["-y",
|
|
139
|
+
args: ["-y", PACKAGE_NAME_LATEST],
|
|
140
140
|
};
|
|
141
141
|
config.servers = servers;
|
|
142
142
|
return { target: "vscode", scope, status: writeJson(filePath, config), location: filePath };
|
|
@@ -178,7 +178,7 @@ const installWarp = () => {
|
|
|
178
178
|
const config = readJson(filePath);
|
|
179
179
|
config[SERVER_NAME] = {
|
|
180
180
|
command: "npx",
|
|
181
|
-
args: ["-y",
|
|
181
|
+
args: ["-y", PACKAGE_NAME_LATEST],
|
|
182
182
|
env: {},
|
|
183
183
|
working_directory: null,
|
|
184
184
|
start_on_launch: true,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crush-protocol/mcp-client",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.4.24",
|
|
4
|
+
"description": "MCP server for market data, backtests, live strategies, and trading via Crush",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://crush.xyz",
|