@wevo-ai/pulse-mcp 0.0.0-stage → 0.1.0-test.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +457 -2
- package/dist/THIRD_PARTY_NOTICES.txt +236 -0
- package/dist/public-index.js +23138 -0
- package/package.json +48 -4
package/README.md
CHANGED
|
@@ -1,3 +1,458 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Local Pulse public API MCP server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Local stdio MCP server → WEVO Pulse public API (`/api/public/v1`), **prod**
|
|
4
|
+
by default (`https://platform.wevo.ai`); WEVO developers opt into dev or
|
|
5
|
+
staging explicitly (see [Environments](#environments)). Claude Code, Claude Desktop,
|
|
6
|
+
Cursor, and VS Code launch it as a child process. No local Pulse backend,
|
|
7
|
+
Docker, or deployment is required; the only listener is the short-lived
|
|
8
|
+
`127.0.0.1` callback used while you sign in.
|
|
9
|
+
|
|
10
|
+
## Prior design documents
|
|
11
|
+
|
|
12
|
+
- [MCP Auth, Credits & Distribution Plan (Oct 8 draft)](https://app.notion.com/p/3f3bf908bd6881ea8f19fc34d3f0010f)
|
|
13
|
+
- [Pulse Public API MVP spec](https://app.notion.com/p/3edbf908bd68819bb7afe2ee9a66a333)
|
|
14
|
+
- [WEV-4086: private MCP server](https://linear.app/wevo/issue/WEV-4086)
|
|
15
|
+
|
|
16
|
+
This implements the plan's **local development** option: public v1 tools
|
|
17
|
+
acting as one signed-in user. Sign-in runs Authorization Code + PKCE in your
|
|
18
|
+
browser, started by the server itself on the first tool call (or by the
|
|
19
|
+
`login` CLI command), and stores a refreshable token; the server refreshes it
|
|
20
|
+
without re-approval. The older ticket proposes Device Code, but WEVO's Auth0 tenant
|
|
21
|
+
does not offer Device Code to third-party (developer portal) apps.
|
|
22
|
+
|
|
23
|
+
## Install and sign in
|
|
24
|
+
|
|
25
|
+
Requires **Node.js 22 or newer** on `PATH`. The package `@wevo-ai/pulse-mcp`
|
|
26
|
+
is one bundled file with no runtime dependencies; its command is
|
|
27
|
+
`wevo-pulse-public-mcp`. MCP clients launch it with `npx`. No clone, build,
|
|
28
|
+
or CodeArtifact access is needed.
|
|
29
|
+
|
|
30
|
+
> **Restricted package.** `@wevo-ai/pulse-mcp` is planned as a **restricted**
|
|
31
|
+
> (private) npm package for now; see [Package and publish](#package-and-publish).
|
|
32
|
+
> `npx -y @wevo-ai/pulse-mcp` then works only for npm users who belong to the
|
|
33
|
+
> `@wevo-ai` npm organization, sit on a team with read access to the package,
|
|
34
|
+
> and are authenticated to `registry.npmjs.org` (`npm login`, or an `.npmrc`
|
|
35
|
+
> line `//registry.npmjs.org/:_authToken=${NPM_TOKEN}`). Everyone else gets a 404. **Customers should use the [Claude Desktop bundle](#connect-clients)
|
|
36
|
+
> (`wevo-pulse.mcpb`)**: it is self-contained and needs no npm account.
|
|
37
|
+
>
|
|
38
|
+
> **Not published yet.** Until it is, run `npm pack` in this package and
|
|
39
|
+
> replace `-y @wevo-ai/pulse-mcp` below with
|
|
40
|
+
> `-y --package /ABS/PATH/TO/wevo-ai-pulse-mcp-0.1.0.tgz wevo-pulse-public-mcp`.
|
|
41
|
+
|
|
42
|
+
### Environments
|
|
43
|
+
|
|
44
|
+
With no `WEVO_PULSE_BASE_URL`, the server and `login` use **prod**. Each
|
|
45
|
+
environment has its own Auth0 tenant; `login` picks the matching defaults:
|
|
46
|
+
|
|
47
|
+
| Environment | `WEVO_PULSE_BASE_URL` | Auth0 domain | Audience |
|
|
48
|
+
| -------------- | -------------------------------- | ---------------------- | ------------- |
|
|
49
|
+
| prod (default) | `https://platform.wevo.ai` | `auth.wevo.ai` | `persona-api` |
|
|
50
|
+
| staging | `https://platform-stage.wevo.ai` | `auth-staging.wevo.ai` | `persona-api` |
|
|
51
|
+
| dev | `https://platform-dev.wevo.ai` | `auth-dev.wevo.ai` | `persona-api` |
|
|
52
|
+
|
|
53
|
+
WEVO developers set `WEVO_PULSE_BASE_URL=https://platform-dev.wevo.ai` (or
|
|
54
|
+
the staging origin) themselves, in `mcp.env` or the client's `env`. Logins are
|
|
55
|
+
stored per origin, so switching environments needs one `login` per origin.
|
|
56
|
+
|
|
57
|
+
> **Prod launch pending.** `https://platform.wevo.ai` serves
|
|
58
|
+
> `/api/public/v1` only after the prod public API host launches (WEV-4085);
|
|
59
|
+
> until then prod calls fail there. `https://personas-api.wevo.ai` reaches the
|
|
60
|
+
> same prod API and uses the same prod Auth0 defaults in the meantime.
|
|
61
|
+
|
|
62
|
+
### Sign in
|
|
63
|
+
|
|
64
|
+
1. **Client ID.** **Dev** (`https://platform-dev.wevo.ai`) and **staging**
|
|
65
|
+
(`https://platform-stage.wevo.ai`) have WEVO's own MCP login client built
|
|
66
|
+
in: skip to step 3 (WEVO developers only need `WEVO_PULSE_BASE_URL` from
|
|
67
|
+
step 2). Prod has no default login client yet, so `login` there needs
|
|
68
|
+
`WEVO_PULSE_CLIENT_ID`. Open the developer portal (`<origin>/developer`)
|
|
69
|
+
and create a **Public** app in your own organization (an app registered in
|
|
70
|
+
another organization returns `403 api_client_org_mismatch`; Public apps
|
|
71
|
+
created before October 7, 2026 have no refresh tokens, so create a new
|
|
72
|
+
one). Callback URL, exactly: `http://127.0.0.1:47615/callback`. Select the
|
|
73
|
+
scopes below. Setting `WEVO_PULSE_CLIENT_ID` on dev or staging overrides
|
|
74
|
+
the built-in client.
|
|
75
|
+
2. Save settings in the per-user config file, which every run loads
|
|
76
|
+
automatically:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mkdir -p ~/.config/wevo-pulse-mcp
|
|
80
|
+
(umask 077 && cat > ~/.config/wevo-pulse-mcp/mcp.env <<'EOF'
|
|
81
|
+
# Prod only, until WEVO's own login client ships there:
|
|
82
|
+
# WEVO_PULSE_CLIENT_ID=your_public_app_client_id
|
|
83
|
+
# WEVO developers only (default is prod):
|
|
84
|
+
# WEVO_PULSE_BASE_URL=https://platform-dev.wevo.ai
|
|
85
|
+
EOF
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
3. Sign in. **No terminal needed:** in your MCP client, call any WEVO tool or
|
|
90
|
+
just say "log in to WEVO". When nobody is signed in, the server opens your
|
|
91
|
+
browser at WEVO sign-in and the tool returns `login_started` at once with
|
|
92
|
+
the sign-in link (`authorize_url`) as a fallback; it does not wait for you.
|
|
93
|
+
Sign in, then retry the request: the next call uses the new login. A
|
|
94
|
+
sign-in stays open for 5 minutes; a later call after that starts a fresh
|
|
95
|
+
one. Clients that support MCP URL elicitation are asked to show the
|
|
96
|
+
sign-in page themselves instead of the server opening a browser.
|
|
97
|
+
|
|
98
|
+
From a terminal instead (or on a machine without a desktop browser):
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx -y @wevo-ai/pulse-mcp login
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
On your **first** login a one-time **consent screen** lists the requested
|
|
105
|
+
scopes: approve it. Auth0 always asks once for an app with a loopback
|
|
106
|
+
(`127.0.0.1`) callback; silent refreshes never prompt, and later logins ask
|
|
107
|
+
again only if the requested scopes change. `--no-browser` (or
|
|
108
|
+
`WEVO_PULSE_NO_BROWSER=1`, which also applies to server-started sign-in)
|
|
109
|
+
prints the URL instead of opening a browser. The command confirms the
|
|
110
|
+
signed-in user, org, app, and scopes. `npx -y @wevo-ai/pulse-mcp status`
|
|
111
|
+
shows the API origin and active credential later; `logout` revokes and
|
|
112
|
+
deletes it; `help` lists commands and settings. The MCP tools `login`,
|
|
113
|
+
`auth_status`, and `logout` do the same from inside a client.
|
|
114
|
+
|
|
115
|
+
For all tools: `pulse:read pulse:write personas:read personas:write
|
|
116
|
+
personas:outputs:read assets:read assets:write`. Read-only use needs only the
|
|
117
|
+
corresponding read scopes. The API still checks user permissions, app grants,
|
|
118
|
+
org membership, resource ownership/sharing, and credits. Call `whoami` first
|
|
119
|
+
and confirm user, org, app, scopes, and expiry.
|
|
120
|
+
|
|
121
|
+
### Stored login
|
|
122
|
+
|
|
123
|
+
The token is stored per user at `~/.config/wevo-pulse-mcp/credentials.json`
|
|
124
|
+
(`$XDG_CONFIG_HOME/wevo-pulse-mcp`, or `%APPDATA%\wevo-pulse-mcp` on Windows;
|
|
125
|
+
`WEVO_PULSE_CONFIG_DIR` overrides), owner-only `0600`, keyed by API origin.
|
|
126
|
+
Every client on the machine shares it, and running servers pick it up on their
|
|
127
|
+
next call; no restart is needed. They refresh the access token shortly before
|
|
128
|
+
expiry and once after a `401`, persisting Auth0's rotated refresh token
|
|
129
|
+
atomically under a lock file so several MCP clients can share one login. When
|
|
130
|
+
the refresh token expires or is revoked, the next tool call starts browser
|
|
131
|
+
sign-in again (`login_started`). Tokens are never printed or logged.
|
|
132
|
+
|
|
133
|
+
Sign-in uses the fixed callback port `47615`. One sign-in runs per server
|
|
134
|
+
process; while it is open, further calls reuse it and return the same link.
|
|
135
|
+
If another process (a second MCP client or a terminal `login`) holds the port
|
|
136
|
+
mid-sign-in, tools return `login_port_busy`: finish that sign-in and retry.
|
|
137
|
+
On prod without a client ID (see step 1) they return `login_unavailable`,
|
|
138
|
+
naming `WEVO_PULSE_CLIENT_ID`. Stopping the server
|
|
139
|
+
cancels its open sign-in.
|
|
140
|
+
|
|
141
|
+
### Configuration files
|
|
142
|
+
|
|
143
|
+
Settings come from process variables plus at most one env file, chosen in
|
|
144
|
+
this order:
|
|
145
|
+
|
|
146
|
+
1. `WEVO_PULSE_ENV_FILE`, if set. Use an absolute path; a missing file fails
|
|
147
|
+
startup.
|
|
148
|
+
2. The package-root `.env` (monorepo checkouts only; installed packages have
|
|
149
|
+
none).
|
|
150
|
+
3. `mcp.env` in the config directory above (`~/.config/wevo-pulse-mcp/mcp.env`
|
|
151
|
+
by default).
|
|
152
|
+
|
|
153
|
+
Missing implicit files are ignored. Process variables win over file values.
|
|
154
|
+
`WEVO_PULSE_BASE_URL` is an **origin only**, without `/api` or
|
|
155
|
+
`/api/public/v1`, and defaults to prod (`https://platform.wevo.ai`); HTTPS is required except for loopback
|
|
156
|
+
test APIs. Timeout (`WEVO_PULSE_TIMEOUT_MS`): 1–300000 ms. See
|
|
157
|
+
[`.env.example`](.env.example) for every setting.
|
|
158
|
+
|
|
159
|
+
Login options: `WEVO_PULSE_CALLBACK_PORT` (must match a registered callback),
|
|
160
|
+
`WEVO_PULSE_CLIENT_ID` (built in for dev and staging; required on prod until
|
|
161
|
+
WEVO's own login client ships there),
|
|
162
|
+
`WEVO_PULSE_AUTH0_DOMAIN` / `WEVO_PULSE_AUTH0_AUDIENCE` (required only for
|
|
163
|
+
origins outside [Environments](#environments)),
|
|
164
|
+
`WEVO_PULSE_AUTH0_ORGANIZATION` (users in several orgs), and
|
|
165
|
+
`WEVO_PULSE_SCOPES` (subset of the app's scopes; `offline_access` is always
|
|
166
|
+
added), and `WEVO_PULSE_NO_BROWSER=1` (return the sign-in link without opening
|
|
167
|
+
a browser).
|
|
168
|
+
|
|
169
|
+
### Fixed token override (CI/tests)
|
|
170
|
+
|
|
171
|
+
`WEVO_PULSE_TOKEN` (process env or env file) overrides the stored login and is
|
|
172
|
+
never refreshed; while it is set the server never starts browser sign-in. Use a user-delegated **access token**, without `Bearer `, from
|
|
173
|
+
a developer portal app (for example via the
|
|
174
|
+
[API docs test client](https://github.com/wevo-conversion/pulse-api-docs-test-client)).
|
|
175
|
+
Do not use an ID token, client secret, or client-credentials/M2M token. A
|
|
176
|
+
normal Pulse web-app token is insufficient unless its client is registered for
|
|
177
|
+
public API use. Keep tokens out of client JSON, shell history, and commits.
|
|
178
|
+
|
|
179
|
+
## Connect clients
|
|
180
|
+
|
|
181
|
+
Clients need only the command: the server reads
|
|
182
|
+
`~/.config/wevo-pulse-mcp/mcp.env` and the stored login itself, and starts
|
|
183
|
+
browser sign-in on the first tool call when nobody is signed in. MCP reserves
|
|
184
|
+
stdout for JSON-RPC; `npx -y` installs quietly, and the server logs only to
|
|
185
|
+
stderr.
|
|
186
|
+
|
|
187
|
+
**Claude Code** — register once:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
claude mcp add --transport stdio --scope user \
|
|
191
|
+
wevo-pulse-public -- npx -y @wevo-ai/pulse-mcp
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Run `/mcp`, then ask: “Use wevo-pulse-public to check my identity and list my
|
|
195
|
+
Personas.”
|
|
196
|
+
|
|
197
|
+
**Cursor** — merge into `~/.cursor/mcp.json` (user) or `.cursor/mcp.json` (project):
|
|
198
|
+
|
|
199
|
+
```json
|
|
200
|
+
{
|
|
201
|
+
"mcpServers": {
|
|
202
|
+
"wevo-pulse-public": {
|
|
203
|
+
"command": "npx",
|
|
204
|
+
"args": ["-y", "@wevo-ai/pulse-mcp"]
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Enable it in Cursor's MCP settings; refresh/restart after configuration changes.
|
|
211
|
+
|
|
212
|
+
**Claude Desktop** — either:
|
|
213
|
+
|
|
214
|
+
- **One-click bundle** (recommended for customers while the npm package is
|
|
215
|
+
restricted): open `wevo-pulse.mcpb` (Settings → Extensions → Install
|
|
216
|
+
Extension). The bundle embeds the server, so it needs no npm account,
|
|
217
|
+
registry access, Node install, or env file; Desktop runs it on its built-in
|
|
218
|
+
Node.js. It prompts for the API origin (prefilled with prod,
|
|
219
|
+
`https://platform.wevo.ai`) plus two optional fields. Leave the **access
|
|
220
|
+
token** empty, then ask Claude anything that uses WEVO (or "log in to
|
|
221
|
+
WEVO"): a browser window opens to sign in, and the next request works. No
|
|
222
|
+
terminal is needed. On prod, until WEVO's own login client ships there,
|
|
223
|
+
fill in the **client ID** field (`WEVO_PULSE_CLIENT_ID`, step 1 above);
|
|
224
|
+
dev and staging need none. The login lives in the same credentials file as a
|
|
225
|
+
terminal `login`, so both share it and its refresh. Pasting an access token instead stores it in the OS keychain and
|
|
226
|
+
disables browser sign-in; it is never refreshed, so replace it when it
|
|
227
|
+
expires. If you set `XDG_CONFIG_HOME` or `WEVO_PULSE_CONFIG_DIR` only in
|
|
228
|
+
your shell, Desktop will not see a terminal login. Build the bundle with `npm run mcpb`
|
|
229
|
+
(output: `dist/wevo-pulse.mcpb`) and share the file directly.
|
|
230
|
+
- **JSON config**: the Cursor `mcpServers` JSON in
|
|
231
|
+
`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS
|
|
232
|
+
(Settings → Developer → Edit Config), then restart Claude Desktop.
|
|
233
|
+
|
|
234
|
+
Neither makes the server reachable from the claude.ai website.
|
|
235
|
+
|
|
236
|
+
**VS Code / GitHub Copilot** — `.vscode/mcp.json` uses `servers`:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"servers": {
|
|
241
|
+
"wevo-pulse-public": {
|
|
242
|
+
"type": "stdio",
|
|
243
|
+
"command": "npx",
|
|
244
|
+
"args": ["-y", "@wevo-ai/pulse-mcp"]
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Other stdio clients use the same command and arguments. To keep settings
|
|
251
|
+
elsewhere, add `"env": { "WEVO_PULSE_ENV_FILE": "/Users/YOU/path/mcp.env" }`
|
|
252
|
+
(JSON configs do not expand `~`). GUI apps may not inherit a shell-managed
|
|
253
|
+
`PATH` (nvm, fnm, Volta): if the client cannot find `npx`, use its absolute
|
|
254
|
+
path from `which npx`. On Windows clients that cannot launch `npx` directly,
|
|
255
|
+
use `"command": "cmd"` with `"args": ["/c", "npx", "-y", "@wevo-ai/pulse-mcp"]`.
|
|
256
|
+
|
|
257
|
+
### From a monorepo checkout (WEVO developers)
|
|
258
|
+
|
|
259
|
+
From the `wevo-pulse` repository root, using Node 25 from `.nvmrc`:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
make install-api-client install-mcp
|
|
263
|
+
make build-api-client build-mcp
|
|
264
|
+
cp -n packages/wevo-pulse-mcp/.env.example packages/wevo-pulse-mcp/.env
|
|
265
|
+
chmod 600 packages/wevo-pulse-mcp/.env # then set WEVO_PULSE_BASE_URL (dev and staging need no WEVO_PULSE_CLIENT_ID)
|
|
266
|
+
./scripts/with-node.sh node packages/wevo-pulse-mcp/dist/public-index.js login
|
|
267
|
+
claude mcp add --transport stdio --scope user wevo-pulse-public -- \
|
|
268
|
+
/ABS/PATH/TO/wevo-pulse/scripts/with-node.sh node \
|
|
269
|
+
/ABS/PATH/TO/wevo-pulse/packages/wevo-pulse-mcp/dist/public-index.js
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The gitignored package `.env` loads automatically, regardless of the client's
|
|
273
|
+
working directory, and takes the place of `mcp.env`. Login uses the same
|
|
274
|
+
per-user credentials file as the npm package. Other clients use
|
|
275
|
+
`/ABS/PATH/TO/wevo-pulse/scripts/with-node.sh` as `command` and
|
|
276
|
+
`["node", "/ABS/PATH/TO/wevo-pulse/packages/wevo-pulse-mcp/dist/public-index.js"]`
|
|
277
|
+
as `args`. The wrapper selects Node 25 without writing to stdout.
|
|
278
|
+
|
|
279
|
+
## Run and develop
|
|
280
|
+
|
|
281
|
+
No shared daemon needs starting first: each MCP client starts its own process.
|
|
282
|
+
To run manually from the repository root:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
./scripts/with-node.sh node packages/wevo-pulse-mcp/dist/public-index.js
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
A quiet process waiting on stdin is expected. Ctrl-C stops it. For interactive
|
|
289
|
+
protocol inspection after signing in:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
./scripts/with-node.sh npx @modelcontextprotocol/inspector \
|
|
293
|
+
./scripts/with-node.sh node packages/wevo-pulse-mcp/dist/public-index.js
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
For source iteration, run `npm run dev:public` inside this package. Reconnect
|
|
297
|
+
after watch-process restarts. Compiled clients need `make build-mcp` followed
|
|
298
|
+
by restart/reconnect. `npm start` also runs the compiled public server.
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
make test-mcp typecheck-mcp lint-mcp
|
|
302
|
+
make code-quality
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Tests cover MCP discovery/calls, all route mappings and request schemas,
|
|
306
|
+
configuration validation, auth/error propagation, 204 deletes, idempotency,
|
|
307
|
+
timeouts, redirects, and a real stdio child process against a loopback fixture
|
|
308
|
+
API. Login tests cover PKCE, callback state handling, credential file
|
|
309
|
+
permissions/locking, refresh-token rotation, single 401 retry, env-token
|
|
310
|
+
precedence, and in-server sign-in (auto-start, reuse, success, timeout,
|
|
311
|
+
busy port, URL elicitation, logout, and a stdio child whose stdout carries only
|
|
312
|
+
JSON-RPC) against a loopback fake Auth0; they never contact real Auth0. Tests
|
|
313
|
+
never launch real billable Pulses.
|
|
314
|
+
|
|
315
|
+
## Package and publish
|
|
316
|
+
|
|
317
|
+
`npm run build` uses esbuild to bundle `src/public-index.ts` and the legacy
|
|
318
|
+
`src/index.ts` into self-contained ESM files in `dist/` (local sourcemaps),
|
|
319
|
+
plus `dist/THIRD_PARTY_NOTICES.txt` for the inlined dependencies. Runtime
|
|
320
|
+
libraries, including `@wevo/pulse-api-client`, are `devDependencies` on
|
|
321
|
+
purpose: they are inlined, so the published package installs nothing else. Add
|
|
322
|
+
new runtime libraries the same way.
|
|
323
|
+
|
|
324
|
+
`npm pack` builds first, then ships only the `wevo-pulse-public-mcp` bin,
|
|
325
|
+
notices, README, and `package.json` (about 150 kB). The legacy
|
|
326
|
+
`wevo-pulse-mcp` server targets internal Persona/Audience APIs, so it stays
|
|
327
|
+
monorepo-only (`node dist/index.js`). `npm run mcpb` writes
|
|
328
|
+
`dist/wevo-pulse.mcpb` for Claude Desktop with a pinned `@anthropic-ai/mcpb`.
|
|
329
|
+
|
|
330
|
+
The package publishes as `@wevo-ai/pulse-mcp` in WEVO's `@wevo-ai` npm org,
|
|
331
|
+
with **restricted** access for now (public later).
|
|
332
|
+
The `@wevo` scope on public npm belongs to an unrelated owner: never publish
|
|
333
|
+
or document install commands under it. Internal packages such as
|
|
334
|
+
`@wevo/pulse-api-client` stay on private CodeArtifact and are only inlined
|
|
335
|
+
into the bundle.
|
|
336
|
+
|
|
337
|
+
Publishing is gated by `"private": true`. `publishConfig` pins
|
|
338
|
+
`registry.npmjs.org` with `"access": "restricted"`, so a CodeArtifact login
|
|
339
|
+
that rewrites the default registry cannot capture the publish and the first
|
|
340
|
+
publish cannot go public by accident.
|
|
341
|
+
|
|
342
|
+
Restricted access means (per npm docs:
|
|
343
|
+
[private packages](https://docs.npmjs.com/about-private-packages),
|
|
344
|
+
[paid organization plan](https://docs.npmjs.com/upgrading-to-a-paid-organization-plan),
|
|
345
|
+
[visibility](https://docs.npmjs.com/package-scope-access-level-and-visibility),
|
|
346
|
+
[CI auth](https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow)):
|
|
347
|
+
|
|
348
|
+
- The `@wevo-ai` org must be on the paid **npm Teams** plan, billed per org
|
|
349
|
+
member (every member, not just publishers).
|
|
350
|
+
- Only org members on a team granted read access can view or install it.
|
|
351
|
+
Each installer needs their own npm account in the org and must authenticate
|
|
352
|
+
to `registry.npmjs.org` (`npm login`, or a read-only granular token via
|
|
353
|
+
`.npmrc`). Anonymous `npx` gets a 404.
|
|
354
|
+
- The [MCP Registry](https://modelcontextprotocol.io/registry/package-types)
|
|
355
|
+
lists npm servers only from the public npm registry and verifies `mcpName`
|
|
356
|
+
from the published `package.json`, so no MCP Registry listing is possible
|
|
357
|
+
while restricted.
|
|
358
|
+
- Customers outside the org use the `.mcpb` bundle, which embeds the server.
|
|
359
|
+
|
|
360
|
+
To publish:
|
|
361
|
+
|
|
362
|
+
1. Confirm the `@wevo-ai` org is on npm Teams, then remove `"private": true`.
|
|
363
|
+
2. Publish from CI, not a laptop: a `workflow_dispatch` job modeled on
|
|
364
|
+
`.github/workflows/api-client.yml` (Node from `.nvmrc`,
|
|
365
|
+
`make install-api-client install-mcp test-mcp`, `npm version`,
|
|
366
|
+
`npm publish` with `id-token: write`, using npm trusted publishing
|
|
367
|
+
configured for `@wevo-ai/pulse-mcp`). Do not pass `--provenance`: npm
|
|
368
|
+
generates [provenance](https://docs.npmjs.com/trusted-publishers) only for
|
|
369
|
+
public packages published from public repositories, and both are private
|
|
370
|
+
here. Attach `dist/wevo-pulse.mcpb` to the GitHub release.
|
|
371
|
+
3. Going public later: set `publishConfig.access` to `"public"` (or
|
|
372
|
+
`npm access set status=public @wevo-ai/pulse-mcp`), then add `mcpName` and
|
|
373
|
+
a `server.json` for an MCP Registry listing.
|
|
374
|
+
|
|
375
|
+
The server version reported at MCP `initialize` comes from `package.json`:
|
|
376
|
+
`scripts/build.mjs` injects it with esbuild `define` (unbundled `tsx` runs
|
|
377
|
+
report `0.0.0-dev`).
|
|
378
|
+
|
|
379
|
+
## Tools and workflow
|
|
380
|
+
|
|
381
|
+
Routes below are relative to `/api/public/v1`.
|
|
382
|
+
|
|
383
|
+
| Tools | API | Scope |
|
|
384
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------- | ---------------------------------------- |
|
|
385
|
+
| `login`, `auth_status`, `logout` | Browser sign-in; local credential status; sign out (no `/api` call) | None |
|
|
386
|
+
| `whoami` | `GET /me` | Valid user token |
|
|
387
|
+
| `list_personas`, `get_persona` | `GET /personas`, `GET /personas/{id}` | `personas:read` |
|
|
388
|
+
| `get_persona_research_profile`, `get_persona_personality_profile` | `GET /personas/{id}/research-profile`, `GET /personas/{id}/personality-profile` | `personas:outputs:read` |
|
|
389
|
+
| `create_persona`, `update_persona`, `delete_persona` | `POST /personas`, `PATCH/DELETE /personas/{id}` | `personas:write` |
|
|
390
|
+
| `generate_persona`, `get_persona_generation` | `POST /personas/generations`, `GET /personas/generations/{id}` | write / read |
|
|
391
|
+
| `create_url_asset`, `list_assets`, `get_asset`, `delete_asset` | `POST/GET /assets`, `GET/DELETE /assets/{id}` | `assets:write` / `assets:read` |
|
|
392
|
+
| `list_pulses`, `get_pulse`, `get_pulse_results` | `GET /pulses`, `GET /pulses/{id}`, `GET /pulses/{id}/results` | `pulse:read` |
|
|
393
|
+
| `launch_pulse` | `POST /pulses` | `pulse:write` + Pulse product permission |
|
|
394
|
+
| `launch_compare`, `get_compare`, `get_compare_results` | `POST /compares`, `GET /compares/{id}`, `GET /compares/{id}/results` | write + Compare permission / read |
|
|
395
|
+
|
|
396
|
+
`create_persona` (structured fields) and `generate_persona` (description) both
|
|
397
|
+
return a full generation payload: `generation_id`, overall `status`, optional
|
|
398
|
+
`persona_id`, and states for `core`, `research_profile`, `personality`,
|
|
399
|
+
`demographics`, `image`, and `grounding`. Keep the generation ID. Poll
|
|
400
|
+
`get_persona_generation` no more often than every **10 seconds**, narrating
|
|
401
|
+
component progress to the user. Report completion only when every component is
|
|
402
|
+
`completed` or `skipped`; if any component or overall generation is `failed`,
|
|
403
|
+
name the component and stop. Read research/personality output only after their
|
|
404
|
+
components finish.
|
|
405
|
+
|
|
406
|
+
Flow: `whoami` → select/create and fully complete Persona → `create_url_asset`
|
|
407
|
+
→ poll `get_asset` until `ready` → `launch_pulse` → poll `get_pulse` →
|
|
408
|
+
`get_pulse_results` after `completed` or `partial`. Partial Pulses expose
|
|
409
|
+
successful sections. Stop on failure. Compare 2–6 completed Pulses, then
|
|
410
|
+
retrieve status/results. Tool callers should send an arguments object (`{}` for
|
|
411
|
+
no filters).
|
|
412
|
+
|
|
413
|
+
Generation, Pulse launch, and Compare launch require `idempotency_key`. Use a
|
|
414
|
+
unique key per intended operation; retain it and identical inputs when retrying
|
|
415
|
+
an uncertain response. API retention is 24 hours; failed Persona generations
|
|
416
|
+
can restart with the same key under the API's documented semantics. The server
|
|
417
|
+
never retries writes automatically. Asset/manual Persona creation lack public
|
|
418
|
+
API idempotency: inspect existing resources before repeating uncertain creates.
|
|
419
|
+
Writes can spend credits. Effect annotations do not replace client approval
|
|
420
|
+
or API authorization.
|
|
421
|
+
|
|
422
|
+
Errors set MCP `isError: true`. HTTP failures preserve `{status, body,
|
|
423
|
+
retry_after}`; `body` is the public error envelope, including request ID.
|
|
424
|
+
`401`: invalid/expired token; `login_started` (sign-in opened: finish it at
|
|
425
|
+
`authorize_url`, then retry); `login_port_busy` or `login_unavailable` (see
|
|
426
|
+
[Stored login](#stored-login)). `403`:
|
|
427
|
+
scopes, app registration, membership, or permissions. `402`: insufficient credits. `429`: follow retry guidance when
|
|
428
|
+
provided. Network errors report an unknown outcome without raw transport errors.
|
|
429
|
+
|
|
430
|
+
## Boundaries and hosted migration
|
|
431
|
+
|
|
432
|
+
`public-server.ts` owns tools and turns `login_required` into a background
|
|
433
|
+
sign-in; `public-client.ts` owns HTTP transport and the 401 retry; `src/auth/`
|
|
434
|
+
owns login, the per-process sign-in session (`session.ts`), the credential
|
|
435
|
+
file, and refresh;
|
|
436
|
+
`public-index.ts` dispatches CLI subcommands or connects stdio. Typed requests use
|
|
437
|
+
`createPublicPulseClient` in `@wevo/pulse-api-client`, generated from
|
|
438
|
+
`contracts/openapi-public-v1.json`. Regenerate with `make api-contract`; verify
|
|
439
|
+
with `make api-contract-check`. The broad internal contract remains separate
|
|
440
|
+
because it accepts launch fields absent from public v1.
|
|
441
|
+
|
|
442
|
+
The planned hosted endpoint uses **Streamable HTTP**. Before exposing it,
|
|
443
|
+
implement per-user OAuth authorization code + PKCE, resource metadata,
|
|
444
|
+
audience validation, refresh/revocation, rate limits, and the agreed downstream
|
|
445
|
+
authorization design. Never expose this single-user local credential setup
|
|
446
|
+
through a shared network listener. Credit attribution and launch billing readiness remain
|
|
447
|
+
prerequisites from the design plan. No Auth0, AWS, Terraform, or deployment
|
|
448
|
+
changes are included here.
|
|
449
|
+
|
|
450
|
+
Image upload and SSE-to-MCP progress are deferred. URL
|
|
451
|
+
Assets, full tracked Persona generation, output reads, polling, and public
|
|
452
|
+
results support the local end-to-end workflow.
|
|
453
|
+
|
|
454
|
+
The existing `dist/index.js` and `npm run dev` remain available in the
|
|
455
|
+
monorepo for internal Persona/Audience integrations; see
|
|
456
|
+
[legacy setup](docs/internal-server.md). The published package omits them.
|
|
457
|
+
Use **`dist/public-index.js`**, **`wevo-pulse-public-mcp`**, or **`npm start`** for
|
|
458
|
+
this public API server. It registers no internal Audience/chat tools.
|