wontopos-mcp 1.0.10 → 1.0.12
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 +33 -6
- package/index.mjs +54 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,12 +40,15 @@ claude mcp add wontopos --env WONTOPOS_API_KEY=wos-live-... -- npx -y wontopos-m
|
|
|
40
40
|
`WONTOPOS_USER_ID` picks the store this tool remembers into (optional, default
|
|
41
41
|
`"default"`) - one per project, per person, or per agent.
|
|
42
42
|
|
|
43
|
-
Store ids are folded: lowercased, and anything outside `[a-z0-9_]` becomes `_
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
Store ids are folded: lowercased, and anything outside `[a-z0-9_]` becomes `_`, so
|
|
44
|
+
`My-Project`, `my_project` and `MY.PROJECT` all name **one store**. The boot line
|
|
45
|
+
prints the folded id, which is the one that actually holds the memories. Creating a
|
|
46
|
+
second id that folds onto an existing one is refused with `409 conflict_error`
|
|
47
|
+
rather than silently sharing it, so pick ids that stay distinct after the fold.
|
|
48
|
+
|
|
49
|
+
The id must also match `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`. An id outside that (`선우`,
|
|
50
|
+
`田中`, an email address) cannot be used at all: creating it answers 400 and every
|
|
51
|
+
other call 404s. Romanize it, or key the store on an internal id.
|
|
49
52
|
|
|
50
53
|
Create a key in the [console](https://wontopos.com). Optional env:
|
|
51
54
|
`WONTOPOS_USER_ID` (default store, default `"default"`), `WONTOPOS_MODEL`
|
|
@@ -114,6 +117,30 @@ automatic retries, redirect refusal, response caps, and key hygiene apply as-is.
|
|
|
114
117
|
|
|
115
118
|
## Changelog
|
|
116
119
|
|
|
120
|
+
- **1.0.12** - a server that could not answer anything reported itself ready. A store id
|
|
121
|
+
outside `[A-Za-z0-9][A-Za-z0-9._-]{0,63}` (`선우`, `田中`, an email) cannot be created
|
|
122
|
+
and cannot be reached, so every tool call 404s - and 1.0.11 warned about it and then
|
|
123
|
+
served anyway. Worse, the boot check told the agent to fix it with `create_store`,
|
|
124
|
+
which answers 400 on that same id. A bad API key has always exited loudly; an id that
|
|
125
|
+
nothing at runtime can repair is the same situation, so it now exits too. The exception
|
|
126
|
+
is `WONTOPOS_ALLOW_STORE_OVERRIDE=1`, where the agent names a store per call and the
|
|
127
|
+
configured one is only a default - there the server still has work to do, so it warns
|
|
128
|
+
and serves.
|
|
129
|
+
- **1.0.11** - fixes a regression 1.0.10 introduced, published the same day. 1.0.10 was
|
|
130
|
+
right that the folded id should be *announced* and wrong to also *send* it. The API
|
|
131
|
+
records the raw id next to the folded one on purpose: that is how it tells a genuine
|
|
132
|
+
collision (`alice-smith` vs `alice.smith`, two people, one collection) from the same id
|
|
133
|
+
typed again. Sending the pre-folded form destroyed the signal, so a store created as
|
|
134
|
+
`My-Project` answered a later `create_store` for `my_project` with **409
|
|
135
|
+
conflict_error** - the store reported colliding with itself. Reads and writes were
|
|
136
|
+
never affected (the API folds those on lookup either way). Now the raw id travels and
|
|
137
|
+
only the messages speak in folded terms. Also corrected: 1.0.10 warned that an id with
|
|
138
|
+
no latin alphanumerics (`선우`, `田中`) makes every such id share one store. Measured
|
|
139
|
+
against the live rule, that is not what happens - store ids must match
|
|
140
|
+
`[A-Za-z0-9][A-Za-z0-9._-]{0,63}`, so creating one answers 400 and every other call
|
|
141
|
+
404s. It is unusable, not shared, and the warning now says so. And the general fold
|
|
142
|
+
warning was dropped from this package: the SDK emits its own on the boot call, and two
|
|
143
|
+
near-identical lines in a host log is worse than one.
|
|
117
144
|
- **1.0.10** - the store id is announced as the id that actually holds the memories.
|
|
118
145
|
1.0.8 fixed this for whitespace and stopped there: the API also lowercases an id and
|
|
119
146
|
turns anything outside `[a-z0-9_]` into `_`, so `WONTOPOS_USER_ID=My-Project` read and
|
package/index.mjs
CHANGED
|
@@ -47,25 +47,31 @@ const ALLOW_STORE_OVERRIDE = flag(process.env.WONTOPOS_ALLOW_STORE_OVERRIDE);
|
|
|
47
47
|
// untouched. Say it out loud instead.
|
|
48
48
|
const STORE_FROM_ENV = (process.env.WONTOPOS_USER_ID || "").trim();
|
|
49
49
|
const STORE_AS_CONFIGURED = STORE_FROM_ENV || "default";
|
|
50
|
-
/** The API's store-id
|
|
50
|
+
/** The API's store-id fold, mirrored: lowercase, anything outside [a-z0-9_] → "_".
|
|
51
|
+
* The collection that holds the memories is named from this, so it is the honest
|
|
52
|
+
* answer to "which store am I on" — WONTOPOS_USER_ID=My-Project reads and writes
|
|
53
|
+
* `my_project`, while the ready line, the boot check and create_store all announced
|
|
54
|
+
* "My-Project", handing the operator their own spelling back as confirmation.
|
|
55
|
+
* 1.0.8 fixed exactly that lie for whitespace and stopped there.
|
|
51
56
|
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* The collision it implies is the heavier half: ids differing only by case or
|
|
60
|
-
* punctuation are ONE store and therefore one set of memories. `Alice.Smith`,
|
|
61
|
-
* `alice-smith` and `alice_smith` are the same person as far as memory is concerned. */
|
|
57
|
+
* Used for MESSAGES ONLY. 1.0.10 also sent it, and that was wrong: the API records
|
|
58
|
+
* the RAW id alongside the folded one precisely so it can tell a real collision
|
|
59
|
+
* ("alice-smith" vs "alice.smith", different people, one collection) from the same
|
|
60
|
+
* id typed again. Sending the already-folded form destroys that signal — a store
|
|
61
|
+
* created as `My-Project` answered a later create for `my_project` with
|
|
62
|
+
* 409 conflict_error, claiming the store collided with itself. The raw id goes to
|
|
63
|
+
* the API, which owns this mapping; we only stop lying about the result. */
|
|
62
64
|
const canonicalStoreId = (s) => s.toLowerCase().replace(/[^a-z0-9_]/g, "_");
|
|
63
|
-
const
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*
|
|
68
|
-
|
|
65
|
+
const STORE_FOLDED = canonicalStoreId(STORE_AS_CONFIGURED);
|
|
66
|
+
/** What every request carries: the id as configured, trimmed. The API folds it. */
|
|
67
|
+
const STORE = STORE_AS_CONFIGURED;
|
|
68
|
+
/** Store ids are code-level identifiers — the API requires
|
|
69
|
+
* `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`, so an id with no latin alphanumerics at all
|
|
70
|
+
* ("선우", "田中") is not merely folded, it is unusable: creation answers 400 and
|
|
71
|
+
* every other call 404s, because the `__` it folds to can never be created either.
|
|
72
|
+
* Measured against the live rule, not inferred. */
|
|
73
|
+
const STORE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
74
|
+
const STORE_ID_UNUSABLE = !STORE_ID_RE.test(STORE);
|
|
69
75
|
// Cap what a tool result may inject into the model's context. The SDK's 64MB cap
|
|
70
76
|
// protects the process; this protects the conversation (a 2MB memory must not
|
|
71
77
|
// become 2MB of context). Measured in UTF-8 BYTES, not JS chars: `str.length`
|
|
@@ -559,24 +565,35 @@ await server.connect(transport);
|
|
|
559
565
|
};
|
|
560
566
|
}
|
|
561
567
|
console.error(
|
|
562
|
-
`wontopos-mcp ${VERSION} ready (store: ${
|
|
568
|
+
`wontopos-mcp ${VERSION} ready (store: ${STORE_FOLDED}${STORE_FROM_ENV ? "" : " — FALLBACK: WONTOPOS_USER_ID is not set"}${READ_ONLY ? ", read-only" : ""})`
|
|
563
569
|
);
|
|
564
570
|
// Say it at boot, once, when the configured id is not the id that holds the memories.
|
|
565
571
|
// The operator wrote this value by hand in a host config file and has no other way to
|
|
566
572
|
// learn it was folded — and the ready line above, which used to repeat their spelling
|
|
567
573
|
// back to them, was the very thing that made it look fine.
|
|
568
|
-
|
|
574
|
+
// The fold itself is NOT announced here: now that the raw id is what travels, the
|
|
575
|
+
// SDK's own warning (2.2.27) fires on the boot check and says the same thing. Two
|
|
576
|
+
// near-identical lines in a host log is worse than one. The ready line above already
|
|
577
|
+
// names the folded store, which is the part the SDK does not cover.
|
|
578
|
+
//
|
|
579
|
+
// This one has no SDK equivalent — the SDK knows the fold, not the creation rule.
|
|
580
|
+
// A key that can do nothing exits(1). An id that can do nothing used to WARN and then
|
|
581
|
+
// serve — so the host reported a healthy MCP server whose every call 404'd, and the
|
|
582
|
+
// boot check's own advice ("create_store") was impossible: creating this id answers
|
|
583
|
+
// 400 by the same rule. Nothing the agent does at runtime can repair it, so it belongs
|
|
584
|
+
// on the same side as the bad key.
|
|
585
|
+
//
|
|
586
|
+
// Unless the store is not pinned: under ALLOW_STORE_OVERRIDE the agent supplies an id
|
|
587
|
+
// per call and the configured one is only a default, so the server still has work.
|
|
588
|
+
if (STORE_ID_UNUSABLE) {
|
|
569
589
|
console.error(
|
|
570
|
-
`wontopos-mcp: WONTOPOS_USER_ID ${JSON.stringify(
|
|
571
|
-
"
|
|
572
|
-
"
|
|
590
|
+
`wontopos-mcp: WONTOPOS_USER_ID ${JSON.stringify(STORE)} is not a usable store id. The API requires English ` +
|
|
591
|
+
"letters, digits and . _ - (1-64 chars, starting with a letter or digit), so creating it answers 400 and " +
|
|
592
|
+
"every other call 404s. Romanize it or pick a latin id."
|
|
573
593
|
);
|
|
574
|
-
if (
|
|
575
|
-
console.error(
|
|
576
|
-
|
|
577
|
-
`${JSON.stringify(STORE)}, so EVERY id on this key with no a-z0-9 characters lands in this same store. ` +
|
|
578
|
-
"Use a latin-alphanumeric id (romanize it, or add a suffix) if these stores must stay apart."
|
|
579
|
-
);
|
|
594
|
+
if (!ALLOW_STORE_OVERRIDE) {
|
|
595
|
+
console.error("wontopos-mcp: every tool call would fail and no tool could repair it. Exiting.");
|
|
596
|
+
process.exit(1);
|
|
580
597
|
}
|
|
581
598
|
}
|
|
582
599
|
|
|
@@ -585,7 +602,7 @@ if (STORE !== STORE_AS_CONFIGURED) {
|
|
|
585
602
|
// A missing store is recoverable (the agent can create_store) → warn and serve.
|
|
586
603
|
mem.stats().then(
|
|
587
604
|
(s) => {
|
|
588
|
-
console.error(`wontopos-mcp: store "${
|
|
605
|
+
console.error(`wontopos-mcp: store "${STORE_FOLDED}" verified (${s?.total_memories ?? "?"} memories).`);
|
|
589
606
|
// Verified, but on the fallback store — the case a misconfiguration hides in.
|
|
590
607
|
// The seeded `default` always exists, so this check passes and the operator has
|
|
591
608
|
// no other signal that the store they configured is not the one in use.
|
|
@@ -603,15 +620,18 @@ mem.stats().then(
|
|
|
603
620
|
process.exit(1);
|
|
604
621
|
} else if (status === 404) {
|
|
605
622
|
console.error(
|
|
606
|
-
`wontopos-mcp: the key works but store "${
|
|
607
|
-
(
|
|
608
|
-
|
|
609
|
-
|
|
623
|
+
`wontopos-mcp: the key works but store "${STORE_FOLDED}" does not exist — ` +
|
|
624
|
+
(STORE_ID_UNUSABLE
|
|
625
|
+
// create_store answers 400 on this id by the same rule, so do not send them there.
|
|
626
|
+
? "and it cannot be created under this id. Set WONTOPOS_USER_ID to a latin-alphanumeric id."
|
|
627
|
+
: READ_ONLY
|
|
628
|
+
? "fix WONTOPOS_USER_ID (read-only mode cannot create stores)."
|
|
629
|
+
: "ask the agent to create it (create_store) or fix WONTOPOS_USER_ID.")
|
|
610
630
|
);
|
|
611
631
|
} else if (status === 402) {
|
|
612
632
|
console.error("wontopos-mcp: the key works but the account has no card or balance (402) — top up at https://wontopos.com/console.");
|
|
613
633
|
} else {
|
|
614
|
-
console.error(`wontopos-mcp: could not verify store "${
|
|
634
|
+
console.error(`wontopos-mcp: could not verify store "${STORE_FOLDED}" (${e?.message ?? e}) — continuing anyway.`);
|
|
615
635
|
}
|
|
616
636
|
}
|
|
617
637
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wontopos-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.12",
|
|
4
4
|
"mcpName": "com.wontopos/mcp",
|
|
5
5
|
"description": "(beta) Wontopos (WOS) long-term memory as an MCP server — one memory across Claude Code, Claude Desktop, Cursor, ChatGPT, and your own agents.",
|
|
6
6
|
"keywords": [
|