mcp-lsp-driver 0.0.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.
- package/LICENSE +21 -0
- package/README.md +468 -0
- package/dist/capabilities.d.ts +181 -0
- package/dist/capabilities.js +11 -0
- package/dist/formatting.d.ts +33 -0
- package/dist/formatting.js +67 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +13 -0
- package/dist/interfaces.d.ts +38 -0
- package/dist/interfaces.js +8 -0
- package/dist/resolver.d.ts +81 -0
- package/dist/resolver.js +171 -0
- package/dist/schemas.d.ts +41 -0
- package/dist/schemas.js +62 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.js +557 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.js +8 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 EFLKumo
|
|
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,468 @@
|
|
|
1
|
+
# MCP LSP Driver SDK
|
|
2
|
+
|
|
3
|
+
A TypeScript SDK that bridges Language Server Protocol (LSP) capabilities with the Model Context Protocol (MCP). Designed for IDE plugin developers building AI-assisted coding tools for VS Code, JetBrains, and other editors.
|
|
4
|
+
|
|
5
|
+
## Core Philosophy
|
|
6
|
+
|
|
7
|
+
- **Fuzzy-to-Exact Resolution**: LLMs interact via semantic anchors (`symbolName`, `lineHint`), and the SDK resolves them to precise coordinates
|
|
8
|
+
- **Disk-Based Truth**: All read operations reflect the state of files on disk, ignoring unsaved IDE buffers
|
|
9
|
+
- **Human-in-the-Loop Edits**: Write operations require explicit user approval before applying changes
|
|
10
|
+
- **Type Safety**: Strict TypeScript with no `any` types
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install mcp-lsp-driver
|
|
16
|
+
# or
|
|
17
|
+
pnpm add mcp-lsp-driver
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
24
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
25
|
+
import { installMcpLspDriver, type IdeCapabilities } from 'mcp-lsp-driver'
|
|
26
|
+
import * as fs from 'fs/promises'
|
|
27
|
+
|
|
28
|
+
// 1. Create your MCP server
|
|
29
|
+
const server = new McpServer({
|
|
30
|
+
name: 'my-ide-mcp-server',
|
|
31
|
+
version: '1.0.0'
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
// 2. Implement File Access (required)
|
|
35
|
+
const fileAccess = {
|
|
36
|
+
readFile: async (uri: string) => {
|
|
37
|
+
return await fs.readFile(uri, 'utf-8')
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 3. Implement User Interaction (required for edits)
|
|
42
|
+
const userInteraction = {
|
|
43
|
+
previewAndApplyEdits: async (operation) => {
|
|
44
|
+
// Show diff in your IDE and get user approval
|
|
45
|
+
return await showDiffDialog(operation)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 4. Implement LSP Capability Providers
|
|
50
|
+
const definition = {
|
|
51
|
+
provideDefinition: async (uri, position) => {
|
|
52
|
+
// Call your IDE's LSP to get definition
|
|
53
|
+
return await lspClient.getDefinition(uri, position)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const diagnostics = {
|
|
58
|
+
provideDiagnostics: async (uri) => {
|
|
59
|
+
// Get diagnostics from your IDE for the file
|
|
60
|
+
return await lspClient.getDiagnostics(uri)
|
|
61
|
+
},
|
|
62
|
+
getWorkspaceDiagnostics: async () => {
|
|
63
|
+
// Optional: Get all diagnostics in the workspace
|
|
64
|
+
return await lspClient.getWorkspaceDiagnostics()
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const outline = {
|
|
69
|
+
provideDocumentSymbols: async (uri) => {
|
|
70
|
+
// Get document symbols from your IDE
|
|
71
|
+
return await lspClient.getDocumentSymbols(uri)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const filesystem = {
|
|
76
|
+
getFileTree: async (folderPath) => {
|
|
77
|
+
// Get file tree excluding git-ignored files
|
|
78
|
+
return await yourIDE.getFileTree(folderPath)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 5. Register LSP tools and resources on the server
|
|
83
|
+
const capabilities: IdeCapabilities = {
|
|
84
|
+
fileAccess,
|
|
85
|
+
userInteraction,
|
|
86
|
+
definition,
|
|
87
|
+
diagnostics,
|
|
88
|
+
outline,
|
|
89
|
+
filesystem,
|
|
90
|
+
onDiagnosticsChanged: (callback) => {
|
|
91
|
+
// Register for diagnostic changes
|
|
92
|
+
yourIDE.onDiagnosticsChanged((uri) => callback(uri))
|
|
93
|
+
},
|
|
94
|
+
// Add more capabilities as needed
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
installMcpLspDriver({ server, capabilities })
|
|
98
|
+
|
|
99
|
+
// 6. Connect to transport (you control the server lifecycle)
|
|
100
|
+
const transport = new StdioServerTransport()
|
|
101
|
+
await server.connect(transport)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
### Core Interfaces
|
|
107
|
+
|
|
108
|
+
#### `FileAccessProvider` (Required)
|
|
109
|
+
|
|
110
|
+
Provides disk access for reading files:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
interface FileAccessProvider {
|
|
114
|
+
readFile(uri: UnifiedUri): Promise<string>
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### `UserInteractionProvider` (Required for edits)
|
|
119
|
+
|
|
120
|
+
Handles user approval for edit operations:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
interface UserInteractionProvider {
|
|
124
|
+
previewAndApplyEdits(operation: PendingEditOperation): Promise<boolean>
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Capability Providers
|
|
129
|
+
|
|
130
|
+
All capability providers receive `ExactPosition` coordinates (0-based). The SDK handles fuzzy-to-exact conversion before calling these.
|
|
131
|
+
|
|
132
|
+
#### `DefinitionProvider`
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
interface DefinitionProvider {
|
|
136
|
+
provideDefinition(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### `ReferencesProvider`
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
interface ReferencesProvider {
|
|
144
|
+
provideReferences(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### `HierarchyProvider`
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
interface HierarchyProvider {
|
|
152
|
+
provideCallHierarchy(
|
|
153
|
+
uri: UnifiedUri,
|
|
154
|
+
position: ExactPosition,
|
|
155
|
+
direction: 'incoming' | 'outgoing'
|
|
156
|
+
): Promise<CodeSnippet[]>
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### `DiagnosticsProvider`
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
interface DiagnosticsProvider {
|
|
164
|
+
provideDiagnostics(uri: UnifiedUri): Promise<Diagnostic[]>
|
|
165
|
+
getWorkspaceDiagnostics?(): Promise<Diagnostic[]> // Optional workspace diagnostics
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### `OutlineProvider`
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
interface OutlineProvider {
|
|
173
|
+
provideDocumentSymbols(uri: UnifiedUri): Promise<DocumentSymbol[]>
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### `FilesystemProvider`
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
interface FilesystemProvider {
|
|
181
|
+
getFileTree(folderPath: string): Promise<string[]>
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Provides filesystem access with git-ignore support. Returns file/folder paths in a directory tree, excluding git-ignored files.
|
|
186
|
+
|
|
187
|
+
#### `GlobalFindProvider`
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
interface GlobalFindProvider {
|
|
191
|
+
globalFind(query: string, options: GlobalFindOptions): Promise<GlobalFindMatch[]>
|
|
192
|
+
globalReplace(query: string, replaceWith: string, options: GlobalFindOptions): Promise<number>
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Provides global find and replace functionality across the workspace. `GlobalFindOptions` includes:
|
|
197
|
+
- `caseSensitive`: Whether the search is case-sensitive (default: false)
|
|
198
|
+
- `exactMatch`: Whether to match exact words only (default: false)
|
|
199
|
+
- `regexMode`: Whether the query is a regular expression (default: false)
|
|
200
|
+
|
|
201
|
+
`GlobalFindMatch` includes:
|
|
202
|
+
- `uri`: File URI containing the match
|
|
203
|
+
- `line`: 1-based line number
|
|
204
|
+
- `column`: 1-based column number
|
|
205
|
+
- `matchText`: The matching text
|
|
206
|
+
- `context`: Context around the match (e.g., the full line)
|
|
207
|
+
|
|
208
|
+
### IdeCapabilities
|
|
209
|
+
|
|
210
|
+
Combine all providers into a single configuration:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
interface IdeCapabilities {
|
|
214
|
+
fileAccess: FileAccessProvider // Required
|
|
215
|
+
userInteraction?: UserInteractionProvider // Required for apply_edit tool
|
|
216
|
+
definition?: DefinitionProvider // Enables goto_definition tool
|
|
217
|
+
references?: ReferencesProvider // Enables find_references tool
|
|
218
|
+
hierarchy?: HierarchyProvider // Enables call_hierarchy tool
|
|
219
|
+
diagnostics?: DiagnosticsProvider // Enables diagnostics resources
|
|
220
|
+
outline?: OutlineProvider // Enables outline resource
|
|
221
|
+
filesystem?: FilesystemProvider // Enables filesystem resource
|
|
222
|
+
globalFind?: GlobalFindProvider // Enables global_find and global_replace tools
|
|
223
|
+
onDiagnosticsChanged?: (callback: OnDiagnosticsChangedCallback) => void
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## MCP Tools
|
|
228
|
+
|
|
229
|
+
The SDK automatically registers tools based on which capabilities you provide:
|
|
230
|
+
|
|
231
|
+
### `goto_definition`
|
|
232
|
+
|
|
233
|
+
Navigate to the definition of a symbol.
|
|
234
|
+
|
|
235
|
+
**Inputs:**
|
|
236
|
+
- `uri`: File path or URI
|
|
237
|
+
- `symbol_name`: Text of the symbol to find
|
|
238
|
+
- `line_hint`: Approximate line number (1-based)
|
|
239
|
+
- `order_hint`: Which occurrence if symbol appears multiple times (0-based, default: 0)
|
|
240
|
+
|
|
241
|
+
### `find_references`
|
|
242
|
+
|
|
243
|
+
Find all references to a symbol.
|
|
244
|
+
|
|
245
|
+
**Inputs:** Same as `goto_definition`
|
|
246
|
+
|
|
247
|
+
### `call_hierarchy`
|
|
248
|
+
|
|
249
|
+
Get call hierarchy for a function or method.
|
|
250
|
+
|
|
251
|
+
**Inputs:**
|
|
252
|
+
- Same as `goto_definition`, plus:
|
|
253
|
+
- `direction`: `'incoming'` (callers) or `'outgoing'` (callees)
|
|
254
|
+
|
|
255
|
+
### `apply_edit`
|
|
256
|
+
|
|
257
|
+
Apply a text edit to a file (requires user approval).
|
|
258
|
+
|
|
259
|
+
**Inputs:**
|
|
260
|
+
- `uri`: File path or URI
|
|
261
|
+
- `search_text`: Exact text to replace (must be unique in file)
|
|
262
|
+
- `replace_text`: New text to insert
|
|
263
|
+
- `description`: Rationale for the edit
|
|
264
|
+
|
|
265
|
+
### `global_find`
|
|
266
|
+
|
|
267
|
+
Search for text across the entire workspace.
|
|
268
|
+
|
|
269
|
+
**Inputs:**
|
|
270
|
+
- `query`: The search query (required)
|
|
271
|
+
- `case_sensitive`: Whether the search is case-sensitive (optional, default: false)
|
|
272
|
+
- `exact_match`: Whether to match exact words only (optional, default: false)
|
|
273
|
+
- `regex_mode`: Whether the query is a regular expression (optional, default: false)
|
|
274
|
+
|
|
275
|
+
**Returns:**
|
|
276
|
+
- Array of matches with file URI, line, column, matching text, and context
|
|
277
|
+
- Total number of matches found
|
|
278
|
+
|
|
279
|
+
### `global_replace`
|
|
280
|
+
|
|
281
|
+
Replace all occurrences of text across the entire workspace.
|
|
282
|
+
|
|
283
|
+
**Inputs:**
|
|
284
|
+
- `query`: The search query (required)
|
|
285
|
+
- `replace_with`: The replacement text (required)
|
|
286
|
+
- `case_sensitive`: Whether the search is case-sensitive (optional, default: false)
|
|
287
|
+
- `exact_match`: Whether to match exact words only (optional, default: false)
|
|
288
|
+
- `regex_mode`: Whether the query is a regular expression (optional, default: false)
|
|
289
|
+
|
|
290
|
+
**Returns:**
|
|
291
|
+
- Number of replacements made
|
|
292
|
+
- Success status and message
|
|
293
|
+
|
|
294
|
+
## MCP Resources
|
|
295
|
+
|
|
296
|
+
The SDK automatically registers resources based on which capabilities you provide:
|
|
297
|
+
|
|
298
|
+
### `lsp://diagnostics/{path}`
|
|
299
|
+
|
|
300
|
+
Get diagnostics (errors, warnings) for a specific file.
|
|
301
|
+
|
|
302
|
+
**Resource URI Pattern:** `lsp://diagnostics/{path}`
|
|
303
|
+
|
|
304
|
+
**Example:** `lsp://diagnostics/src/main.ts`
|
|
305
|
+
|
|
306
|
+
Returns diagnostics formatted as markdown with location, severity, and message information.
|
|
307
|
+
|
|
308
|
+
**Subscription Support:** If your IDE implements `onDiagnosticsChanged` capability, these resources become subscribable. When diagnostics change, the driver sends resource update notifications.
|
|
309
|
+
|
|
310
|
+
### `lsp://diagnostics/workspace`
|
|
311
|
+
|
|
312
|
+
Get diagnostics across the entire workspace.
|
|
313
|
+
|
|
314
|
+
**Resource URI:** `lsp://diagnostics/workspace`
|
|
315
|
+
|
|
316
|
+
Only available if your `DiagnosticsProvider` implements the optional `getWorkspaceDiagnostics()` method.
|
|
317
|
+
|
|
318
|
+
Returns workspace diagnostics grouped by file, formatted as markdown.
|
|
319
|
+
|
|
320
|
+
**Subscription Support:** If your IDE implements `onDiagnosticsChanged` capability, this resource becomes subscribable.
|
|
321
|
+
|
|
322
|
+
### `lsp://outline/{path}`
|
|
323
|
+
|
|
324
|
+
Get the document outline (symbol tree) for a file.
|
|
325
|
+
|
|
326
|
+
**Resource URI Pattern:** `lsp://outline/{path}`
|
|
327
|
+
|
|
328
|
+
**Example:** `lsp://outline/src/components/Button.tsx`
|
|
329
|
+
|
|
330
|
+
Returns document symbols formatted as a hierarchical markdown outline, including:
|
|
331
|
+
- Symbol names and kinds (class, function, method, etc.)
|
|
332
|
+
- Source locations
|
|
333
|
+
- Nested children (e.g., methods within classes)
|
|
334
|
+
|
|
335
|
+
No subscription support for this resource (read-only).
|
|
336
|
+
|
|
337
|
+
### `lsp://files/{path}`
|
|
338
|
+
|
|
339
|
+
Get the file tree for a directory, excluding git-ignored files.
|
|
340
|
+
|
|
341
|
+
**Resource URI Pattern:** `lsp://files/{path}`
|
|
342
|
+
|
|
343
|
+
**Example:** `lsp://files/src`
|
|
344
|
+
|
|
345
|
+
Returns a list of file/folder paths in the directory tree, formatted as markdown. Git-ignored files and directories are automatically excluded from the results.
|
|
346
|
+
|
|
347
|
+
No subscription support for this resource (read-only).
|
|
348
|
+
|
|
349
|
+
## Subscription and Change Notifications
|
|
350
|
+
|
|
351
|
+
When your IDE supports the `onDiagnosticsChanged` capability, diagnostic resources become subscribable:
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
const capabilities: IdeCapabilities = {
|
|
355
|
+
fileAccess,
|
|
356
|
+
diagnostics: {
|
|
357
|
+
provideDiagnostics: async (uri) => { /* ... */ },
|
|
358
|
+
getWorkspaceDiagnostics: async () => { /* ... */ }
|
|
359
|
+
},
|
|
360
|
+
onDiagnosticsChanged: (callback) => {
|
|
361
|
+
// Register your IDE's diagnostic change listener
|
|
362
|
+
yourIDE.onDiagnosticsChanged((uri) => {
|
|
363
|
+
// Call the callback when diagnostics change
|
|
364
|
+
callback(uri)
|
|
365
|
+
})
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
When diagnostics change, call the registered callback with the affected file URI. The driver will send MCP resource update notifications to subscribers.
|
|
371
|
+
|
|
372
|
+
## Symbol Resolution
|
|
373
|
+
|
|
374
|
+
The SDK uses a robust algorithm to handle imprecise LLM positioning:
|
|
375
|
+
|
|
376
|
+
1. Target the `lineHint` (converting 1-based to 0-based)
|
|
377
|
+
2. Search for `symbolName` in that line
|
|
378
|
+
3. **Robustness Fallback**: If not found, scan +/- 2 lines (configurable)
|
|
379
|
+
4. Use `orderHint` to select the Nth occurrence if needed
|
|
380
|
+
|
|
381
|
+
Configure the search radius:
|
|
382
|
+
|
|
383
|
+
```typescript
|
|
384
|
+
installMcpLspDriver({ server, capabilities, config: {
|
|
385
|
+
resolverConfig: {
|
|
386
|
+
lineSearchRadius: 5 // Default: 2
|
|
387
|
+
}
|
|
388
|
+
}})
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
## Type Definitions
|
|
392
|
+
|
|
393
|
+
### Position Types
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// 0-based exact coordinates (internal)
|
|
397
|
+
interface ExactPosition {
|
|
398
|
+
line: number
|
|
399
|
+
character: number
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// Fuzzy position from LLM
|
|
403
|
+
interface FuzzyPosition {
|
|
404
|
+
symbolName: string
|
|
405
|
+
lineHint: number // 1-based
|
|
406
|
+
orderHint?: number // 0-based, default: 0
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Range on disk
|
|
410
|
+
interface DiskRange {
|
|
411
|
+
start: ExactPosition
|
|
412
|
+
end: ExactPosition
|
|
413
|
+
}
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Result Types
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
interface CodeSnippet {
|
|
420
|
+
uri: UnifiedUri
|
|
421
|
+
range: DiskRange
|
|
422
|
+
content: string
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
interface Diagnostic {
|
|
426
|
+
uri: UnifiedUri
|
|
427
|
+
range: DiskRange
|
|
428
|
+
severity: 'error' | 'warning' | 'information' | 'hint'
|
|
429
|
+
message: string
|
|
430
|
+
source?: string
|
|
431
|
+
code?: string | number
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
type EditResult =
|
|
435
|
+
| { success: true; message: string }
|
|
436
|
+
| { success: false; message: string; reason: 'UserRejected' | 'IOError' | 'ValidationFailed' }
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
## Development
|
|
440
|
+
|
|
441
|
+
```bash
|
|
442
|
+
# Install dependencies
|
|
443
|
+
pnpm install
|
|
444
|
+
|
|
445
|
+
# Build
|
|
446
|
+
pnpm build
|
|
447
|
+
|
|
448
|
+
# Run tests
|
|
449
|
+
pnpm test
|
|
450
|
+
|
|
451
|
+
# Run tests in watch mode
|
|
452
|
+
pnpm test:watch
|
|
453
|
+
|
|
454
|
+
# Lint
|
|
455
|
+
pnpm lint
|
|
456
|
+
|
|
457
|
+
# Format
|
|
458
|
+
pnpm format
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Requirements
|
|
462
|
+
|
|
463
|
+
- Node.js >= 18.0.0
|
|
464
|
+
- TypeScript >= 5.7.0
|
|
465
|
+
|
|
466
|
+
## License
|
|
467
|
+
|
|
468
|
+
MIT
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Providers for MCP LSP Driver SDK
|
|
3
|
+
*
|
|
4
|
+
* The Plugin Developer provides an implementation of IdeCapabilities.
|
|
5
|
+
* The SDK exposes tools based on which optional providers are defined.
|
|
6
|
+
*
|
|
7
|
+
* Note: All inputs here use ExactPosition. The SDK handles the
|
|
8
|
+
* Fuzzy -> Exact conversion before calling these.
|
|
9
|
+
*/
|
|
10
|
+
import type { FileAccessProvider, UserInteractionProvider } from './interfaces.js';
|
|
11
|
+
import type { CodeSnippet, Diagnostic, DocumentSymbol, ExactPosition, UnifiedUri } from './types.js';
|
|
12
|
+
/**
|
|
13
|
+
* Provides go-to-definition functionality.
|
|
14
|
+
*/
|
|
15
|
+
export interface DefinitionProvider {
|
|
16
|
+
/**
|
|
17
|
+
* Returns definition location reading strictly from disk context.
|
|
18
|
+
*
|
|
19
|
+
* @param uri - The URI of the file
|
|
20
|
+
* @param position - The exact position to find the definition for
|
|
21
|
+
* @returns Array of code snippets representing definition locations
|
|
22
|
+
*/
|
|
23
|
+
provideDefinition(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Provides find-references functionality.
|
|
27
|
+
*/
|
|
28
|
+
export interface ReferencesProvider {
|
|
29
|
+
/**
|
|
30
|
+
* Finds all references to the symbol at the given position.
|
|
31
|
+
*
|
|
32
|
+
* @param uri - The URI of the file
|
|
33
|
+
* @param position - The exact position to find references for
|
|
34
|
+
* @returns Array of code snippets representing reference locations
|
|
35
|
+
*/
|
|
36
|
+
provideReferences(uri: UnifiedUri, position: ExactPosition): Promise<CodeSnippet[]>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Provides call hierarchy functionality.
|
|
40
|
+
*/
|
|
41
|
+
export interface HierarchyProvider {
|
|
42
|
+
/**
|
|
43
|
+
* Provides call hierarchy information for the symbol at the given position.
|
|
44
|
+
*
|
|
45
|
+
* @param uri - The URI of the file
|
|
46
|
+
* @param position - The exact position to get call hierarchy for
|
|
47
|
+
* @param direction - Whether to get incoming or outgoing calls
|
|
48
|
+
* @returns Array of code snippets representing call hierarchy items
|
|
49
|
+
*/
|
|
50
|
+
provideCallHierarchy(uri: UnifiedUri, position: ExactPosition, direction: 'incoming' | 'outgoing'): Promise<CodeSnippet[]>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Provides diagnostics (errors, warnings) for a file.
|
|
54
|
+
*/
|
|
55
|
+
export interface DiagnosticsProvider {
|
|
56
|
+
/**
|
|
57
|
+
* Gets diagnostics for a file.
|
|
58
|
+
*
|
|
59
|
+
* @param uri - The URI of the file
|
|
60
|
+
* @returns Array of diagnostics for the file
|
|
61
|
+
*/
|
|
62
|
+
provideDiagnostics(uri: UnifiedUri): Promise<Diagnostic[]>;
|
|
63
|
+
/**
|
|
64
|
+
* Gets diagnostics for all files in the workspace.
|
|
65
|
+
* If not provided, the workspace diagnostics resource will not be available.
|
|
66
|
+
*
|
|
67
|
+
* @returns Array of diagnostics for all files in the workspace
|
|
68
|
+
*/
|
|
69
|
+
getWorkspaceDiagnostics?(): Promise<Diagnostic[]>;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Provides document outline (symbols) for a file.
|
|
73
|
+
*/
|
|
74
|
+
export interface OutlineProvider {
|
|
75
|
+
/**
|
|
76
|
+
* Gets the document symbols (outline) for a file.
|
|
77
|
+
*
|
|
78
|
+
* @param uri - The URI of the file
|
|
79
|
+
* @returns Array of document symbols representing the file's outline
|
|
80
|
+
*/
|
|
81
|
+
provideDocumentSymbols(uri: UnifiedUri): Promise<DocumentSymbol[]>;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Provides filesystem access with git-ignore support.
|
|
85
|
+
*/
|
|
86
|
+
export interface FilesystemProvider {
|
|
87
|
+
/**
|
|
88
|
+
* Gets the file tree for a directory, excluding git-ignored files.
|
|
89
|
+
*
|
|
90
|
+
* @param folderPath - The path to the folder to read
|
|
91
|
+
* @returns Array of file/folder paths in the directory tree
|
|
92
|
+
*/
|
|
93
|
+
getFileTree(folderPath: string): Promise<string[]>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Search options for global find operations.
|
|
97
|
+
*/
|
|
98
|
+
export interface GlobalFindOptions {
|
|
99
|
+
/** Whether the search is case-sensitive */
|
|
100
|
+
caseSensitive: boolean;
|
|
101
|
+
/** Whether to match exact words only */
|
|
102
|
+
exactMatch: boolean;
|
|
103
|
+
/** Whether the query is a regular expression */
|
|
104
|
+
regexMode: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* A match result from a global find operation.
|
|
108
|
+
*/
|
|
109
|
+
export interface GlobalFindMatch {
|
|
110
|
+
/** The URI of the file containing the match */
|
|
111
|
+
uri: UnifiedUri;
|
|
112
|
+
/** 1-based line number of the match */
|
|
113
|
+
line: number;
|
|
114
|
+
/** 1-based column of the match */
|
|
115
|
+
column: number;
|
|
116
|
+
/** The matching text */
|
|
117
|
+
matchText: string;
|
|
118
|
+
/** Context around the match (e.g., the full line) */
|
|
119
|
+
context: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Provides global find functionality across the workspace.
|
|
123
|
+
*/
|
|
124
|
+
export interface GlobalFindProvider {
|
|
125
|
+
/**
|
|
126
|
+
* Performs a global find operation across the workspace.
|
|
127
|
+
*
|
|
128
|
+
* @param query - The search query
|
|
129
|
+
* @param options - Search options (case sensitivity, exact match, regex mode)
|
|
130
|
+
* @returns Array of matches found
|
|
131
|
+
*/
|
|
132
|
+
globalFind(query: string, options: GlobalFindOptions): Promise<GlobalFindMatch[]>;
|
|
133
|
+
/**
|
|
134
|
+
* Performs a global replace operation across the workspace.
|
|
135
|
+
* The query and options are decoded from the ID generated by globalFind.
|
|
136
|
+
*
|
|
137
|
+
* @param query - The search query (decoded from the ID)
|
|
138
|
+
* @param replaceWith - The replacement text
|
|
139
|
+
* @param options - Search options (decoded from the ID)
|
|
140
|
+
* @returns The number of replacements made
|
|
141
|
+
*/
|
|
142
|
+
globalReplace(query: string, replaceWith: string, options: GlobalFindOptions): Promise<number>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Callback that gets invoked when diagnostics change.
|
|
146
|
+
* Used for MCP resource subscription support.
|
|
147
|
+
*/
|
|
148
|
+
export type OnDiagnosticsChangedCallback = (uri: UnifiedUri) => void;
|
|
149
|
+
/**
|
|
150
|
+
* The complete set of capabilities that an IDE plugin can provide.
|
|
151
|
+
* The SDK will automatically register tools based on which providers are defined.
|
|
152
|
+
*/
|
|
153
|
+
export interface IdeCapabilities {
|
|
154
|
+
/** Mandatory: Provides file system access for reading files from disk */
|
|
155
|
+
fileAccess: FileAccessProvider;
|
|
156
|
+
/** Optional: Provides user interaction for edit operations */
|
|
157
|
+
userInteraction?: UserInteractionProvider;
|
|
158
|
+
/** Optional: Provides go-to-definition functionality */
|
|
159
|
+
definition?: DefinitionProvider;
|
|
160
|
+
/** Optional: Provides find-references functionality */
|
|
161
|
+
references?: ReferencesProvider;
|
|
162
|
+
/** Optional: Provides call hierarchy functionality */
|
|
163
|
+
hierarchy?: HierarchyProvider;
|
|
164
|
+
/** Optional: Provides diagnostics for files */
|
|
165
|
+
diagnostics?: DiagnosticsProvider;
|
|
166
|
+
/** Optional: Provides document outline (symbols) for files */
|
|
167
|
+
outline?: OutlineProvider;
|
|
168
|
+
/** Optional: Provides filesystem access with git-ignore support */
|
|
169
|
+
filesystem?: FilesystemProvider;
|
|
170
|
+
/** Optional: Provides global find and replace functionality */
|
|
171
|
+
globalFind?: GlobalFindProvider;
|
|
172
|
+
/**
|
|
173
|
+
* Optional: Called by the driver to register a callback for diagnostics changes.
|
|
174
|
+
* When this is provided, the diagnostics resources become subscribable.
|
|
175
|
+
* The plugin should call the registered callback whenever diagnostics change for a URI.
|
|
176
|
+
*
|
|
177
|
+
* @param callback - The callback to invoke when diagnostics change
|
|
178
|
+
*/
|
|
179
|
+
onDiagnosticsChanged?: (callback: OnDiagnosticsChangedCallback) => void;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capability Providers for MCP LSP Driver SDK
|
|
3
|
+
*
|
|
4
|
+
* The Plugin Developer provides an implementation of IdeCapabilities.
|
|
5
|
+
* The SDK exposes tools based on which optional providers are defined.
|
|
6
|
+
*
|
|
7
|
+
* Note: All inputs here use ExactPosition. The SDK handles the
|
|
8
|
+
* Fuzzy -> Exact conversion before calling these.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=capabilities.js.map
|