@riskmodels/mcp 1.0.1 → 1.0.4

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/INSTALL.md CHANGED
@@ -5,8 +5,9 @@ Copy-paste configs for Claude Desktop, Cursor, and Zed. Works with any [MCP](htt
5
5
  ## Prerequisites (one time)
6
6
 
7
7
  ```bash
8
- # 1. Get an API key (Stripe card on file, $20 free credit before first charge)
9
- npm install -g riskmodels
8
+ # 0. Node.js LTS (includes npx). macOS/Homebrew: brew install node; others: https://nodejs.org
9
+ # 1. Get an API key: https://riskmodels.app/get-key (or generate from the dashboard after sign-in)
10
+ npm install -g riskmodels@latest
10
11
  riskmodels config init # stores key at ~/.config/riskmodels/config.json
11
12
 
12
13
  # 2. Build the MCP server (from this repo)
@@ -0,0 +1,221 @@
1
+ # NPM Republish Checklist: @riskmodels/mcp
2
+
3
+ **Goal:** Re-enable the `npx @riskmodels/mcp` stdio install path by republishing to npm and updating the MCP Registry listing.
4
+
5
+ **Prerequisites:**
6
+ - [x] PR #124 merged (stdio build fixed — render tool split out)
7
+ - [ ] npm auth as @riskmodels org member
8
+ - [ ] SDK published at ^0.1.2 (or update version accordingly)
9
+
10
+ ---
11
+
12
+ ## Step 1: Pre-flight Checks
13
+
14
+ ```bash
15
+ cd RiskModels_API/mcp
16
+
17
+ # Verify npm auth
18
+ npm whoami
19
+ # Should show: <your-npm-username> (with @riskmodels org access)
20
+
21
+ # Check current package.json
22
+ npm pkg get name version mcpName
23
+ # Expected: @riskmodels/mcp, 1.0.4, io.github.BlueWaterCorp/riskmodels
24
+
25
+ # Verify SDK is published
26
+ npm view @riskmodels/sdk version
27
+ # Should show: 0.1.2 (or higher)
28
+ ```
29
+
30
+ ---
31
+
32
+ ## Step 2: Build
33
+
34
+ ```bash
35
+ # Clean build
36
+ cd RiskModels_API/mcp
37
+ rm -rf dist node_modules
38
+ npm install
39
+
40
+ # Build (this must succeed cleanly)
41
+ npm run build
42
+
43
+ # Verify dist/ exists and has expected files
44
+ ls -la dist/
45
+ # Should see: index.js, index.d.ts, etc.
46
+ ```
47
+
48
+ **If build fails:** Stop and fix. Do not proceed to publish.
49
+
50
+ ---
51
+
52
+ ## Step 3: Update Dependencies for Publish
53
+
54
+ ```bash
55
+ cd RiskModels_API/mcp
56
+
57
+ # Temporarily swap file: dependency to published range
58
+ # DO NOT COMMIT THIS CHANGE
59
+ npm pkg set 'dependencies.@riskmodels/sdk=^0.1.2'
60
+
61
+ # Verify
62
+ npm pkg get dependencies.@riskmodels/sdk
63
+ # Should show: ^0.1.2 (not file:...)
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Step 4: Dry Run
69
+
70
+ ```bash
71
+ cd RiskModels_API/mcp
72
+
73
+ # Verify package contents
74
+ npm publish --dry-run
75
+
76
+ # Check output for:
77
+ # - Correct version (1.0.4)
78
+ # - Correct name (@riskmodels/mcp)
79
+ # - Correct mcpName in metadata
80
+ # - Files included (dist/, README.md, etc.)
81
+ # - No file: dependencies
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Step 5: Publish
87
+
88
+ ```bash
89
+ cd RiskModels_API/mcp
90
+
91
+ # Publish to npm
92
+ npm publish
93
+
94
+ # Verify on npm
95
+ npm view @riskmodels/mcp version mcpName dependencies
96
+ # Should show:
97
+ # - version: 1.0.4
98
+ # - mcpName: io.github.BlueWaterCorp/riskmodels
99
+ # - dependencies.@riskmodels/sdk: ^0.1.2
100
+ ```
101
+
102
+ ---
103
+
104
+ ## Step 6: Restore Development Dependency
105
+
106
+ ```bash
107
+ cd RiskModels_API/mcp
108
+
109
+ # Restore file: dependency for local development
110
+ npm pkg set 'dependencies.@riskmodels/sdk=file:../packages/riskmodels-sdk'
111
+
112
+ # Verify
113
+ npm pkg get dependencies.@riskmodels/sdk
114
+ # Should show: file:../packages/riskmodels-sdk
115
+
116
+ # Reinstall to restore symlink
117
+ npm install
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Step 7: Update MCP Registry Listing
123
+
124
+ Edit `RiskModels_API/mcp/server.json` to add the `packages` array:
125
+
126
+ ```json
127
+ {
128
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
129
+ "name": "io.github.BlueWaterCorp/riskmodels",
130
+ "title": "RiskModels",
131
+ "description": "US equity risk: decompose any stock into market/sector/subsector/residual bets + ETF hedge ratios.",
132
+ "websiteUrl": "https://riskmodels.app",
133
+ "repository": {
134
+ "url": "https://github.com/BlueWaterCorp/RiskModels_API",
135
+ "source": "github"
136
+ },
137
+ "version": "1.0.4",
138
+ "packages": [
139
+ {
140
+ "name": "@riskmodels/mcp",
141
+ "registry": "npm"
142
+ }
143
+ ],
144
+ "remotes": [
145
+ {
146
+ "type": "streamable-http",
147
+ "url": "https://riskmodels.app/api/mcp/sse"
148
+ }
149
+ ]
150
+ }
151
+ ```
152
+
153
+ ---
154
+
155
+ ## Step 8: Re-publish to MCP Registry
156
+
157
+ ```bash
158
+ cd RiskModels_API/mcp
159
+
160
+ # Authenticate (if not already)
161
+ mcp-publisher login github
162
+
163
+ # Publish updated manifest
164
+ mcp-publisher publish
165
+
166
+ # Verify
167
+ open https://registry.modelcontextprotocol.io/servers/io.github.BlueWaterCorp/riskmodels
168
+ ```
169
+
170
+ ---
171
+
172
+ ## Step 9: Test the npx Path
173
+
174
+ ```bash
175
+ # Test that npx works (in a temp directory, no local install)
176
+ cd /tmp
177
+ mkdir mcp-test && cd mcp-test
178
+
179
+ # This should download and run the MCP server
180
+ npx @riskmodels/mcp
181
+
182
+ # Expected: Server starts, outputs stdio transport
183
+ # Ctrl+C to exit
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Verification Checklist
189
+
190
+ - [ ] `npm whoami` shows @riskmodels org member
191
+ - [ ] `npm run build` succeeds cleanly
192
+ - [ ] `npm publish --dry-run` shows correct files, no file: deps
193
+ - [ ] `npm publish` succeeds
194
+ - [ ] `npm view @riskmodels/mcp version` shows 1.0.4
195
+ - [ ] `server.json` has `packages[]` block added
196
+ - [ ] `mcp-publisher publish` succeeds
197
+ - [ ] Registry shows both remote and package options
198
+ - [ ] `npx @riskmodels/mcp` works in clean environment
199
+
200
+ ---
201
+
202
+ ## Rollback (if needed)
203
+
204
+ If something goes wrong:
205
+
206
+ ```bash
207
+ # Unpublish (within 24h of publish)
208
+ npm unpublish @riskmodels/mcp@1.0.4
209
+
210
+ # Or deprecate
211
+ npm deprecate @riskmodels/mcp@1.0.4 "Deprecated due to issue X, use 1.0.5+"
212
+ ```
213
+
214
+ ---
215
+
216
+ ## References
217
+
218
+ - Original runbook: `RiskModels_API/mcp/PUBLISHING.md`
219
+ - Build fix PR: #124
220
+ - Registry: https://registry.modelcontextprotocol.io
221
+ - npm package: https://www.npmjs.com/package/@riskmodels/mcp
package/PUBLISHING.md ADDED
@@ -0,0 +1,83 @@
1
+ # Publishing the RiskModels MCP server to the Official MCP Registry
2
+
3
+ Namespace: **`io.github.BlueWaterCorp/riskmodels`** (verified via GitHub org
4
+ membership — GitHub namespaces have **no remote-URL restriction**).
5
+ Manifest: [`server.json`](./server.json) (schema `2025-12-11`).
6
+
7
+ ## What we list now: the hosted remote (no npm needed)
8
+
9
+ `server.json` currently declares **only the hosted `streamable-http` remote**
10
+ (`https://riskmodels.app/api/mcp/sse`). That endpoint already works in
11
+ production, so listing it requires **no npm publish, no build, no `mcpName`** —
12
+ just GitHub auth. The stdio npm package is a fast-follow (see below).
13
+
14
+ ### Steps (require GitHub auth as a BlueWaterCorp org member)
15
+
16
+ 1. **Install the publisher CLI** (`mcp-publisher`):
17
+ download from https://github.com/modelcontextprotocol/registry/releases
18
+ (or `brew install mcp-publisher` if available).
19
+
20
+ 2. **Authenticate** as a member of the **BlueWaterCorp** GitHub org (this
21
+ authorizes the `io.github.BlueWaterCorp/*` namespace):
22
+ ```bash
23
+ mcp-publisher login github
24
+ ```
25
+
26
+ 3. **Publish** from the dir holding `server.json`:
27
+ ```bash
28
+ cd mcp
29
+ mcp-publisher publish
30
+ ```
31
+
32
+ 4. **Verify:** search https://registry.modelcontextprotocol.io for `riskmodels`.
33
+
34
+ ## Fast-follow: re-add the stdio npm package (`@riskmodels/mcp`)
35
+
36
+ The `npx @riskmodels/mcp` stdio package was intentionally **left off this
37
+ listing** because its standalone build is broken and needs a small refactor
38
+ first. This is additive — adding `packages[]` back to `server.json` later does
39
+ not disturb the live remote listing.
40
+
41
+ **Why it's broken (since 2026-05-20, PR #99):** `lib/mcp/tools/riskmodels-tools.ts`
42
+ (compiled into the stdio bundle via `mcp/tsconfig.json`'s
43
+ `include: ["../lib/mcp/tools/**"]`) imports `@/lib/artifacts/render-client`,
44
+ which imports `@/lib/artifacts/gcp-id-token`. The standalone `tsc` build can't
45
+ resolve the `@/` alias, and `tsc` wouldn't rewrite it for runtime anyway.
46
+
47
+ **Why a tsconfig-paths patch is not enough:** the `riskmodels_render_artifact`
48
+ tool authenticates to **GCP Cloud Run** to render. A public `npx` user has no
49
+ GCP credentials, so that tool cannot function in the stdio context — it is
50
+ **hosted-only**. The fix is to keep the render tool (and its render-client /
51
+ gcp-id-token deps) out of the public stdio bundle, e.g. split the render-tool
52
+ registration into a hosted-only module that `mcp/src/server.ts` does not import.
53
+
54
+ **When fixed**, to re-enable the npm package:
55
+ 1. Refactor so the stdio build (`cd mcp && npm run build`) compiles clean.
56
+ 2. Add `"mcpName": "io.github.BlueWaterCorp/riskmodels"` to `mcp/package.json`
57
+ (already added on this branch — keep it).
58
+ 3. Publish npm `@riskmodels/mcp@1.0.4` (latest on npm is `1.0.2`). The `file:`
59
+ SDK dep must become a published range at publish time:
60
+ ```bash
61
+ cd mcp
62
+ npm whoami # @riskmodels org member
63
+ npm run build # must succeed first
64
+ npm pkg set 'dependencies.@riskmodels/sdk=^0.1.2' # do NOT commit
65
+ npm publish --dry-run # confirm version/mcpName/^0.1.2/files
66
+ npm publish
67
+ npm pkg set 'dependencies.@riskmodels/sdk=file:../packages/riskmodels-sdk' # restore
68
+ npm view @riskmodels/mcp version mcpName dependencies
69
+ ```
70
+ Build with `cd mcp && npm run build` — **not** the repo-root `npm run build`
71
+ (that runs `next build` and OOMs; irrelevant to the npm package).
72
+ 4. Add the `packages[]` block back to `server.json` and re-run `mcp-publisher publish`.
73
+
74
+ ## Next: aggregators (#2)
75
+ Once on the official registry, PulseMCP / Glama / Smithery / mcp.so largely
76
+ ingest from it. Glama also auto-indexes public GitHub MCP servers; the OSS
77
+ `mcp-submit` tool submits to 10+ directories at once.
78
+
79
+ ## Known cosmetic follow-ups (not blockers)
80
+ - `.well-known/mcp.json` advertises `transport: "sse"` but the server is
81
+ Streamable HTTP — reconcile to avoid confusing strict clients.
82
+ - `/api/health` reports `version` from `process.env.API_VERSION` (falls back to
83
+ `2.0.0-agent`); set `API_VERSION=3.0.0-agent` in prod to match the OpenAPI spec.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  NPM package: `@riskmodels/mcp`
4
4
 
5
- Release note: publish `@riskmodels/sdk` first, then add the published SDK version as a runtime dependency before publishing this package.
5
+ Release note: publish **`@riskmodels/sdk`** to npm first, then **`@riskmodels/mcp`**. In this monorepo, `mcp/package.json` uses `"@riskmodels/sdk": "file:../packages/riskmodels-sdk"` so `cd mcp && npm ci && npm run build` works without publishing; **before `npm publish` of `@riskmodels/mcp`**, replace that dependency with a semver range (e.g. `^0.1.1`) after `@riskmodels/sdk` is live on the registry.
6
6
 
7
7
  **Decompose** a US stock into market, sector, subsector, and residual risk &mdash; with SPY / sector / subsector **ETF hedge ratios**. One call, daily history since 2006.
8
8
 
@@ -86,6 +86,8 @@ Run `riskmodels config init` once — the CLI's stored key is automatically pick
86
86
 
87
87
  Base URL resolution: `RISKMODELS_API_BASE` env → `apiBaseUrl` in CLI config → `https://riskmodels.app` default.
88
88
 
89
+ **Hosted transport (`POST https://riskmodels.app/api/mcp/sse`):** send header `Accept: application/json, text/event-stream`. Without it, some clients receive **406 Not Acceptable**.
90
+
89
91
  ---
90
92
 
91
93
  ## Python SDK on PyPI
@@ -107,12 +109,27 @@ This repo includes **`.cursor/mcp.json`** pointing at `node` + `mcp/dist/index.j
107
109
  ### Claude Desktop / `npx` (common mistakes)
108
110
 
109
111
  - **There is no `mcp` subcommand on the npm package.** The CLI binary is **`riskmodels`**. Do **not** run `npx -y riskmodels-cli mcp` — that legacy package does not provide the new installer flow.
112
+ - **Preferred (deterministic):** pin the CLI package so `npx` does not resolve a stale cache — e.g. `RISKMODELS_API_KEY=... npx -y riskmodels@latest install` (writes MCP configs via `riskmodels install`). Same flow as [Quickstart](https://riskmodels.app/quickstart).
110
113
  - **Use one of these:**
111
- - **`npx -y @riskmodels/mcp`** — future published stdio package target used by `npx riskmodels install`.
114
+ - **`npx -y @riskmodels/mcp`** — stdio MCP package merged into configs by `npx -y riskmodels@latest install` / global `riskmodels install`.
112
115
  - **`riskmodels mcp-config`** — prints a ready-to-paste `mcpServers` block for Claude Desktop (`--client claude-desktop`) or Cursor. Use **`riskmodels mcp-config --embed-key`** only if you want the key in the JSON env block.
113
116
  - **`riskmodels mcp`** — runs the stdio MCP server (same as `node mcp/dist/index.js`). Requires `mcp/dist/index.js` to exist (build `mcp/` first), or set **`RISKMODELS_MCP_SERVER_PATH`** to that file.
114
117
  - **`node /absolute/path/to/RiskModels_API/mcp/dist/index.js`** — always works if the build exists.
115
118
 
119
+ ### Claude Code (`claude` CLI)
120
+
121
+ The **`riskmodels install`** command merges MCP into **Claude Desktop** (`claude_desktop_config.json`) and **Cursor** — not into **Claude Code** (the `claude` terminal application), which maintains its own MCP configuration.
122
+
123
+ After you have run `riskmodels install` and have a key in `~/.config/riskmodels/config.json`, register the stdio server for Claude Code:
124
+
125
+ ```bash
126
+ claude mcp add --scope user --transport stdio riskmodels -- npx -y @riskmodels/mcp
127
+ ```
128
+
129
+ Restart **`claude`**, then run **`claude mcp list`** — `riskmodels` should show as connected. If it does not, use the **hosted** `mcp-remote` transport with `AUTHORIZATION=Bearer <key>` (same JSON pattern as in the “Hosted endpoint” section below).
130
+
131
+ `@riskmodels/sdk` powers in-tool SDK calls inside `@riskmodels/mcp`; published builds use Node ESM with `.js` import specifiers so `npx -y @riskmodels/mcp` loads under Node 18+.
132
+
116
133
  ### Hosted endpoint (`https://riskmodels.app/api/mcp/sse`)
117
134
 
118
135
  The hosted endpoint implements the **MCP Streamable HTTP** transport (current SDK spec, successor to legacy SSE+companion-POST). Stateless mode: each `POST` carries a JSON-RPC 2.0 message and returns the response synchronously. Auth via `Authorization: Bearer <key>` (primary) or `?api_key=<key>` query param (fallback for clients that can't set headers, e.g. `EventSource`).
@@ -124,7 +141,7 @@ Paste into Claude Desktop / Cursor via the `mcp-remote` proxy:
124
141
  "mcpServers": {
125
142
  "riskmodels": {
126
143
  "command": "npx",
127
- "args": ["mcp-remote", "https://riskmodels.app/api/mcp/sse"],
144
+ "args": ["-y", "mcp-remote", "https://riskmodels.app/api/mcp/sse"],
128
145
  "env": { "AUTHORIZATION": "Bearer rm_agent_live_..." }
129
146
  }
130
147
  }
@@ -0,0 +1,68 @@
1
+ {
2
+ "schema_version": "benchmark-master/1.0",
3
+ "n_contexts": 2,
4
+ "aliases": {
5
+ "70-30-large-small": "BW-BENCH-EQ70-30",
6
+ "70/30": "BW-BENCH-EQ70-30",
7
+ "eq70-30": "BW-BENCH-EQ70-30",
8
+ "ivv": "BW-BENCH-SPY",
9
+ "s&p 500": "BW-BENCH-SPY",
10
+ "sp500": "BW-BENCH-SPY",
11
+ "spx": "BW-BENCH-SPY",
12
+ "spy": "BW-BENCH-SPY",
13
+ "us-large-small-70-30": "BW-BENCH-EQ70-30"
14
+ },
15
+ "contexts": {
16
+ "BW-BENCH-EQ70-30": {
17
+ "bw_bench_id": "BW-BENCH-EQ70-30",
18
+ "name": "70/30 US Large/Small all-equity blend (70% IWB + 30% IWM)",
19
+ "benchmark_kind": "blend",
20
+ "aliases": [
21
+ "70/30",
22
+ "EQ70-30",
23
+ "70-30-large-small",
24
+ "US-LARGE-SMALL-70-30"
25
+ ],
26
+ "methodology": "Fixed-weight all-equity blend: 70% iShares Russell 1000 ETF (IWB) + 30% iShares Russell 2000 ETF (IWM). Each component's in-ERM3 weight vector is renormalized to 1, scaled by its notional weight, and the two are summed over the union of symbols at each teo the components share. Illustrative large/small split (IWB \u222a IWM \u2248 Russell 3000).",
27
+ "rebalance_schedule": "Notional weights fixed at 70/30; the component weight vectors drift with the underlying ETF holdings (no rebalancing of the blend itself in v1).",
28
+ "observation_mode": "reality",
29
+ "proxy": null,
30
+ "components": [
31
+ {
32
+ "source_kind": "etf",
33
+ "ref": "IWB",
34
+ "weight": 0.7
35
+ },
36
+ {
37
+ "source_kind": "etf",
38
+ "ref": "IWM",
39
+ "weight": 0.3
40
+ }
41
+ ],
42
+ "benchmark_context_version": "benchmark-context/1.0",
43
+ "notes": ""
44
+ },
45
+ "BW-BENCH-SPY": {
46
+ "bw_bench_id": "BW-BENCH-SPY",
47
+ "name": "S&P 500 (proxy: iShares Core S&P 500 ETF, IVV)",
48
+ "benchmark_kind": "index_proxy",
49
+ "aliases": [
50
+ "SPY",
51
+ "S&P 500",
52
+ "SP500",
53
+ "SPX",
54
+ "IVV"
55
+ ],
56
+ "methodology": "Float-adjusted market-cap-weighted S&P 500 constituents, proxied by iShares Core S&P 500 ETF (IVV)'s published daily holdings. The benchmark surface = IVV's in-ERM3 holdings renormalized to weights summing to 1 (cash / non-ERM3 lines dropped, as for any portfolio surface).",
57
+ "rebalance_schedule": "S&P 500 reconstitution is quarterly (effective the 3rd Friday of Mar/Jun/Sep/Dec) plus ad-hoc index changes; the surface tracks IVV's daily-published holdings, so per-teo weights move with IVV (which itself tracks the index ~daily).",
58
+ "observation_mode": "reality",
59
+ "proxy": {
60
+ "source_kind": "etf",
61
+ "ref": "IVV"
62
+ },
63
+ "components": [],
64
+ "benchmark_context_version": "benchmark-context/1.0",
65
+ "notes": "v1 proxies the index via IVV; a direct S&P-constituent feed would be a follow-on."
66
+ }
67
+ }
68
+ }