sublime-mcp 1.3.0 → 1.3.1

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.
@@ -0,0 +1,6 @@
1
+ [
2
+ {
3
+ "caption": "MCP Commander: Server Status",
4
+ "command": "mcp_server_status"
5
+ }
6
+ ]
package/README.md CHANGED
@@ -1,185 +1,84 @@
1
- # sublime-mcp
1
+ # MCP Commander
2
2
 
3
3
  <!-- mcp-name: io.github.dpc00/sublime-mcp -->
4
4
 
5
- The most complete Sublime Text / AI integration available. sublime-mcp lets
6
- Claude Code (or any MCP client) do anything in ST that a human can do from the
7
- keyboard read files, navigate, edit with full undo history, search across the
8
- project, run builds, send commands to a Terminus terminal, evaluate arbitrary
9
- Python in ST's main thread, and more. If you use ST as your primary editor,
10
- this closes the gap between "AI that edits files" and "AI that works in your
11
- editor."
5
+ Exposes Sublime Text to AI assistants (Claude Code, Cursor, etc.) via the
6
+ Model Context Protocol. The MCP server is built directly into the ST plugin
7
+ no separate process or external dependency required.
12
8
 
13
9
  63 tools covering reading, navigation, editing, searching, build, Terminus
14
10
  integration, settings, layout, menus, console log, and live Python scripting.
15
11
 
16
12
  ## Architecture
17
13
 
14
+ The plugin runs two local servers on startup:
15
+
16
+ | Server | Default port | Purpose |
17
+ |--------|-------------|---------|
18
+ | MCP SSE | 9502 (Win) / 9503 (Mac/Linux) | MCP 2024-11-05 SSE transport — connect your agent here |
19
+ | HTTP bridge | 9500 (Win) / 9501 (Mac/Linux) | Internal REST API used by the SSE dispatcher |
20
+
18
21
  ```
19
22
  Claude Code (MCP client)
20
- stdio / MCP protocol
23
+ MCP SSE (port 9502)
21
24
 
22
- mcp_server.py Python process you run outside ST
23
- │ HTTP 127.0.0.1:9500
24
-
25
- sublime_mcp.py ← ST plugin, HTTP server on ST's main thread
25
+ sublime_mcp.py ST plugin MCP server + HTTP bridge, all in one file
26
26
  │ sublime API
27
27
 
28
28
  Sublime Text 4
29
29
  ```
30
30
 
31
- | File | Role |
32
- |------|------|
33
- | `sublime_mcp.py` | ST plugin — runs an HTTP server inside Sublime Text |
34
- | `mcp_server.py` | MCP server — wraps the HTTP API for MCP clients |
35
-
36
31
  ## Installation
37
32
 
38
- ### 1. Install the ST plugin via Package Control
33
+ ### 1. Install via Package Control
39
34
 
40
35
  1. Open the Command Palette (`Ctrl+Shift+P`)
41
36
  2. Run **Package Control: Install Package**
42
- 3. Search for **sublime-mcp** and install
43
-
44
- ST loads it automatically. You should see:
45
-
46
- ```
47
- sublime-mcp: listening on 127.0.0.1:9500
48
- ```
37
+ 3. Search for **MCP Commander** and install
49
38
 
50
- in the ST console (`View › Show Console`).
51
-
52
- > **Manual install (alternative):** copy `sublime_mcp.py` and `sublime_mcp_browse.py`
53
- > from the repo into your `Packages/User/` folder.
54
-
55
- ### 2. Install the MCP server
39
+ The plugin loads automatically. Check `View › Show Console` for:
56
40
 
57
41
  ```
58
- pip install sublime-mcp
59
- ```
60
-
61
- ### 3. Register with Claude Code
62
-
63
- Add to `~/.claude/mcp.json` (or `~/.claude/settings.json`):
64
-
65
- ```json
66
- {
67
- "mcpServers": {
68
- "sublime-mcp": {
69
- "command": "sublime-mcp"
70
- }
71
- }
72
- }
42
+ sublime-mcp: MCP SSE on 127.0.0.1:9502, HTTP bridge on 127.0.0.1:9500
73
43
  ```
74
44
 
