wontopos-mcp 1.0.25 → 1.0.27
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 +43 -63
- package/index.mjs +1073 -191
- package/npm-shrinkwrap.json +1220 -0
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -6,11 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
[Wontopos (WOS)](https://wontopos.com) long-term memory as an [MCP](https://modelcontextprotocol.io) server.
|
|
8
8
|
|
|
9
|
-
Memory belongs to your **
|
|
9
|
+
Memory belongs to your **workspace**, not to a tool. The same store recalls in
|
|
10
10
|
Claude Code, Claude Desktop, Cursor — and in ChatGPT via Actions with the same
|
|
11
11
|
API ([openapi.json](https://api.wontopos.com/openapi.json)) — so a conversation
|
|
12
12
|
started in one tool continues in another. The same recall in every language - no language
|
|
13
|
-
is privileged - with bounded context
|
|
13
|
+
is privileged - with bounded context per recall: the recent turns, at most 20 memories and at most
|
|
14
|
+
20 rows of the surrounding conversation.
|
|
14
15
|
|
|
15
16
|
## Claude Code
|
|
16
17
|
|
|
@@ -50,12 +51,13 @@ The id must also match `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`. An id outside that (an
|
|
|
50
51
|
in a non-Latin script, an email address) cannot be used at all: creating it answers 400 and every
|
|
51
52
|
other call 404s. Romanize it, or key the store on an internal id.
|
|
52
53
|
|
|
53
|
-
Create a key in the [console](https://wontopos.com).
|
|
54
|
+
Create a key in the [console](https://wontopos.com). The server needs a standard API key:
|
|
55
|
+
with an admin key (`wos-admin-...`) it exits at startup. Optional env:
|
|
54
56
|
|
|
55
57
|
| Variable | What it sets |
|
|
56
58
|
|---|---|
|
|
57
59
|
| `WONTOPOS_USER_ID` | The store every tool call uses. Default `"default"`. |
|
|
58
|
-
| `WONTOPOS_MODEL` | The engine. Default `tablet-2` — same token price as `tablet-1` and the one that can serve photos and re-ask. Also `tablet-1`, `scroll-1`, `scroll-1.2`. |
|
|
60
|
+
| `WONTOPOS_MODEL` | The engine. Default `tablet-2` — same token price as `tablet-1` and the one that can serve photos and re-ask. Also `tablet-1`, `scroll-1`, `scroll-1.2`, `scroll-2`. |
|
|
59
61
|
| `WONTOPOS_VERIFY` | Default re-ask passes for `search`, 0-3. Default `0`. Each pass is another engine call, billed for what it delivers; the agent can raise it per call. |
|
|
60
62
|
| `WONTOPOS_MAX_IMAGES` | Default photo results per `search`, 0-5. Default `0` — see below. |
|
|
61
63
|
| `WONTOPOS_BASE_URL` | A different API host. Leave unset for the default. |
|
|
@@ -66,6 +68,10 @@ Create a key in the [console](https://wontopos.com). Optional env:
|
|
|
66
68
|
| `WONTOPOS_HTTP_ALLOWED_HOSTS` | Comma-separated `Host` values to accept in HTTP mode. A tunnel forwards its own name, and an undeclared one is refused 403. |
|
|
67
69
|
| `WONTOPOS_READ_ONLY` | `1` / `true` / `yes` / `on` / `y` / `t` = read tools only, see Security. A value that is none of those (and none of `0` / `false` / `no` / `off` / `n` / `f`) stops the server rather than being read as off. |
|
|
68
70
|
| `WONTOPOS_ALLOW_STORE_OVERRIDE` | `1` (same spellings) = multi-store; default = pinned, see Security. |
|
|
71
|
+
| `WONTOPOS_MEMORY_SLEEP` | `1` (same spellings) = `think_back` begins with what the store's last sleep wrote: a note on how to read it, the core, and the names of the four boxes with when each last changed, read from the store each time it opens. Adds `open_box`, which opens a box by its number or name. A sleep itself runs on your own model through the SDK (`sleep`), not in this server. Default off. Comes with the working-memory tools (`scroll-2`). |
|
|
72
|
+
| `WONTOPOS_MEMORY_SEEN` | `1` (same spellings) = adds `memory_recent`, the recent conversation newest first with how many memories you held for each reply, and `memory_seen`, those memories for one line as they stand now. Default off. Comes with the working-memory tools (`scroll-2`). |
|
|
73
|
+
|
|
74
|
+
The working-memory, store-setup and router switches are listed by `npx -y wontopos-mcp --help`.
|
|
69
75
|
|
|
70
76
|
**Why photos default to none.** Not because the model cannot see them - `view_image`
|
|
71
77
|
hands over the actual picture - but because the rows ride on *every* search, and most
|
|
@@ -117,20 +123,25 @@ quietly ignored, and that refusal would otherwise land on every search.
|
|
|
117
123
|
|
|
118
124
|
| Tool | What the agent does with it |
|
|
119
125
|
|---|---|
|
|
120
|
-
| `recall` | One-call context: the **last 20 turns** (oldest first, one entry per utterance, so ten exchanges) plus relevant long-term memories and surroundings. First call when past context matters. `limit` (5-20) widens the sweep; `context_limit` (0-20) sets how much surrounding conversation rides along, `0` for the memories alone.
|
|
121
|
-
| `remember` | Store what the user said that is worth keeping. `speaker: "me"` = the agent's own spoken commitments. Fetched content (search results, files) is not a memory. |
|
|
126
|
+
| `recall` | One-call context: the **last 20 turns** (oldest first, one entry per utterance, so ten exchanges) plus relevant long-term memories and surroundings. First call when past context matters. `limit` (5-20) widens the sweep; `context_limit` (0-20) sets how much surrounding conversation rides along, `0` for the memories alone. |
|
|
127
|
+
| `remember` | Store what the user said that is worth keeping. `speaker: "me"` = the agent's own spoken commitments; a registered speaker's name = what that person said. Fetched content (search results, files) is not a memory. |
|
|
122
128
|
| `store_turn` | Record one exchange as short-term history - what the user said and what the agent replied. This is what fills `recall`'s 20-turn window — one call appends two entries — and nothing else writes it, so the agent is told to call it after **each** exchange. A turn is billed like any write and is kept long-term as well, searchable afterwards. |
|
|
123
129
|
| `search` | Search stored memories. `filters` narrows by TIME or topic (`event_from`/`event_to` = when the content happened, `categories`) — for "what did we decide in June?", which a query alone will not pin down. `verify` (0-3) spends extra passes to reach further back; `max_images` (0-5) asks for photos. Answers with `memories`, plus `self_memories` (the assistant's own words, which `filters` do not narrow), `images` and `verify_used` when those applied. |
|
|
124
130
|
| `update` | Rewrite a memory the user's own words contradicted - keeps what is still true, adds what changed. |
|
|
125
131
|
| `forget` | Delete one memory by id. |
|
|
126
132
|
| `list_memories` | Browse everything stored (original text + metadata, paged) - "what do you know about me?", housekeeping. |
|
|
127
|
-
| `engram` | Multi-hop retrieval
|
|
133
|
+
| `engram` | Multi-hop retrieval: `deep_recall` (thorough), `timeline` (when did X), `gather` (everything related), `equilibrium` (replies that have started to loop or flatten), `tone_stabilizer` (back to the assistant's usual register). The API is the authority - an unknown name answers with the list it accepts. |
|
|
128
134
|
| `view_image` | Fetch the actual picture behind an image memory, as an image the model can look at rather than a caption it can only paraphrase. One photo per call. |
|
|
129
135
|
| `usage` | What this key has spent and what is left — its lifetime cost, its workspace and per-store cost over the last `days` days, and the account's prepaid balance. Free to call. Lets an agent decide whether to keep going. |
|
|
130
136
|
| `stats` | Counts for a store. Not the number of things a person told you, so it is a cheap check rather than an answer to "how much do you remember about me?" - `list_memories` answers that. |
|
|
131
137
|
| `revisions` | How much of the store has been changed since it was written: counts by default, up to 20 memories on request. |
|
|
132
138
|
| `create_store` | Creates the pinned store after asking the user (any store with `ALLOW_STORE_OVERRIDE=1`). |
|
|
133
139
|
|
|
140
|
+
On Scroll 2 the working-memory tools join them: `think_back`, `think_further`,
|
|
141
|
+
`look_around`, `search_again`, `done_thinking`, `user_answered`, `why`, `settings`,
|
|
142
|
+
`update_settings`, and with their switches `timeline`, `look_at_photo`, `open_box`,
|
|
143
|
+
`memory_recent`, `memory_seen`. Each describes itself in `tools/list`.
|
|
144
|
+
|
|
134
145
|
## Running it over HTTP yourself
|
|
135
146
|
|
|
136
147
|
Some hosts reach a URL rather than spawning a command. The same server answers over
|
|
@@ -147,7 +158,7 @@ WONTOPOS_HTTP_TOKEN="$TOKEN" \
|
|
|
147
158
|
npx -y wontopos-mcp
|
|
148
159
|
```
|
|
149
160
|
|
|
150
|
-
Same
|
|
161
|
+
Same store, same 20-turn window. Callers send
|
|
151
162
|
`Authorization: Bearer <token>`.
|
|
152
163
|
|
|
153
164
|
It binds `127.0.0.1` unless `WONTOPOS_HTTP_HOST` says otherwise, and **will not start without a token**: the reason to run this mode
|
|
@@ -190,17 +201,10 @@ connect to the hosted endpoint instead. Same memory, same stores, same account:
|
|
|
190
201
|
by the model — the tools take no store argument, so a prompt-injected model cannot move
|
|
191
202
|
to a sibling store.
|
|
192
203
|
|
|
193
|
-
It offers six of the
|
|
194
|
-
`stats` · `engram` — the retrieval core plus one write.
|
|
195
|
-
`create_store`, `revisions`, `store_turn`, `view_image` and `usage` are local-only. This list
|
|
196
|
-
has been wrong twice: it once accounted for nine tools with `revisions` in neither
|
|
197
|
-
column, and then named `revisions` as hosted when the endpoint has never served it.
|
|
204
|
+
It offers six of the tools above: `recall` · `search` · `remember` · `list_memories` ·
|
|
205
|
+
`stats` · `engram` — the retrieval core plus one write. Every other tool is local-only.
|
|
198
206
|
Six is what the endpoint answers `tools/list` with today.
|
|
199
207
|
|
|
200
|
-
The endpoint is a protocol adapter, not a second way in: every tool call re-enters the
|
|
201
|
-
ordinary `/api/v1/memory` routes carrying your key, so the same authentication, rate
|
|
202
|
-
limits, billing gates and tenant isolation apply — the same code, not a copy of it.
|
|
203
|
-
|
|
204
208
|
## One memory, many tools
|
|
205
209
|
|
|
206
210
|
Same `WONTOPOS_API_KEY` + same store id ⇒ the memory follows you:
|
|
@@ -225,6 +229,13 @@ advertise different limits.
|
|
|
225
229
|
|
|
226
230
|
## Changelog
|
|
227
231
|
|
|
232
|
+
- **1.0.27** - adds the `ask` tool for your skills, the working-memory tools, reading the sleep's files,
|
|
233
|
+
photos and `seen` on or off, a lock file for its dependencies, and the subscription week in `usage`.
|
|
234
|
+
An admin key is refused at start: this server needs a standard key.
|
|
235
|
+
- **1.0.26** - reads are retried on 408/502/503/504 and on an answer that dropped
|
|
236
|
+
mid-body: the `wontopos` SDK pin moves to **2.2.46**. `@modelcontextprotocol/sdk` 1.32.1 or later is
|
|
237
|
+
required, for the fixes it and its dependencies carry.
|
|
238
|
+
|
|
228
239
|
- **1.0.25** - replies pass a host that checks them against their schemas. The output
|
|
229
240
|
schemas were closed to fields they do not name, so a validating client refused most
|
|
230
241
|
tools whenever the service added one. A reply over the byte cap now loses only what
|
|
@@ -240,10 +251,10 @@ advertise different limits.
|
|
|
240
251
|
the person running the server to set `WONTOPOS_MODEL` to another model. Underneath,
|
|
241
252
|
the `wontopos` SDK pin moves to **2.2.44**.
|
|
242
253
|
|
|
243
|
-
- **1.0.23** - on a duplicate
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
to **2.2.43**.
|
|
254
|
+
- **1.0.23** - on a duplicate (models older than Scroll 2; Scroll 2 stores a repeat),
|
|
255
|
+
`remember` now says how to find the memory the write matched: in `duplicate_of` when
|
|
256
|
+
the reply has it, otherwise with `search`, before combining both facts or updating that
|
|
257
|
+
memory. Underneath, the `wontopos` SDK pin moves to **2.2.43**.
|
|
247
258
|
|
|
248
259
|
- **1.0.22** - back to beta, and less for the model to read. 1.0.19 to 1.0.21 said this
|
|
249
260
|
server was stable, but it is not ready yet, and this release changes the shape of
|
|
@@ -353,11 +364,7 @@ advertise different limits.
|
|
|
353
364
|
URL" while the boot check said "continuing anyway" — the same situation as an
|
|
354
365
|
unusable store id, which has exited since 1.0.12, and now so does this.
|
|
355
366
|
|
|
356
|
-
The count range is no longer restated.
|
|
357
|
-
the SDK's exported `SEARCH_LIMIT_MIN`/`MAX` and `CONTEXT_LIMIT_MIN`/`MAX` instead of
|
|
358
|
-
spelling `5` and `20` into four places — this package has already shipped `search`
|
|
359
|
-
declaring 1..60 while `recall` said 5..20 and the service capped at 50, and a copy is
|
|
360
|
-
a copy whether or not it agrees today.
|
|
367
|
+
The count range is no longer restated.
|
|
361
368
|
|
|
362
369
|
The oversized-reply path no longer produces unparseable text. A single memory too big to
|
|
363
370
|
drop used to be handled by slicing the serialized JSON — no closing bracket,
|
|
@@ -370,10 +377,7 @@ advertise different limits.
|
|
|
370
377
|
asked for. `WONTOPOS_VERIFY` or `WONTOPOS_MAX_IMAGES` set against an engine without
|
|
371
378
|
that capability made *every* search fail with "needs Tablet 2 or newer … search
|
|
372
379
|
without it" — advice the caller could not act on, having asked for nothing. A
|
|
373
|
-
per-call ask is still refused; a default is dropped. `
|
|
374
|
-
the range `recall` has always had, and out of range is refused rather than quietly
|
|
375
|
-
adjusted — this schema used to accept 1-60 while the service capped at 50 with no
|
|
376
|
-
floor. `create_store`'s description no longer interpolates the configured store id,
|
|
380
|
+
per-call ask is still refused; a default is dropped. `create_store`'s description no longer interpolates the configured store id,
|
|
377
381
|
which handed the model a `WONTOPOS_USER_ID` like an email address every session.
|
|
378
382
|
Six free-text arguments that declared a size limit but did not enforce one now do.
|
|
379
383
|
|
|
@@ -393,17 +397,14 @@ advertise different limits.
|
|
|
393
397
|
of its arrays one level down, so the biggest reply this server produces was the one
|
|
394
398
|
that fell through to a string cut, which is the one result that is not valid JSON.
|
|
395
399
|
It now finds lists by shape, drops whole entries, and says how many went.
|
|
396
|
-
|
|
400
|
+
Three more, found by auditing this server against fixes the SDKs already carry:
|
|
397
401
|
a date-only `event_date` in any spelling but zero-padded ISO (`2026-3-14`,
|
|
398
402
|
`March 14, 2026`) was parsed as LOCAL midnight and stored **one day early** on
|
|
399
403
|
every UTC+ host — the exact shift the padded path was written to avoid, reached
|
|
400
404
|
through the one spelling it did not recognize. `WONTOPOS_READ_ONLY=on` read as
|
|
401
405
|
OFF: an operator who believed they had installed a consult-only server got one
|
|
402
406
|
whose agent can delete, with nothing in the boot output to say so, so an
|
|
403
|
-
unrecognized value now stops the server instead of being guessed.
|
|
404
|
-
`ALLOW_STORE_OVERRIDE` a `user_id` from the model is trimmed and checked the way
|
|
405
|
-
the configured one always was — `"alice "` folds to the collection `alice_`, a
|
|
406
|
-
store nothing else reads. And when a trimmed reply carries a paging cursor, the
|
|
407
|
+
unrecognized value now stops the server instead of being guessed. And when a trimmed reply carries a paging cursor, the
|
|
407
408
|
note says the cursor points past what was dropped and names the `limit` to
|
|
408
409
|
re-request with: those entries were not merely truncated, they were unreachable.
|
|
409
410
|
|
|
@@ -426,27 +427,13 @@ advertise different limits.
|
|
|
426
427
|
configured one is only a default - there the server still has work to do, so it warns
|
|
427
428
|
and serves.
|
|
428
429
|
- **1.0.11** - fixes a regression 1.0.10 introduced, published the same day. 1.0.10 was
|
|
429
|
-
right that the folded id should be *announced* and wrong to also *send* it.
|
|
430
|
-
records the raw id next to the folded one on purpose: that is how it tells a genuine
|
|
431
|
-
collision (`alice-smith` vs `alice.smith`, two people, one collection) from the same id
|
|
432
|
-
typed again. Sending the pre-folded form destroyed the signal, so a store created as
|
|
433
|
-
`My-Project` answered a later `create_store` for `my_project` with **409
|
|
434
|
-
conflict_error** - the store reported colliding with itself. Now the raw id travels and
|
|
430
|
+
right that the folded id should be *announced* and wrong to also *send* it. Now the raw id travels and
|
|
435
431
|
only the messages speak in folded terms. Also corrected: 1.0.10 warned that an id with
|
|
436
|
-
no latin alphanumerics makes every such id share one store.
|
|
437
|
-
against the live rule, that is not what happens - store ids must match
|
|
438
|
-
`[A-Za-z0-9][A-Za-z0-9._-]{0,63}`, so creating one answers 400 and every other call
|
|
439
|
-
404s. It is unusable, not shared, and the warning now says so. And the general fold
|
|
432
|
+
no latin alphanumerics makes every such id share one store. It is unusable, not shared, and the warning now says so. And the general fold
|
|
440
433
|
warning was dropped from this package: the SDK emits its own on the boot call, and two
|
|
441
434
|
near-identical lines in a host log is worse than one.
|
|
442
435
|
- **1.0.10** - the store id is announced as the id that actually holds the memories.
|
|
443
|
-
|
|
444
|
-
turns anything outside `[a-z0-9_]` into `_`, so `WONTOPOS_USER_ID=My-Project` read and
|
|
445
|
-
wrote `my_project` while the ready line, the boot check and `create_store` all repeated
|
|
446
|
-
the operator's own spelling back as confirmation. The fold mattered because it collided:
|
|
447
|
-
ids differing only by case or punctuation reached ONE store then (case still does), and
|
|
448
|
-
1.0.10 also warned that an id with no latin alphanumerics folds to underscores that every
|
|
449
|
-
such id shares, which 1.0.11 above corrects. Both were stated at boot. Underneath, the `wontopos` SDK floor
|
|
436
|
+
Underneath, the `wontopos` SDK floor
|
|
450
437
|
moved to **2.2.27**: the declared range said `^2.2.24` while the lockfile still pinned
|
|
451
438
|
**2.2.22**, so this package was built and tested against an SDK five releases old,
|
|
452
439
|
including the one where store ids collapsed silently. A test now compares the LOCKED
|
|
@@ -457,20 +444,13 @@ advertise different limits.
|
|
|
457
444
|
from a YAML block or heredoc made every call fail with an unparseable-URL error that
|
|
458
445
|
named neither the variable nor the cause); MCP SDK bumped to 1.30 and a vulnerable
|
|
459
446
|
transitive `fast-uri` patched.
|
|
460
|
-
- **1.0.9** -
|
|
447
|
+
- **1.0.9** - `search` takes `filters` -
|
|
461
448
|
`event_from`/`event_to` (when the content HAPPENED), `time_from`/`time_to` (when it was
|
|
462
|
-
written), `categories`, `min_importance`. The
|
|
463
|
-
it was in neither the spec nor any client, so "what did we decide in June?" ranked the
|
|
464
|
-
whole store and hoped. A filter chooses what is searched, not what is kept
|
|
465
|
-
afterwards, so a narrow filter still fills your `limit` from inside it. The object is
|
|
449
|
+
written), `categories`, `min_importance`. The object is
|
|
466
450
|
`.strict()`: a typo like `catagories` is refused instead of silently widening the search
|
|
467
451
|
back to everything.
|
|
468
|
-
- **1.0.8** -
|
|
469
|
-
it
|
|
470
|
-
built from the raw env while the boot check, the ready line and `create_store`
|
|
471
|
-
used the trimmed value, so `create_store` made `alice` while every read and write
|
|
472
|
-
went to `" alice \n"` — a different collection — and the console still printed
|
|
473
|
-
`store "alice" verified`. And an oversized result was capped by slicing the
|
|
452
|
+
- **1.0.8** - a bug found by driving the server over stdio rather than reading
|
|
453
|
+
it: an oversized result was capped by slicing the
|
|
474
454
|
serialized JSON, handing the model truncated JSON with no closing bracket and a final
|
|
475
455
|
memory cut mid-sentence (measured: 131,041 bytes of unparseable text from a 764 KB
|
|
476
456
|
search). Now whole entries are dropped instead, the reply stays valid JSON, and
|