@appsoftwareltd/etherpk-mcp 0.4.3 → 0.6.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 CHANGED
@@ -1,150 +1,186 @@
1
1
  # @appsoftwareltd/etherpk-mcp
2
2
 
3
3
  An [MCP](https://modelcontextprotocol.io) server that gives your AI agent (Claude Code, Codex,
4
- Cursor and the like) one of your synced [EtherPK](https://etherpk.com) knowledge graphs, run on
5
- the same computer as the agent.
4
+ Cursor and the like) one of your [EtherPK](https://etherpk.com) knowledge graphs, run on the same
5
+ computer as the agent. The agent can search your notes by words or by meaning, follow links,
6
+ list tasks, and read and edit documents without breaking EtherPK's format.
6
7
 
7
- EtherPK's Sync Server never sees your notes in the clear, so nothing hosted can serve them. This
8
- program is EtherPK's **Headless Client**: to the Sync Server it is one of your devices - so it can
9
- hold your keys, read a graph and keep it in sync. To your agent, it is an MCP server.
8
+ This is EtherPK's **Headless Client**: EtherPK with no editor. Set up depends on where the graph
9
+ lives:
10
10
 
11
- Protected documents are listed by name only, never served.
11
+ - **A local graph folder.** Point it at the folder. It reads and writes the markdown there and
12
+ keeps a search index of it. No sign-in, no server.
13
+ - **A synced graph.** EtherPK's Sync Server never sees your notes unencrypted. The Headless
14
+ Client signs in as one of your devices, holds your keys, keeps the graph in sync and serves it
15
+ from your own computer.
16
+
17
+ The agent gets the same tools either way. Protected documents are listed by name only and never
18
+ served.
12
19
 
13
20
  Needs Node.js 22 or later.
14
21
 
15
- ## Set up
22
+ ## Set up: a synced graph
16
23
 
17
24
  Open the graph in EtherPK, pick **Settings → Agents**, and copy the two commands it shows with your
18
- server and graph filled in. They are:
25
+ server and graph filled in:
19
26
 
20
27
  ```sh
21
- # Once per computer. Prompts for an account-wide Personal Access Token (make one at
22
- # https://sync.etherpk.com/account/tokens, also reachable from "Access tokens" in
23
- # EtherPK's account menu), then shows a short code and the address of your EtherPK:
24
- # open EtherPK there in a browser where you're signed in with your graphs unlocked -
25
- # any page will do - and confirm the code. The same step as adding a phone.
28
+ # Once per computer. Asks for an account-wide Personal Access Token (from
29
+ # https://sync.etherpk.com/account/tokens, or "Access tokens" in EtherPK's account menu),
30
+ # then shows a short code: confirm it in any browser tab where EtherPK is signed in and
31
+ # unlocked. The same step as adding a phone.
26
32
  npx @appsoftwareltd/etherpk-mcp login --sync-server https://sync.etherpk.com
27
33
 
28
- # Self-hosting your own Sync Server? Give its address instead:
29
- # npx @appsoftwareltd/etherpk-mcp login --sync-server https://sync.your-domain.example
30
-
31
- # No EtherPK to hand on this computer (a server you reach over SSH, say)? Press r while
32
- # login is waiting, or use your Recovery Code from the start:
33
- # npx @appsoftwareltd/etherpk-mcp login --sync-server https://sync.etherpk.com --recovery-code
34
-
35
34
  # Tell the agent about the graph (Claude Code shown; the Agents tab has the others).
36
35
  claude mcp add etherpk -- npx @appsoftwareltd/etherpk-mcp serve --sync-server https://sync.etherpk.com --graph <graph id>
37
- ```client
36
+ ```
37
+
38
+ Self-hosting? Give your own server's address to `login`. By default `login` gets your keys by
39
+ Device Approval: confirm the code it shows in EtherPK on any device where your account is
40
+ unlocked. If there's no EtherPK to hand, press `r` while `login` is waiting, or add
41
+ `--recovery-code`, and type your Recovery Code instead. For a scripted setup, `ETHERPK_PAT` and
42
+ `ETHERPK_RECOVERY_CODE` stand in for the prompts.
38
43
 
39
44
  `npx @appsoftwareltd/etherpk-mcp graphs` lists the graphs each signed-in account can reach, by
40
- name and id. For a scripted setup, `ETHERPK_PAT` and `ETHERPK_RECOVERY_CODE` stand in for the
41
- prompts.
45
+ name and id. A graph nobody has opened since names started being stored on the server is opened
46
+ once to read its name; `(unnamed)` means it has none.
42
47
 
43
- ## More than one Sync Server
48
+ One computer can be signed in to several Sync Servers - your own beside the managed service, say.
49
+ Run `login` once per server. `--sync-server` then says which one a command means; it can be left
50
+ off while only one is signed in, and the commands the Agents tab shows always include it.
44
51
 
45
- One computer can be signed in to several Sync Servers at once - your own self-hosted one beside
46
- the managed service, say. Run `login` once per server; every login lives in the one config file.
47
- `--sync-server <url>` then says which server a command means:
52
+ ## Set up: a local graph folder
53
+
54
+ No sign-in and no Sync Server required. The agent gets the same tools over the folder's
55
+ markdown, beside the files themselves, which it can still read and write directly. **Settings → Agents** shows the
56
+ command with your folder's path filled in once you've recorded the path on the General tab:
48
57
 
49
58
  ```sh
50
- npx @appsoftwareltd/etherpk-mcp login --sync-server https://sync.your-domain.example
51
- npx @appsoftwareltd/etherpk-mcp graphs # every server, in turn
52
- npx @appsoftwareltd/etherpk-mcp serve --sync-server https://sync.your-domain.example --graph <graph id>
53
- npx @appsoftwareltd/etherpk-mcp logout --sync-server https://sync.your-domain.example
59
+ claude mcp add etherpk -- npx @appsoftwareltd/etherpk-mcp serve --folder /path/to/your/notes
54
60
  ```
55
61
 
56
- While only one server is signed in, `--sync-server` can be left off `graphs`, `serve` and
57
- `logout`. With two or more, `serve` and `logout` refuse to guess and ask for it. The commands
58
- the Agents tab shows always include it, so they stay right whatever else the computer is signed
59
- in to. `logout --all` forgets every server at once.
60
-
61
- Every command runs through `npx`, which fetches the package but never puts `etherpk-mcp` on your
62
- PATH. If you'd rather type the short form, `npm install -g @appsoftwareltd/etherpk-mcp` once and
63
- drop the `npx @appsoftwareltd/` prefix; the program's own hints follow whichever way you ran it.
62
+ The folder must already be an EtherPK graph (open it in EtherPK once). Edits made in an editor,
63
+ or by the agent writing files directly, are picked up before the next tool call, and the index
64
+ follows within a second or so. A tool's write is in the file when the tool returns; if a write
65
+ fails, the agent is told why and the edit is retried on the next write. The index lives under
66
+ the cache directory, never in the folder.
67
+
68
+ ## Commands and flags
69
+
70
+ Every command is `npx @appsoftwareltd/etherpk-mcp <command>`. `npx` never puts `etherpk-mcp` on
71
+ your PATH; for the short form, `npm install -g @appsoftwareltd/etherpk-mcp` once. `--help` (`-h`)
72
+ prints this reference, `--version` (`-v`) the version.
73
+
74
+ | Command | What it does |
75
+ | --- | --- |
76
+ | `login --sync-server <url> [--pat <token>] [--recovery-code]` | Sign this computer in as a device of your account on that Sync Server. Asks for a Personal Access Token unless given one, then unlocks your keys by Device Approval or, with `--recovery-code`, your Recovery Code. Lists the graphs it can reach when done. |
77
+ | `graphs [--sync-server <url>]` | List the synced graphs each signed-in account can reach, by name, id and your role. Without `--sync-server`, every signed-in server in turn. |
78
+ | `serve --graph <id or name> [--sync-server <url>] [--no-semantic]` | Serve one synced graph to the agent over stdio. |
79
+ | `serve --folder <path> [--no-semantic]` | Serve a local graph folder the same way. The folder must already be an EtherPK graph. |
80
+ | `logout [--sync-server <url> \| --all]` | Forget that server's token and keys and delete its cached graphs. `--all` forgets every server and clears the whole cache, semantic runtime and model included. Revoke the token at the portal too if the computer isn't yours to keep. |
81
+ | `semantic setup` | Install the embedding runtime (about 300 MB, through your npm) and the 23 MB model into the cache directory. Once per computer. |
82
+ | `semantic status` | Whether semantic search is set up here, and each cached graph's embedding progress. |
83
+ | `semantic remove` | Delete the runtime and model. Each graph's stored vectors stay in its cache and are reused if you set up again. |
84
+
85
+ | Flag | Applies to | Meaning |
86
+ | --- | --- | --- |
87
+ | `--sync-server <url>` | `login`, `graphs`, `serve --graph`, `logout` | Which Sync Server the command means. Required for `login`; elsewhere optional while only one server is signed in. `serve` and `logout` refuse to guess when several are. |
88
+ | `--pat <token>` | `login` | The Personal Access Token, instead of the prompt. |
89
+ | `--recovery-code` | `login` | Unlock with your Recovery Code instead of waiting for Device Approval. Pressing `r` while `login` waits does the same. |
90
+ | `--graph <id or name>` | `serve` | The synced graph to serve. Exclusive with `--folder`. |
91
+ | `--folder <path>` | `serve` | The local graph folder to serve. Exclusive with `--graph` and `--sync-server`. |
92
+ | `--no-semantic` | `serve` | Keep this agent text-only even when semantic search is set up. |
93
+ | `--all` | `logout` | Every server at once. |
94
+
95
+ | Environment variable | Meaning |
96
+ | --- | --- |
97
+ | `ETHERPK_PAT` | Stands in for the token prompt, for a scripted `login`. |
98
+ | `ETHERPK_RECOVERY_CODE` | Stands in for the Recovery Code prompt, for a scripted `login --recovery-code`. |
99
+ | `ETHERPK_MCP_CONFIG` | The config file holding the logins. Default `~/.config/etherpk/mcp.json` (`XDG_CONFIG_HOME` respected). |
100
+ | `ETHERPK_MCP_CACHE_DIR` | The cache root for graphs, the semantic runtime and the model. Default `~/.cache/etherpk/mcp` (`XDG_CACHE_HOME` respected). Set it in the agent registration's `env` as well as your shell: the agent starts `serve` with its own environment. |
101
+ | `ETHERPK_MCP_SEMANTIC_THREADS` | Threads for the embedding model. Default a quarter of the cores, at most four. |
102
+ | `ETHERPK_MCP_DEBUG_MEMORY` | `1` logs the process's memory use every 10 seconds and on every progress line. |
64
103
 
65
104
  ## What the agent gets
66
105
 
67
106
  `list_documents`, `read_document`, `search`, `backlinks`, `tasks`, `edit_document` (an exact,
68
- unique old→new replacement that merges with anyone typing elsewhere on the page),
69
- `append_document` (a page, or a day's journal entry, created if needed) and `create_page`.
70
- One running instance serves one graph.
107
+ unique old→new replacement; on a synced graph it merges with anyone typing elsewhere on the
108
+ page), `append_document` (a page, or a day's journal entry, created if needed) and
109
+ `create_page`. One running instance serves one graph.
110
+
111
+ No skill or extra setup is needed: the server describes its tools and the graph, and Claude Code
112
+ reaches for them when you ask about your notes. To make that a rule rather than a good guess, add
113
+ one line to your `CLAUDE.md`: *"My notes live in EtherPK; use the etherpk MCP tools for anything
114
+ I've written down, and `search` in semantic mode for questions."*
71
115
 
72
116
  ## Searching by meaning
73
117
 
74
- `search` matches words. With one more step it can also match **meaning** - "when do I pay my
75
- taxes" finds the note that says "due 31 January" - by running a small embedding model on this
76
- computer; nothing is sent anywhere, and protected documents are never embedded. Once per
77
- computer:
118
+ `search` matches words. With one more step it also matches **meaning** - "when do I pay my taxes"
119
+ finds the note that says "due 31 January" - by running a small embedding model on this computer.
120
+ Nothing is sent anywhere, and protected documents are never embedded.
78
121
 
79
122
  ```sh
80
- npx @appsoftwareltd/etherpk-mcp semantic setup # ~300 MB runtime (via your npm) + a 23 MB model, into the cache dir
123
+ npx @appsoftwareltd/etherpk-mcp semantic setup
81
124
  ```
82
125
 
83
- Semantic setup installs the native runtime into `~/.cache/etherpk/mcp/runtime/` and the three
84
- model files into `~/.cache/etherpk/mcp/models/all-MiniLM-L6-v2-int8/`.
85
-
86
- - **Any order, no restart.** Run it before or after registering the agent, even while an agent
87
- is connected: a running `serve` notices within 30 seconds and starts building; until
88
- then a search by meaning is refused with this command in the message, so the agent can tell
89
- you what to run. Nothing in the registration changes (`--no-semantic` on `serve` is the only
90
- switch, to keep one agent text-only).
91
- - **What the agent gets.** `search` accepts `mode: "semantic"` (and `"hybrid"`, both groups
92
- side by side). Every result carries the document, its kind, the breadcrumb of headings and
93
- parent bullets, the passage's 0-based line range and its text with a similarity score - the
94
- agent is told to cite them. Passage text has bullet markers and `[[ ]]` stripped: right for
95
- quoting, wrong as the `old` text of `edit_document`, which should come from `read_document`.
96
- - **Progress.** The first pass over a large graph takes minutes and runs in the background;
97
- after that only edits are processed. `semantic status` lists each cached graph with how many
98
- passages are done; every semantic result says `embedded`/`total` and `complete`; run by
99
- hand, `serve` prints a line every 30 seconds. `semantic remove` deletes runtime and model.
100
- - **Load on the machine.** The first pass uses a quarter of the cores, at most four, and pauses
101
- between model calls; `ETHERPK_MCP_SEMANTIC_THREADS=8` in the registration's `env` makes it
102
- faster and hotter. `ETHERPK_MCP_DEBUG_MEMORY=1` logs the process's memory if you ever need
103
- to see it.
104
- - **One cache directory for both.** Setup and `serve` must see the same cache root - by default
105
- `~/.cache/etherpk/mcp` (`C:\Users\<you>\.cache\etherpk\mcp` on Windows). If you set
106
- `ETHERPK_MCP_CACHE_DIR` in your shell, put it in the agent registration's `env` too, since
107
- the agent spawns `serve` with its own environment.
126
+ - **Any order, no restart.** Run it before or after registering the agent, even while one is
127
+ connected: a running `serve` notices within 30 seconds and starts building. Until then a
128
+ search by meaning is refused with this command in the message, so the agent can tell you what
129
+ to run.
130
+ - **What changes.** `search` accepts `mode: "semantic"` (and `"hybrid"`, both groups side by
131
+ side). Each result carries the document, the breadcrumb of headings and parent bullets, the
132
+ passage's line range and its text with a similarity score. Passage text has bullet markers and
133
+ `[[ ]]` stripped, so it's right for quoting and wrong as the `old` text of `edit_document`,
134
+ which should come from `read_document`.
135
+ - **Progress.** The first pass over a large graph takes minutes, in the background; after that
136
+ only edits are processed. Every semantic result says `embedded` / `total` and `complete`, and
137
+ `semantic status` shows each cached graph's progress.
138
+ - **Only while it runs.** The store is built and kept current by `serve`, which exists only while
139
+ an agent session has it open. To keep a graph current without an agent, run it by hand:
140
+ `npx @appsoftwareltd/etherpk-mcp serve --graph <id> </dev/null &` (or `--folder <path>`).
141
+ - **Load.** The first pass uses a quarter of the cores, at most four, and pauses between model
142
+ calls. `ETHERPK_MCP_SEMANTIC_THREADS=8` in the registration's `env` makes it faster and hotter.
108
143
 
109
144
  ## What this client keeps on your computer
110
145
 
111
- - **Keys**: `~/.config/etherpk/mcp.json`, one entry per Sync Server, readable only by your user -
112
- the same trust as a browser you've signed in on. (On Windows both paths sit under your user
113
- folder: `C:\Users\<you>\.config\etherpk\` and `C:\Users\<you>\.cache\etherpk\`.)
114
- - **A cache of each graph you serve**: `~/.cache/etherpk/mcp/`, so a restart catches up on what
115
- changed instead of downloading everything again. It holds your notes readably, like a signed-in
116
- browser's own storage does. It is never the source of truth: on every start the Sync Server is
117
- asked what moved and only that is fetched, edits made elsewhere arrive as they happen, and a
118
- newer version of this program discards a cache it no longer understands and rebuilds it.
119
-
120
- Revoke the token at the portal to cut the agent off, and `npx @appsoftwareltd/etherpk-mcp logout`
121
- to forget that server's keys and delete its cache on that computer (`--all` for every server,
122
- which also removes the semantic runtime and model).
146
+ - **Keys** in `~/.config/etherpk/mcp.json`, one entry per Sync Server, readable only by your
147
+ user - the same trust as a browser you've signed in on.
148
+ - **A cache of each synced graph you serve** under `~/.cache/etherpk/mcp/`, so a restart fetches
149
+ what changed rather than everything. It holds your notes readably, as a signed-in browser's
150
+ storage does. It's never the source of truth: on every start the Sync Server is asked what
151
+ moved, edits made elsewhere arrive as they happen, and a newer version of this program
152
+ discards a cache it no longer understands and rebuilds it.
153
+ - **For a folder**, only its index and (once set up) its vectors, under
154
+ `local/<folder name>-<hash of its path>/` in the same cache directory. Nothing is written into
155
+ the folder. Moving or renaming the folder starts the index over.
156
+
157
+ On Windows both paths sit under your user folder: `C:\Users\<you>\.config\etherpk\` and
158
+ `C:\Users\<you>\.cache\etherpk\`. Revoke the token at the portal to cut an agent off; `logout`
159
+ forgets the keys and deletes the cache on this computer.
123
160
 
124
161
  ## Building and publishing
125
162
 
126
- From the EtherPK monorepo (`apps/mcp`; the bundle compiles the Client's own sync, crypto and
127
- index code in through a `$lib` alias, so it builds from the repo, not from this folder alone):
163
+ From the EtherPK monorepo (`apps/mcp`). The bundle compiles the Client's own sync, crypto and
164
+ index code in through a `$lib` alias, so it builds from the repo, not from this folder alone:
128
165
 
129
166
  ```sh
130
- pnpm install # once, at the repo root
167
+ pnpm install # once, at the repo root
131
168
  pnpm --filter @appsoftwareltd/etherpk-mcp check # type-check
132
- pnpm --filter @appsoftwareltd/etherpk-mcp test # unit tests (loopback relay, no server)
169
+ pnpm --filter @appsoftwareltd/etherpk-mcp test # unit tests, no server needed
133
170
  pnpm --filter @appsoftwareltd/etherpk-mcp build # dist/main.js; run it with node dist/main.js
134
171
  ```
135
172
 
136
- To release: bump `version` in `package.json` (the CLI reads its version from there), then from
137
- `apps/mcp` in a real terminal (both the login and the publish need a browser or one-time code,
138
- which needs a TTY):
173
+ To release, bump `version` in `package.json` (the CLI reads it from there), then from `apps/mcp`
174
+ in a real terminal, since both the login and the publish need a one-time code:
139
175
 
140
176
  ```sh
141
- npm whoami || npm login # only if not already signed in (or the token has expired); needs publish rights on @appsoftwareltd
142
- pnpm publish --access public --no-git-checks # prepack runs the build; pnpm rewrites workspace:* deps
143
- npx -y @appsoftwareltd/etherpk-mcp@<version> --version # verify, once the registry lists it (a few minutes)
177
+ npm whoami || npm login # needs publish rights on @appsoftwareltd
178
+ pnpm publish --access public --no-git-checks # prepack builds; pnpm rewrites workspace:* deps
179
+ npx -y @appsoftwareltd/etherpk-mcp@<version> --version # verify, once the registry lists it
144
180
  ```
145
181
 
146
182
  The end-to-end specs in `tests-sync/agents/` build and drive this bundle against a real Sync
147
- Server; the technical notes are in the repo under `docs/docs/technical/Headless Client.md`.
183
+ Server and a real folder; the technical notes are in the repo under
184
+ `docs/docs/technical/Headless Client.md`.
148
185
 
149
- Full guide, including how the cache stays current and what an agent can and can't do:
150
- <https://docs.etherpk.com/using-ai-agents-with-your-notes>.
186
+ Full guide: <https://docs.etherpk.com/using-ai-agents-with-your-notes>.