equisense-research-mcp 0.3.0 → 0.3.1
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 +11 -28
- package/index.js +10 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,30 +14,13 @@ Published on npm: [`equisense-research-mcp`](https://www.npmjs.com/package/equis
|
|
|
14
14
|
|
|
15
15
|
## Quick start
|
|
16
16
|
|
|
17
|
-
### 1.
|
|
17
|
+
### 1. Generate a token (self-serve)
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Log in to the EquiSense web app and open **Settings → Claude → Connect Claude**. You get a **research-scoped, individually-revocable** token, shown once. Copy it (the web UI even pre-fills the full config block for you).
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
# Prod (must be on an admin-allowlisted IP)
|
|
23
|
-
curl -X POST "https://equisense.ai/api/v1/admin/auth/mint-mcp-token?phoneNumber=9876543210"
|
|
24
|
-
|
|
25
|
-
# Dev
|
|
26
|
-
curl -X POST "http://localhost:8080/api/v1/admin/auth/mint-mcp-token?phoneNumber=9876543210"
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
Response:
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"token": "<payload>.<sig>",
|
|
33
|
-
"expiresAt": 1777777777,
|
|
34
|
-
"userId": "user-abc",
|
|
35
|
-
"phone": "9876543210",
|
|
36
|
-
"ttlSeconds": 7776000
|
|
37
|
-
}
|
|
38
|
-
```
|
|
21
|
+
The token authenticates as `Authorization: Bearer <token>` and is limited to the research API — it cannot trade, change account settings, or mint further tokens. Revoke it any time from the same Settings page; revocation takes effect immediately.
|
|
39
22
|
|
|
40
|
-
|
|
23
|
+
> The old admin endpoint `POST /api/v1/admin/auth/mint-mcp-token` is **deprecated** — it issued full-account session tokens with no per-token revocation. Use Settings → Claude instead.
|
|
41
24
|
|
|
42
25
|
### 2. Register the MCP with Claude Code
|
|
43
26
|
|
|
@@ -46,7 +29,7 @@ Copy the `token`. Treat it like a password.
|
|
|
46
29
|
```bash
|
|
47
30
|
claude mcp add equisense-research --scope local \
|
|
48
31
|
--env EQUISENSE_BASE_URL=https://equisense.ai \
|
|
49
|
-
--env EQUISENSE_MCP_TOKEN='<token from
|
|
32
|
+
--env EQUISENSE_MCP_TOKEN='<token from Settings → Claude>' \
|
|
50
33
|
-- npx -y equisense-research-mcp
|
|
51
34
|
```
|
|
52
35
|
|
|
@@ -84,14 +67,15 @@ You should get back `{ answer, companyName, isin, detectedIntent, followUpQuesti
|
|
|
84
67
|
|---|---|---|
|
|
85
68
|
| `EQUISENSE_BASE_URL` | `http://localhost:8080` | Backend root URL |
|
|
86
69
|
| `EQUISENSE_TIMEOUT_MS` | `90000` | Per-request timeout (research queries can take 30–90s) |
|
|
87
|
-
| `EQUISENSE_MCP_TOKEN` | **required** |
|
|
70
|
+
| `EQUISENSE_MCP_TOKEN` | **required** | Scoped bearer token from Settings → Claude. Treat like a password. |
|
|
88
71
|
|
|
89
72
|
## Security notes
|
|
90
73
|
|
|
91
|
-
- The
|
|
92
|
-
-
|
|
74
|
+
- The token is **research-scoped** — it can only call the research API (`/api/v1/research/*`), enforced by the backend registering its authenticator only on those paths. It cannot trade, change account settings, or mint further tokens.
|
|
75
|
+
- The token is **individually revocable** from Settings → Claude. Revocation is immediate: a revoked token gets a `401` on the next call, with no signature-only fallback.
|
|
76
|
+
- Tokens last 90 days. The wrapper also sends the token as a legacy `Cookie: ES_AUTH` header so older admin-minted session tokens keep working during migration; new scoped tokens authenticate via `Authorization: Bearer`.
|
|
93
77
|
- Never commit the token. Never log it. Never paste it into chat.
|
|
94
|
-
- Each `ask_equisense` call counts against the
|
|
78
|
+
- Each `ask_equisense` call counts against the user's `AI_EQUITY_RESEARCH` daily quota — same metering as the web UI.
|
|
95
79
|
|
|
96
80
|
---
|
|
97
81
|
|
|
@@ -128,12 +112,11 @@ The Java app (Spring Boot 3.1) is too old for the Spring AI MCP server starter (
|
|
|
128
112
|
| Symptom | Likely cause | Fix |
|
|
129
113
|
|---|---|---|
|
|
130
114
|
| `FATAL: EQUISENSE_MCP_TOKEN env var is required` on startup | Env var unset or empty | Pass `--env EQUISENSE_MCP_TOKEN=...` to `claude mcp add` |
|
|
131
|
-
| `Auth failed (HTTP 401)
|
|
115
|
+
| `Auth failed (HTTP 401)` | Token expired, revoked, or `auth.token.secret` rotated | Generate a fresh token in Settings → Claude and update the env |
|
|
132
116
|
| `AI_EQUITY_RESEARCH quota exhausted (HTTP 402)` | Daily quota hit | Wait until tomorrow OR upgrade the user's plan |
|
|
133
117
|
| `Rate limited (HTTP 429)` | Transient | Retry in a few seconds |
|
|
134
118
|
| `Forbidden (HTTP 403)` | User doesn't have `AI_EQUITY_RESEARCH` feature | Check the user's license/plan |
|
|
135
119
|
| Hangs > 90s with no response | Backend research query timed out | Bump `EQUISENSE_TIMEOUT_MS`; check backend logs |
|
|
136
|
-
| `403` minting in prod | Your IP isn't admin-allowlisted | SSH to prod box and mint from there, or have an admin mint for you |
|
|
137
120
|
|
|
138
121
|
## License
|
|
139
122
|
|
package/index.js
CHANGED
|
@@ -178,7 +178,7 @@ function createServer() {
|
|
|
178
178
|
const server = new Server(
|
|
179
179
|
{
|
|
180
180
|
name: "equisense-research",
|
|
181
|
-
version: "0.3.
|
|
181
|
+
version: "0.3.1",
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
capabilities: {
|
|
@@ -187,21 +187,20 @@ function createServer() {
|
|
|
187
187
|
},
|
|
188
188
|
);
|
|
189
189
|
|
|
190
|
-
// Capture the client identity once the initialize handshake completes, so
|
|
191
|
-
// callRest can forward it as X-MCP-Client for auto-naming the connection.
|
|
192
|
-
server.oninitialized = () => {
|
|
193
|
-
try {
|
|
194
|
-
clientName = server.getClientVersion()?.name || null;
|
|
195
|
-
} catch {
|
|
196
|
-
clientName = null;
|
|
197
|
-
}
|
|
198
|
-
};
|
|
199
|
-
|
|
200
190
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
201
191
|
tools: TOOLS,
|
|
202
192
|
}));
|
|
203
193
|
|
|
204
194
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
195
|
+
// Capture the client identity here rather than via the `initialized`
|
|
196
|
+
// notification: a tool call can only arrive after initialize has completed,
|
|
197
|
+
// so getClientVersion() is reliably populated by now. The notification
|
|
198
|
+
// callback raced the first call (it could fire after the call's fetch had
|
|
199
|
+
// already built its headers), leaving the connection un-named on first use.
|
|
200
|
+
try {
|
|
201
|
+
clientName = server.getClientVersion()?.name || clientName;
|
|
202
|
+
} catch { /* leave clientName as-is */ }
|
|
203
|
+
|
|
205
204
|
const { name, arguments: args } = request.params;
|
|
206
205
|
const handler = TOOL_HANDLERS[name];
|
|
207
206
|
if (!handler) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "equisense-research-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "MCP server wrapper for the EquiSense AI equity-research API. Exposes a single ask_equisense tool that proxies POST /api/v1/research/ask, authenticated via a scoped, revocable token minted in Settings → Claude.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|