wontopos-mcp 1.0.6 → 1.0.7
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/index.mjs +30 -6
- package/package.json +2 -2
package/index.mjs
CHANGED
|
@@ -27,8 +27,12 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
27
27
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
28
28
|
import { z } from "zod";
|
|
29
29
|
import { Client, WosError } from "wontopos";
|
|
30
|
+
import { createRequire } from "node:module";
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
// Read the version from package.json rather than restating it: a hand-kept copy
|
|
33
|
+
// silently drifts (1.0.6 shipped announcing itself as "1.0.5" in the MCP
|
|
34
|
+
// handshake, so hosts logged — and bug reports cited — the wrong build).
|
|
35
|
+
const VERSION = createRequire(import.meta.url)("./package.json").version;
|
|
32
36
|
const flag = (v) => ["1", "true", "yes"].includes((v ?? "").trim().toLowerCase());
|
|
33
37
|
const READ_ONLY = flag(process.env.WONTOPOS_READ_ONLY);
|
|
34
38
|
// Store pinning (default ON): every call goes to WONTOPOS_USER_ID and the tools
|
|
@@ -61,6 +65,22 @@ function truncateToBytes(s, maxBytes) {
|
|
|
61
65
|
return s.slice(0, read);
|
|
62
66
|
}
|
|
63
67
|
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
68
|
+
const DATE_ONLY_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
69
|
+
/** Canonicalize event_date to the full RFC3339 the API requires.
|
|
70
|
+
* The API accepts only a complete date-TIME: a bare "2026-03-14" — the form a
|
|
71
|
+
* model naturally emits, and the form this tool's own example suggested — came
|
|
72
|
+
* back as an opaque 400 "Invalid request body or parameters." Normalize here
|
|
73
|
+
* instead of asking every agent to guess the shape.
|
|
74
|
+
* Returns null when the value is not a date at all, so the caller can refuse it. */
|
|
75
|
+
function normalizeEventDate(raw) {
|
|
76
|
+
const s = String(raw).trim();
|
|
77
|
+
if (Number.isNaN(Date.parse(s))) return null;
|
|
78
|
+
// Date-only is completed by string append, never through Date: parsing and
|
|
79
|
+
// re-serializing would re-interpret it in the host's zone and can shift the
|
|
80
|
+
// stated day by one, which is exactly the fact the user was pinning down.
|
|
81
|
+
if (DATE_ONLY_RE.test(s)) return `${s}T00:00:00Z`;
|
|
82
|
+
return new Date(s).toISOString();
|
|
83
|
+
}
|
|
64
84
|
|
|
65
85
|
// First env var with a NON-EMPTY value wins. `??` only skips null/undefined, so
|
|
66
86
|
// an empty WONTOPOS_API_KEY="" would shadow a valid WOS_API_KEY — the exact bug
|
|
@@ -174,7 +194,10 @@ server.registerTool(
|
|
|
174
194
|
"('Sunwoo prefers dark mode in the console'), not a chat log. For your own side, store only " +
|
|
175
195
|
"commitments you actually SAID to the user (speaker 'me') — never internal reasoning or thinking " +
|
|
176
196
|
"output. Do NOT store fetched material: web search results, crawled pages, file contents, and " +
|
|
177
|
-
"tool outputs are session context, not memories.
|
|
197
|
+
"tool outputs are session context, not memories. A memory close enough to one already stored is " +
|
|
198
|
+
"rejected as status 'duplicate' and is NOT saved — the match is by meaning, not by exact text, so " +
|
|
199
|
+
"when a new fact only narrows or contrasts an existing one ('allergic to shellfish' next to " +
|
|
200
|
+
"'allergic to peanuts'), write it as one sentence that states both, or supersede the old one with update.",
|
|
178
201
|
inputSchema: {
|
|
179
202
|
content: z.string().describe("The memory, as one self-contained sentence."),
|
|
180
203
|
speaker: z
|
|
@@ -184,7 +207,7 @@ server.registerTool(
|
|
|
184
207
|
event_date: z
|
|
185
208
|
.string()
|
|
186
209
|
.nullish()
|
|
187
|
-
.describe("
|
|
210
|
+
.describe("When the event actually happened, if different from now. A plain date ('2026-03-14') or a full RFC3339 timestamp; a bare date is read as UTC midnight."),
|
|
188
211
|
...storeArg,
|
|
189
212
|
},
|
|
190
213
|
},
|
|
@@ -194,11 +217,12 @@ server.registerTool(
|
|
|
194
217
|
throw new Error("content too long (max 8192 bytes) — a memory is one fact; backfill large text with the SDK's add_bulk.");
|
|
195
218
|
if (speaker && speaker !== "me")
|
|
196
219
|
throw new Error("speaker must be 'me' (something the agent itself said) or omitted (the user's fact).");
|
|
197
|
-
|
|
198
|
-
|
|
220
|
+
const eventDate = event_date ? normalizeEventDate(event_date) : null;
|
|
221
|
+
if (event_date && !eventDate)
|
|
222
|
+
throw new Error("event_date is not a parseable date — use a date (2026-07-01) or RFC3339 (2026-07-01T09:00:00Z).");
|
|
199
223
|
const metadata = {};
|
|
200
224
|
if (speaker) metadata.speaker = speaker;
|
|
201
|
-
if (
|
|
225
|
+
if (eventDate) metadata.event_date = eventDate;
|
|
202
226
|
return mem.add(content, uid(user_id), metadata);
|
|
203
227
|
})
|
|
204
228
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wontopos-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
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": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
35
|
-
"wontopos": "^2.2.
|
|
35
|
+
"wontopos": "^2.2.22",
|
|
36
36
|
"zod": "^3.23.0"
|
|
37
37
|
}
|
|
38
38
|
}
|