@cerefox/memory 1.2.1 → 1.3.0-beta.2
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/AGENT_GUIDE.md +67 -5
- package/AGENT_QUICK_REFERENCE.md +32 -3
- package/README.md +13 -3
- package/dist/bin/cerefox.js +2694 -1968
- package/dist/server-assets/_shared/ef-meta/index.ts +2 -2
- package/dist/server-assets/_shared/mcp-tools/get-document.ts +43 -1
- package/dist/server-assets/_shared/mcp-tools/get-help-content.ts +5 -4
- package/dist/server-assets/_shared/mcp-tools/index.ts +7 -1
- package/dist/server-assets/_shared/mcp-tools/ingest.ts +9 -2
- package/dist/server-assets/_shared/mcp-tools/partial-edits.ts +489 -0
- package/dist/server-assets/_shared/partial-edits/index.ts +493 -0
- package/dist/server-assets/db/migrations/0019_partial_edit_audit_ops.sql +49 -0
- package/dist/server-assets/db/rpcs.sql +105 -20
- package/dist/server-assets/db/schema.sql +6 -2
- package/dist/server-assets/supabase/functions/cerefox-ingest/index.ts +4 -0
- package/docs/guides/cli.md +5 -3
- package/docs/guides/configuration.md +8 -0
- package/docs/guides/connect-agents.md +11 -9
- package/docs/guides/operational-cost.md +1 -1
- package/docs/guides/ops-scripts.md +15 -2
- package/package.json +1 -1
|
@@ -1293,6 +1293,10 @@ $$;
|
|
|
1293
1293
|
DROP FUNCTION IF EXISTS cerefox_ingest_document(UUID, TEXT, TEXT, TEXT, TEXT, JSONB, TEXT, JSONB, TEXT, TEXT, TEXT, INT, BOOLEAN);
|
|
1294
1294
|
DROP FUNCTION IF EXISTS cerefox_ingest_document(UUID, TEXT, TEXT, TEXT, TEXT, JSONB, TEXT, JSONB, TEXT, TEXT, TEXT, INT, BOOLEAN, TEXT, BOOLEAN);
|
|
1295
1295
|
DROP FUNCTION IF EXISTS cerefox_ingest_document(UUID, TEXT, TEXT, TEXT, TEXT, JSONB, TEXT, JSONB, TEXT, TEXT, TEXT, INT, BOOLEAN, TEXT, BOOLEAN, SMALLINT);
|
|
1296
|
+
-- iter-33: return shape gains content_hash + size_warning, so the 16-arg form
|
|
1297
|
+
-- must be dropped before the 17-arg CREATE below (Postgres will not replace a
|
|
1298
|
+
-- function whose RETURNS TABLE changed).
|
|
1299
|
+
DROP FUNCTION IF EXISTS cerefox_ingest_document(UUID, TEXT, TEXT, TEXT, TEXT, JSONB, TEXT, JSONB, TEXT, TEXT, TEXT, INT, BOOLEAN, TEXT, BOOLEAN, SMALLINT, JSONB);
|
|
1296
1300
|
CREATE FUNCTION cerefox_ingest_document(
|
|
1297
1301
|
p_document_id UUID DEFAULT NULL,
|
|
1298
1302
|
p_title TEXT DEFAULT 'Untitled',
|
|
@@ -1324,14 +1328,30 @@ CREATE FUNCTION cerefox_ingest_document(
|
|
|
1324
1328
|
-- content_format for the chunks being written (iter-28D). 2 = exact-partition
|
|
1325
1329
|
-- (blind-stitch reconstruction); default 1 = legacy (E'\n\n'-join). Stamped on
|
|
1326
1330
|
-- every chunk this call inserts.
|
|
1327
|
-
p_content_format SMALLINT DEFAULT 1
|
|
1331
|
+
p_content_format SMALLINT DEFAULT 1,
|
|
1332
|
+
-- iter-33 (partial edits): when NULL, audit behaves exactly as before
|
|
1333
|
+
-- ('create' / 'update-content'). When set, it is a JSONB array of
|
|
1334
|
+
-- {"op": "...", "detail": "..."} and ONE audit entry is written per element,
|
|
1335
|
+
-- so a cerefox_edit batch records what it actually did rather than
|
|
1336
|
+
-- flattening to 'update-content'. NULL-means-today, per the #183 lesson:
|
|
1337
|
+
-- a parameter that substitutes its own concrete default is how store policy
|
|
1338
|
+
-- got silently overridden for a whole release.
|
|
1339
|
+
p_operations JSONB DEFAULT NULL
|
|
1328
1340
|
)
|
|
1329
1341
|
RETURNS TABLE (
|
|
1330
1342
|
document_id UUID,
|
|
1331
1343
|
chunk_count INT,
|
|
1332
1344
|
total_chars INT,
|
|
1333
1345
|
operation TEXT,
|
|
1334
|
-
version_id UUID
|
|
1346
|
+
version_id UUID,
|
|
1347
|
+
-- iter-33: the hash just written, on CREATE as well as update (#189). A
|
|
1348
|
+
-- document is now born holding its own concurrency token, so the author
|
|
1349
|
+
-- never has to re-read it or fall back to last_write_wins.
|
|
1350
|
+
content_hash TEXT,
|
|
1351
|
+
-- iter-33: true when the new size crosses `document_size_warning_chars`
|
|
1352
|
+
-- (dormant when that config is unset/0). A signal, never a refusal: an
|
|
1353
|
+
-- insert-only workflow otherwise never sees a document grow.
|
|
1354
|
+
size_warning BOOLEAN
|
|
1335
1355
|
)
|
|
1336
1356
|
LANGUAGE plpgsql
|
|
1337
1357
|
SECURITY DEFINER
|
|
@@ -1348,6 +1368,9 @@ DECLARE
|
|
|
1348
1368
|
v_chunk JSONB;
|
|
1349
1369
|
v_snap RECORD;
|
|
1350
1370
|
v_status TEXT;
|
|
1371
|
+
v_op JSONB; -- iter-33: per-operation audit element
|
|
1372
|
+
v_size_warn_at INT;
|
|
1373
|
+
v_size_warning BOOLEAN := FALSE;
|
|
1351
1374
|
BEGIN
|
|
1352
1375
|
-- ── Zero-chunk guard (v0.3.1) ────────────────────────────────────────
|
|
1353
1376
|
-- Refuse to create or update a document with no chunks. Three reasons:
|
|
@@ -1506,21 +1529,68 @@ BEGIN
|
|
|
1506
1529
|
setweight(to_tsvector('english', COALESCE(c->>'content', '')), 'B')
|
|
1507
1530
|
FROM jsonb_array_elements(p_chunks) AS c;
|
|
1508
1531
|
|
|
1509
|
-
-- ── Audit
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1532
|
+
-- ── Audit entries ────────────────────────────────────────────────
|
|
1533
|
+
-- p_operations NULL (every pre-iter-33 caller): one entry, exactly as before.
|
|
1534
|
+
-- p_operations set (cerefox_insert / cerefox_edit): one entry per operation,
|
|
1535
|
+
-- each under its own operation value, so the trail distinguishes "added to"
|
|
1536
|
+
-- from "rewrote" from "removed" instead of flattening to 'update-content'.
|
|
1537
|
+
-- The CHECK constraint on cerefox_audit_log.operation is the allow-list: a
|
|
1538
|
+
-- handler label that drifts from it aborts this transaction rather than
|
|
1539
|
+
-- silently recording something the readers of the trail cannot interpret.
|
|
1540
|
+
IF p_operations IS NULL OR jsonb_array_length(p_operations) = 0 THEN
|
|
1541
|
+
PERFORM cerefox_create_audit_entry(
|
|
1542
|
+
p_document_id := v_doc_id,
|
|
1543
|
+
p_version_id := v_version_id,
|
|
1544
|
+
p_operation := v_operation,
|
|
1545
|
+
p_author := p_author,
|
|
1546
|
+
p_author_type := p_author_type,
|
|
1547
|
+
p_size_before := CASE WHEN v_operation = 'create' THEN NULL ELSE v_old_chars END,
|
|
1548
|
+
p_size_after := v_total_chars,
|
|
1549
|
+
p_description := v_operation || ': ' || p_title || ' (' || v_chunk_count || ' chunks, ' || v_total_chars || ' chars)'
|
|
1550
|
+
|| CASE WHEN p_last_write_wins AND v_operation = 'update-content'
|
|
1551
|
+
THEN ' [last-write-wins]' ELSE '' END
|
|
1552
|
+
);
|
|
1553
|
+
ELSE
|
|
1554
|
+
FOR v_op IN SELECT * FROM jsonb_array_elements(p_operations) LOOP
|
|
1555
|
+
PERFORM cerefox_create_audit_entry(
|
|
1556
|
+
p_document_id := v_doc_id,
|
|
1557
|
+
p_version_id := v_version_id,
|
|
1558
|
+
p_operation := v_op->>'op',
|
|
1559
|
+
p_author := p_author,
|
|
1560
|
+
p_author_type := p_author_type,
|
|
1561
|
+
-- Sizes describe the whole write, so they go on the last entry
|
|
1562
|
+
-- only; per-operation sizes would double-count a single write.
|
|
1563
|
+
p_size_before := NULL,
|
|
1564
|
+
p_size_after := NULL,
|
|
1565
|
+
p_description := COALESCE(v_op->>'detail', v_op->>'op')
|
|
1566
|
+
);
|
|
1567
|
+
END LOOP;
|
|
1568
|
+
-- One sizing entry for the write as a whole.
|
|
1569
|
+
PERFORM cerefox_create_audit_entry(
|
|
1570
|
+
p_document_id := v_doc_id,
|
|
1571
|
+
p_version_id := v_version_id,
|
|
1572
|
+
p_operation := v_operation,
|
|
1573
|
+
p_author := p_author,
|
|
1574
|
+
p_author_type := p_author_type,
|
|
1575
|
+
p_size_before := CASE WHEN v_operation = 'create' THEN NULL ELSE v_old_chars END,
|
|
1576
|
+
p_size_after := v_total_chars,
|
|
1577
|
+
p_description := 'partial edit: ' || p_title || ' ('
|
|
1578
|
+
|| jsonb_array_length(p_operations) || ' operation(s), '
|
|
1579
|
+
|| v_chunk_count || ' chunks, ' || v_total_chars || ' chars)'
|
|
1580
|
+
);
|
|
1581
|
+
END IF;
|
|
1582
|
+
|
|
1583
|
+
-- ── Size signal (iter-33) ────────────────────────────────────────
|
|
1584
|
+
-- Dormant unless an operator sets a threshold. Never blocks the write: a
|
|
1585
|
+
-- size policy is not a correctness rule, and an agent that only ever
|
|
1586
|
+
-- inserts otherwise never sees the document grow past its split point.
|
|
1587
|
+
v_size_warn_at := cerefox_config_int('document_size_warning_chars', 0);
|
|
1588
|
+
IF v_size_warn_at > 0 AND v_total_chars > v_size_warn_at THEN
|
|
1589
|
+
v_size_warning := TRUE;
|
|
1590
|
+
END IF;
|
|
1522
1591
|
|
|
1523
|
-
RETURN QUERY SELECT v_doc_id, v_chunk_count, v_total_chars, v_operation,
|
|
1592
|
+
RETURN QUERY SELECT v_doc_id, v_chunk_count, v_total_chars, v_operation,
|
|
1593
|
+
v_version_id, p_content_hash, v_size_warning;
|
|
1524
1594
|
END;
|
|
1525
1595
|
$$;
|
|
1526
1596
|
|
|
@@ -1584,12 +1654,19 @@ SET search_path = public, pg_catalog
|
|
|
1584
1654
|
AS $$
|
|
1585
1655
|
INSERT INTO cerefox_audit_log (
|
|
1586
1656
|
document_id, version_id, operation, author, author_type,
|
|
1587
|
-
size_before, size_after, description
|
|
1657
|
+
size_before, size_after, description, created_at
|
|
1588
1658
|
)
|
|
1589
1659
|
VALUES (
|
|
1590
1660
|
p_document_id, p_version_id, p_operation, p_author,
|
|
1591
1661
|
CASE WHEN p_author_type IN ('user', 'agent') THEN p_author_type ELSE 'user' END,
|
|
1592
|
-
p_size_before, p_size_after, p_description
|
|
1662
|
+
p_size_before, p_size_after, p_description,
|
|
1663
|
+
-- clock_timestamp(), not the NOW() default: NOW() is the TRANSACTION's
|
|
1664
|
+
-- start time, so every audit entry written by one cerefox_edit batch
|
|
1665
|
+
-- would share a timestamp and the order of operations inside the batch
|
|
1666
|
+
-- would be unrecoverable from the trail (iter-33). clock_timestamp()
|
|
1667
|
+
-- advances within a transaction, so entries stay orderable. Outside a
|
|
1668
|
+
-- batch this is indistinguishable from the old behaviour.
|
|
1669
|
+
clock_timestamp()
|
|
1593
1670
|
)
|
|
1594
1671
|
RETURNING id AS audit_id, cerefox_audit_log.created_at;
|
|
1595
1672
|
$$;
|
|
@@ -2148,7 +2225,12 @@ DECLARE
|
|
|
2148
2225
|
-- surviving history depended on who saved last.
|
|
2149
2226
|
'version_retention_hours', 'version_cleanup_enabled',
|
|
2150
2227
|
-- Optional features, off by default (iteration 29).
|
|
2151
|
-
'relations_enabled'
|
|
2228
|
+
'relations_enabled',
|
|
2229
|
+
-- Iteration 33: flag writes that push a document past this many chars
|
|
2230
|
+
-- (0 = off). Partial edits make writes cheap, so an insert-only agent
|
|
2231
|
+
-- never assembles the document and never sees it grow past its split
|
|
2232
|
+
-- point. A signal in the write's response, never a refusal.
|
|
2233
|
+
'document_size_warning_chars'
|
|
2152
2234
|
];
|
|
2153
2235
|
BEGIN
|
|
2154
2236
|
IF NOT (p_key = ANY(v_allowed)) THEN
|
|
@@ -2343,7 +2425,10 @@ SET search_path = public, pg_catalog
|
|
|
2343
2425
|
AS $$
|
|
2344
2426
|
-- Keep in lockstep with the `@version:` marker in schema.sql (cut_release.ts
|
|
2345
2427
|
-- enforces it). Bump whenever schema.sql OR rpcs.sql changes.
|
|
2346
|
-
|
|
2428
|
+
-- 0.11.0 supersedes 0.10.6 (v1.2.1, #191): this branch carries that fix plus
|
|
2429
|
+
-- the partial-edit surface, and both migrations (0019, 0020) are in the
|
|
2430
|
+
-- sequence, so a store deploying this gets everything from both lines.
|
|
2431
|
+
SELECT '0.11.0'::TEXT;
|
|
2347
2432
|
$$;
|
|
2348
2433
|
|
|
2349
2434
|
-- ── cerefox_content_format_stats ─────────────────────────────────────────────
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
-- Requires extensions: vector (pgvector), uuid-ossp
|
|
6
6
|
-- These are enabled at the top of db_deploy.py before this file is applied.
|
|
7
7
|
--
|
|
8
|
-
-- @version: 0.
|
|
8
|
+
-- @version: 0.11.0
|
|
9
9
|
-- The `@version` marker above is read by the schema-version-mismatch banner
|
|
10
10
|
-- (see /api/v1/schema-version). Bump it whenever schema.sql OR rpcs.sql
|
|
11
11
|
-- changes in a way that requires `cerefox server deploy` to be re-run —
|
|
@@ -125,7 +125,11 @@ CREATE TABLE IF NOT EXISTS cerefox_audit_log (
|
|
|
125
125
|
operation IN ('create', 'update-content', 'update-metadata', 'delete',
|
|
126
126
|
'status-change', 'archive', 'unarchive', 'restore',
|
|
127
127
|
-- iteration 29: graph edges are auditable writes too
|
|
128
|
-
'relation-set', 'relation-delete'
|
|
128
|
+
'relation-set', 'relation-delete',
|
|
129
|
+
-- iteration 33: partial edits. Distinct from 'update-content'
|
|
130
|
+
-- so the trail separates "added to" from "rewrote" from
|
|
131
|
+
-- "removed" — one entry per operation in a cerefox_edit batch.
|
|
132
|
+
'insert', 'replace-section', 'delete-section')
|
|
129
133
|
),
|
|
130
134
|
CONSTRAINT cerefox_audit_log_author_type_check CHECK (author_type IN ('user', 'agent'))
|
|
131
135
|
);
|
|
@@ -753,6 +753,10 @@ Deno.serve(async (req: Request) => {
|
|
|
753
753
|
title: title.trim(),
|
|
754
754
|
chunk_count: chunks.length,
|
|
755
755
|
total_chars: totalChars,
|
|
756
|
+
// #189: the concurrency token, on CREATE as well as update. Without it the
|
|
757
|
+
// author of a new document had to re-read it, or pass last_write_wins, to
|
|
758
|
+
// make its first edit — and callers took the second.
|
|
759
|
+
content_hash: ingestResult[0].content_hash ?? contentHash,
|
|
756
760
|
project_id: projectId,
|
|
757
761
|
project_name: project_name ?? null,
|
|
758
762
|
}),
|
package/docs/guides/cli.md
CHANGED
|
@@ -46,7 +46,7 @@ cerefox document ingest --paste --title "<title>" [OPTIONS] # stdin
|
|
|
46
46
|
| `--metadata` | `-m` | JSON | _not provided_ | Extra metadata as a JSON object, e.g. `'{"tags":["work"]}'`. **On update, omitting this keeps the document's existing metadata** (v0.11.1); pass `'{}'` to deliberately clear all metadata. |
|
|
47
47
|
| `--update-if-exists` | `-u` | flag | off | Title/source-path-based fallback update. Mutually exclusive with `--document-id`. |
|
|
48
48
|
| `--document-id` | `-i` | UUID | _none_ | Deterministic ID-based update. Errors if the document doesn't exist. |
|
|
49
|
-
| `--expected-content-hash` | — | sha256 | _none_ | **Required on content updates** (v0.11 optimistic concurrency): the `content_hash` of the version this edit is based on, shown by `cerefox document get` / `cerefox search
|
|
49
|
+
| `--expected-content-hash` | — | sha256 | _none_ | **Required on content updates** (v0.11 optimistic concurrency): the `content_hash` of the version this edit is based on, shown by `cerefox document get` / `cerefox search` — and printed by **every write, including create** (v1.3.0), so a script can chain edits without re-reading. Stale → conflict error (re-read, merge, retry). |
|
|
50
50
|
| `--last-write-wins` | — | flag | off | Skip the concurrency check and overwrite regardless of concurrent changes. For re-sync flows where an external source of truth makes conflicts meaningless. Recorded in the audit log. |
|
|
51
51
|
| `--source` | — | str | `paste` / `file` | Source label recorded on the document. |
|
|
52
52
|
| `--author` | — | str | `CEREFOX_AUTHOR_NAME` or `unknown` | Audit-log author identity. |
|
|
@@ -611,7 +611,7 @@ cerefox config set relations_enabled true # tools appear in every agent's lis
|
|
|
611
611
|
cerefox config set relations_enabled false # hidden again; no data removed
|
|
612
612
|
```
|
|
613
613
|
|
|
614
|
-
Agents see
|
|
614
|
+
Agents see 12 tools with the flag off and 16 with it on. See
|
|
615
615
|
[`configuration.md`](configuration.md) for the full runtime-config surface.
|
|
616
616
|
|
|
617
617
|
### `cerefox config list` / `cerefox config get` / `cerefox config set`
|
|
@@ -720,7 +720,9 @@ Every MCP parameter has an exact-name CLI flag (kebab-cased). Short forms exist
|
|
|
720
720
|
| `cerefox_search(query, match_count, project_name, metadata_filter, requestor)` | `cerefox search "<q>" --match-count N --project-name <name> --metadata-filter '<json>' --requestor <name>` |
|
|
721
721
|
| `cerefox_ingest(title, content, project_name, metadata, update_if_exists, document_id, expected_content_hash, last_write_wins, source, author, author_type)` (file) | `cerefox document ingest <path> --title <t> --project-name <n> --metadata '<json>' --update-if-exists\|--document-id <uuid> --expected-content-hash <hash>\|--last-write-wins --source <s> --author <a> --author-type <t>` |
|
|
722
722
|
| `cerefox_ingest(...)` (paste) | `printf '...' \| cerefox document ingest --paste --title "<t>"` (same flags) |
|
|
723
|
-
| `cerefox_get_document(document_id, version_id, requestor)` | `cerefox document get <id> --version-id <vid> --requestor <name>` |
|
|
723
|
+
| `cerefox_get_document(document_id, version_id, outline, requestor)` | `cerefox document get <id> --version-id <vid> --outline --requestor <name>` |
|
|
724
|
+
| `cerefox_insert(document_id, text, position, anchor_heading, section_part, expected_content_hash, requestor)` | `cerefox document insert <id> -t <text\|-\|@file> -p <position> -a <anchor> --section-part <part> --expected-hash <hash> --requestor <name>` |
|
|
725
|
+
| `cerefox_edit(document_id, operations, expected_content_hash, requestor)` | `cerefox document edit-parts <id> -o <json\|-\|@file> --expected-hash <hash> --requestor <name>` |
|
|
724
726
|
| `cerefox_list_versions(document_id, requestor)` | `cerefox document version list <id> --requestor <name>` |
|
|
725
727
|
| `cerefox_list_projects(requestor)` | `cerefox project list --requestor <name>` |
|
|
726
728
|
| `cerefox_set_document_projects(document_id, project_names, author)` | `cerefox document set-projects <id> <name...> --author <a> --author-type <t>` (or `--clear` to remove all) |
|
|
@@ -122,6 +122,14 @@ This handles intermittent OpenAI API errors (500s) that would otherwise cause se
|
|
|
122
122
|
> **dormant**: the table stays empty, `lifecycle_status` defaults to `active`,
|
|
123
123
|
> search is untouched, and the tools do not appear in any agent's tool list
|
|
124
124
|
> until you opt in with `cerefox config set relations_enabled true`.
|
|
125
|
+
>
|
|
126
|
+
> **Size signal for partial edits.** `document_size_warning_chars` (default `0`
|
|
127
|
+
> = off) makes every write report when a document has grown past the given
|
|
128
|
+
> size. It exists because partial edits (v1.3.0) make writes cheap: an agent
|
|
129
|
+
> that only ever inserts never assembles the document, so it never sees it
|
|
130
|
+
> approach the point where it should be split. A signal only — writes are never
|
|
131
|
+
> blocked. `cerefox config set document_size_warning_chars 50000` mirrors the
|
|
132
|
+
> maintainers' own split-at-~50K practice.
|
|
125
133
|
|
|
126
134
|
> **Deployment-wide defaults (v1.1.0+).** `min_search_score`,
|
|
127
135
|
> `min_term_coverage`, and `search_alpha` can also be set **once, in the
|
|
@@ -72,7 +72,7 @@ in the container.
|
|
|
72
72
|
- **Easiest:** `cerefox-local configure-agent` wires it up (registers an MCP server named
|
|
73
73
|
`cerefox-local` with Claude Code if the `claude` CLI is present, else prints the snippet).
|
|
74
74
|
- **Manual:** point the client at `command: cerefox-local, args: ["mcp"]` (stdio). That proxies
|
|
75
|
-
to `cerefox mcp` in the container; the same
|
|
75
|
+
to `cerefox mcp` in the container; the same 12 core tools, identical behavior to every other path.
|
|
76
76
|
- The cloud paths above (remote Edge Function, GPT Actions) **do not apply** to a local-only
|
|
77
77
|
install — there are no Edge Functions.
|
|
78
78
|
|
|
@@ -131,7 +131,7 @@ in the container.
|
|
|
131
131
|
|
|
132
132
|
### What it is
|
|
133
133
|
|
|
134
|
-
The local Cerefox MCP server runs on your machine and exposes the same
|
|
134
|
+
The local Cerefox MCP server runs on your machine and exposes the same 12 core tools as the remote
|
|
135
135
|
Edge Function, communicating with clients over stdio.
|
|
136
136
|
|
|
137
137
|
The local server ships as an npm package — **[`@cerefox/memory`](https://www.npmjs.com/package/@cerefox/memory)** — built with the official `@modelcontextprotocol/sdk`.
|
|
@@ -186,7 +186,7 @@ Once configured, every Path A client has these tools:
|
|
|
186
186
|
| `cerefox_set_document_projects` | Set a document's project memberships to exactly the given list (destructive replace; metadata-only, no content change). Use `cerefox_ingest` with singular `project_name` for non-destructive "add". |
|
|
187
187
|
| `cerefox_get_help` | Retrieve Cerefox conventions (the same content as `AGENT_QUICK_REFERENCE.md`) over MCP. Optional `topic` parameter does a case-insensitive H2 substring match. Call this whenever you are uncertain. |
|
|
188
188
|
|
|
189
|
-
> All
|
|
189
|
+
> All 12 core tools are available on both Path A (local and remote MCP) and Path B (GPT Actions
|
|
190
190
|
> via dedicated Edge Functions, except `cerefox_get_help` which is MCP-only). MCP tools use
|
|
191
191
|
> `project_name` (human-readable); primitive Edge Functions (Path B) use `project_id` (UUID).
|
|
192
192
|
|
|
@@ -212,7 +212,7 @@ For the full tool reference, search Cerefox for "How AI Agents Use Cerefox".
|
|
|
212
212
|
After setup, ask your client:
|
|
213
213
|
|
|
214
214
|
> "What tools do you have available?"
|
|
215
|
-
> Expected:
|
|
215
|
+
> Expected: 12 tools listed (`cerefox_search`, `cerefox_ingest`, `cerefox_insert`, `cerefox_edit`, `cerefox_get_document`,
|
|
216
216
|
> `cerefox_list_versions`, `cerefox_list_projects`, `cerefox_list_metadata_keys`,
|
|
217
217
|
> `cerefox_metadata_search`, `cerefox_set_document_projects`, `cerefox_get_audit_log`,
|
|
218
218
|
> `cerefox_get_help`).
|
|
@@ -306,7 +306,7 @@ pick it up automatically.
|
|
|
306
306
|
to primitive Edge Functions. This means each MCP tool call costs a single Edge Function
|
|
307
307
|
invocation.
|
|
308
308
|
|
|
309
|
-
A single HTTPS URL gives any remote-capable MCP client all
|
|
309
|
+
A single HTTPS URL gives any remote-capable MCP client all 12 core tools with full hybrid
|
|
310
310
|
search -- no Python, no `uv`, no local repository clone needed.
|
|
311
311
|
|
|
312
312
|
**URL format:**
|
|
@@ -487,7 +487,7 @@ Replace `<your-project-ref>` with your Supabase project ref.
|
|
|
487
487
|
**Step 3 — Verify:**
|
|
488
488
|
|
|
489
489
|
Launch Codex and use the `/mcp` slash command to confirm the `cerefox` server is connected
|
|
490
|
-
and all
|
|
490
|
+
and all 12 tools are listed.
|
|
491
491
|
|
|
492
492
|
**Notes:**
|
|
493
493
|
- `bearer_token_env_var` is the **name** of the env var (e.g. `"CEREFOX_ACCESS_TOKEN"`), not the
|
|
@@ -610,7 +610,7 @@ In the action editor, paste this schema (replace `<your-project-ref>`):
|
|
|
610
610
|
openapi: 3.1.0
|
|
611
611
|
info:
|
|
612
612
|
title: Cerefox Knowledge Base
|
|
613
|
-
version: 3.
|
|
613
|
+
version: 3.1.0
|
|
614
614
|
servers:
|
|
615
615
|
- url: https://<your-project-ref>.supabase.co/functions/v1
|
|
616
616
|
paths:
|
|
@@ -780,7 +780,9 @@ paths:
|
|
|
780
780
|
project_id?, project_name?, # set when a project was assigned on create
|
|
781
781
|
skipped?, # true when identical content was deduplicated
|
|
782
782
|
updated?, # true when an existing doc was updated
|
|
783
|
-
content_hash
|
|
783
|
+
content_hash, # the new hash — returned on CREATE as well as
|
|
784
|
+
# update, so a new document is born holding
|
|
785
|
+
# its own concurrency token (#189)
|
|
784
786
|
message?, # human note on dedup/skip/update
|
|
785
787
|
note? } # note when a flag (e.g. update_if_exists) was overridden
|
|
786
788
|
'400':
|
|
@@ -1134,7 +1136,7 @@ user + `CEREFOX_OAUTH_OWNER_ID` pin, and register the Claude OAuth App
|
|
|
1134
1136
|
Client Secret from the pre-registered OAuth App (setup-supabase Step 7d).
|
|
1135
1137
|
5. Save. Claude runs the OAuth flow → redirects you to the **Cerefox consent page** (sign
|
|
1136
1138
|
in with the owner email/password from Step 7c, then **Allow**) → returns to Claude. The
|
|
1137
|
-
connector shows as connected with **
|
|
1139
|
+
connector shows as connected with **12 tools** (16 if you have enabled document relations). (If you've approved before, Supabase
|
|
1138
1140
|
auto-consents and the page just flashes through — that's expected.)
|
|
1139
1141
|
6. **Mobile**: connectors are account-level, so `CerefoxMCP` appears in the Claude mobile
|
|
1140
1142
|
app automatically — run one search from your phone to confirm.
|
|
@@ -74,7 +74,7 @@ paths go through **Edge Functions**, which the free tier caps at 500,000/month:
|
|
|
74
74
|
500K/month is generous for a single human-driven agent. But **automated or
|
|
75
75
|
high-frequency agents on the remote path** can approach it. The lever: point those
|
|
76
76
|
agents at the **local stdio MCP server** (`cerefox mcp`) instead of the remote Edge
|
|
77
|
-
Function — it exposes the identical
|
|
77
|
+
Function — it exposes the identical 12 core tools (plus the 4 relation tools when enabled), talks to the Data API directly, and
|
|
78
78
|
costs **zero** Edge Function invocations (bonus: lower latency, and it works offline
|
|
79
79
|
against a reachable database). If you do exceed the free EF quota, Supabase's Pro
|
|
80
80
|
plan ($25/mo, 2M invocations included) is the next step.
|
|
@@ -124,6 +124,19 @@ bun scripts/backup_create.ts && bun scripts/db_migrate.ts
|
|
|
124
124
|
|
|
125
125
|
---
|
|
126
126
|
|
|
127
|
+
## backup_create.ts / backup_restore.ts — thin shims over the CLI
|
|
128
|
+
|
|
129
|
+
> **These delegate to `cerefox backup create` / `cerefox backup restore`.** They
|
|
130
|
+
> used to carry their own capture and restore logic, which is how #166 half-
|
|
131
|
+
> healed: the fixes that taught backups to capture project memberships (v1.0.7),
|
|
132
|
+
> then relations and `lifecycle_status` (v1.1.0), landed in the CLI command and
|
|
133
|
+
> never reached the scripts. Anyone following the pre-migration recipe below got
|
|
134
|
+
> a snapshot missing all of them, silently.
|
|
135
|
+
>
|
|
136
|
+
> They now delegate, so there is one capture path, one restore path, and one
|
|
137
|
+
> format. Prefer the CLI command directly; the scripts remain for the muscle
|
|
138
|
+
> memory and for recipes that already reference them.
|
|
139
|
+
|
|
127
140
|
## backup_create.ts — Create a backup
|
|
128
141
|
|
|
129
142
|
Exports all documents, chunks, and metadata to a JSON file in the backup directory. (End users use `cerefox backup create`.)
|
|
@@ -135,8 +148,8 @@ bun scripts/backup_create.ts [OPTIONS]
|
|
|
135
148
|
| Option | Description |
|
|
136
149
|
|--------|-------------|
|
|
137
150
|
| `--label LABEL` | Optional label appended to the filename (e.g. `pre-migration`) |
|
|
138
|
-
| `--dir DIR` | Directory to write backup to (default: `./
|
|
139
|
-
| `--git-commit` | Stage and commit the backup file to git after writing |
|
|
151
|
+
| `--dir DIR` | Directory to write backup to (default: `./backups`) |
|
|
152
|
+
| `--git-commit` | Stage and commit the backup file to git after writing. Performed by this script after the snapshot is written — `cerefox backup create --git` is a documented no-op, so the flag is deliberately not forwarded. |
|
|
140
153
|
|
|
141
154
|
Backup filename format: `cerefox-{YYYYMMDDTHHMMSSZ}[-{label}].json`
|
|
142
155
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cerefox/memory",
|
|
3
|
-
"version": "1.2
|
|
3
|
+
"version": "1.3.0-beta.2",
|
|
4
4
|
"description": "Cerefox — user-owned shared memory for AI agents. CLI + stdio MCP server + web UI + ingestion for a knowledge base on your own Supabase project (or fully self-hosted with Cerefox Local).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/fstamatelopoulos/cerefox",
|