@rubytech/create-maxy-code 0.1.153 → 0.1.156

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy-code",
3
- "version": "0.1.153",
3
+ "version": "0.1.156",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy-code": "./dist/index.js"
@@ -67,10 +67,10 @@ When the owner is an external Person (non-operator archive), the anchor is the c
67
67
  1. Run the owner-confirmation flow, persist `$ownerUserId` / `$ownerPersonId`. The owner identity resolves to a single `ownerNodeId` (elementId of the AdminUser or external Person) used in every write call.
68
68
  2. For each file the operator approves, load its reference, parse the CSV into typed `rows[]` matching the reference's row schema.
69
69
  3. **Selective-ingest gate.** Before invoking any write tool, check the parsed row count against the reference's `selectiveIngestThreshold`. If the count exceeds the threshold, pause and ask the operator to filter the import along the natural axes named in the reference (for `Connections.csv`: Company, Position, Connected On). Apply the filter to `rows[]` before continuing. Compress on write, never after — a 5,000-row blanket import is a landfill, a 200-row filtered import is signal. See [§Selective-ingest](#selective-ingest-threshold-bulk-archives).
70
- 4. Invoke the deterministic write tool the reference names. For all archive references this is `mcp__memory__memory-archive-write` with `{archiveType, ownerNodeId, rows}` — the Cypher body is fixed server-side per `archiveType`, so the agent supplies parsed rows, never Cypher. The tool batches rows at 500 per transaction internally.
70
+ 4. Invoke the deterministic write tool the reference names. For all archive references this is `mcp__plugin_memory_memory__memory-archive-write` with `{archiveType, ownerNodeId, rows}` — the Cypher body is fixed server-side per `archiveType`, so the agent supplies parsed rows, never Cypher. The tool batches rows at 500 per transaction internally.
71
71
  5. After each file emit `[linkedin-import] file=<name> rows=<n> created=<n> matched=<n> ms=<elapsed>` using the counters returned by the write tool.
72
72
 
