Skip to content

Commit e7725ea

Browse files
committed
docs: update PROTOCOL.md with complete VS Code tool specs and streamline README
- Added comprehensive specifications for all 12 MCP tools from VS Code extension - Documented complete input/output schemas with Zod validation details - Added detailed output format examples for each tool showing MCP response structure - Enhanced tool descriptions with parameter requirements and optional fields - Added implementation notes about naming conventions and blocking operations - Added prominent warning about Claude Code v1.0.27 compatibility issues - Streamlined installation to single unified configuration - Made snacks.nvim a required dependency to reduce support complexity - Reorganized content flow: install → demo → usage → advanced config - Added `<leader>ab` keybind for adding current buffer to Claude context - Simplified Key Commands section with line range syntax for ClaudeCodeAdd - Condensed verbose sections while preserving essential information - Improved overall readability and reduced decision paralysis for users - Added `<leader>ab` keybind to match README configuration - Maintained consistency between main README and development config These changes provide users with complete protocol documentation for building integrations while making the README more approachable for quick adoption. Change-Id: I7f30e85c6a4b4c5516fe7a491a9a2f73d2fd497d Signed-off-by: Thomas Kosiewski <[email protected]>
1 parent 2603ec0 commit e7725ea

File tree

3 files changed

+408
-392
lines changed

3 files changed

+408
-392
lines changed

PROTOCOL.md

Lines changed: 343 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -132,46 +132,361 @@ According to the MCP spec, Claude should be able to call tools, but **current im
132132

133133
## Available MCP Tools
134134

135-
The extensions register these tools that Claude can (theoretically) call:
135+
The VS Code extension registers 12 tools that Claude can call. Here's the complete specification:
136136

137-
### Core Tools
137+
### 1. openFile
138138

139-
1. **openFile** - Open a file and optionally select text
139+
**Description**: Open a file in the editor and optionally select a range of text
140140

141-
```json
142-
{
143-
"filePath": "/path/to/file.js",
144-
"startText": "function hello", // Find and select from this text
145-
"endText": "}" // To this text
146-
}
147-
```
141+
**Input**:
148142

149-
2. **openDiff** - Show a diff and wait for user action (blocking!)
143+
```json
144+
{
145+
"filePath": "/path/to/file.js",
146+
"preview": false,
147+
"startText": "function hello",
148+
"endText": "}",
149+
"selectToEndOfLine": false,
150+
"makeFrontmost": true
151+
}
152+
```
153+
154+
- `filePath` (string, required): Path to the file to open
155+
- `preview` (boolean, default: false): Whether to open in preview mode
156+
- `startText` (string, optional): Text pattern to find selection start
157+
- `endText` (string, optional): Text pattern to find selection end
158+
- `selectToEndOfLine` (boolean, default: false): Extend selection to end of line
159+
- `makeFrontmost` (boolean, default: true): Make the file the active editor tab
160+
161+
**Output**: When `makeFrontmost=true`, returns simple message:
162+
163+
```json
164+
{
165+
"content": [
166+
{
167+
"type": "text",
168+
"text": "Opened file: /path/to/file.js"
169+
}
170+
]
171+
}
172+
```
173+
174+
When `makeFrontmost=false`, returns detailed JSON:
175+
176+
```json
177+
{
178+
"content": [
179+
{
180+
"type": "text",
181+
"text": "{\"success\": true, \"filePath\": \"/absolute/path/to/file.js\", \"languageId\": \"javascript\", \"lineCount\": 42}"
182+
}
183+
]
184+
}
185+
```
186+
187+
### 2. openDiff
188+
189+
**Description**: Open a git diff for the file (blocking operation)
190+
191+
**Input**:
192+
193+
```json
194+
{
195+
"old_file_path": "/path/to/original.js",
196+
"new_file_path": "/path/to/modified.js",
197+
"new_file_contents": "// Modified content...",
198+
"tab_name": "Proposed changes"
199+
}
200+
```
201+
202+
- `old_file_path` (string): Path to original file
203+
- `new_file_path` (string): Path to new file
204+
- `new_file_contents` (string): Contents of the new file
205+
- `tab_name` (string): Tab name for the diff view
206+
207+
**Output**: Returns MCP-formatted response:
208+
209+
```json
210+
{
211+
"content": [
212+
{
213+
"type": "text",
214+
"text": "FILE_SAVED"
215+
}
216+
]
217+
}
218+
```
219+
220+
or
221+
222+
```json
223+
{
224+
"content": [
225+
{
226+
"type": "text",
227+
"text": "DIFF_REJECTED"
228+
}
229+
]
230+
}
231+
```
232+
233+
Based on whether the user saves or rejects the diff.
234+
235+
### 3. getCurrentSelection
150236

