obelisk-mcp 0.1.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.
Files changed (5) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/dist/cli.mjs +8342 -0
  4. package/dist/mcp.mjs +43807 -0
  5. package/package.json +41 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zachary Hannum
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,211 @@
1
+ # Obelisk
2
+
3
+ Inline comments and GitHub-style suggested edits for [Obsidian](https://obsidian.md).
4
+
5
+ Select a passage, leave a comment on it, and optionally propose a replacement
6
+ that can be applied with one click. Comments are stored in the note's own
7
+ frontmatter, so they travel with the file through sync, git, export and rename.
8
+ There is no sidecar database to fall out of step with the vault.
9
+
10
+ > An *obelus* (†) was the mark ancient editors drew in the margin of a
11
+ > manuscript to say: this passage is disputed.
12
+
13
+ ## Status
14
+
15
+ Pre-release. Anchoring, decoration, the sidebar, suggested edits and the agent
16
+ integration are implemented. Not yet released or submitted to the community
17
+ plugin list, and not yet exercised against a large vault.
18
+
19
+ ## Features
20
+
21
+ - **Comment on any passage.** Select text, right-click, *Add comment*.
22
+ - **Markdown everywhere.** Comments and replies are ordinary markdown, with a
23
+ Write/Preview pair while you type. Links, lists, callouts, embeds and math
24
+ render in the sidebar exactly as they would in a note.
25
+ - **Suggested edits.** A proposal is a fenced ` ```suggestion ` block *inside*
26
+ the comment, the way GitHub does it. It renders as a diff against the quoted
27
+ passage with an Apply button, so one comment can explain itself and propose a
28
+ change, and a reply can offer a counter-proposal. Applying is refused if the
29
+ underlying text has changed since. It also resolves the comment, and *Reopen*
30
+ is there if the comment asked something the edit did not answer.
31
+ - **Sidebar.** All of a note's comments in document order, or newest first from
32
+ the sort toggle; click one to scroll the editor to it. Chips filter to open
33
+ comments, to comments carrying a suggestion, or to one agent's review pass.
34
+ Resolved comments stay in the list, greyed rather than hidden, since they are
35
+ still highlighted in the note.
36
+ - **In-text highlighting.** Commented passages are highlighted, with a †
37
+ marker that opens the comment in the sidebar.
38
+ - **Stored in frontmatter.** Plain YAML under an `obelisk` key. Readable,
39
+ diffable, portable.
40
+ - **Survives editing.** A comment is anchored to the text it quotes, so it
41
+ keeps up with edits anywhere else in the note, including ones made outside
42
+ Obsidian. Edit or delete the quoted passage itself and the comment detaches:
43
+ flagged in the sidebar, highlighting nothing, never moved onto a different
44
+ passage and never dropped. Restore the text and it reattaches. Resolved
45
+ comments are exempt from the flag, because a resolved comment usually
46
+ detaches when the edit it asked for is made.
47
+ - **The editor you already use.** Comments are written in Obsidian's own
48
+ markdown editor, so Cmd+B, list continuation, `[[` autocompletion and live
49
+ preview work in a comment exactly as they do in a note.
50
+ - **Threaded replies.** On any comment, stored alongside it, and markdown all
51
+ the way down.
52
+ - **Editable.** Rewrite a comment or a reply in the same composer that wrote
53
+ it, suggestion button and all, from the card's *Edit* button or by
54
+ right-clicking the passage. Edited bodies are marked as such; the anchor is
55
+ left alone, so changing what you said never changes what you said it about.
56
+ - **Deletable.** A whole comment from the card's *Delete*, or a single reply
57
+ from the trash icon in its header, so striking one remark out of a thread
58
+ does not take the conversation with it. Both offer an undo rather than a
59
+ confirmation dialog.
60
+ - **Open to agents.** A command-line tool and an MCP server can read and write
61
+ the same comments from outside Obsidian, so a model can review a note into
62
+ your sidebar, or answer the comments you left for it. Its comments are
63
+ badged, and a whole review pass is one chip in the header with a *dismiss
64
+ all* on it. See below.
65
+
66
+ ## Data format
67
+
68
+ ```yaml
69
+ ---
70
+ obelisk:
71
+ - id: cq7fk2m9x
72
+ author: zach
73
+ created: 2026-08-29T14:02:11.000Z
74
+ body: |-
75
+ This paragraph does two things at once.
76
+
77
+ ```suggestion
78
+ The horse bolted.
79
+ ```
80
+ anchor:
81
+ from: { line: 12, col: 0 }
82
+ to: { line: 12, col: 47 }
83
+ quote: The horse, which had been standing there, bolted.
84
+ ---
85
+ ```
86
+
87
+ A comment is one piece of markdown. A proposed edit is a ` ```suggestion `
88
+ fenced block inside it, whose content replaces exactly the anchored range when
89
+ applied, so one comment can hold prose, a link and a proposal at once.
90
+
91
+ The `quote` is what a comment is anchored by. The line/column range records
92
+ where the passage was when the comment was written. It orders the sidebar and
93
+ breaks ties when a quote appears twice, and is never rewritten. Lines are
94
+ counted from the first line *after* the frontmatter block, so adding a comment
95
+ never invalidates the others.
96
+
97
+ A comment written by a model carries one more key, `origin`, holding the model
98
+ and an id shared by every comment in that review pass. Its absence means a
99
+ person wrote it, so nothing already in a vault needs migrating.
100
+
101
+ ## Agents
102
+
103
+ The same comments, from outside Obsidian. A model reviews a note and its
104
+ remarks appear in the sidebar of the note you already have open; or you leave
105
+ comments asking for things and a model reads them, makes the edits, and
106
+ resolves them.
107
+
108
+ ```bash
109
+ npm run build
110
+ npm link # puts `obelisk` and `obelisk-mcp` on PATH
111
+
112
+ obelisk list note.md
113
+ obelisk comment note.md --quote "The horse, which had been standing there, bolted." \
114
+ --body "Two clauses fighting over one sentence." --run r7k2mq
115
+ ```
116
+
117
+ For an agent that speaks MCP, register the server with it. Nothing is published
118
+ to npm yet, so point at the built file:
119
+
120
+ ```bash
121
+ npm run build # from the root of this repo
122
+ claude mcp add obelisk --scope user -- \
123
+ node "$PWD/dist/mcp.mjs" --vault /path/to/your/vault
124
+ ```
125
+
126
+ `$PWD` fills in this repo's path, so the vault is the only one you have to
127
+ supply, and it has to be a real one. A path that does not exist makes `node`
128
+ exit before it says anything, which reaches the agent as `CONNECTION_CLOSED`
129
+ and names nothing; if you see that, the path in `claude mcp get obelisk` is the
130
+ first thing to check.
131
+
132
+ Two things bite here, both of them silent:
133
+
134
+ - **Scope.** `claude mcp add` defaults to `local`, which files the server under
135
+ the directory you happened to run it in. Run it from this repo and you get a
136
+ server that exists only while you are in this repo, the one place you have no
137
+ notes to comment on. `--scope user` registers it everywhere; `--scope
138
+ project` writes a `.mcp.json` in the vault instead, if the vault is a repo
139
+ and everyone working in it should get the server.
140
+ - **`npx obelisk-mcp` only works inside this repo.** The package is not on npm
141
+ yet, and inside the repo npx resolves the bin out of the local
142
+ `package.json`. Anywhere else it goes to the registry and 404s. Use the
143
+ absolute path above, or `npm link` first and register `obelisk-mcp`.
144
+
145
+ Both paths have to be absolute. The server is spawned without a shell, so a `~`
146
+ in a config file stays a literal tilde, and the process inherits the agent's
147
+ working directory rather than the vault's.
148
+
149
+ **There is nothing to start.** It speaks MCP over stdio: the agent spawns a
150
+ process when a session opens and kills it when the session ends, so
151
+ `obelisk-mcp` is never run by hand and there is no port and no daemon. One
152
+ process per session is also what makes a session's comments share one run chip
153
+ in the sidebar. Rebuild while a session is open and it keeps the old process;
154
+ reconnect it from `/mcp`, or start a new session.
155
+
156
+ To check the registration, `claude mcp list`, or `/mcp` inside a session. To
157
+ check the server itself with no agent in the way:
158
+
159
+ ```bash
160
+ printf '%s\n' \
161
+ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
162
+ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
163
+ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
164
+ | node dist/mcp.mjs --vault /abs/path/to/vault
165
+ ```
166
+
167
+ That should print the handshake and then the four tools. A server that fails
168
+ this fails the same way for an agent, which is worth knowing before you go
169
+ looking at the agent's end of it.
170
+
171
+ For an agent that does not speak MCP, paste
172
+ [`docs/agents-fragment.md`](docs/agents-fragment.md) into the vault's
173
+ `AGENTS.md` or `CLAUDE.md`.
174
+
175
+ The one rule worth knowing: **the quote is the anchor.** A line number is never
176
+ one. A model asked for a line will produce a plausible wrong number, and a
177
+ plausible wrong number attaches a comment to the wrong paragraph without ever
178
+ looking like an error, so `--near-line` only picks between identical quotes and
179
+ takes a number copied out of `obelisk list`. `--quote` has to appear in the
180
+ note character for character, and if it does not, or appears twice, nothing is
181
+ written and the tool says so. `obelisk list` prints the body line-numbered so
182
+ the exact text is there to copy.
183
+
184
+ Writes are frontmatter-only and leave the body byte-identical, so they are safe
185
+ while the note is open in Obsidian; a write also re-reads the file first and
186
+ refuses if it changed underneath.
187
+
188
+ ## Development
189
+
190
+ ```bash
191
+ npm install
192
+ npm run dev # watch build, plugin only
193
+ npm run build # typecheck, then main.js plus dist/cli.mjs and dist/mcp.mjs
194
+ ```
195
+
196
+ `src/core/` is the half that does not import Obsidian: the model, the anchor
197
+ arithmetic, the YAML and the four verbs. The plugin, the CLI and the MCP server
198
+ are three front ends over it.
199
+
200
+ `site/` is the documentation site, an Astro project of its own with its own
201
+ `npm install`. It is not part of `npm run build`.
202
+
203
+ Symlink the repo into a test vault to try it:
204
+
205
+ ```bash
206
+ ln -s "$PWD" /path/to/vault/.obsidian/plugins/obelisk
207
+ ```
208
+
209
+ ## License
210
+
211
+ MIT