73
- **Doctrine:** raw Cypher and `cypher-shell` invocations are forbidden in this skill and its references. Writes route through `mcp__memory__memory-archive-write` (bulk archives) or `mcp__memory__memory-write` / `mcp__memory__memory-update` (single-node enrichments like `profile.md`). If a CSV needs a write shape no current MCP tool supports, file a task to extend `memory-archive-write` with a new `archiveType` handler — never improvise via Bash. See [librarian's LOUD-FAIL prerogative](../../../../templates/specialists/agents/librarian.md#prerogatives).
73
+ **Doctrine:** raw Cypher and `cypher-shell` invocations are forbidden in this skill and its references. Writes route through `mcp__plugin_memory_memory__memory-archive-write` (bulk archives) or `mcp__plugin_memory_memory__memory-write` / `mcp__plugin_memory_memory__memory-update` (single-node enrichments like `profile.md`). If a CSV needs a write shape no current MCP tool supports, file a task to extend `memory-archive-write` with a new `archiveType` handler — never improvise via Bash. See [librarian's LOUD-FAIL prerogative](../../../../templates/specialists/agents/librarian.md#prerogatives).
74
74
 
75
75
  **LOUD-FAIL on parse errors (structurally enforced).** When LinkedIn parser tools land that follow the `mcp__*__*-import-parse` naming convention, the harness-level `platform/plugins/admin/hooks/archive-ingest-gate.sh` will record an `isError: true` response and block every subsequent tool call this turn until the operator submits the next prompt. The hook also denies edits to `platform/plugins/*/lib/*` and JavaScript test runners (`vitest`, `bun test`, `npm test`, `npx jest`) unconditionally. The skill's "no Bash improvisation" doctrine above is the contract; the hook is the enforcement. See [.docs/hooks.md](../../../../../.docs/hooks.md) for the full gate surface.
76
76
 
@@ -52,7 +52,7 @@ Resolved at skill start via the owner-confirmation flow. The owner is either an
52
52
 
53
53
  ## Write surface
54
54
 
55
- This reference invokes a single MCP tool: `mcp__memory__memory-archive-write` with `archiveType: "linkedin-connections"`. The Cypher body — Person upsert by `linkedinUrl`, `CONNECTED_ON_LINKEDIN` edge from owner, optional `:Organization` + `WORKS_FOR` when company is non-empty — lives server-side in [`platform/plugins/memory/mcp/src/tools/memory-archive-write.ts`](../../../../memory/mcp/src/tools/memory-archive-write.ts). The agent does not author or pipe Cypher; it parses CSV rows into the tool's row schema and dispatches one (or more, for filtered re-imports) tool call.
55
+ This reference invokes a single MCP tool: `mcp__plugin_memory_memory__memory-archive-write` with `archiveType: "linkedin-connections"`. The Cypher body — Person upsert by `linkedinUrl`, `CONNECTED_ON_LINKEDIN` edge from owner, optional `:Organization` + `WORKS_FOR` when company is non-empty — lives server-side in [`platform/plugins/memory/mcp/src/tools/memory-archive-write.ts`](../../../../memory/mcp/src/tools/memory-archive-write.ts). The agent does not author or pipe Cypher; it parses CSV rows into the tool's row schema and dispatches one (or more, for filtered re-imports) tool call.
56
56
 
57
57
  ### Tool input shape
58
58
 
@@ -110,7 +110,6 @@ Rows missing a position but present with a company produce a `WORKS_FOR` edge wi
110
110
 
111
111
  ## Post-import verification (operator-side, not agent-side)
112
112
 
113
- After ingest, the operator can verify counts via the `specialists:librarian` specialist's read tools — `mcp__memory__memory-search` with `labels: ["Person"]` plus a filter, or a direct read query through `mcp__graph__maxy-graph-read_neo4j_cypher`:
114
113
 
115
114
  ```cypher
116
115
  // Owner → connections count
@@ -132,4 +131,4 @@ These are **read queries**, not writes. Cypher writes from the agent are forbidd
132
131
  | Tool error "row connectedOn is not ISO 8601" | Parser left `Connected On` in `"23 Apr 2026"` form | Convert to `YYYY-MM-DD` before passing to the tool |
133
132
  | Tool error "ownerNodeId not found" | Owner-confirmation flow not run, or operator typed the wrong id | Re-run owner confirmation; pass the resulting `elementId` as `ownerNodeId` |
134
133
  | `WORKS_FOR` count « connection count | Many rows have blank company | Expected — LinkedIn doesn't force connections to list a current employer |
135
- | Tool not present in `init` frame | `specialists:librarian` spawned without the `mcp__memory__memory-archive-write` token | Loud-fail per librarian's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
134
+ | Tool not present in `init` frame | `specialists:librarian` spawned without the `mcp__plugin_memory_memory__memory-archive-write` token | Loud-fail per librarian's prerogatives. Do not improvise via Bash. Operator must remediate (re-seed specialist templates) |
@@ -34,7 +34,7 @@ The owner-confirmation flow at the start of the skill resolves the operator's `:
34
34
 
35
35
  ## Write surface
36
36
 
37
- This reference invokes `mcp__memory__memory-update` once with the parsed row's properties:
37
+ This reference invokes `mcp__plugin_memory_memory__memory-update` once with the parsed row's properties:
38
38
 
39
39
  ```json
40
40
  {
@@ -82,7 +82,6 @@ The parser converts:
82
82
 
83
83
  ## Post-import verification (operator-side, read-only)
84
84
 
85
- A direct read query through `mcp__memory__memory-search` (`labels: ["UserProfile"]`) or `mcp__graph__maxy-graph-read_neo4j_cypher`:
86
85
 
87
86
  ```cypher
88
87
  MATCH (au:AdminUser {userId: $ownerUserId})-[:HAS_PROFILE]->(up:UserProfile)
@@ -36,7 +36,6 @@ Present one row per cluster, in a numbered list. The owner picks one of three ac
36
36
 
37
37
  ## Method
38
38
 
39
- 1. **Pull the candidate set.** Call `memory-search` for the topic phrase, or `mcp__graph__maxy-graph-read_neo4j_cypher` for a project or date range. Bound the set: never cluster more than 500 nodes in one run. If the set is larger, ask the owner to narrow. Pass `fields: ["name", "summary"]` (or the keys you actually cluster on) — full bodies blow up the token budget without changing clustering, since ranking sees the full text either way. See `platform/plugins/memory/references/graph-primitives.md` § Projecting `memory-search` fields.
40
39
  2. **Cluster by embedding similarity.** Use the existing embedding on each node. Group nodes whose pairwise similarity is above the cluster threshold (default 0.78). Clusters of one are surfaced separately as "isolated" rows the owner can wire as standalone concepts or skip.
41
40
  3. **Name each cluster.** Compose a one-line name from the highest-weighted terms shared across the cluster's sections. Never use a name that is just a copy of a document title; the name should generalise the cluster.
42
41
  4. **Present proposals.** One numbered row per cluster, in the format above.
@@ -35,7 +35,6 @@ The flow:
35
35
 
36
36
  2. **Read the file head** to discover senders before the script runs. Read the first ~50 lines (or use a per-source preview heuristic). Extract distinct sender display names. The operator never sees the script's own counters — surface a one-line histogram (`Sender '<name>' (<count> messages)`) per distinct sender.
37
37
 
38
- 3. **List candidate `:AdminUser` and existing `:Person`** rows for the senders via `mcp__graph__maxy-graph-read_neo4j_cypher`.
39
38
 
40
39
  4. **Iterate the histogram, one operator question per distinct senderName.** For each sender: `"Sender '<name>' (<count> messages) — pick existing :AdminUser/:Person or block?"`. The operator either picks an existing elementId or names "block" (refuses to map to a node). **Never auto-create a `:Person`** — the operator must confirm a canonical node, mirroring `feedback_archives_are_not_documents.md`'s closed-set discipline.
41
40
 
@@ -189,7 +188,6 @@ For an empty-delta re-import (`delta.kind === "empty-delta"`): emit only message
189
188
 
190
189
  ## Verification (post-write)
191
190
 
192
- Run via `mcp__graph__maxy-graph-read_neo4j_cypher`:
193
191
 
194
192
  - `MATCH (a:ConversationArchive { conversationIdentity: $cid }) RETURN elementId(a), a.source, a.lastIngestedMessageAt, a.lastIngestedMessageHash` — `source` matches `--source`; counters agree with the JSON summary.
195
193
  - `MATCH (a:ConversationArchive { conversationIdentity: $cid })-[:HAS_SECTION]->(c:Section) RETURN count(c)` — equals `chunks`.
@@ -1,13 +1,12 @@
1
1
  ---
2
2
  name: conversation-archive-enrich
3
- description: Source-agnostic Phase 2 for any `:KnowledgeDocument` — walks the `:Section` chunks of one named archive and asks the operator to confirm derived claims row-by-row. Fires only when the operator names a specific archive and asks for insights/enrichment; never auto-fires on Phase 1 completion. Per-row gate (wire / skip / reject) over four kinds — `mention`, `task`, `preference`, `observed-relationship`. Re-runs are idempotent on `(elementId(chunk), kind, contentHash)`, so collapsing duplicates is structural. Invokes the read-only MCP tool `mcp__memory__conversation-archive-derive-insights` to obtain proposals; never writes from the tool's return path. Each `wire` decision runs the proposal's returned `mergeCypher` via `mcp__graph__maxy-graph-write_neo4j_cypher`, or, for `task`, mints the `:Task` via `mcp__work__work-create` first and then runs the REFERENCES merge.
4
3
  ---
5
4
 
6
5
  # Conversation Archive — chunk-anchored insight derivation
7
6
 
8
7
  **Invoked from `specialists:librarian`** — the admin agent dispatches the librarian when the operator names an existing `:KnowledgeDocument` and asks for enrichment / derived insights; the librarian loads this skill.
9
8
 
10
- One skill. Walks one `:KnowledgeDocument`'s chunks in pages. Per chunk, Haiku surfaces high-confidence claims via `mcp__memory__conversation-archive-derive-insights`; per claim, the operator decides `wire / skip / reject`. The tool is read-only; the only writes happen through this skill's per-row dispatch.
9
+ One skill. Walks one `:KnowledgeDocument`'s chunks in pages. Per chunk, Haiku surfaces high-confidence claims via `mcp__plugin_memory_memory__conversation-archive-derive-insights`; per claim, the operator decides `wire / skip / reject`. The tool is read-only; the only writes happen through this skill's per-row dispatch.
11
10
 
12
11
  ## When to invoke
13
12
 
@@ -21,7 +20,7 @@ Never auto-fire after a Phase 1 ingest completes — `conversation-archive` (the
21
20
 
22
21
  ## Resolve the archive
23
22
 
24
- Operator phrasing usually names participants or the source file, not an `elementId`. Resolve via `mcp__memory__memory-search`:
23
+ Operator phrasing usually names participants or the source file, not an `elementId`. Resolve via `mcp__plugin_memory_memory__memory-search`:
25
24
 
26
25
  ```
27
26
  memory-search { query: "<operator's phrasing>", labels: ["KnowledgeDocument"], expandHops: 0, fields: ["title"] }
@@ -34,7 +33,7 @@ If multiple `:KnowledgeDocument` rows match, ask the operator to pick by `title`
34
33
  Page through the chunks with the read-only MCP tool. Default page size is 5 chunks.
35
34
 
36
35
  ```
37
- mcp__memory__conversation-archive-derive-insights {
36
+ mcp__plugin_memory_memory__conversation-archive-derive-insights {
38
37
  archiveElementId: "<elementId>",
39
38
  chunkOffset: 0,
40
39
  chunkLimit: 5,
@@ -70,22 +69,19 @@ Dispatch per kind. Provenance (`createdByTool`, `createdBySession`, `createdAt`)
70
69
 
71
70
  The proposal carries `disambiguation.needsResolution[0]` naming the entity to resolve.
72
71
 
73
- 1. Resolve via `mcp__memory__memory-search { query: "<displayName>", labels: ["Person", "Organization"], expandHops: 0 }`.
74
- 2. If multiple candidates: ask the operator to pick by `elementId`. If zero candidates: ask the operator `mint via contact-create / reject`. Minting goes through `mcp__contacts__contact-create` (operator-confirmed canonical Person/Organization — never auto-mint).
75
- 3. Run the `mergeCypher` via `mcp__graph__maxy-graph-write_neo4j_cypher` with `mergeParams` plus `targetElementId=<resolved elementId>`.
72
+ 1. Resolve via `mcp__plugin_memory_memory__memory-search { query: "<displayName>", labels: ["Person", "Organization"], expandHops: 0 }`.
73
+ 2. If multiple candidates: ask the operator to pick by `elementId`. If zero candidates: ask the operator `mint via contact-create / reject`. Minting goes through `mcp__plugin_contacts_contacts__contact-create` (operator-confirmed canonical Person/Organization — never auto-mint).
76
74
 
77
75
  A re-run against the same `(chunkElementId, target, contentHash)` collapses on the MERGE — no duplicate edges.
78
76
 
79
77
  ### `task`
80
78
 
81
- 1. Mint the `:Task` via `mcp__work__work-create` with `title=mergeParams.taskTitle`, optional due hint from `mergeParams.taskDueHint`, `affects=archiveElementId`, `raisedDuringConversationKey=chunkElementId`.
82
- 2. Run the proposal's `mergeCypher` via `mcp__graph__maxy-graph-write_neo4j_cypher` with `mergeParams` plus `taskElementId=<minted Task elementId>`.
79
+ 1. Mint the `:Task` via `mcp__plugin_work_work__work-create` with `title=mergeParams.taskTitle`, optional due hint from `mergeParams.taskDueHint`, `affects=archiveElementId`, `raisedDuringConversationKey=chunkElementId`.
83
80
 
84
81
  The `:Task` itself is the durable artefact; the `REFERENCES` edge to the chunk records the evidence that produced it.
85
82
 
86
83
  ### `preference`
87
84
 
88
- No disambiguation step — the `:Preference` node is account-scoped and MERGE-keyed on `(accountId, contentHash)`. Run the proposal's `mergeCypher` directly via `mcp__graph__maxy-graph-write_neo4j_cypher` with `mergeParams` (no additional substitutions).
89
85
 
90
86
  The `mergeCypher` MERGEs the `:Preference`, sets category/key/value on first create, and creates the `(:Preference)-[:OBSERVED_IN]->(chunk)` edge that ties the preference to its evidence.
91
87
 
@@ -93,7 +89,7 @@ The `mergeCypher` MERGEs the `:Preference`, sets category/key/value on first cre
93
89
 
94
90
  Two-entity resolution. The proposal carries `disambiguation.needsResolution` with `subject` and `object`.
95
91
 
96
- 1. Resolve each via `mcp__memory__memory-search` as in `mention`. Reject the proposal if either entity does not resolve and the operator declines to mint via `contact-create`.
92
+ 1. Resolve each via `mcp__plugin_memory_memory__memory-search` as in `mention`. Reject the proposal if either entity does not resolve and the operator declines to mint via `contact-create`.
97
93
  2. Run the `mergeCypher` with `mergeParams` plus `subjectElementId=<resolved>` and `objectElementId=<resolved>`.
98
94
 
99
95
  The merged `:RELATED_TO` edge carries `operatorConfirmed: true` so downstream queries can filter speculative relationships out.
@@ -102,11 +98,11 @@ The merged `:RELATED_TO` edge carries `operatorConfirmed: true` so downstream qu
102
98
 
103
99
  `skip` — the operator wants to move on without writing. Note locally and continue. Skips are not persisted; the proposal re-surfaces on the next run.
104
100
 
105
- `reject` — the operator deems the claim wrong. Call `mcp__memory__conversation-archive-enrich-rejection` with `mode: "record"` and the proposal's `chunkElementId`, `kind`, `contentHash`, `archiveElementId`. The tool appends a line to the account's `data/accounts/<accountId>/state/conversation-archive-enrich-rejections.jsonl` sidecar; on every subsequent walk the `conversation-archive-derive-insights` tool filters proposals matching any recorded `(chunkElementId, kind, contentHash)` tuple. Duplicate `record` calls for the same key are silent no-ops.
101
+ `reject` — the operator deems the claim wrong. Call `mcp__plugin_memory_memory__conversation-archive-enrich-rejection` with `mode: "record"` and the proposal's `chunkElementId`, `kind`, `contentHash`, `archiveElementId`. The tool appends a line to the account's `data/accounts/<accountId>/state/conversation-archive-enrich-rejections.jsonl` sidecar; on every subsequent walk the `conversation-archive-derive-insights` tool filters proposals matching any recorded `(chunkElementId, kind, contentHash)` tuple. Duplicate `record` calls for the same key are silent no-ops.
106
102
 
107
103
  ## Wire undoes prior rejection
108
104
 
109
- After a successful `wire` (any kind), call `mcp__memory__conversation-archive-enrich-rejection` with `mode: "undo"` and the same `(chunkElementId, kind, contentHash)` triple. Operators who change their minds and wire a once-rejected claim should not have to manage rejection state by hand — the wire-then-undo pairing keeps the JSONL aligned with the live graph. Calling `undo` for a key that was never rejected is a silent no-op (`beforeCount=0, afterCount=0`).
105
+ After a successful `wire` (any kind), call `mcp__plugin_memory_memory__conversation-archive-enrich-rejection` with `mode: "undo"` and the same `(chunkElementId, kind, contentHash)` triple. Operators who change their minds and wire a once-rejected claim should not have to manage rejection state by hand — the wire-then-undo pairing keeps the JSONL aligned with the live graph. Calling `undo` for a key that was never rejected is a silent no-op (`beforeCount=0, afterCount=0`).
110
106
 
111
107
  ## Observability
112
108
 
@@ -140,7 +136,6 @@ And one end-of-walk summary:
140
136
 
141
137
  ## Verification (post-enrich)
142
138
 
143
- Run via `mcp__graph__maxy-graph-read_neo4j_cypher`:
144
139
 
145
140
  - All wired writes carry `createdByTool='conversation-archive-derive-insights'`. Count per kind:
146
141
  ```
@@ -187,7 +187,6 @@ After `memory-ingest` returns the new KnowledgeDocument's `documentNodeId`, this
187
187
  **Entity sources.** The dispatch brief's "key entities to connect" list. Brief shape: prose names of Persons, Organizations, Services, Tasks, Events, KnowledgeDocuments, BrandingData that the document describes or references. Example: *"Person nodes for Joel Smalley, Adam Mackay, Dan McLeod; LocalBusiness / Organization nodes for Real Agent / Real Agency; Any existing Task nodes related to Real Agent Lettings."* Extract every named entity from the brief before any `memory-write`.
188
188
 
189
189
  **Resolution.** For each named entity:
190
- 1. Resolve the elementId via `memory-search` (preferred — handles fuzzy name matching against existing graph nodes) or a single-shot `MATCH (n:<Label> { <identifying-prop>: $value, accountId: $accountId }) RETURN elementId(n)` via `mcp__graph__maxy-graph-read_neo4j_cypher` for exact-match lookups. For `memory-search` calls here, pass `fields: ["name"]` (or whatever single key you need) — you only want the elementId match, not the full bio/notes/sourceUrl payload. See `platform/plugins/memory/references/graph-primitives.md` § Projecting `memory-search` fields.
191
190
  2. If the entity resolves to exactly one node, write the edge from KD to that node (see edge-type table below).
192
191
  3. If the entity resolves to zero nodes, append it to the orphan list (do NOT create a placeholder Person/Organization — that's classifier-emitted `documentEdges` territory, not brief-wiring).
193
192
  4. If the entity resolves to multiple nodes (ambiguity — two Persons named "Joel"), pick the one whose context best fits the brief and document (e.g. last-mentioned-recently, or matching account). Surface the choice in the operator narrative so it can be corrected.
@@ -71,7 +71,7 @@ When the user-turn context contains a block beginning with `[system: <name>-hook
71
71
  2. Execute that single `Task` dispatch before composing your reply to the operator. Forward the dispatch prompt verbatim — do not paraphrase, do not surface the dispatch in chat.
72
72
  3. When the subagent returns its one-line summary, continue with your normal response to the operator's prompt. The subagent's summary is not surfaced; your assistant text addresses the operator's prompt, not the background pass.
73
73
 
74
- These directives are never operator-driven. The `pre-turn-graph-pass.sh` directive (Tasks 425, 430) is the running example: it asks you to scan the operator turn you just received and dispatch one `database-operator` Task per candidate write (new mentions, ideas, commitments, contacts, learnings the operator stated this turn), using the `<prior-writes>` skip-list to avoid duplicates and attach to existing nodes by elementId. You are the session-walker; the specialist only sees per-write briefs. Zero candidate writes ⇒ zero dispatches — never invent one to look busy. The per-turn pass covers every operator turn; the final assistant reply of the session is picked up by the `/end` retrospective walk.
74
+ These directives are never operator-driven. The `pre-turn-graph-pass.sh` directive (Tasks 425, 430) is the running example: it asks you to scan the operator turn you just received and dispatch one `database-operator` Task per candidate write (new mentions, ideas, commitments, contacts, learnings the operator stated this turn), using the prior-writes skip-list to avoid duplicates and attach to existing nodes by elementId. You are the session-walker; the specialist only sees per-write briefs. Zero candidate writes ⇒ zero dispatches — never invent one to look busy. The per-turn pass covers every operator turn; the final assistant reply of the session is picked up by the `/end` retrospective walk.
75
75
 
76
76
  ## SOUL.md
77
77
 
@@ -3,7 +3,7 @@ name: librarian
3
3
  description: "Foreground ingester for the memory graph. Owns external-archive and document ingestion — PDFs, web pages, plain text, conversation transcripts (WhatsApp / Telegram / Signal / iMessage / Slack / LinkedIn DMs / Zoom / meeting minutes), LinkedIn Basic Data Exports, and post-unzip trees the admin agent forwards. Loads `document-ingest`, `conversation-archive`, `conversation-archive-enrich`, and `linkedin-import` skills. Returns to the admin agent with a structured outcome line; never interacts with the operator directly except through the dispatching agent."
4
4
  summary: "Owns foreground ingest of documents, conversation transcripts, and external archives into the memory graph."
5
5
  model: claude-sonnet-4-5
6
- tools: mcp__memory__memory-ingest-extract, mcp__memory__memory-ingest, mcp__memory__memory-ingest-web, mcp__memory__memory-classify, mcp__memory__memory-archive-write, mcp__memory__memory-write, mcp__memory__memory-update, mcp__memory__memory-search, mcp__memory__conversation-archive-derive-insights, mcp__memory__conversation-archive-enrich-rejection, mcp__graph__maxy-graph-read_neo4j_cypher, mcp__graph__maxy-graph-write_neo4j_cypher, mcp__contacts__contact-create, mcp__work__work-create, Read, Bash
6
+ tools: mcp__plugin_memory_memory__memory-ingest-extract, mcp__plugin_memory_memory__memory-ingest, mcp__plugin_memory_memory__memory-ingest-web, mcp__plugin_memory_memory__memory-archive-write, mcp__plugin_memory_memory__memory-write, mcp__plugin_memory_memory__memory-update, mcp__plugin_memory_memory__memory-search, mcp__plugin_memory_memory__conversation-archive-derive-insights, mcp__plugin_memory_memory__conversation-archive-enrich-rejection, mcp__plugin_contacts_contacts__contact-create, mcp__plugin_work_work__work-create, Read, Bash
7
7
  ---
8
8
 
9
9
  # Librarian