151-
```json
152-
{
153-
"old_file_path": "/path/to/original.js",
154-
"new_file_path": "/path/to/modified.js",
155-
"new_file_contents": "// Modified content...",
156-
"tab_name": "Proposed changes"
157-
}
158-
```
237+
**Description**: Get the current text selection in the active editor
238+
239+
**Input**: None
240+
241+
**Output**: Returns JSON-stringified selection data:
242+
243+
```json
244+
{
245+
"content": [
246+
{
247+
"type": "text",
248+
"text": "{\"success\": true, \"text\": \"selected content\", \"filePath\": \"/path/to/file\", \"selection\": {\"start\": {\"line\": 0, \"character\": 0}, \"end\": {\"line\": 0, \"character\": 10}}}"
249+
}
250+
]
251+
}
252+
```
253+
254+
Or when no active editor:
255+
256+
```json
257+
{
258+
"content": [
259+
{
260+
"type": "text",
261+
"text": "{\"success\": false, \"message\": \"No active editor found\"}"
262+
}
263+
]
264+
}
265+
```
266+
267+
### 4. getLatestSelection
268+
269+
**Description**: Get the most recent text selection (even if not in active editor)
270+
271+
**Input**: None
272+
273+
**Output**: JSON-stringified selection data or `{success: false, message: "No selection available"}`
274+
275+
### 5. getOpenEditors
276+
277+
**Description**: Get information about currently open editors
278+
279+
**Input**: None
280+
281+
**Output**: Returns JSON-stringified array of open tabs:
282+
283+
```json
284+
{
285+
"content": [
286+
{
287+
"type": "text",
288+
"text": "{\"tabs\": [{\"uri\": \"file:///path/to/file\", \"isActive\": true, \"label\": \"filename.ext\", \"languageId\": \"javascript\", \"isDirty\": false}]}"
289+
}
290+
]
291+
}
292+
```
293+
294+
### 6. getWorkspaceFolders
295+
296+
**Description**: Get all workspace folders currently open in the IDE
297+
298+
**Input**: None
299+
300+
**Output**: Returns JSON-stringified workspace information:
301+
302+
```json
303+
{
304+
"content": [
305+
{
306+
"type": "text",
307+
"text": "{\"success\": true, \"folders\": [{\"name\": \"project-name\", \"uri\": \"file:///path/to/workspace\", \"path\": \"/path/to/workspace\"}], \"rootPath\": \"/path/to/workspace\"}"
308+
}
309+
]
310+
}
311+
```
312+
313+
### 7. getDiagnostics
314+
315+
**Description**: Get language diagnostics from VS Code
316+
317+
**Input**:
318+
319+
```json
320+
{
321+
"uri": "file:///path/to/file.js"
322+
}
323+
```
324+
325+
- `uri` (string, optional): File URI to get diagnostics for. If not provided, gets diagnostics for all files.
326+
327+
**Output**: Returns JSON-stringified array of diagnostics per file:
328+
329+
```json
330+
{
331+
"content": [
332+
{
333+
"type": "text",
334+
"text": "[{\"uri\": \"file:///path/to/file\", \"diagnostics\": [{\"message\": \"Error message\", \"severity\": \"Error\", \"range\": {\"start\": {\"line\": 0, \"character\": 0}}, \"source\": \"typescript\"}]}]"
335+
}
336+
]
337+
}
338+
```
339+
340+
### 8. checkDocumentDirty
341+
342+
**Description**: Check if a document has unsaved changes (is dirty)
343+
344+
**Input**:
345+
346+
```json
347+
{
348+
"filePath": "/path/to/file.js"
349+
}
350+
```
351+
352+
- `filePath` (string, required): Path to the file to check
353+
354+
**Output**: Returns document dirty status:
355+
356+
```json
357+
{
358+
"content": [
359+
{
360+
"type": "text",
361+
"text": "{\"success\": true, \"filePath\": \"/path/to/file.js\", \"isDirty\": true, \"isUntitled\": false}"
362+
}
363+
]
364+
}
365+
```
366+
367+
Or when document not open:
368+
369+
```json
370+
{
371+
"content": [
372+
{
373+
"type": "text",
374+
"text": "{\"success\": false, \"message\": \"Document not open: /path/to/file.js\"}"
375+
}
376+
]
377+
}
378+
```
379+
380+
### 9. saveDocument
381+
382+
**Description**: Save a document with unsaved changes
383+
384+
**Input**:
385+
386+
```json
387+
{
388+
"filePath": "/path/to/file.js"
389+
}
390+
```
391+
392+
- `filePath` (string, required): Path to the file to save
393+
394+
**Output**: Returns save operation result:
395+
396+
```json
397+
{
398+
"content": [
399+
{
400+
"type": "text",
401+
"text": "{\"success\": true, \"filePath\": \"/path/to/file.js\", \"saved\": true, \"message\": \"Document saved successfully\"}"
402+
}
403+
]
404+
}
405+
```
406+
407+
Or when document not open:
408+
409+
```json
410+
{
411+
"content": [
412+
{
413+
"type": "text",
414+
"text": "{\"success\": false, \"message\": \"Document not open: /path/to/file.js\"}"
415+
}
416+
]
417+
}
418+
```
419+
420+
### 10. close_tab
421+
422+
**Description**: Close a tab by name
423+
424+
**Input**:
425+
426+
```json
427+
{
428+
"tab_name": "filename.js"
429+
}
430+
```
431+
432+
- `tab_name` (string, required): Name of the tab to close
433+
434+
**Output**: Returns `{content: [{type: "text", text: "TAB_CLOSED"}]}`
435+
436+
### 11. closeAllDiffTabs
437+
438+
**Description**: Close all diff tabs in the editor
439+
440+
**Input**: None
441+
442+
**Output**: Returns `{content: [{type: "text", text: "CLOSED_${count}_DIFF_TABS"}]}`
443+
444+
### 12. executeCode
445+
446+
**Description**: Execute Python code in the Jupyter kernel for the current notebook file
447+
448+
**Input**:
449+
450+
```json
451+
{
452+
"code": "print('Hello, World!')"
453+
}
454+
```
455+
456+
- `code` (string, required): The code to be executed on the kernel
457+
458+
**Output**: Returns execution results with mixed content types:
459+
460+
```json
461+
{
462+
"content": [
463+
{
464+
"type": "text",
465+
"text": "Hello, World!"
466+
},
467+
{
468+
"type": "image",
469+
"data": "base64_encoded_image_data",
470+
"mimeType": "image/png"
471+
}
472+
]
473+
}
474+
```
159475

