mcp-lsp-driver 0.1.0 → 0.2.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
@@ -37,7 +37,9 @@ const fileAccess = {
37
37
  return await fs.readFile(uri, 'utf-8')
38
38
  },
39
39
 
40
- getFileTree: (uri: string) => yourIDE.workspace.files
40
+ getFileTree: (uri: string) => yourIDE.workspace.getFileTree(uri),
41
+
42
+ readDirectory: (uri: string) => yourIDE.workspace.readDirectory(uri)
41
43
  }
42
44
 
43
45
  // 3. Implement User Interaction (required for edits)
@@ -109,6 +111,7 @@ Provides disk access for reading files:
109
111
  interface FileAccessProvider {
110
112
  readFile(uri: UnifiedUri): Promise<string>
111
113
  getFileTree(folderPath: UnifiedUri): Promise<string[]>
114
+ readDirectory(folderPath: UnifiedUri): Promise<string[]>
112
115
  }
113
116
  ```
114
117
 
@@ -320,9 +323,21 @@ Returns document symbols formatted as a hierarchical markdown outline, including
320
323
 
321
324
  No subscription support for this resource (read-only).
322
325
 
326
+ ### `lsp://filetree/{path}`
327
+
328
+ Get the complete file tree for a directory, excluding git-ignored files.
329
+
330
+ **Resource URI Pattern:** `lsp://filetree/{+path}`
331
+
332
+ **Example:** `lsp://filetree/src`, `lsp://filetree/.`
333
+
334
+ Returns a JSON array of all file paths in the directory tree (recursive). Use "." for the root directory.
335
+
336
+ No subscription support for this resource (read-only).
337
+
323
338
  ### `lsp://files/{path}`
324
339
 
325
- For directories: gets the file tree for a directory, excluding git-ignored files. For files: gets file content with optional line range.
340
+ For directories: returns directory children (git-ignored files excluded, similar to `ls`). For files: gets file content with optional line range.
326
341
 
327
342
  **Resource URI Pattern:** `lsp://files/{+path}`
328
343
 
@@ -10,6 +10,9 @@ export const makeToolResult = (result) => ({
10
10
  * Normalizes a URI to handle Windows/Unix path separator differences.
11
11
  */
12
12
  export function normalizeUri(uri) {
13
+ if (uri.includes('..')) {
14
+ throw new Error('URI could not include ".." operator');
15
+ }
13
16
  // If it's already a file:// URI, leave it alone
14
17
  if (uri.startsWith('file://')) {
15
18
  return uri;
@@ -20,13 +20,19 @@ export interface FileAccessProvider {
20
20
  * @throws Error if the file cannot be read
21
21
  */
22
22
  readFile(uri: UnifiedUri): Promise<string>;
23
+ /**
24
+ * Read children in a directory, exluding git-ignored files, similar to Unix `ls` command
25
+ * @param relativePath - The path to the folder to read
26
+ * @returns Array of file/folder paths in the directory
27
+ */
28
+ readDirectory(relativePath: UnifiedUri): Promise<string[]>;
23
29
  /**
24
30
  * Gets the file tree for a directory, excluding git-ignored files.
25
31
  *
26
- * @param folderPath - The path to the folder to read
32
+ * @param relativePath - The path to the folder to read
27
33
  * @returns Array of file/folder paths in the directory tree
28
34
  */
29
- getFileTree(folderPath: UnifiedUri): Promise<string[]>;
35
+ getFileTree?: (relativePath: UnifiedUri) => Promise<string[]>;
30
36
  }
31
37
  /**
32
38
  * Provides user interaction capabilities for edit operations.
package/dist/server.js CHANGED
@@ -465,12 +465,28 @@ function registerApplyEditTool(server, capabilities, resolver) {
465
465
  * - lsp://files/path/to/file.ext#L21-L28 - read line range
466
466
  */
467
467
  function registerFilesystemResource(server, capabilities) {
468
- const fileAccessProvider = capabilities.fileAccess;
468
+ const { readFile, readDirectory, getFileTree } = capabilities.fileAccess;
469
+ if (getFileTree !== undefined) {
470
+ const fileTreeTemplate = new ResourceTemplate('lsp://filetree/{+path}', {
471
+ list: undefined,
472
+ });
473
+ server.registerResource('fileTree', fileTreeTemplate, {
474
+ description: 'Access file tree inside a relative path or use "." for root.',
475
+ }, async (uri, { path }) => ({
476
+ contents: [
477
+ {
478
+ uri: uri.toString(),
479
+ mimeType: 'application/json',
480
+ text: JSON.stringify((await getFileTree(normalizeUri(path))) ?? ''),
481
+ },
482
+ ],
483
+ }));
484
+ }
469
485
  const filesystemTemplate = new ResourceTemplate('lsp://files/{+path}', {
470
486
  list: undefined, // Cannot enumerate all directories
471
487
  });
472
488
  server.registerResource('filesystem', filesystemTemplate, {
473
- description: 'Access filesystem resources. For directories: returns file tree (git-ignored files excluded). ' +
489
+ description: 'Access filesystem resources. For directories: returns children (git-ignored files excluded). ' +
474
490
  'For files: returns file content. Supports line ranges with #L23 or #L23-L30 fragment.',
475
491
  }, async (uri, variables) => {
476
492
  const uriString = uri.toString();
@@ -488,7 +504,7 @@ function registerFilesystemResource(server, capabilities) {
488
504
  const lineRange = parseLineRange(fragment);
489
505
  // Try reading as a file first
490
506
  try {
491
- const content = await fileAccessProvider.readFile(normalizedPath);
507
+ const content = await readFile(normalizedPath);
492
508
  // If we have a line range, extract those lines
493
509
  const resultContent = lineRange
494
510
  ? extractLines(content, lineRange)
@@ -505,7 +521,7 @@ function registerFilesystemResource(server, capabilities) {
505
521
  }
506
522
  catch {
507
523
  // File reading failed, try as directory
508
- const files = await fileAccessProvider.getFileTree(normalizedPath);
524
+ const files = await readDirectory(normalizedPath);
509
525
  return {
510
526
  contents: [
511
527
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-lsp-driver",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "MCP LSP Driver for IDE plugins to easily expose LSP features via an MCP server.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",