75
- Then restart Claude Code. Tools will appear with the `mcp__sublime-mcp__` prefix.
76
-
77
- ## Windows + WSL setup
45
+ > **Manual install:** copy `sublime_mcp.py` (and optionally `sublime_mcp_browse.py`)
46
+ > into your `Packages/User/` folder.
78
47
 
79
- If you run Sublime Text on **both** Windows and WSL, you can give Claude Code
80
- in each environment its own MCP entry pointing at the local ST instance, plus
81
- an optional cross-side entry for the other one.
48
+ ### 2. Register with Claude Code
82
49
 
83
- **Requirements:** WSL2 with [mirrored networking](https://learn.microsoft.com/en-us/windows/wsl/networking#mirrored-mode-networking)
84
- (Windows 11 default). This makes `127.0.0.1` on the WSL side reach Windows
85
- ports, and vice versa.
86
-
87
- ### How it works
88
-
89
- | ST instance | Port | Reached from |
90
- |---|---|---|
91
- | Windows ST | `9500` | Windows `127.0.0.1:9500` or WSL `127.0.0.1:9500` (mirrored) |
92
- | WSL ST | `9501` | WSL `127.0.0.1:9501` |
93
-
94
- Each ST instance runs its own copy of `sublime_mcp.py` on its own port. The
95
- MCP server process always runs on the same side as Claude Code — it just points
96
- at the right port via `SUBLIME_MCP_BASE`.
97
-
98
- ### Step 1 — Install the plugin in both ST instances
99
-
100
- Install via Package Control in each ST instance (Windows and WSL ST separately).
101
-
102
- **WSL ST** — after installing, edit the port in the installed plugin:
103
-
104
- ```
105
- ~/.config/sublime-text/Packages/sublime-mcp/sublime_mcp.py
106
- ```
107
-
108
- ```python
109
- _PORT = 9501 # line 22 of sublime_mcp.py
110
- ```
111
-
112
- ### Step 2 — Install the MCP server on both sides
50
+ Add to `~/.claude/settings.json` under `"mcpServers"`:
113
51
 
114
52
  **Windows:**
115
- ```
116
- pip install sublime-mcp
117
- ```
118
-
119
- **WSL:**
120
- ```
121
- pip3 install sublime-mcp
53
+ ```json
54
+ "sublime-mcp": { "type": "sse", "url": "http://127.0.0.1:9502/sse" }
122
55
  ```
123
56
 
124
- ### Step 3 — Windows `~/.claude/mcp.json`
125
-
57
+ **Mac / Linux:**
126
58
  ```json
127
- {
128
- "mcpServers": {
129
- "sublime-mcp": {
130
- "command": "sublime-mcp"
131
- },
132
- "sublime-mcp-wsl": {
133
- "command": "wsl",
134
- "args": ["sublime-mcp"],
135
- "env": { "SUBLIME_MCP_BASE": "http://127.0.0.1:9501" }
136
- }
137
- }
138
- }
59
+ "sublime-mcp": { "type": "sse", "url": "http://127.0.0.1:9503/sse" }
139
60
  ```
140
61
 
141
- - `sublime-mcp` runs as a Windows process → auto-detects port `9500` → Windows ST
142
- - `sublime-mcp-wsl` runs inside WSL via the `wsl` command → `127.0.0.1:9501` is WSL's loopback → WSL ST
143
-
144
- ### Step 4 — WSL `~/.claude/mcp.json`
62
+ Restart Claude Code. Tools appear with the `mcp__sublime-mcp__` prefix.
145
63
 
146
- ```json
147
- {
148
- "mcpServers": {
149
- "sublime-mcp": {
150
- "command": "sublime-mcp",
151
- "env": { "SUBLIME_MCP_BASE": "http://127.0.0.1:9501" }
152
- },
153
- "sublime-mcp-win": {
154
- "command": "sublime-mcp",
155
- "env": { "SUBLIME_MCP_BASE": "http://127.0.0.1:9500" }
156
- }
157
- }
158
- }
159
- ```
64
+ ## Server management
160
65
 
161
- - `sublime-mcp` runs in WSL `127.0.0.1:9501` WSL ST
162
- - `sublime-mcp-win` runs in WSL `127.0.0.1:9500` reaches Windows ST via mirrored networking
66
+ The MCP server starts automatically when ST loads the plugin. To stop or
67
+ restart it, open the Command Palette and run:
163
68
 
164
- ### Tool prefixes
69
+ > **MCP Commander: Server Status**
165
70
 
166
- | Claude Code session | Tool prefix for WSL ST | Tool prefix for Windows ST |
167
- |---|---|---|
168
- | Windows | `mcp__sublime-mcp-wsl__` | `mcp__sublime-mcp__` |
169
- | WSL | `mcp__sublime-mcp__` | `mcp__sublime-mcp-win__` |
71
+ The panel shows whether the server is running and on which port, and lets you
72
+ start or stop it with a single keypress.
170
73
 
171
74
  ## Tab and Sheet Indexing
172
75
 
173
- **IMPORTANT:** Users refer to tabs by 1-based numbering (tab 1, tab 2, etc.), but
76
+ **IMPORTANT:** Users refer to tabs by 1-based numbering (tab 1, tab 2, etc.), but
174
77
  `get_sheets()` returns 0-based indexes. Always convert user tab references before using:
175
78
  - User **tab 1** = index 0
176
79
  - User **tab 2** = index 1
177
- - User **tab 3** = index 2
178
- - etc.
179
80
 
180
- When closing or targeting a specific tab, always verify the index by calling `get_sheets()`
181
- first, and close by path (preferred) or by focusing then closing the active file.
182
- **Never change focus without user awareness.**
81
+ When targeting a specific tab, call `get_sheets()` first to verify the index.
183
82
 
184
83
  ## Tools
185
84
 
@@ -191,23 +90,23 @@ first, and close by path (preferred) or by focusing then closing the active file
191
90
  | `get_selection` | Current selection(s): text and begin/end line+col for each |
192
91
  | `get_cursor_context` | `lines` lines above and below cursor, with 1-based line numbers prepended |
193
92
  | `get_open_files` | All files open in the current window (path, name, is_dirty) |
194
- | `get_sheets` | All sheets (tabs) in the window by index — includes images and untitled buffers. Returns index, type, path, name, is_dirty |
195
- | `get_sheet_content` | Content of any tab by sheet index (from `get_sheets`). Works for text, untitled, and Terminus tabs; returns path only for image tabs |
93
+ | `get_sheets` | All sheets (tabs) in the window by index — includes images and untitled buffers |
94
+ | `get_sheet_content` | Content of any tab by sheet index (from `get_sheets`) |
196
95
  | `get_project_folders` | Project root folder paths |
197
96
  | `get_file_content` | Full content of any already-open file by path |
198
- | `get_view_content` | Full content of any open tab by name (partial match). Works for Terminus tabs and nameless views |
199
- | `get_view_size` | Total character count of any open tab. Use to compute offsets before `get_view_chars` |
200
- | `get_view_chars` | Text at character offsets begin..end (0-based, end exclusive). Clamps to buffer bounds |
201
- | `get_view_phantoms` | Phantom HTML and extracted plain text from a named view; filters by phantom key |
202
- | `get_output_panel` | Text content of a named output panel. Omit name for the active panel; `name='exec'` for build output |
97
+ | `get_view_content` | Full content of any open tab by name (partial match, case-insensitive) |
98
+ | `get_view_size` | Total character count of any open tab |
99
+ | `get_view_chars` | Text at character offsets begin..end (0-based, end exclusive) |
100
+ | `get_view_phantoms` | Phantom HTML and extracted plain text from a named view |
101
+ | `get_output_panel` | Text content of a named output panel (`name='exec'` for build output) |
203
102
  | `get_active_panel` | Active panel id and, if it is an output panel, its content |
204
103
  | `get_symbols` | All symbols (functions, classes, etc.) in the active file with line numbers |
205
104
  | `lookup_symbol` | Find where a symbol is defined across all open files |
206
105
  | `get_project_data` | Raw `.sublime-project` JSON for the current project |
207
106
  | `get_variables` | ST build variables: `$file`, `$project_path`, `$platform`, etc. |
208
- | `get_command_palette` | Command Palette entries from installed `*.sublime-commands` resources; filterable by package, command, or caption |
209
- | `get_commands` | Runnable command ids from loaded command classes, optionally merged with palette metadata |
210
- | `get_menu_items` | Menu items from `*.sublime-menu` resources; filterable by menu filename, caption, or command |
107
+ | `get_command_palette` | Command Palette entries from installed `*.sublime-commands` resources |
108
+ | `get_commands` | Runnable command ids from loaded command classes |
109
+ | `get_menu_items` | Menu items from `*.sublime-menu` resources |
211
110
  | `get_syntaxes` | All syntax definitions available in ST (name + path) |
212
111
  | `get_scope_at_cursor` | Full syntax scope string at the cursor position |
213
112
  | `get_word_at_cursor` | Word under the cursor and its line/col |
@@ -230,10 +129,10 @@ first, and close by path (preferred) or by focusing then closing the active file
230
129
 
231
130
  | Tool | Description |
232
131
  |------|-------------|
233
- | `str_replace_based_edit_tool` | ST-native editor: `str_replace` (unique match), `insert` (after line N), `create` (new file), `view` (numbered content). Full undo, gutter diff, 30s highlight. Auto-opens file if needed |
132
+ | `str_replace_based_edit_tool` | ST-native editor: `str_replace`, `insert`, `create`, `view`. Full undo, gutter diff, 30s highlight |
234
133
  | `replace_selection` | Replace the current selection(s) with text |
235
134
  | `replace_lines` | Replace lines begin..end (inclusive, 1-based) in the active file |
236
- | `insert_snippet` | Insert at the cursor using ST snippet syntax (`$1` for tab stops, etc.) |
135
+ | `insert_snippet` | Insert at the cursor using ST snippet syntax |
237
136
  | `duplicate_line` | Duplicate the current line(s) |
238
137
  | `toggle_comment` | Toggle line comment, or block comment if `block=True` |
239
138
  | `sort_lines` | Sort selected lines, or all lines if nothing is selected |
@@ -241,24 +140,24 @@ first, and close by path (preferred) or by focusing then closing the active file
241
140
  | `fold_lines` | Fold (collapse) lines begin..end in the active file |
242
141
  | `undo` | Undo the last edit |
243
142
  | `redo` | Redo the last undone edit |
244
- | `run_command` | Run any ST command with optional args. `scope='window'` (default) or `'view'` |
143
+ | `run_command` | Run any ST command with optional args |
245
144
 
246
145
  ### Search
247
146
 
248
147
  | Tool | Description |
249
148
  |------|-------------|
250
- | `find_in_file` | Find all occurrences of a pattern in the active file. Returns `{line, col, text}` list |
251
- | `find_in_files` | Search across project folders (or a supplied list). Skips `.git`, `__pycache__`, `node_modules`, `.venv`. Returns `{path, line, match}` list, capped at `max_results` (default 200) |
149
+ | `find_in_file` | Find all occurrences of a pattern in the active file |
150
+ | `find_in_files` | Search across project folders. Skips `.git`, `__pycache__`, `node_modules`, `.venv` |
252
151
 
253
152
  ### File / Project
254
153
 
255
154
  | Tool | Description |
256
155
  |------|-------------|
257
- | `save_file` | Save the active file |
156
+ | `save_file` | Save the active file (or a specific file by path) |
258
157
  | `save_all` | Save all open files |
259
158
  | `close_file` | Close a file by path, or the active file if path is omitted |
260
159
  | `revert_file` | Revert the active file to its last saved state |
261
- | `add_folder` | Add a folder to the current project (no-op if already present) |
160
+ | `add_folder` | Add a folder to the current project |
262
161
  | `remove_folder` | Remove a folder from the current project by path |
263
162
 
264
163
  ### Syntax / Encoding
@@ -266,92 +165,61 @@ first, and close by path (preferred) or by focusing then closing the active file
266
165
  | Tool | Description |
267
166
  |------|-------------|
268
167
  | `set_syntax` | Set the syntax of the active file by name (case-insensitive partial match) |
269
- | `set_encoding` | Set the character encoding of the active file (e.g. `'UTF-8'`, `'Western (Windows 1252)'`) |
168
+ | `set_encoding` | Set the character encoding of the active file |
270
169
 
271
170
  ### Settings / Window
272
171
 
273
172
  | Tool | Description |
274
173
  |------|-------------|
275
- | `set_setting` | Set a ST setting by key. `scope='view'` (default) or `'window'` |
174
+ | `set_setting` | Set a ST setting by key |
276
175
  | `toggle_sidebar` | Show or hide the sidebar |
277
- | `set_layout` | Set the window pane layout. Accepts a ST layout dict with `cols`, `rows`, `cells` |
176
+ | `set_layout` | Set the window pane layout |
278
177
  | `set_status` | Write a message to ST's status bar |
279
178
 
280
179
  ### Build
281
180
 
282
181
  | Tool | Description |
283
182
  |------|-------------|
284
- | `run_build` | Trigger the current build system, or pass `cmd`/`shell_cmd` + `working_dir` for a custom command |
183
+ | `run_build` | Trigger the current build system, or pass `cmd`/`shell_cmd` for a custom command |
285
184
 
286
185
  ### Terminus Integration
287
186
 
288
187
  [Terminus](https://github.com/randy3k/Terminus) is a popular ST terminal package.
289
188
  `send_to_view` is Terminus-aware: when targeting a Terminus tab it uses
290
- `terminus_send_string` to type text into the terminal session rather than
291
- inserting into a buffer.
189
+ `terminus_send_string` to type text into the terminal session.
292
190
 
293
191
  | Tool | Description |
294
192
  |------|-------------|
295
- | `send_to_view` | Send a string to any open tab by name. For Terminus tabs, types the text as if the user typed it. Include a trailing `\n` to execute a command |
193
+ | `send_to_view` | Send text to any open tab. For Terminus tabs, types as if the user typed it. Include `\n` to execute |
296
194
 
297
195
  ### Scripting
298
196
 
299
197
  | Tool | Description |
300
198
  |------|-------------|
301
- | `eval_python` | Execute arbitrary Python in ST's main thread. Locals available: `sublime`, `window`, `view`, `print`. Returns captured stdout in `output` |
302
- | `get_console_log` | Recent ST console output (plugin log messages and stdout). `tail=N` limits to last N entries; `tail=0` returns all |
199
+ | `eval_python` | Execute arbitrary Python in ST's main thread. Returns captured stdout in `output` |
200
+ | `eval_python_latest` | Execute Python in the system interpreter outside ST's sandbox |
201
+ | `get_console_log` | Recent ST console output. `tail=N` limits to last N entries |
202
+ | `get_console_full` | Entire captured ST console buffer since startup |
303
203
 
304
204
  ## Configuration
305
205
 
306
- ### Port
307
-
308
- The plugin listens on `9500` by default. The MCP server auto-detects the port:
309
- - Windows → `9500`
310
- - WSL / Linux → `9501`
311
-
312
- Override with the `SUBLIME_MCP_BASE` environment variable:
313
-
314
- ```json
315
- {
316
- "mcpServers": {
317
- "sublime-mcp": {
318
- "command": "sublime-mcp",
319
- "env": { "SUBLIME_MCP_BASE": "http://127.0.0.1:9500" }
320
- }
321
- }
322
- }
323
- ```
324
-
325
- To change the plugin's port, edit `_PORT` near the top of `sublime_mcp.py` in your ST `Packages/sublime-mcp/` folder.
326
-
327
- ### Timeout
328
-
329
- The MCP server waits up to 10 seconds for each HTTP response. Edit `TIMEOUT` in
330
- `mcp_server.py` if you need longer (e.g. for slow `eval_python` calls).
331
-
332
- ## Security note
333
-
334
- The HTTP server binds to `127.0.0.1` only and accepts any request without
335
- authentication. Do not expose port 9500 to a network interface.
336
-
337
- ## Requirements
206
+ ### Ports
338
207
 
339
- - Sublime Text 4
340
- - Python 3.10+ (for the MCP server process)
341
- - `pip install mcp httpx`
342
- - Terminus package (optional, required only for `send_to_view` on terminal tabs)
208
+ | Server | Windows | Mac/Linux | Env var override |
209
+ |--------|---------|-----------|-----------------|
210
+ | MCP SSE | 9502 | 9503 | `SUBLIME_MCP_MCP_PORT` |
211
+ | HTTP bridge | 9500 | 9501 | `SUBLIME_MCP_PORT` |
343
212
 
344
- ## Getting Claude to use the tools well
213
+ ### Telling Claude how to use the tools
345
214
 
346
- Add a section like this to your project's `CLAUDE.md` (or `~/.claude/CLAUDE.md`
347
- for global use):
215
+ Add a section like this to your project's `CLAUDE.md` (or `~/.claude/CLAUDE.md`):
348
216
 
349
217
  ```markdown
350
218
  ## Sublime Text MCP tools
351
219
 
352
- sublime-mcp is connected. Prefer it over standard file tools when working in ST:
220
+ MCP Commander is connected. Prefer it over standard file tools when working in ST:
353
221
 
354
- - Read files with `get_active_file` or `get_file_content` rather than Read tool
222
+ - Read files with `get_active_file` or `get_file_content` rather than the Read tool
355
223
  - Edit with `str_replace_based_edit_tool` — edits appear live with gutter diff and undo
356
224
  - Use `find_in_files` for project-wide search
357
225
  - Use `send_to_view` to run commands in a Terminus terminal tab
@@ -362,44 +230,42 @@ Tab indexing: `get_sheets()` returns 0-based indexes; users refer to tabs
362
230
  1-based. Always call `get_sheets()` first when targeting a specific tab.
363
231
  ```
364
232
 
365
- ## Known limitations / Roadmap
233
+ ## Security note
234
+
235
+ Both servers bind to `127.0.0.1` only and accept any request without
236
+ authentication. Do not expose these ports to a network interface.
366
237
 
367
- - **No multi-window support** — tools target the most recently focused ST window only
238
+ ## Requirements
239
+
240
+ - Sublime Text 4
241
+ - Terminus package (optional — only required for `send_to_view` on terminal tabs)
242
+
243
+ ## Known limitations
244
+
245
+ - **No multi-window support** — tools target the most recently focused ST window
368
246
  - **No image editing** — `get_sheet_content` returns the path for image tabs, not pixel data
369
- - **Terminus dependency is optional** — `send_to_view` degrades gracefully if Terminus isn't installed, but terminal interaction requires it
370
247
  - **No ST3 support** — the plugin uses ST4 APIs throughout
371
248
 
372
- Contributions welcome in any of these areas. See below.
373
-
374
249
  ## Testing
375
250
 
376
251
  The test suite requires Sublime Text to be running with `sublime_mcp.py` loaded.
377
252
 
378
253
  ```
379
- cd C:\Users\donal\projects\sublime-mcp
254
+ cd /path/to/sublime-mcp
380
255
  pip install httpx pytest
381
- pytest tests/test_http_api.py -v
256
+ pytest tests/ -v
382
257
  ```
383
258
 
384
- 111 tests covering all 60 HTTP API endpoints. Expected result: 109 passed, 2 skipped
385
- (the skips are environment-dependent: one requires an open saved file, one requires
386
- a Terminus tab). Zero failures on a clean ST session.
387
-
388
259
  ## Contributing
389
260
 
390
- The project has two independent pieces — the ST plugin (`sublime_mcp.py`) and
391
- the MCP server (`mcp_server.py`) — which makes it easy to contribute to either
392
- without touching the other.
393
-
394
261
  **Adding a tool:**
395
- 1. Add an HTTP handler in `sublime_mcp.py` (runs on ST's main thread via `_on_main`)
396
- 2. Add the corresponding `@mcp.tool()` function in `mcp_server.py`
262
+ 1. Add a handler function in `sublime_mcp.py` (run via `_on_main` for ST API calls)
263
+ 2. Add an entry to `_MCP_TOOLS` and the `_GET` / `_POST` routing dicts
397
264
  3. Add a row to the Tools table in `README.md`
398
265
 
399
266
  **Good first issues:**
400
267
  - Multi-window support (`sublime.windows()` instead of `sublime.active_window()`)
401
268
  - `get_diagnostics` — expose LSP error/warning annotations
402
269
  - `set_bookmark` / `clear_bookmarks` — write counterparts to `get_bookmarks`
403
- - Any gap identified in the [JetBrains MCP feature set](https://github.com/JetBrains/mcp-jetbrains)
404
270
 
405
271
  Open an issue or PR on [GitHub](https://github.com/dpc00/sublime-mcp).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sublime-mcp",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "MCP server for Sublime Text 4 — exposes editor state and editing tools to AI assistants via the Model Context Protocol.",
5
5
  "type": "module",
6
6
  "bin": {