neotoma 0.9.1 → 0.10.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 +7 -6
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +19 -2
- package/dist/actions.js.map +1 -1
- package/dist/services/mcp_oauth.d.ts +9 -7
- package/dist/services/mcp_oauth.d.ts.map +1 -1
- package/dist/services/mcp_oauth.js +170 -13
- package/dist/services/mcp_oauth.js.map +1 -1
- package/dist/services/root_landing/site_nav.d.ts.map +1 -1
- package/dist/services/root_landing/site_nav.js +8 -3
- package/dist/services/root_landing/site_nav.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Your agents forget. Neotoma makes them remember.
|
|
4
4
|
|
|
5
|
-
Versioned records — contacts, tasks, decisions, finances — that persist across Claude, Cursor, ChatGPT, OpenClaw, and every agent you run. Open-source. Local-first. Deterministic. MIT licensed.
|
|
5
|
+
Versioned records — contacts, tasks, decisions, finances — that persist across Claude, Cursor, ChatGPT, OpenClaw, IronClaw, and every agent you run. Open-source. Local-first. Deterministic. MIT licensed.
|
|
6
6
|
|
|
7
7
|
**[neotoma.io](https://neotoma.io)** · **[Evaluate](https://neotoma.io/evaluate)** · **[Install](https://neotoma.io/install)** · **[Documentation](https://neotoma.io/docs)**
|
|
8
8
|
|
|
@@ -38,6 +38,7 @@ graph LR
|
|
|
38
38
|
MCP --> ChatGPT
|
|
39
39
|
MCP --> Cursor
|
|
40
40
|
MCP --> OpenClaw
|
|
41
|
+
MCP --> IronClaw
|
|
41
42
|
```
|
|
42
43
|
|
|
43
44
|
- **Deterministic.** Same observations always produce the same versioned entity snapshots. No ordering sensitivity.
|
|
@@ -51,7 +52,7 @@ graph LR
|
|
|
51
52
|
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
53
|
| **Privacy-first** | Your data stays local. Never used for training. User-controlled storage, optional encryption at rest. Full export and deletion control. |
|
|
53
54
|
| **Deterministic** | Same input always produces same output. Schema-first extraction, hash-based entity IDs, full provenance. No silent mutation. |
|
|
54
|
-
| **Cross-platform** | One memory graph across Claude, ChatGPT, Cursor, OpenClaw, Codex, and CLI. MCP-based access. No platform lock-in. Works alongside native memory. |
|
|
55
|
+
| **Cross-platform** | One memory graph across Claude, ChatGPT, Cursor, OpenClaw, IronClaw, Codex, and CLI. MCP-based access. No platform lock-in. Works alongside native memory. |
|
|
55
56
|
|
|
56
57
|
## State guarantees
|
|
57
58
|
|
|
@@ -121,14 +122,14 @@ Three interfaces. One state invariant. Every interface provides the same determi
|
|
|
121
122
|
| Interface | Description |
|
|
122
123
|
| -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
123
124
|
| **REST API** | Full HTTP interface for application integration. Entities, relationships, observations, schema, timeline, and version history. |
|
|
124
|
-
| **MCP Server** | Model Context Protocol for Claude, ChatGPT, Cursor, OpenClaw, Codex, and more. Agents store and retrieve state through structured tool calls. |
|
|
125
|
+
| **MCP Server** | Model Context Protocol for Claude, ChatGPT, Cursor, OpenClaw, IronClaw, Codex, and more. Agents store and retrieve state through structured tool calls. |
|
|
125
126
|
| **CLI** | Command-line for scripting and direct access. Inspect entities, replay timelines, and manage state from the terminal. |
|
|
126
127
|
|
|
127
128
|
All three map to the same OpenAPI-backed operations. MCP tool calls log the equivalent CLI invocation.
|
|
128
129
|
|
|
129
130
|
## Who this is for
|
|
130
131
|
|
|
131
|
-
People building a personal operating system with AI agents across their life — wiring together tools like Claude, Cursor, ChatGPT, OpenClaw, and custom scripts to manage contacts, tasks, finances, code, content, and other domains. The same person operates their agents, builds new pipelines, and debugs state drift. These are three operational modes, not separate personas:
|
|
132
|
+
People building a personal operating system with AI agents across their life — wiring together tools like Claude, Cursor, ChatGPT, OpenClaw, IronClaw, and custom scripts to manage contacts, tasks, finances, code, content, and other domains. The same person operates their agents, builds new pipelines, and debugs state drift. These are three operational modes, not separate personas:
|
|
132
133
|
|
|
133
134
|
| Mode | What you're doing | The tax you pay without Neotoma | What you get back |
|
|
134
135
|
| ---- | ----------------- | ------------------------------- | ----------------- |
|
|
@@ -155,7 +156,7 @@ Schema is flexible — store any entity type with whatever fields the message im
|
|
|
155
156
|
|
|
156
157
|
## Current status
|
|
157
158
|
|
|
158
|
-
**Version:** v0.
|
|
159
|
+
**Version:** v0.9.1 · **Releases:** 26 · **License:** MIT
|
|
159
160
|
|
|
160
161
|
### What is guaranteed (even in preview)
|
|
161
162
|
|
|
@@ -217,7 +218,7 @@ npm test
|
|
|
217
218
|
|
|
218
219
|
Neotoma exposes state via MCP. Local storage only in preview. Local built-in auth.
|
|
219
220
|
|
|
220
|
-
**Setup guides:** [Cursor](https://neotoma.io/neotoma-with-cursor) · [Claude Code](https://neotoma.io/neotoma-with-claude-code) · [Claude](https://neotoma.io/neotoma-with-claude) · [ChatGPT](https://neotoma.io/neotoma-with-chatgpt) · [Codex](https://neotoma.io/neotoma-with-codex) · [OpenClaw](https://neotoma.io/neotoma-with-openclaw)
|
|
221
|
+
**Setup guides:** [Cursor](https://neotoma.io/neotoma-with-cursor) · [Claude Code](https://neotoma.io/neotoma-with-claude-code) · [Claude](https://neotoma.io/neotoma-with-claude) · [ChatGPT](https://neotoma.io/neotoma-with-chatgpt) · [Codex](https://neotoma.io/neotoma-with-codex) · [OpenCode](docs/integrations/hooks/opencode.md) · [OpenClaw](https://neotoma.io/neotoma-with-openclaw) · [IronClaw](https://neotoma.io/neotoma-with-ironclaw)
|
|
221
222
|
|
|
222
223
|
For local source iteration, use the stable dev shim (`scripts/run_neotoma_mcp_stdio_dev_shim.sh` or `npm run dev:mcp:dev-shim`) instead of pointing installed MCP clients at a `tsx watch` stdio process. The shim keeps the client-facing JSON-RPC stream stable and asks clients to refresh or reconnect when the tool interface changes.
|
|
223
224
|
|
package/dist/actions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAmK9B,eAAO,MAAM,GAAG,6CAAY,CAAC;AAif7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAU5D;AA4PD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAmBhD;
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAmK9B,eAAO,MAAM,GAAG,6CAAY,CAAC;AAif7B;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,GAAG,OAAO,CAU5D;AA4PD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAmBhD;AA4sHD,KAAK,oBAAoB,GAAG;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,4BAA4B,EAAE,iBAAiB,CAAC;IAC3E,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;;;;;;;;;;;;;cA+fS,MAAM;gBACJ,MAAM;2BACK,MAAM;qBACZ,MAAM;mBACR,MAAM;wBACD,MAAM;uBACP,MAAM;;;;;;;;;mBA3JV,MAAM;qBACJ,MAAM;wBACH,MAAM,GAAG,IAAI;2BACV,MAAM;;wBAET,MAAM;uBACP,MAAM,EAAE;wBACP,MAAM;uBACP,MAAM;;kBA9NX,MAAM;oBACJ,MAAM;yBACD,MAAM;4BACH,MAAM;2BACP,MAAM;;+BA4NF,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;;;2BAkFlC,MAAM;0BACP,MAAM;0BACN,MAAM;;GA2F3B;AAuhED,wBAAsB,eAAe;;;eA2FpC"}
|
package/dist/actions.js
CHANGED
|
@@ -1689,21 +1689,38 @@ app.post("/mcp/oauth/token", oauthTokenLimit, express.urlencoded({ extended: tru
|
|
|
1689
1689
|
try {
|
|
1690
1690
|
const grant_type = req.body?.grant_type;
|
|
1691
1691
|
const code = req.body?.code;
|
|
1692
|
+
const refresh_token = req.body?.refresh_token;
|
|
1692
1693
|
logger.info("[MCP OAuth] Token request received", {
|
|
1693
1694
|
grant_type: grant_type ?? null,
|
|
1694
1695
|
has_code: typeof code === "string" && code.length > 0,
|
|
1695
1696
|
code_hint: typeof code === "string" ? code.slice(0, 8) : null,
|
|
1697
|
+
has_refresh_token: typeof refresh_token === "string" && refresh_token.length > 0,
|
|
1696
1698
|
host: req.header("host") ?? null,
|
|
1697
1699
|
});
|
|
1698
|
-
if (grant_type !== "authorization_code") {
|
|
1700
|
+
if (grant_type !== "authorization_code" && grant_type !== "refresh_token") {
|
|
1699
1701
|
logger.warn("[MCP OAuth] Token rejected: unsupported grant_type", {
|
|
1700
1702
|
grant_type: grant_type ?? null,
|
|
1701
1703
|
});
|
|
1702
1704
|
return res.status(400).json({
|
|
1703
1705
|
error: "unsupported_grant_type",
|
|
1704
|
-
error_description: "Only authorization_code
|
|
1706
|
+
error_description: "Only authorization_code and refresh_token are supported",
|
|
1705
1707
|
});
|
|
1706
1708
|
}
|
|
1709
|
+
if (grant_type === "refresh_token") {
|
|
1710
|
+
if (!refresh_token || typeof refresh_token !== "string") {
|
|
1711
|
+
logger.warn("[MCP OAuth] Token refresh rejected: missing refresh_token");
|
|
1712
|
+
return res
|
|
1713
|
+
.status(400)
|
|
1714
|
+
.json({ error: "invalid_request", error_description: "refresh_token is required" });
|
|
1715
|
+
}
|
|
1716
|
+
const { refreshAccessToken } = await import("./services/mcp_oauth.js");
|
|
1717
|
+
const token = await refreshAccessToken(refresh_token);
|
|
1718
|
+
logger.info("[MCP OAuth] Token refreshed", {
|
|
1719
|
+
has_refresh_token: Boolean(token.refresh_token),
|
|
1720
|
+
});
|
|
1721
|
+
res.setHeader("Content-Type", "application/json");
|
|
1722
|
+
return res.json(token);
|
|
1723
|
+
}
|
|
1707
1724
|
if (!code || typeof code !== "string") {
|
|
1708
1725
|
logger.warn("[MCP OAuth] Token rejected: missing code");
|
|
1709
1726
|
return res
|