@mnemoverse/mcp-memory-server 0.10.2 → 0.12.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 +81 -15
- package/dist/errors.d.ts +90 -7
- package/dist/errors.js +179 -45
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +0 -21
- package/dist/index.js +13 -1474
- package/dist/index.js.map +1 -1
- package/dist/limits.d.ts +68 -0
- package/dist/limits.js +69 -0
- package/dist/limits.js.map +1 -0
- package/dist/names.d.ts +76 -4
- package/dist/names.js +118 -8
- package/dist/names.js.map +1 -1
- package/dist/prompts.d.ts +25 -0
- package/dist/prompts.js +110 -0
- package/dist/prompts.js.map +1 -0
- package/dist/render.d.ts +114 -3
- package/dist/render.js +157 -9
- package/dist/render.js.map +1 -1
- package/dist/requests.d.ts +34 -3
- package/dist/requests.js +12 -3
- package/dist/requests.js.map +1 -1
- package/dist/resources.d.ts +28 -0
- package/dist/resources.js +97 -0
- package/dist/resources.js.map +1 -0
- package/dist/shared.d.ts +52 -0
- package/dist/shared.js +52 -0
- package/dist/shared.js.map +1 -0
- package/dist/time.d.ts +10 -21
- package/dist/time.js +19 -1
- package/dist/time.js.map +1 -1
- package/dist/tools.d.ts +134 -0
- package/dist/tools.js +2437 -0
- package/dist/tools.js.map +1 -0
- package/package.json +24 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Mnemoverse Memory
|
|
2
2
|
|
|
3
|
-
**Persistent memory for AI agents over MCP.** Tell it a recalled memory helped or misled, and it re-ranks what comes back next. One key across Claude Code, Cursor, VS Code and ChatGPT.
|
|
3
|
+
**Persistent memory for AI agents over MCP.** Tell it a recalled memory helped or misled, and it re-ranks what comes back next. Shared rooms let several agents work from one memory. One key or OAuth across Claude Code, Cursor, VS Code and ChatGPT.
|
|
4
4
|
|
|
5
5
|
`@mnemoverse/mcp-memory-server` is the MIT-licensed MCP server for the hosted Mnemoverse memory engine.
|
|
6
6
|
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
|
|
14
14
|
## What is Mnemoverse Memory?
|
|
15
15
|
|
|
16
|
-
Mnemoverse is a hosted memory engine for AI agents, reached over the Model Context Protocol. Mnemoverse stores what your agents learn — decisions, preferences, lessons — and returns it in any connected tool, so one memory follows you across Claude Code, Cursor, VS Code and ChatGPT with
|
|
16
|
+
Mnemoverse is a hosted memory engine for AI agents, reached over the Model Context Protocol. Mnemoverse stores what your agents learn — decisions, preferences, lessons — and returns it in any connected tool, so one memory follows you across Claude Code, Cursor, VS Code and ChatGPT with one account: an API key in a local config, or an OAuth sign-in on the hosted endpoint. Mnemoverse re-ranks recall from outcomes: report that a recalled memory helped and a Rescorla-Wagner update on the prediction error raises it, report that it misled and it sinks — a different mechanism from similarity scoring, usable alongside it.
|
|
17
17
|
|
|
18
|
-
**What is open source here, and what is not.** This repository, the MCP server, is MIT, and so is the Python SDK. The memory engine they talk to is a hosted service with a free tier
|
|
18
|
+
**What is open source here, and what is not.** This repository, the MCP server, is MIT, and so is the Python SDK. The memory engine they talk to is a hosted service with a free tier. Self-hosting the engine is available on Enterprise plans by agreement, when security or compliance requirements call for it; by default we run it for you.
|
|
19
19
|
|
|
20
20
|
## How it compares
|
|
21
21
|
|
|
22
|
-
Most agent memory today lives in one of three places. Per-tool instruction files — `CLAUDE.md`, `.cursorrules`, `AGENTS.md` — are versioned and readable, but each copy belongs to one repo and one tool, and nothing follows you to the next window. A vector store behind RAG retrieves by similarity, and similarity never changes because advice helped or misled. Local-first memory servers win on privacy and latency, and ask you to run and update the infrastructure yourself. Mnemoverse is the managed, cross-tool option in that landscape: nothing to deploy, one
|
|
22
|
+
Most agent memory today lives in one of three places. Per-tool instruction files — `CLAUDE.md`, `.cursorrules`, `AGENTS.md` — are versioned and readable, but each copy belongs to one repo and one tool, and nothing follows you to the next window. A vector store behind RAG retrieves by similarity, and similarity never changes because advice helped or misled. Local-first memory servers win on privacy and latency, and ask you to run and update the infrastructure yourself. Mnemoverse is the managed, cross-tool option in that landscape: nothing to deploy, one account everywhere, and ranking that moves with reported outcomes. If you need memory inside your own perimeter, a local-first server is the better choice; this one is hosted by default, with Enterprise self-hosting by agreement.
|
|
23
23
|
|
|
24
24
|
The consolidation stage of the engine — HDBSCAN clustering with Von Restorff protection, so distinctive memories are not absorbed into the average — is designed in and currently switched off on the hosted service; our docs say so rather than hide it.
|
|
25
25
|
|
|
@@ -27,9 +27,26 @@ The consolidation stage of the engine — HDBSCAN clustering with Von Restorff p
|
|
|
27
27
|
|
|
28
28
|
## Quick Start
|
|
29
29
|
|
|
30
|
+
### No key: the hosted endpoint
|
|
31
|
+
|
|
32
|
+
If your client signs in over OAuth, you do not need a key at all. Create a free account at [console.mnemoverse.com](https://console.mnemoverse.com/sign-up?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server) (no credit card), then connect the hosted endpoint.
|
|
33
|
+
|
|
34
|
+
Claude Code:
|
|
35
|
+
```bash
|
|
36
|
+
claude mcp add -s user --transport http mnemoverse https://mcp.mnemoverse.com/mcp
|
|
37
|
+
```
|
|
38
|
+
Then run `/mcp` in a session, select `mnemoverse` and choose **Authenticate**.
|
|
39
|
+
|
|
40
|
+
Cursor, in `.cursor/mcp.json`:
|
|
41
|
+
```json
|
|
42
|
+
{ "mcpServers": { "mnemoverse": { "url": "https://mcp.mnemoverse.com/mcp" } } }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Claude Desktop, Windsurf, VS Code and ChatGPT: [Remote MCP setup](https://mnemoverse.com/docs/api/remote-mcp-server). The local server below is the other path: it runs on your machine and reads an API key.
|
|
46
|
+
|
|
30
47
|
### 1. Get a free API key
|
|
31
48
|
|
|
32
|
-
Sign up at [console.mnemoverse.com](https://console.mnemoverse.com?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server) — takes 30 seconds, no credit card.
|
|
49
|
+
Sign up at [console.mnemoverse.com](https://console.mnemoverse.com/sign-up?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server) — takes 30 seconds, no credit card.
|
|
33
50
|
|
|
34
51
|
**Check the key before you put it in a config.** Both forms ask for the key at a masked prompt and never pass it as a command argument, so it lands neither in your shell history nor in the process list.
|
|
35
52
|
|
|
@@ -82,7 +99,7 @@ claude mcp add mnemoverse -s user -e MNEMOVERSE_API_KEY=mk_live_YOUR_KEY -e MNEM
|
|
|
82
99
|
|
|
83
100
|
[](https://cursor.com/en/install-mcp?name=mnemoverse&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBtbmVtb3ZlcnNlL21jcC1tZW1vcnktc2VydmVyQGxhdGVzdCJdLCJlbnYiOnsiTU5FTU9WRVJTRV9BUElfS0VZIjoibWtfbGl2ZV9ZT1VSX0tFWSIsIk1ORU1PVkVSU0VfQVBJX1VSTCI6Imh0dHBzOi8vY29yZS5tbmVtb3ZlcnNlLmNvbS9hcGkvdjEifX0%3D)
|
|
84
101
|
|
|
85
|
-
The install button carries the placeholder key `mk_live_YOUR_KEY`, not yours, so the shortest path is to skip the button: add the JSON below to `~/.cursor/mcp.json`, merging it with any servers already there, and put your own key in place. Get one at [console.mnemoverse.com](https://console.mnemoverse.com?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server). If you did click the button, edit the same key in the `mcp.json` it wrote; Cursor keeps MCP environment values in that file, not in a settings form. Until the key is real the server starts and lists its tools, but every tool call is refused.
|
|
102
|
+
The install button carries the placeholder key `mk_live_YOUR_KEY`, not yours, so the shortest path is to skip the button: add the JSON below to `~/.cursor/mcp.json`, merging it with any servers already there, and put your own key in place. Get one at [console.mnemoverse.com](https://console.mnemoverse.com/sign-up?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server). If you did click the button, edit the same key in the `mcp.json` it wrote; Cursor keeps MCP environment values in that file, not in a settings form. Until the key is real the server starts and lists its tools, but every tool call is refused.
|
|
86
103
|
|
|
87
104
|
```json
|
|
88
105
|
{
|
|
@@ -272,11 +289,25 @@ If it doesn't remember: check that the client was fully restarted and the config
|
|
|
272
289
|
| `memory_feedback` | Rate memories as helpful or not (improves future recall) |
|
|
273
290
|
| `memory_stats` | Check how many memories stored, which domains exist |
|
|
274
291
|
| `memory_create_room` | Create a shared memory room; its address works as a `domain` on write/read |
|
|
275
|
-
| `memory_invite_to_room` | Mint
|
|
292
|
+
| `memory_invite_to_room` | Mint an invite (code + link) for a room you own; single-use unless `max_uses` allows more |
|
|
276
293
|
| `memory_join_room` | Join a shared room with an invite code (`mnvr_...`) |
|
|
277
294
|
| `memory_list_rooms` | List rooms you own or joined, with each room's address to use as `domain` |
|
|
278
295
|
| `vault_list` | List Vault secrets by alias and purpose — the secret value is never returned |
|
|
279
296
|
|
|
297
|
+
### Prompts
|
|
298
|
+
|
|
299
|
+
Three named shortcuts for clients that show MCP prompts as commands (Claude Code as `/mcp__mnemoverse__<name>`). Each one only asks the model to use the tools above; none of them calls the API itself.
|
|
300
|
+
|
|
301
|
+
| Prompt | Arguments | What it asks for |
|
|
302
|
+
|------|------|-------------|
|
|
303
|
+
| `recall` | `topic` | Search memory for a topic with `memory_read` and summarize only what comes back |
|
|
304
|
+
| `save_insight` | `insight`, optional `domain` | Store an insight with `memory_write` and confirm what was stored |
|
|
305
|
+
| `what_do_you_know` | `subject` | A briefing from `memory_read` that flags what is not stored |
|
|
306
|
+
|
|
307
|
+
### Resources
|
|
308
|
+
|
|
309
|
+
`memory://item/{memory_id}` opens one saved memory by its id (the `id:` line of a `memory_read` result) for clients that attach MCP resources. It returns the memory's `memory_id`, `content` and `domain` as JSON. It reads your own store only: a memory read from a shared room cannot be opened by id.
|
|
310
|
+
|
|
280
311
|
### Tool surface stability
|
|
281
312
|
|
|
282
313
|
`tools/list` is frozen per released version, so a client can save the list it
|
|
@@ -288,21 +319,56 @@ saw and diff it against what the server serves today, by version.
|
|
|
288
319
|
and what a tool returns, as the CHANGELOG rules state.
|
|
289
320
|
- **Within a MINOR** (x.Y.0): tools and annotation fields may be added, never
|
|
290
321
|
removed or renamed, and no declared annotation field disappears or flips
|
|
291
|
-
silently. Every addition has a line in the CHANGELOG under that version.
|
|
292
|
-
|
|
293
|
-
|
|
322
|
+
silently. Every addition has a line in the CHANGELOG under that version. A
|
|
323
|
+
MINOR may also add an output schema (`outputSchema`, with
|
|
324
|
+
`structuredContent` returned alongside the same text) to a tool that did
|
|
325
|
+
not have one; once declared, that schema's fields are add-only under this
|
|
326
|
+
same rule. Where this server's output schema deliberately differs from the
|
|
327
|
+
hosted connector's, the CHANGELOG entry says so; today that is
|
|
328
|
+
`memory_id` in every output schema, a plain string here and a
|
|
329
|
+
GUID-validated string there (this package's ids are opaque);
|
|
330
|
+
`memory_list_recent`'s `next_cursor`, optional here (absent when the
|
|
331
|
+
service sent a continuation token this client will not pass on) and
|
|
332
|
+
required there; `memory_stats`, which carries five optional fields
|
|
333
|
+
(`episodes`, `prototypes`, `hebbian_edges`, `avg_valence`,
|
|
334
|
+
`avg_importance`) the connector's schema does not declare; the room
|
|
335
|
+
tools (`memory_create_room`, `memory_invite_to_room`, `memory_join_room`,
|
|
336
|
+
`memory_list_rooms`), where several fields the connector marks required
|
|
337
|
+
are optional here (`name`, `scope`, `already_member`, and the invite's
|
|
338
|
+
`code`, `scope`, `room_address` and `expires_at`), because a value core
|
|
339
|
+
did not send is an honest outcome here rather than a placeholder; and
|
|
340
|
+
`memory_list_rooms` and `vault_list`, which drop a row with no usable
|
|
341
|
+
identity (`room_id`, `address`, `role`; `alias`, `context`) from the data,
|
|
342
|
+
reported once on stderr, instead of emitting empty strings into required
|
|
343
|
+
fields.
|
|
344
|
+
- **Removing or renaming a tool or a tool's input parameter, or dropping or
|
|
345
|
+
renaming a declared annotation field,** is announced one MINOR ahead: the
|
|
346
|
+
tool (or parameter) stays, its description says
|
|
294
347
|
`deprecated since x.y, removed in x.z`, and the change lands only in the
|
|
295
|
-
announced version, with its CHANGELOG line. A
|
|
348
|
+
announced version, with its CHANGELOG line. A renamed parameter is accepted
|
|
349
|
+
under both names until then (0.11: `memory_feedback`'s `atom_ids` became
|
|
350
|
+
`memory_ids`; its removal, first announced for 0.12, lands in 0.13, since
|
|
351
|
+
0.12 shipped sooner than that announcement assumed). A rename is announced by naming
|
|
296
352
|
both the old and the new name; the version pair alone does not say what a
|
|
297
353
|
client should look for. Because a MINOR may add a field but not remove one, a
|
|
298
354
|
renamed annotation field is declared under both names until the announced
|
|
299
355
|
version.
|
|
300
356
|
- Any difference between two servers of the same version is a bug. Report it
|
|
301
|
-
with both `tools/list` outputs.
|
|
357
|
+
with both `tools/list` outputs. One exception, by configuration: a server
|
|
358
|
+
built on the `/shared` entry point may ask for its own noun in the three
|
|
359
|
+
descriptions that name the server (`wording.serverNoun`, below), which
|
|
360
|
+
changes those three description strings and nothing else; tool names,
|
|
361
|
+
input and output schemas and annotations never vary by configuration.
|
|
302
362
|
|
|
303
|
-
The list above is the 0.
|
|
363
|
+
The list above is the 0.12 surface: ten tools, each declaring all four hints.
|
|
304
364
|
The hosted connector at `mcp.mnemoverse.com/mcp` serves the same ten.
|
|
305
365
|
|
|
366
|
+
**If the hosted connector stops answering in a session.** A client can keep showing the connector as connected while every call in that session fails with "not connected". Reconnecting it on claude.ai does not revive a session that is already stuck; reconnect from inside the session instead (in Claude Code, `/mcp`, then sign in again). Meanwhile this local server, set up with an API key from the same account as in the Quick Start, reaches the same memory and does not depend on that session's sign-in.
|
|
367
|
+
|
|
368
|
+
### Building a second MCP server on this package
|
|
369
|
+
|
|
370
|
+
`@mnemoverse/mcp-memory-server/shared` is the entry point another server registers these same tools from, instead of keeping its own copy (ADR-025, mnemoverse-core). It exports `registerMemoryTools`/`registerMemoryPrompts`/`registerMemoryResources`, the three typed error classes (`ApiError`, `NetworkError`, `UnreadableBodyError`), `MAX_RESULT_CHARS`/`capResult`, and two optional dependencies a hosted deployment injects to speak in its own voice: `wording` (its own server noun and error vocabulary, including an OAuth mode under which no 401 or 403 explanation names an API key) and `writeAuthor` (vouching for the end user behind a write). See [`docs/shared.md`](./docs/shared.md) for the full contract.
|
|
371
|
+
|
|
306
372
|
## Use cases
|
|
307
373
|
|
|
308
374
|
The pattern that pays off first is cross-tool continuity: a decision made while pairing in Claude Code is there when you open Cursor an hour later, and the preference you stated in VS Code holds in a ChatGPT session that evening. Teams use shared rooms the same way — one place where an agent's lessons about a codebase accumulate instead of being re-taught per seat. And because recall re-ranks from feedback, the memories that keep proving useful surface first, which matters once a store grows past what anyone curates by hand.
|
|
@@ -348,7 +414,7 @@ The retrieval model is published: [arXiv:2603.08965](https://arxiv.org/abs/2603.
|
|
|
348
414
|
- [Cursor](https://mnemoverse.com/docs/api/cursor) · [VS Code](https://mnemoverse.com/docs/api/vs-code) · [Claude Code](https://mnemoverse.com/docs/api/claude) · [ChatGPT](https://mnemoverse.com/docs/api/chatgpt)
|
|
349
415
|
- [Python SDK](https://mnemoverse.com/docs/api/python-sdk)
|
|
350
416
|
- [API Reference](https://mnemoverse.com/docs/api/reference)
|
|
351
|
-
- [Console (get API key)](https://console.mnemoverse.com?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server)
|
|
417
|
+
- [Console (get API key)](https://console.mnemoverse.com/sign-up?utm_source=npm&utm_medium=readme&utm_campaign=mcp-memory-server)
|
|
352
418
|
|
|
353
419
|
**Background reading**
|
|
354
420
|
|
|
@@ -395,7 +461,7 @@ What each tool sends:
|
|
|
395
461
|
| `memory_write` | the `content`, `concepts`, and `domain` you pass |
|
|
396
462
|
| `memory_read` | the `query`, plus any filters: `domain`, `since`/`until`, `exclude_author`, `top_k`, `order_by` |
|
|
397
463
|
| `memory_list_recent` | the feed filters: `domain`, `since`/`until`, `exclude_author`, `limit`, `cursor` |
|
|
398
|
-
| `memory_feedback` | the `
|
|
464
|
+
| `memory_feedback` | the `memory_ids` being rated (sent to the API as `atom_ids`), the `outcome` score, and the `domain` when you pass one (a shared room's address) |
|
|
399
465
|
| `memory_create_room` | the room `name` and `description` |
|
|
400
466
|
| `memory_invite_to_room` | the `room_id`, invite `scope`, and expiry |
|
|
401
467
|
| `memory_join_room` | the invite `code` |
|
package/dist/errors.d.ts
CHANGED
|
@@ -76,6 +76,41 @@
|
|
|
76
76
|
* outright, see `validatedKeysUrl` below, but this constant stays the
|
|
77
77
|
* fallback for both). */
|
|
78
78
|
export declare const KEYS_URL = "https://console.mnemoverse.com/dashboard/keys";
|
|
79
|
+
/**
|
|
80
|
+
* How a server that registers these tools wants its failures worded (STEP4-2,
|
|
81
|
+
* STEP4-3, owner decisions 2026-09-24). Every field is optional, and every
|
|
82
|
+
* field's absence means exactly what this file already does today: the
|
|
83
|
+
* whole point is that a consumer supplying no `wording` at all gets
|
|
84
|
+
* byte-identical text to before this type existed.
|
|
85
|
+
*
|
|
86
|
+
* - `serverNoun`: what the three tool descriptions that name themselves
|
|
87
|
+
* call this deployment ("this server" vs "this connector"). Read by
|
|
88
|
+
* src/tools.ts at registration time; ignored by this module.
|
|
89
|
+
* - `auth`: which credential the CALLER holds, not which one core issued.
|
|
90
|
+
* "api-key" (default) keeps every existing MNEMOVERSE_API_KEY-flavoured
|
|
91
|
+
* sentence. "oauth" is for a server whose user never sees an API key at
|
|
92
|
+
* all (a hosted connector minting a key on their behalf): no 401/403
|
|
93
|
+
* explanation under this mode names MNEMOVERSE_API_KEY, an env var, an
|
|
94
|
+
* MCP config file, or the keys console; each says what an OAuth user can
|
|
95
|
+
* actually do instead (reconnect, sign in again, check the plan, wait
|
|
96
|
+
* for the retry window).
|
|
97
|
+
* - `keysUrl`: replaces {@link KEYS_URL} wherever the api-key vocabulary
|
|
98
|
+
* prints a console URL, for a deployment whose key-management page is
|
|
99
|
+
* not console.mnemoverse.com. Has no effect under `auth: "oauth"`, which
|
|
100
|
+
* prints no console URL at all.
|
|
101
|
+
* - `rawDetail`: whether the wire body's raw tail (STEP4-3; e.g. `Raw
|
|
102
|
+
* detail — Mnemoverse API error 401 on …`) is appended after the
|
|
103
|
+
* guidance. Defaults to `true`, unchanged from every release before this
|
|
104
|
+
* one. Held in reserve for a deployment whose core-side error envelopes
|
|
105
|
+
* are found to echo request content back in `details`: set to `false`
|
|
106
|
+
* only once that check finds something to hide.
|
|
107
|
+
*/
|
|
108
|
+
export interface Wording {
|
|
109
|
+
serverNoun?: "this server" | "this connector";
|
|
110
|
+
auth?: "api-key" | "oauth";
|
|
111
|
+
keysUrl?: string;
|
|
112
|
+
rawDetail?: boolean;
|
|
113
|
+
}
|
|
79
114
|
/** Everything known about one failed call, at the moment it failed. */
|
|
80
115
|
export interface ApiFailure {
|
|
81
116
|
/** HTTP status. */
|
|
@@ -146,12 +181,16 @@ export declare function parseErrorEnvelope(body: string): ErrorEnvelope;
|
|
|
146
181
|
export declare function retryAfterSeconds(header: string | null | undefined): number | undefined;
|
|
147
182
|
/**
|
|
148
183
|
* The agent-facing explanation for one failed call, with the raw body kept
|
|
149
|
-
* after it.
|
|
184
|
+
* after it (unless `wording.rawDetail === false`, STEP4-3).
|
|
150
185
|
*
|
|
151
186
|
* Total by construction: every status reaches a sentence, and the fallback says
|
|
152
187
|
* that it has no specific guidance instead of inventing some.
|
|
188
|
+
*
|
|
189
|
+
* `wording` (STEP4-2/3, owner 2026-09-24) is optional and, absent, resolves
|
|
190
|
+
* to exactly today's behaviour: every call site before this release passes
|
|
191
|
+
* none, so every existing pin stays byte-identical.
|
|
153
192
|
*/
|
|
154
|
-
export declare function explainApiFailure(f: ApiFailure): string;
|
|
193
|
+
export declare function explainApiFailure(f: ApiFailure, wording?: Wording): string;
|
|
155
194
|
/**
|
|
156
195
|
* The request never got an answer at all: DNS, connectivity, a host that does
|
|
157
196
|
* not listen, or this client's own probe deadline firing.
|
|
@@ -172,7 +211,7 @@ export declare function explainApiFailure(f: ApiFailure): string;
|
|
|
172
211
|
* that case now. Every sentence below asserts that nothing answered, so it may
|
|
173
212
|
* only be reached when nothing did.
|
|
174
213
|
*/
|
|
175
|
-
export declare function explainNetworkFailure(method: string, path: string, cause: unknown): string;
|
|
214
|
+
export declare function explainNetworkFailure(method: string, path: string, cause: unknown, wording?: Wording): string;
|
|
176
215
|
/** A 2xx-or-not response whose BODY this client could not turn into the JSON
|
|
177
216
|
* this API speaks. The status is known — a reply arrived — which is the whole
|
|
178
217
|
* difference between this and {@link ApiFailure} or a transport failure. */
|
|
@@ -212,7 +251,7 @@ export interface UnreadableBody {
|
|
|
212
251
|
* say whether the operation ran, because a body it cannot read is no evidence
|
|
213
252
|
* either way. That last clause matters most for a write.
|
|
214
253
|
*/
|
|
215
|
-
export declare function explainUnreadableBody(f: UnreadableBody): string;
|
|
254
|
+
export declare function explainUnreadableBody(f: UnreadableBody, wording?: Wording): string;
|
|
216
255
|
/**
|
|
217
256
|
* {@link explainUnreadableBody} as an error, so a caller can tell "a reply
|
|
218
257
|
* arrived and was unreadable" from "no reply arrived" by TYPE rather than by
|
|
@@ -222,14 +261,25 @@ export declare class UnreadableBodyError extends Error {
|
|
|
222
261
|
readonly status: number;
|
|
223
262
|
readonly method: string;
|
|
224
263
|
readonly path: string;
|
|
225
|
-
|
|
264
|
+
/** The bytes that failed to parse, when they were read at all. Kept so
|
|
265
|
+
* {@link withWording} re-renders the same arm of the explanation. */
|
|
266
|
+
readonly bodyPreview: string | undefined;
|
|
267
|
+
/** `wording` (STEP4-2/3): optional, and absent (every call site before this
|
|
268
|
+
* release) reproduces today's message exactly: see {@link explainUnreadableBody}. */
|
|
269
|
+
constructor(f: UnreadableBody, wording?: Wording);
|
|
270
|
+
/** The same failure, explained under `wording`: see {@link ApiError.withWording}. */
|
|
271
|
+
withWording(wording: Wording | undefined): UnreadableBodyError;
|
|
226
272
|
}
|
|
227
273
|
/** {@link explainNetworkFailure} as an error, so `instanceof` can tell a
|
|
228
274
|
* transport failure from an HTTP one without reading either message. */
|
|
229
275
|
export declare class NetworkError extends Error {
|
|
230
276
|
readonly method: string;
|
|
231
277
|
readonly path: string;
|
|
232
|
-
|
|
278
|
+
/** `wording` (STEP4-2/3): optional, and absent (every call site before this
|
|
279
|
+
* release) reproduces today's message exactly: see {@link explainNetworkFailure}. */
|
|
280
|
+
constructor(method: string, path: string, cause: unknown, wording?: Wording);
|
|
281
|
+
/** The same failure, explained under `wording`: see {@link ApiError.withWording}. */
|
|
282
|
+
withWording(wording: Wording | undefined): NetworkError;
|
|
233
283
|
}
|
|
234
284
|
/**
|
|
235
285
|
* A failed API call, as an ERROR OBJECT rather than a parsed string.
|
|
@@ -249,7 +299,22 @@ export declare class ApiError extends Error {
|
|
|
249
299
|
readonly path: string;
|
|
250
300
|
/** The engine's envelope, already parsed — so a caller never re-parses. */
|
|
251
301
|
readonly envelope: ErrorEnvelope;
|
|
252
|
-
|
|
302
|
+
/** The `Retry-After` header as it arrived, when the response carried one.
|
|
303
|
+
* Kept so {@link withWording} re-renders a 429 with its retry sentence. */
|
|
304
|
+
readonly retryAfter: string | null | undefined;
|
|
305
|
+
/** `wording` (STEP4-2/3): optional, and absent (every call site before this
|
|
306
|
+
* release) reproduces today's message exactly: see {@link explainApiFailure}. */
|
|
307
|
+
constructor(f: ApiFailure, wording?: Wording);
|
|
308
|
+
/**
|
|
309
|
+
* The same failure, explained under `wording`: a new instance of this
|
|
310
|
+
* class whose message is what the constructor would have produced with
|
|
311
|
+
* that `wording`, every field and {@link isBare404} unchanged. The message
|
|
312
|
+
* is a pure function of the failure and the wording, so re-rendering an
|
|
313
|
+
* instance under the wording it was built with gives the same text back.
|
|
314
|
+
* This is how `MemoryToolDeps.wording` reaches an error the consumer's
|
|
315
|
+
* `apiFetch` built without it: see {@link rewordFailure}.
|
|
316
|
+
*/
|
|
317
|
+
withWording(wording: Wording | undefined): ApiError;
|
|
253
318
|
/**
|
|
254
319
|
* A 404 the ENGINE did not answer: silence, or the router's literal
|
|
255
320
|
* defaults. This is what a path the deployment does not serve looks like
|
|
@@ -269,3 +334,21 @@ export declare class ApiError extends Error {
|
|
|
269
334
|
*/
|
|
270
335
|
get isBare404(): boolean;
|
|
271
336
|
}
|
|
337
|
+
/**
|
|
338
|
+
* Re-explain one of this module's three errors under `wording`; hand
|
|
339
|
+
* anything else back untouched.
|
|
340
|
+
*
|
|
341
|
+
* This is how `MemoryToolDeps.wording` reaches the error text (STEP4-2): a
|
|
342
|
+
* consumer's `apiFetch` constructs `ApiError`, `NetworkError` and
|
|
343
|
+
* `UnreadableBodyError` however it likes, and `registerMemoryTools` passes
|
|
344
|
+
* every rejection through here with the `wording` it was given, so the
|
|
345
|
+
* consumer states its wording once, on `deps`, and the constructors need no
|
|
346
|
+
* second copy. Re-rendering is idempotent (see {@link ApiError.withWording}),
|
|
347
|
+
* so an `apiFetch` that does pass the same `wording` to the constructors
|
|
348
|
+
* gets the same text either way; one that passed a different wording gets
|
|
349
|
+
* `deps.wording`, the one source of truth for this registration. A
|
|
350
|
+
* rejection that is none of the three classes (a plain `Error`, an
|
|
351
|
+
* `McpError`) is returned as is: it carries no wording to apply, and its
|
|
352
|
+
* identity may matter to whoever threw it.
|
|
353
|
+
*/
|
|
354
|
+
export declare function rewordFailure(e: unknown, wording: Wording | undefined): unknown;
|