klypix-mcp 1.92.0 → 1.94.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 +207 -18
- package/bin/klypix-install.mjs +9 -5
- package/bin/klypix-worker.mjs +129 -27
- package/package.json +4 -2
- package/src/agent-presence.mjs +1 -1
- package/src/app-bridge-client.mjs +350 -0
- package/src/app-bridge-protocol.mjs +319 -0
- package/src/app-lease.mjs +3 -0
- package/src/app-tools.mjs +1118 -72
- package/src/brain-doctor.mjs +53 -2
- package/src/card-files.mjs +526 -0
- package/src/klypix-core.mjs +91 -65
- package/src/klypix-format.mjs +53 -13
- package/src/mcp-auto-update.mjs +86 -0
- package/src/mcp-presence.mjs +1 -1
- package/src/mcp-supervisor.mjs +63 -18
- package/src/semantic-memory.mjs +16 -1
package/README.md
CHANGED
|
@@ -119,7 +119,7 @@ npx klypix-mcp conformance
|
|
|
119
119
|
|
|
120
120
|
It runs in a temporary fixture and touches nothing else. It checks tool discovery, task memory,
|
|
121
121
|
truthful peer reporting, overlap surfacing, proactive logging, and in-band delivery of a peer note.
|
|
122
|
-
It verifies 15 required coordination behaviours — not
|
|
122
|
+
It verifies 15 required coordination behaviours — not every tool, and not the retrieval engine.
|
|
123
123
|
|
|
124
124
|
---
|
|
125
125
|
|
|
@@ -344,6 +344,82 @@ it lists the tools:
|
|
|
344
344
|
|
|
345
345
|
---
|
|
346
346
|
|
|
347
|
+
## Running as a Claude plugin
|
|
348
|
+
|
|
349
|
+
The KLYPIX Claude plugin starts this server as `npx -y klypix-mcp@1.93.0`: one exact version, never
|
|
350
|
+
a range or `latest`. It sets three variables: `KLYPIX_PLUGIN=1`,
|
|
351
|
+
`KLYPIX_PLUGIN_DATA=${CLAUDE_PLUGIN_DATA}` and `KLYPIX_VAULT=${CLAUDE_PROJECT_DIR}`.
|
|
352
|
+
`KLYPIX_PLUGIN=1` turns on **plugin mode**, which changes how the MCP server behaves and nothing
|
|
353
|
+
else. Every `npx klypix-mcp` command (`install`, `link`, `doctor`, `sessions` and the rest) works
|
|
354
|
+
exactly as described elsewhere in this README. Only `KLYPIX_PLUGIN=1` turns plugin mode on;
|
|
355
|
+
`CLAUDE_PLUGIN_ROOT` on its own does not.
|
|
356
|
+
|
|
357
|
+
**What plugin mode never does**
|
|
358
|
+
|
|
359
|
+
- **Update itself.** It never asks npm for a newer release and never installs one, whatever
|
|
360
|
+
`KLYPIX_AUTO_UPDATE` is set to. You run the version the plugin pins, and a newer version reaches
|
|
361
|
+
you only in a new plugin release.
|
|
362
|
+
- **Run code from outside the package.** It runs only the worker inside the pinned package. It
|
|
363
|
+
never starts or switches to the copy that `npx klypix-mcp install` puts in
|
|
364
|
+
`~/.claude/project-brain`, and it never loads the optional on-device semantic model from that
|
|
365
|
+
folder. Search is keyword-only, so it never downloads model weights.
|
|
366
|
+
- **Write project config files.** It never creates or rewrites rules files, editor MCP configs
|
|
367
|
+
(`.mcp.json`, `.cursor/`, `.codex/config.toml` and the rest) or the `AGENTS.md` brief block, in
|
|
368
|
+
this project or any other. Outside plugin mode, `brain_sync` and the updater do write these files;
|
|
369
|
+
*Security and permissions* explains when.
|
|
370
|
+
- **Change Claude's settings.** It never writes `~/.claude/settings.json`, hooks, permissions or any
|
|
371
|
+
other host configuration.
|
|
372
|
+
- **Collect data or read credentials.** It sends no telemetry or usage data, reads no API keys or
|
|
373
|
+
account tokens, and opens no network port. The one token it reads is the local bridge token the
|
|
374
|
+
KLYPIX app writes for AI tools while it runs (below); it is never logged or returned.
|
|
375
|
+
|
|
376
|
+
**Network.** Plugin mode makes two kinds of request, and both go to the public npm registry. The
|
|
377
|
+
first is npx downloading the pinned package when the plugin starts the server. The second is one
|
|
378
|
+
`npm view klypix-mcp version`, and it runs only when an agent calls `brain_doctor` with
|
|
379
|
+
`check_npm: true`. There are no other requests.
|
|
380
|
+
|
|
381
|
+
**Programs it runs on your computer.** Read-only `git` commands in your project (current branch,
|
|
382
|
+
tags, log) for coordination and release checks. Also `brain_reopen`, described at the end of this
|
|
383
|
+
section. And on Windows, `show_in_klypix` with `bring_to_front: true` while KLYPIX is closed asks
|
|
384
|
+
Windows to open that canvas file in KLYPIX (PowerShell `Start-Process`), at most once every 30
|
|
385
|
+
seconds; it never does so while KLYPIX is running.
|
|
386
|
+
|
|
387
|
+
**The KLYPIX app, when it is running (local, not the network).** On Windows, a tool call that needs
|
|
388
|
+
the KLYPIX app (*App mode*, under *Human control in Klypix*) talks to the app over a local named
|
|
389
|
+
pipe: inter-process communication on this PC. Plugin mode allows it, exactly as outside plugin
|
|
390
|
+
mode. Nothing connects when the server starts; on such a call it reads
|
|
391
|
+
`%APPDATA%\klypix\agent-bridge\endpoint.json` and the bridge token KLYPIX writes in
|
|
392
|
+
`%LOCALAPPDATA%\klypix\agent-bridge`. With KLYPIX closed, or its *AI tools on this PC* switch
|
|
393
|
+
off, nothing connects at all.
|
|
394
|
+
|
|
395
|
+
**What it reads.** In your project: `brain.klypix`, the `.klypix` canvases, the `version` field of
|
|
396
|
+
`package.json` and your git tags. On your computer: the coordination files in the table below. If
|
|
397
|
+
the KLYPIX desktop app is installed, it also reads the app's data folder (`%APPDATA%\klypix`),
|
|
398
|
+
read-only, to see whether the app is running, which canvases it has open, and the readings it saved
|
|
399
|
+
on cards, and, on a call that needs the running app, the app's bridge token (above). It never reads chat history, transcripts or Claude's memory.
|
|
400
|
+
|
|
401
|
+
**What it writes, and where**
|
|
402
|
+
|
|
403
|
+
| Where | What | Why |
|
|
404
|
+
|---|---|---|
|
|
405
|
+
| Your project | Only what a tool call asks for: `brain.klypix` (`brain_note` and the other brain tools), canvases (`create_canvas`, `add_to_canvas`), `klypix-map/graph.json` when `project_map_scan` is called, and `.klypix/claims/<owner>.json` when `brain_sync` is asked to publish a release claim. During a brain write it holds `.claude/brain-capture.lock`, creating the `.claude/` folder if the project has none. The lock file is deleted after the write; the folder stays. Creating a canvas briefly holds `.klypix-create.lock` in the folder. | The KLYPIX app and every other session that writes the brain use the same locks, so two writers never overwrite each other. |
|
|
406
|
+
| The plugin's data folder (`KLYPIX_PLUGIN_DATA`) | Connection receipts (`.supervisors/`), the running-server heartbeat (`.running-servers.json`), the list of projects whose brains you used (`registry.json`, which `search_all_brains` reads), and the last version and git tag seen in each project (`ship-observations/`). Also `extracted/`: copies of the PDFs, Office and other files `read_card_contents` hands to your AI tool as a local path, taken from the canvas you asked about. | Only this server uses these files. If `KLYPIX_PLUGIN_DATA` is not set, or still contains a `${...}` that was never filled in, it uses `CLAUDE_PLUGIN_DATA`. If neither is usable, the files go in `~/.claude/project-brain`, except `extracted/`, which then goes in `<system temp>/klypix-mcp/extracted` (where it always goes outside plugin mode). |
|
|
407
|
+
| `~/.claude/project-brain` (shared) | Presence lanes (`sessions/`), write locks (`locks/`), restore points (`history/`), and small records built from your brain: `.capture-gap.json`, and `enrichment/`, `provenance/`, `.brief-cache-*` and `.guards-*` when the tools that use them run. | Your other KLYPIX sessions on this computer (Claude Code, Codex, Cursor, the app) use the same files on purpose. Through them, a plugin session and a terminal session on the same project see each other, get warnings when they plan to edit the same files, and pass notes. Restore points are kept here so that `npx klypix-mcp brain-history` can still undo a brain write after you remove the plugin. |
|
|
408
|
+
|
|
409
|
+
**`brain_reopen`.** Sometimes a session leaves a note for another session that has already closed.
|
|
410
|
+
An agent can then call `brain_reopen`, and KLYPIX asks you first: in chat with *Reopen* and *Not
|
|
411
|
+
now* buttons, or in a small dialog (PowerShell on Windows, osascript on macOS, zenity or kdialog on
|
|
412
|
+
Linux). Only if you choose *Reopen* does it open a new, visible terminal that runs the app's own
|
|
413
|
+
resume command, `claude --resume <id>` or `codex resume <id>`. *Reopen on your OK* has the details.
|
|
414
|
+
|
|
415
|
+
**After you uninstall the plugin.** Claude Code removes the plugin and deletes its data folder.
|
|
416
|
+
These stay: your brain and canvases, which belong to you; any `.claude/` folder a brain write
|
|
417
|
+
created in a project; and the presence lanes, write locks and restore points in
|
|
418
|
+
`~/.claude/project-brain`. Other KLYPIX tools on this computer share that folder. If you use none,
|
|
419
|
+
you can delete it.
|
|
420
|
+
|
|
421
|
+
---
|
|
422
|
+
|
|
347
423
|
## Task briefing
|
|
348
424
|
|
|
349
425
|
Every Claude Code session starts already knowing the project: a bounded brief of at most 2KB in
|
|
@@ -537,13 +613,17 @@ Apache-2.0 and work with no app installed. The app's interface is available in E
|
|
|
537
613
|
### KLYPIX canvases and your AI tool
|
|
538
614
|
|
|
539
615
|
Beyond project brains, the same connection reads and writes the KLYPIX canvases (spaces) saved on
|
|
540
|
-
your PC. **Your AI tool reads what KLYPIX has already read:**
|
|
541
|
-
|
|
542
|
-
- `read_canvas` prints every card with its id; `read_card_contents` returns what is inside a card
|
|
543
|
-
|
|
544
|
-
reel or web page, an OCR card for a photo, a folder's file list.
|
|
545
|
-
|
|
546
|
-
|
|
616
|
+
your PC. **Your AI tool reads what KLYPIX has already read, and the files a saved canvas holds:**
|
|
617
|
+
|
|
618
|
+
- `read_canvas` prints every card with its id; `read_card_contents` returns what is inside a card.
|
|
619
|
+
From what KLYPIX saved: the transcript on a video card, the text card **Read contents** made for a
|
|
620
|
+
reel or web page, an OCR card for a photo, a folder's file list. From the files embedded in the
|
|
621
|
+
saved canvas, with KLYPIX closed: a text file's words, a photo (a smaller copy when it is large),
|
|
622
|
+
and PDFs, Office and other files as a local path with the previews KLYPIX saved — see *Reading
|
|
623
|
+
what is inside cards* below. Audio and video come back as a path only; what they say comes from a
|
|
624
|
+
reading KLYPIX saved. For a reel, a web page or a video, choose Read contents in KLYPIX first
|
|
625
|
+
(select the card, press Enter), let the canvas save, then ask your AI tool — or, with KLYPIX open
|
|
626
|
+
on Windows, let your AI tool ask KLYPIX to read it (*App mode* below).
|
|
547
627
|
- What a person set up in KLYPIX is respected: cards inside a box **locked from AI tools** are left
|
|
548
628
|
out of every read; frozen cards are marked read-only; collapsed boxes, comments and tags are shown.
|
|
549
629
|
- `klypix_status` tells your AI tool what KLYPIX can do on this PC right now, and which step the person
|
|
@@ -555,6 +635,93 @@ your PC. **Your AI tool reads what KLYPIX has already read:**
|
|
|
555
635
|
again.
|
|
556
636
|
- Text that comes back from cards, pages, reels and files is fenced as data, never instructions.
|
|
557
637
|
|
|
638
|
+
### App mode: your AI tool uses KLYPIX while it is open
|
|
639
|
+
|
|
640
|
+
On Windows, while the KLYPIX app is open and **Settings → Project → AI tools on this PC** is on (it is
|
|
641
|
+
on by default), the same connection reaches the running app. KLYPIX then runs its own code for the
|
|
642
|
+
request, so its keys, consents, caps, freeze and undo apply. With KLYPIX closed or the switch off,
|
|
643
|
+
every tool works in file mode as described above, and a step that needs the app says so in one
|
|
644
|
+
sentence (`APP_NOT_RUNNING`, `ACCESS_OFF`, `BLOCKED`, `NEEDS_APP` …).
|
|
645
|
+
|
|
646
|
+
| Tool | With KLYPIX open (app mode) | Otherwise (file mode) |
|
|
647
|
+
|---|---|---|
|
|
648
|
+
| `read_card_contents` | On a canvas open in KLYPIX, KLYPIX reads the cards itself, the way its Read contents does; each result says who paid (`paid_by`) | Readings KLYPIX already saved, and the files embedded in the canvas |
|
|
649
|
+
| `read_canvas` | A canvas open in KLYPIX is read live: unsaved changes, the person's view (lens, filters, collapsed boxes), and for each card whether it is on screen, hidden by a filter, inside a collapsed box or off screen. View filters never remove a card | The saved file; when the canvas is open in KLYPIX the answer says changes not yet saved are not included |
|
|
650
|
+
| `add_to_canvas` | On a canvas open in KLYPIX the cards appear at once, marked with the tool's name, in one undo step, and KLYPIX saves them | Writes the file; refuses a canvas open in KLYPIX. Project brains are always written as files, which KLYPIX merges |
|
|
651
|
+
| `show_in_klypix` (Windows only) | Selects and frames cards in that canvas's tab, with an optional one-line banner labelled with the tool's name | `APP_NOT_RUNNING`; with `bring_to_front: true`, Windows opens the canvas file in KLYPIX |
|
|
652
|
+
| `brain_lens` | Freshness, provenance, activity, orrery and unresolved come from KLYPIX's own lens code: the picture the person sees | Computed from the saved file |
|
|
653
|
+
| `klypix_status` | Also the canvas in front of the person, their selection, their view, what KLYPIX is ready to read, and how many Gemini readings this tool has left today | What the saved files and the lease say |
|
|
654
|
+
|
|
655
|
+
Who pays for a new reading (`paid_by`):
|
|
656
|
+
|
|
657
|
+
| Card | What KLYPIX does | `paid_by` |
|
|
658
|
+
|---|---|---|
|
|
659
|
+
| Web page link | Fetches and extracts the page from this PC, never through the logged-in debug-port browser | `none` |
|
|
660
|
+
| Photo | Hands your AI tool the original image, for its own model, plus KLYPIX's OCR text when OCR is on | `ai_tool` |
|
|
661
|
+
| PDF, Office or text file, folder | Reads the file embedded in the canvas, on this PC | `none` |
|
|
662
|
+
| YouTube link, reel | Gemini watches it: the person's own key, else KLYPIX's included AI. A reel's video only if the person already allowed KLYPIX's video helper; otherwise its caption and cover, marked partial | `own_gemini_key` or `included_ai` |
|
|
663
|
+
| Video or audio file | Transcription on this PC when it is installed, otherwise Gemini as above | `none`, or as above |
|
|
664
|
+
|
|
665
|
+
- A saved reading comes back first and spends nothing; `refresh: true` asks for a new one.
|
|
666
|
+
- Gemini readings for AI tools are bounded by caps, never by a prompt: 20 a day per tool, 40 a day
|
|
667
|
+
across all AI tools, at most 5 cards per call and 3 reads running per tool.
|
|
668
|
+
- New readings are pinned beside their card with an arrow and the tool's name, emerald for a full
|
|
669
|
+
reading and amber for a partial one; one Ctrl+Z in KLYPIX removes them. The person's selection and
|
|
670
|
+
view do not move.
|
|
671
|
+
- Every answer comes within about 45 seconds. A read still running returns `still_reading` with
|
|
672
|
+
`retry_after_seconds`; asking again with the same arguments picks up the same read and spends
|
|
673
|
+
nothing extra.
|
|
674
|
+
- No input schema changed. `read_card_contents` still requires `canvas` and `card_ids`: to read what
|
|
675
|
+
the person selected in KLYPIX, call `klypix_status` first, which lists the canvas in front of
|
|
676
|
+
them and the selected card ids.
|
|
677
|
+
- KLYPIX's `since`, `storage` and `weight` lenses have no name in `brain_lens`'s `view` list, which
|
|
678
|
+
is frozen; `klypix_status` reports the lens the person has open.
|
|
679
|
+
|
|
680
|
+
**Control.** AI tools are on by default. The person turns them off, or blocks one tool, in KLYPIX's
|
|
681
|
+
Settings → Project, where every request is listed: time, tool, what it asked for, canvas and
|
|
682
|
+
outcome, never card text, links or tokens. Tool names are what each AI tool reports about itself,
|
|
683
|
+
so they are labels, not proof of identity.
|
|
684
|
+
|
|
685
|
+
**How the connection works.** While the switch is on, KLYPIX listens on a named pipe with a new
|
|
686
|
+
random name at every start and writes a new random token to
|
|
687
|
+
`%LOCALAPPDATA%\klypix\agent-bridge\token`, in your Windows profile. On each call that needs
|
|
688
|
+
the app (never at startup) klypix-mcp reads `endpoint.json` and the token again, and both sides
|
|
689
|
+
prove they hold the token before a request is sent; klypix-mcp sends nothing to a pipe that cannot
|
|
690
|
+
prove itself. The token and the pipe name are never logged, returned to the AI tool or shown by
|
|
691
|
+
`brain_doctor`. Any program running under your Windows account can read the token.
|
|
692
|
+
|
|
693
|
+
### Reading what is inside cards
|
|
694
|
+
|
|
695
|
+
A canvas saved by KLYPIX keeps a copy of every file dropped on it. `read_card_contents` hands those
|
|
696
|
+
files to your AI tool as they are, so it reads them with its own model and its own file tools —
|
|
697
|
+
KLYPIX itself extracts nothing here (no OCR, transcription or document-text extraction; those run in
|
|
698
|
+
the KLYPIX app). Pass the ids `read_canvas` prints; every card with something inside has an
|
|
699
|
+
`Inside:` line saying what comes back.
|
|
700
|
+
|
|
701
|
+
| Card | What your AI tool gets |
|
|
702
|
+
|---|---|
|
|
703
|
+
| Text file (`.txt`, `.md`, `.csv`, `.json`, source code, …) | Its words, fenced as data (up to `max_chars` per card, 48,000 characters per answer). A longer file is cut, marked `truncated`, and the whole file is given as a local path. |
|
|
704
|
+
| Photo | The photo itself. A photo too large for one answer comes as a smaller JPEG copy (long edge 1,568 px or less, turned upright from its EXIF orientation), and the full-size original as a local path. Formats vision models do not take (BMP, HEIC, TIFF) come as a path, with the reason. |
|
|
705
|
+
| PDF | A local path to the PDF — Claude Code's Read tool opens it — and KLYPIX's saved image of page 1. |
|
|
706
|
+
| Word, Excel, PowerPoint and other files | A local path to the file, plus the preview KLYPIX saved: a document's opening text, a sheet's first rows. |
|
|
707
|
+
| Folder | Its file list. Add `entry_paths` (up to 8 file paths from the list) to get those files the same way. Paths that would leave the folder are refused; an entry over 64 MB, or one that inflates more than 200 times its stored size, is refused with its size. A folder kept on disk (not embedded) is read from where it is, never outside it. |
|
|
708
|
+
| Audio, video | The reading KLYPIX saved, when there is one. Otherwise a local path and a plain statement that nothing in the answer says what it contains; a video's saved poster frame is attached and labelled as one frame. |
|
|
709
|
+
|
|
710
|
+
Limits, and why:
|
|
711
|
+
|
|
712
|
+
- **One answer stays under 1 MB.** Claude Desktop refuses a whole tool result over 1 MB, so the images
|
|
713
|
+
in one answer share a budget of 800,000 base64 characters (up to 4 images in `read_card_contents`
|
|
714
|
+
and in `read_canvas`). A photo that does not fit even as a smaller copy is named with the reason.
|
|
715
|
+
- **Files go by path, not as embedded blobs.** An MCP embedded resource carrying a PDF is rejected by
|
|
716
|
+
claude.ai's connector layer today, so PDFs and Office files are copied once to a cache folder and
|
|
717
|
+
given as a path: `extracted/` in the plugin's data folder when running as a Claude plugin, otherwise
|
|
718
|
+
`<system temp>/klypix-mcp/extracted`, named `<sha-256 prefix>-<original name>`. A file over 150 MB
|
|
719
|
+
is not copied out. An AI tool without a file-reading tool (Claude Desktop without a filesystem
|
|
720
|
+
connector) gets the previews and the path, not the whole PDF.
|
|
721
|
+
- **An iPhone photo or file** added to a shared space is not stored in the canvas file (KLYPIX fetches
|
|
722
|
+
it while it runs), so it cannot be handed over from the saved canvas; the answer says so.
|
|
723
|
+
- Cards inside a box locked from AI tools are never read, copied or attached.
|
|
724
|
+
|
|
558
725
|
## Measure it yourself
|
|
559
726
|
|
|
560
727
|
Claims about a shared brain — "nothing is lost", "it stays fast" — are unfalsifiable until a
|
|
@@ -689,7 +856,7 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
689
856
|
|
|
690
857
|
---
|
|
691
858
|
|
|
692
|
-
## The 25
|
|
859
|
+
## The verbs: 25, and 26 on Windows
|
|
693
860
|
|
|
694
861
|
| Tool | What it does |
|
|
695
862
|
|---|---|
|
|
@@ -698,7 +865,7 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
698
865
|
| `brain_note` | Capture with the full lifecycle — supersede / re-adopt / ✓ resolve / ~ update / 🛠 skill / `closes:` |
|
|
699
866
|
| `brain_reconcile` | Proposes stale-vs-correction pairs, unrecorded migrations, and the open cards a release ref's commits look to have closed — then closes the exact pairs you confirm |
|
|
700
867
|
| `brain_insights` | Hubs, orphaned decisions, stale questions, area sizes |
|
|
701
|
-
| `brain_lens` | Machine-readable freshness, provenance, activity, timeline, orrery and unresolved views |
|
|
868
|
+
| `brain_lens` | Machine-readable freshness, provenance, activity, timeline, orrery and unresolved views; on a canvas open in KLYPIX (Windows), the first five come from KLYPIX's own lens code |
|
|
702
869
|
| `brain_garden` | Maintenance pass — proposes first; consolidation cannot apply without an approval code the human generates. The separate `repair:"duplicate-partials"` pass is dry-run first and needs no code (it removes only exact repeats and archives nothing) |
|
|
703
870
|
| `brain_doctor` | Self-diagnosis: version, core/enhanced host adapters, active sessions, tool count, projection drift |
|
|
704
871
|
| `brain_message` | Session-to-session coordination notes — to a live session, or queued for one that is not running until it next starts — with a fixed send-time audience and per-recipient pending / offer / acknowledgement / consumption / failure receipts (a directed note is kept 7 days, a broadcast 24h; never written into the brain) |
|
|
@@ -710,16 +877,17 @@ The MCP verbs below are what agents call. These are what **you** call:
|
|
|
710
877
|
| `project_map_scan` | KLYPIX's own zero-install scanner: gitignore-aware file inventory + file-level import edges (relative, tsconfig-alias, and monorepo-workspace imports resolved) written to `klypix-map/graph.json` — which then serves `project_map_context` automatically |
|
|
711
878
|
| `project_map_drift` | Read-only drift report: brain cards whose referenced files are gone or moved (with rename candidates), plus a headline when the checkout itself is behind its origin default branch |
|
|
712
879
|
| `canvas_view` | Returns the board as a structured render spec plus a text summary, and declares an MCP Apps (SEP-1865) UI resource |
|
|
713
|
-
| `read_canvas` | A canvas as markdown: every card with its id, the connection graph, `[[links]]`, `#tags` and tag pills, status, comments, reactions, frozen and collapsed boxes, and the readings KLYPIX already saved on link, video and photo cards; photo cards' images attached, each labelled with its card. Cards inside a box a person locked from AI tools are left out, and counted. Titles as KLYPIX shows them work as names |
|
|
714
|
-
| `read_card_contents` | What is inside up to 5 cards — a reel, YouTube video, web page, video or audio file, photo,
|
|
715
|
-
| `klypix_status` | What KLYPIX can do on this PC right now: whether the app is running and which canvases it has open
|
|
880
|
+
| `read_canvas` | A canvas open in KLYPIX (Windows) is read live from the app: unsaved changes, the person's view, and each card's visibility. Otherwise a canvas as markdown: every card with its id, the connection graph, `[[links]]`, `#tags` and tag pills, status, comments, reactions, frozen and collapsed boxes, and the readings KLYPIX already saved on link, video and photo cards; photo cards' images attached (a smaller copy when large), each labelled with its card; every card with something inside names the `read_card_contents` call that returns it. Cards inside a box a person locked from AI tools are left out, and counted. Titles as KLYPIX shows them work as names |
|
|
881
|
+
| `read_card_contents` | What is inside up to 5 cards — a reel, YouTube video, web page, video or audio file, photo, PDF, Office or text file, or folder. On a canvas open in KLYPIX (Windows), KLYPIX reads them itself with its own readers and says who paid (`paid_by`). Otherwise: readings KLYPIX already saved (transcripts on the card, its Read contents and OCR result cards, folder listings) — fenced as data, marked full or partial, with where they were made (this PC or cloud AI) — and the files embedded in the saved canvas: a text file's words; a photo (a smaller copy when it is large, plus the original's local path); PDFs, Office and other files as a cached local path with KLYPIX's saved previews (a PDF's first page, a document's opening text, a sheet's first rows); folder entries named in `entry_paths`, by the same rules. Audio and video come back as a path, and what they say only from a reading KLYPIX saved. One answer stays under Claude Desktop's 1 MB limit. A card that needs a reading KLYPIX cannot make right now comes back with the one step the person takes; klypix-mcp itself extracts no text |
|
|
882
|
+
| `klypix_status` | What KLYPIX can do on this PC right now: whether the app is running and which canvases it has open, where canvases are read from, and what each feature still needs from the person. With KLYPIX open: the canvas in front of the person, their selection and view, what KLYPIX is ready to read, and the Gemini readings this tool has left today |
|
|
883
|
+
| `show_in_klypix` | Windows only. Selects and frames cards in the running KLYPIX app, with an optional one-line banner labelled with the tool's name; KLYPIX never comes to the front for an AI tool. With KLYPIX closed and `bring_to_front: true`, Windows opens the canvas file in KLYPIX |
|
|
716
884
|
| `search_canvases` | Search across canvases by name, content, tags and tag pills, and the readings KLYPIX saved on cards; returns card ids and dates. Never searches inside a box a person locked from AI tools |
|
|
717
885
|
| `search_all_brains` | Cross-project memory search across every registered brain on this machine |
|
|
718
886
|
| `create_canvas` | New `.klypix` from cards + connections |
|
|
719
|
-
| `add_to_canvas` | Append cards/connections (positions preserved), bordered and readable on KLYPIX's dark and Paper themes; a card's `group` puts it in that titled box.
|
|
887
|
+
| `add_to_canvas` | Append cards/connections (positions preserved), bordered and readable on KLYPIX's dark and Paper themes; a card's `group` puts it in that titled box. On a canvas open in KLYPIX (Windows) the cards go to KLYPIX itself: live, attributed, one undo. When KLYPIX cannot take them it refuses (`OPEN_IN_APP`, `ACCESS_OFF`, `BLOCKED`), a box locked from AI tools (`SCOPE_LOCKED`) or a frozen box (`FROZEN`), and writes nothing; project brains are the exception to the first. Returns the new card ids |
|
|
720
888
|
| `list_canvases` | List every `.klypix` in the vault |
|
|
721
889
|
|
|
722
|
-
Exactly 25
|
|
890
|
+
Exactly 25 on Linux and macOS and 26 on Windows, where `show_in_klypix` is registered; machine-verifiable with `npx klypix-mcp doctor`, whose TOOLS line applies the same rule and whose App bridge line says whether KLYPIX is running, with access on or off.
|
|
723
891
|
|
|
724
892
|
> **`canvas_view`:** no MCP Apps host has been observed rendering the UI resource yet — there is no
|
|
725
893
|
> screenshot and no host-level test. Hosts without the extension get clean text, which is the path
|
|
@@ -892,7 +1060,23 @@ keep lazy first-use indexing instead.
|
|
|
892
1060
|
writes `<cwd>/.codex/config.toml` **inside the project** you run it in, and removes any KLYPIX
|
|
893
1061
|
entry from the global `~/.codex/config.toml`. **`link` writes 14 files inside the project** you
|
|
894
1062
|
run it in; `link --check` audits them without writing.
|
|
1063
|
+
- **The MCP server writes those project files too, outside plugin mode.** `link` and `install` are
|
|
1064
|
+
not the only writers of the 14 files. Each time `brain_sync` starts a task (`phase: "start"`) in
|
|
1065
|
+
a project that has a `brain.klypix`, the server does two things. It adds that project to the
|
|
1066
|
+
machine's registry, `~/.claude/project-brain/registry.json` (the Claude Code hook adds projects
|
|
1067
|
+
there as well). Then it checks the project's KLYPIX-managed files and creates or rewrites any that
|
|
1068
|
+
are missing or out of date. That check covers all 14 files, whichever editors you have. It
|
|
1069
|
+
includes `.mcp.json`, whose entry starts the installed bundle or, when there is none,
|
|
1070
|
+
`npx -y klypix-mcp` with no version pinned, and `.codex/config.toml`. The automatic updater does
|
|
1071
|
+
the same for every registered project seen in the last 14 days, right after it installs an update
|
|
1072
|
+
and otherwise at most once a day. `KLYPIX_AUTO_UPDATE=0` stops the updater's pass. Plugin mode
|
|
1073
|
+
(`KLYPIX_PLUGIN=1`) stops both passes and keeps its registry in the plugin's data folder; see
|
|
1074
|
+
*Running as a Claude plugin*.
|
|
895
1075
|
- **Codex hooks require Codex's own trust approval** and are opt-in via `--codex-hooks`.
|
|
1076
|
+
- **The KLYPIX app bridge is local IPC.** On Windows, a tool call that needs the running KLYPIX app
|
|
1077
|
+
connects over a named pipe on this PC (see *App mode*). Nothing connects at startup or while KLYPIX
|
|
1078
|
+
is closed or its AI-tools switch is off; the client proves the app holds the per-start token before
|
|
1079
|
+
it sends a request, and never logs or returns the token or the pipe name.
|
|
896
1080
|
|
|
897
1081
|
## Current limitations
|
|
898
1082
|
|
|
@@ -918,9 +1102,11 @@ Read this section before you build on any of it.
|
|
|
918
1102
|
- **Drift detection is single-host and opt-in per card.** It needs an `ev:` anchor written by the
|
|
919
1103
|
card's author, and it runs only in the Claude Code hook path — the MCP tools do not compute
|
|
920
1104
|
freshness.
|
|
921
|
-
- **`search_all_brains`
|
|
922
|
-
|
|
923
|
-
|
|
1105
|
+
- **`search_all_brains` only finds registered projects.** The cross-project registry is written by
|
|
1106
|
+
the Claude Code hook and by `brain_sync` when it starts a task, from any MCP host. A project where
|
|
1107
|
+
neither has happened is missing from the results, and nothing reports it: the search just comes
|
|
1108
|
+
back empty. In plugin mode the server keeps its own list in the plugin's data folder and searches
|
|
1109
|
+
that list together with the shared one.
|
|
924
1110
|
- **`npx klypix-mcp link` does not manage `CLAUDE.md`.** It manages `AGENTS.md` and seven other
|
|
925
1111
|
rules files. Only the desktop app writes `CLAUDE.md`.
|
|
926
1112
|
- **A fresh `npx klypix-mcp install` gets lexical retrieval.** The optional on-device model is
|
|
@@ -930,6 +1116,9 @@ Read this section before you build on any of it.
|
|
|
930
1116
|
*does* gate on it — a `gate` job runs `npm ci`, asserts the test chain is intact, runs `npm test`,
|
|
931
1117
|
validates the version/tag, and checks the packed tarball; `publish` declares `needs: gate`, so a
|
|
932
1118
|
red gate means npm never sees a tarball.
|
|
1119
|
+
- **App mode is Windows-only and needs the running KLYPIX app** with AI tools allowed. Everywhere
|
|
1120
|
+
else the tools work in file mode. Tool names in KLYPIX are what each AI tool reports, not a
|
|
1121
|
+
verified identity: any program running as you can read the bridge token.
|
|
933
1122
|
- **`canvas_view`'s MCP Apps UI has never been verified on a real Apps host.**
|
|
934
1123
|
|
|
935
1124
|
## Numbers and methodology
|
package/bin/klypix-install.mjs
CHANGED
|
@@ -289,8 +289,10 @@ const flatten = (code) => code
|
|
|
289
289
|
// nothing in bin/ had imported it directly before.
|
|
290
290
|
// app-lease / app-tools (P0 agent parity): the worker lazily imports the
|
|
291
291
|
// app tools (klypix_status, read_card_contents); klypix-core and the app
|
|
292
|
-
// tools import the lease reader.
|
|
293
|
-
|
|
292
|
+
// tools import the lease reader. app-bridge-protocol / app-bridge-client
|
|
293
|
+
// (P1 agent parity): the app tools lazily import the client of the KLYPIX
|
|
294
|
+
// app bridge, which imports the protocol.
|
|
295
|
+
.replace(/\.\.\/src\/(bench|brain-doctor|agent-presence|agent-rules|capture-gap|enrichment|finding-routing|mcp-presence|mcp-supervisor|mcp-auto-update|presence-relay|repo-state|semantic-memory|runtime-inspector|project-graph|git-capture-install|app-lease|app-tools|app-bridge-protocol|app-bridge-client)\.mjs/g, './$1.mjs')
|
|
294
296
|
.replace(/klypix-worker\.mjs/g, 'klypix-mcp-worker.mjs')
|
|
295
297
|
.replace(/const PKG_VERSION = \(\(\) => \{[\s\S]*?\}\)\(\);/, `const PKG_VERSION = '${VERSION}'; // baked at install (flat layout has no package.json)`);
|
|
296
298
|
|
|
@@ -403,8 +405,10 @@ try {
|
|
|
403
405
|
// @modelcontextprotocol/ext-apps powers the canvas_view MCP App; the server
|
|
404
406
|
// treats it as OPTIONAL (lazy import, degrades to a text-only tool), so a
|
|
405
407
|
// resolve failure here must NOT abort — it's queued but tolerated if missing.
|
|
406
|
-
|
|
407
|
-
|
|
408
|
+
// jpeg-js (card-files.mjs) is lazy too: without it a large photo is handed over
|
|
409
|
+
// by path instead of as a smaller copy.
|
|
410
|
+
const OPTIONAL_DEPS = new Set(['@modelcontextprotocol/ext-apps', 'jpeg-js']);
|
|
411
|
+
const queue = ['jszip', 'fractional-indexing', '@modelcontextprotocol/sdk', 'zod', '@modelcontextprotocol/ext-apps', 'jpeg-js'].map(name => ({ name, fromDir: PKG_ROOT }));
|
|
408
412
|
let deps = 0; const missing = [];
|
|
409
413
|
while (queue.length) {
|
|
410
414
|
const { name, fromDir } = queue.shift();
|
|
@@ -434,7 +438,7 @@ try {
|
|
|
434
438
|
// a newer klypix-format cannot. merge-brains and the driver ship here so
|
|
435
439
|
// brain-history's restore merge, the KLYPIX core and the git driver all
|
|
436
440
|
// find one engine in this directory.
|
|
437
|
-
for (const f of ['global-brain-hook.mjs', 'klypix-format.mjs', 'brain-graveyard.mjs', 'merge-brains.mjs', 'klypix-merge-driver.mjs', 'capture-gap.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'enrichment.mjs', 'provenance.mjs', 'brain-note.mjs', 'brain-evidence.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'app-lease.mjs', 'klypix-core.mjs', 'app-tools.mjs', 'brain-write-lock.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'editor-detect.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'repo-state.mjs', 'result-reconcile.mjs', 'finding-routing.mjs', 'presence-relay.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'canvas-view-app.html']) {
|
|
441
|
+
for (const f of ['global-brain-hook.mjs', 'klypix-format.mjs', 'brain-graveyard.mjs', 'merge-brains.mjs', 'klypix-merge-driver.mjs', 'capture-gap.mjs', 'brain-semantic.mjs', 'semantic-memory.mjs', 'enrichment.mjs', 'provenance.mjs', 'brain-note.mjs', 'brain-evidence.mjs', 'brain-git-hook.mjs', 'git-capture-install.mjs', 'brain-history.mjs', 'app-lease.mjs', 'klypix-core.mjs', 'app-bridge-protocol.mjs', 'app-bridge-client.mjs', 'app-tools.mjs', 'card-files.mjs', 'brain-write-lock.mjs', 'agent-rules.mjs', 'brain-doctor.mjs', 'editor-detect.mjs', 'agent-presence.mjs', 'mcp-presence.mjs', 'repo-state.mjs', 'result-reconcile.mjs', 'finding-routing.mjs', 'presence-relay.mjs', 'mcp-supervisor.mjs', 'mcp-auto-update.mjs', 'runtime-inspector.mjs', 'project-graph.mjs', 'bench.mjs', 'codex-brain-hook.mjs', 'codex-hooks.mjs', 'canvas-view-app.html']) {
|
|
438
442
|
const s = path.join(SRC, f); if (exists(s)) staged.push({ dst: f, content: fs.readFileSync(s, 'utf8') });
|
|
439
443
|
}
|
|
440
444
|
for (const [src, dst] of [
|