wontopos-mcp 1.0.26 → 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 CHANGED
@@ -51,12 +51,13 @@ The id must also match `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`. An id outside that (an
51
51
  in a non-Latin script, an email address) cannot be used at all: creating it answers 400 and every
52
52
  other call 404s. Romanize it, or key the store on an internal id.
53
53
 
54
- Create a key in the [console](https://wontopos.com). Optional env:
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:
55
56
 
56
57
  | Variable | What it sets |
57
58
  |---|---|
58
59
  | `WONTOPOS_USER_ID` | The store every tool call uses. Default `"default"`. |
59
- | `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`. |
60
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. |
61
62
  | `WONTOPOS_MAX_IMAGES` | Default photo results per `search`, 0-5. Default `0` — see below. |
62
63
  | `WONTOPOS_BASE_URL` | A different API host. Leave unset for the default. |
@@ -67,6 +68,10 @@ Create a key in the [console](https://wontopos.com). Optional env:
67
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. |
68
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. |
69
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`.
70
75
 
71
76
  **Why photos default to none.** Not because the model cannot see them - `view_image`
72
77
  hands over the actual picture - but because the rows ride on *every* search, and most
@@ -118,8 +123,8 @@ quietly ignored, and that refusal would otherwise land on every search.
118
123
 
119
124
  | Tool | What the agent does with it |
120
125
  |---|---|
121
- | `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. Both need a limit-aware engine — an older one refuses the whole call, and the tool says which argument to drop. |
122
- | `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. |
123
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. |
124
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. |
125
130
  | `update` | Rewrite a memory the user's own words contradicted - keeps what is still true, adds what changed. |
@@ -132,6 +137,11 @@ quietly ignored, and that refusal would otherwise land on every search.
132
137
  | `revisions` | How much of the store has been changed since it was written: counts by default, up to 20 memories on request. |
133
138
  | `create_store` | Creates the pinned store after asking the user (any store with `ALLOW_STORE_OVERRIDE=1`). |
134
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
+
135
145
  ## Running it over HTTP yourself
136
146
 
137
147
  Some hosts reach a URL rather than spawning a command. The same server answers over
@@ -148,7 +158,7 @@ WONTOPOS_HTTP_TOKEN="$TOKEN" \
148
158
  npx -y wontopos-mcp
149
159
  ```
150
160
 
151
- Same thirteen tools, same store, same 20-turn window. Callers send
161
+ Same store, same 20-turn window. Callers send
152
162
  `Authorization: Bearer <token>`.
153
163
 
154
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
@@ -191,17 +201,10 @@ connect to the hosted endpoint instead. Same memory, same stores, same account:
191
201
  by the model — the tools take no store argument, so a prompt-injected model cannot move
192
202
  to a sibling store.
193
203
 
194
- It offers six of the thirteen: `recall` · `search` · `remember` · `list_memories` ·
195
- `stats` · `engram` — the retrieval core plus one write. `update`, `forget`,
196
- `create_store`, `revisions`, `store_turn`, `view_image` and `usage` are local-only. This list
197
- has been wrong twice: it once accounted for nine tools with `revisions` in neither
198
- 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.
199
206
  Six is what the endpoint answers `tools/list` with today.
200
207
 
201
- The endpoint is a protocol adapter, not a second way in: every tool call re-enters the
202
- ordinary `/api/v1/memory` routes carrying your key, so the same authentication, rate
203
- limits, billing gates and tenant isolation apply — the same code, not a copy of it.
204
-
205
208
  ## One memory, many tools
206
209
 
207
210
  Same `WONTOPOS_API_KEY` + same store id ⇒ the memory follows you:
@@ -226,10 +229,11 @@ advertise different limits.
226
229
 
227
230
  ## Changelog
228
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.
229
235
  - **1.0.26** - reads are retried on 408/502/503/504 and on an answer that dropped
230
- mid-body: the `wontopos` SDK pin moves to **2.2.46**. The recall line says what a
231
- recall returns instead of a token count, raising `verify` adds no language model call,
232
- and memory belongs to a workspace. `@modelcontextprotocol/sdk` 1.32.1 or later is
236
+ mid-body: the `wontopos` SDK pin moves to **2.2.46**. `@modelcontextprotocol/sdk` 1.32.1 or later is
233
237
  required, for the fixes it and its dependencies carry.
234
238
 
235
239
  - **1.0.25** - replies pass a host that checks them against their schemas. The output
@@ -247,10 +251,10 @@ advertise different limits.
247
251
  the person running the server to set `WONTOPOS_MODEL` to another model. Underneath,
248
252
  the `wontopos` SDK pin moves to **2.2.44**.
249
253
 
250
- - **1.0.23** - on a duplicate, `remember` now says how to find the memory the write
251
- matched: in `duplicate_of` when the reply has it, otherwise with `search`, before
252
- combining both facts or updating that memory. Underneath, the `wontopos` SDK pin moves
253
- 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**.
254
258
 
255
259
  - **1.0.22** - back to beta, and less for the model to read. 1.0.19 to 1.0.21 said this
256
260
  server was stable, but it is not ready yet, and this release changes the shape of
@@ -360,11 +364,7 @@ advertise different limits.
360
364
  URL" while the boot check said "continuing anyway" — the same situation as an
361
365
  unusable store id, which has exited since 1.0.12, and now so does this.
362
366
 
363
- The count range is no longer restated. `search` and `recall` build their bounds from
364
- the SDK's exported `SEARCH_LIMIT_MIN`/`MAX` and `CONTEXT_LIMIT_MIN`/`MAX` instead of
365
- spelling `5` and `20` into four places — this package has already shipped `search`
366
- declaring 1..60 while `recall` said 5..20 and the service capped at 50, and a copy is
367
- a copy whether or not it agrees today.
367
+ The count range is no longer restated.
368
368
 
369
369
  The oversized-reply path no longer produces unparseable text. A single memory too big to
370
370
  drop used to be handled by slicing the serialized JSON — no closing bracket,
@@ -377,10 +377,7 @@ advertise different limits.
377
377
  asked for. `WONTOPOS_VERIFY` or `WONTOPOS_MAX_IMAGES` set against an engine without
378
378
  that capability made *every* search fail with "needs Tablet 2 or newer … search
379
379
  without it" — advice the caller could not act on, having asked for nothing. A
380
- per-call ask is still refused; a default is dropped. `search`'s count is now 5-20,
381
- the range `recall` has always had, and out of range is refused rather than quietly
382
- adjusted — this schema used to accept 1-60 while the service capped at 50 with no
383
- 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,
384
381
  which handed the model a `WONTOPOS_USER_ID` like an email address every session.
385
382
  Six free-text arguments that declared a size limit but did not enforce one now do.
386
383
 
@@ -400,17 +397,14 @@ advertise different limits.
400
397
  of its arrays one level down, so the biggest reply this server produces was the one
401
398
  that fell through to a string cut, which is the one result that is not valid JSON.
402
399
  It now finds lists by shape, drops whole entries, and says how many went.
403
- Four more, found by auditing this server against fixes the SDKs already carry:
400
+ Three more, found by auditing this server against fixes the SDKs already carry:
404
401
  a date-only `event_date` in any spelling but zero-padded ISO (`2026-3-14`,
405
402
  `March 14, 2026`) was parsed as LOCAL midnight and stored **one day early** on
406
403
  every UTC+ host — the exact shift the padded path was written to avoid, reached
407
404
  through the one spelling it did not recognize. `WONTOPOS_READ_ONLY=on` read as
408
405
  OFF: an operator who believed they had installed a consult-only server got one
409
406
  whose agent can delete, with nothing in the boot output to say so, so an
410
- unrecognized value now stops the server instead of being guessed. Under
411
- `ALLOW_STORE_OVERRIDE` a `user_id` from the model is trimmed and checked the way
412
- the configured one always was — `"alice "` folds to the collection `alice_`, a
413
- 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
414
408
  note says the cursor points past what was dropped and names the `limit` to
415
409
  re-request with: those entries were not merely truncated, they were unreachable.
416
410
 
@@ -433,27 +427,13 @@ advertise different limits.
433
427
  configured one is only a default - there the server still has work to do, so it warns
434
428
  and serves.
435
429
  - **1.0.11** - fixes a regression 1.0.10 introduced, published the same day. 1.0.10 was
436
- right that the folded id should be *announced* and wrong to also *send* it. The API
437
- records the raw id next to the folded one on purpose: that is how it tells a genuine
438
- collision (`alice-smith` vs `alice.smith`, two people, one collection) from the same id
439
- typed again. Sending the pre-folded form destroyed the signal, so a store created as
440
- `My-Project` answered a later `create_store` for `my_project` with **409
441
- 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
442
431
  only the messages speak in folded terms. Also corrected: 1.0.10 warned that an id with
443
- no latin alphanumerics makes every such id share one store. Measured
444
- against the live rule, that is not what happens - store ids must match
445
- `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`, so creating one answers 400 and every other call
446
- 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
447
433
  warning was dropped from this package: the SDK emits its own on the boot call, and two
448
434
  near-identical lines in a host log is worse than one.
449
435
  - **1.0.10** - the store id is announced as the id that actually holds the memories.
450
- 1.0.8 fixed this for whitespace and stopped there: the API also lowercases an id and
451
- turns anything outside `[a-z0-9_]` into `_`, so `WONTOPOS_USER_ID=My-Project` read and
452
- wrote `my_project` while the ready line, the boot check and `create_store` all repeated
453
- the operator's own spelling back as confirmation. The fold mattered because it collided:
454
- ids differing only by case or punctuation reached ONE store then (case still does), and
455
- 1.0.10 also warned that an id with no latin alphanumerics folds to underscores that every
456
- 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
457
437
  moved to **2.2.27**: the declared range said `^2.2.24` while the lockfile still pinned
458
438
  **2.2.22**, so this package was built and tested against an SDK five releases old,
459
439
  including the one where store ids collapsed silently. A test now compares the LOCKED
@@ -464,19 +444,13 @@ advertise different limits.
464
444
  from a YAML block or heredoc made every call fail with an unparseable-URL error that
465
445
  named neither the variable nor the cause); MCP SDK bumped to 1.30 and a vulnerable
466
446
  transitive `fast-uri` patched.
467
- - **1.0.9** - the one axis meaning cannot narrow: time. `search` takes `filters` -
447
+ - **1.0.9** - `search` takes `filters` -
468
448
  `event_from`/`event_to` (when the content HAPPENED), `time_from`/`time_to` (when it was
469
- written), `categories`, `min_importance`. The API had supported this the whole time but
470
- it was in neither the spec nor any client, so "what did we decide in June?" ranked the
471
- whole store and hoped. The object is
449
+ written), `categories`, `min_importance`. The object is
472
450
  `.strict()`: a typo like `catagories` is refused instead of silently widening the search
473
451
  back to everything.
474
- - **1.0.8** - two bugs found by driving the server over stdio rather than reading
475
- it. A store id with stray whitespace **split the store in two**: the client was
476
- built from the raw env while the boot check, the ready line and `create_store`
477
- used the trimmed value, so `create_store` made `alice` while every read and write
478
- went to `" alice \n"` — a different collection — and the console still printed
479
- `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
480
454
  serialized JSON, handing the model truncated JSON with no closing bracket and a final
481
455
  memory cut mid-sentence (measured: 131,041 bytes of unparseable text from a 764 KB
482
456
  search). Now whole entries are dropped instead, the reply stays valid JSON, and