160-
Returns `FILE_SAVED` or `DIFF_REJECTED` based on user action.
476+
**Notes**:
161477

162-
3. **getCurrentSelection** - Get the current text selection
163-
4. **getOpenEditors** - List all open files
164-
5. **getWorkspaceFolders** - Get project folders
165-
6. **getDiagnostics** - Get errors/warnings from the IDE
166-
7. **saveDocument** - Save a file
167-
8. **close_tab** - Close a tab by name (note the inconsistent naming!)
478+
- All code executed will persist across calls unless the kernel is restarted
479+
- Avoid declaring variables or modifying kernel state unless explicitly requested
480+
- Only available when working with Jupyter notebooks
481+
- Can return multiple content types including text output and images
168482

169483
### Implementation Notes
170484

171485
- Most tools follow camelCase naming except `close_tab` (uses snake_case)
172-
- The `openDiff` tool is unique - it's **blocking** and waits for user interaction
486+
- The `openDiff` tool is **blocking** and waits for user interaction
173487
- Tools return MCP-formatted responses with content arrays
174-
- There's also `executeCode` for Jupyter notebooks in the VS Code extension
488+
- All schemas use Zod validation in the VS Code extension
489+
- Selection-related tools work with the current editor state
175490

176491
## Building Your Own Integration
177492

0 commit comments

Comments
 (0)