@j0hanz/filesystem-mcp 1.8.0 → 1.9.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 (83) hide show
  1. package/README.md +635 -377
  2. package/dist/cli.js +2 -2
  3. package/dist/completions.js +2 -3
  4. package/dist/index.js +2 -2
  5. package/dist/lib/file-operations/{common.d.ts → core.d.ts} +6 -0
  6. package/dist/lib/file-operations/{common.js → core.js} +45 -0
  7. package/dist/lib/file-operations/metadata.d.ts +73 -0
  8. package/dist/lib/file-operations/metadata.js +889 -0
  9. package/dist/lib/file-operations/{search-content.d.ts → search.d.ts} +35 -2
  10. package/dist/lib/file-operations/{search-content.js → search.js} +413 -15
  11. package/dist/lib/file-operations/{glob-engine.d.ts → traversal.d.ts} +18 -1
  12. package/dist/lib/file-operations/{glob-engine.js → traversal.js} +25 -2
  13. package/dist/lib/fs-helpers.js +1 -2
  14. package/dist/lib/observability.js +1 -1
  15. package/dist/lib/{path-validation.d.ts → paths.d.ts} +3 -0
  16. package/dist/lib/{path-validation.js → paths.js} +105 -1
  17. package/dist/lib/utils.d.ts +15 -0
  18. package/dist/lib/utils.js +33 -0
  19. package/dist/resources/generated-instructions.js +6 -6
  20. package/dist/resources/tool-catalog.js +9 -9
  21. package/dist/resources/tool-info.js +3 -3
  22. package/dist/resources/workflows.js +10 -23
  23. package/dist/schemas.js +15 -15
  24. package/dist/server/bootstrap.d.ts +19 -1
  25. package/dist/server/bootstrap.js +103 -9
  26. package/dist/server/roots-manager.d.ts +2 -2
  27. package/dist/server/roots-manager.js +3 -3
  28. package/dist/tools/apply-patch.js +4 -3
  29. package/dist/tools/calculate-hash.js +4 -4
  30. package/dist/tools/create-directory.js +1 -1
  31. package/dist/tools/delete-file.js +3 -3
  32. package/dist/tools/diff-files.js +2 -2
  33. package/dist/tools/edit-file.js +14 -13
  34. package/dist/tools/list-directory.js +5 -7
  35. package/dist/tools/move-file.js +2 -1
  36. package/dist/tools/read-multiple.js +3 -4
  37. package/dist/tools/read.js +3 -3
  38. package/dist/tools/replace-in-files.js +8 -10
  39. package/dist/tools/roots.js +4 -6
  40. package/dist/tools/search-content.js +7 -9
  41. package/dist/tools/search-files.js +4 -6
  42. package/dist/tools/shared.d.ts +2 -1
  43. package/dist/tools/shared.js +2 -1
  44. package/dist/tools/stat-many.js +4 -3
  45. package/dist/tools/stat.js +4 -3
  46. package/dist/tools/task-support.js +1 -1
  47. package/dist/tools/tree.js +3 -4
  48. package/dist/tools/write-file.js +1 -1
  49. package/package.json +4 -4
  50. package/dist/lib/file-operations/file-info.d.ts +0 -10
  51. package/dist/lib/file-operations/file-info.js +0 -143
  52. package/dist/lib/file-operations/gitignore.d.ts +0 -6
  53. package/dist/lib/file-operations/gitignore.js +0 -45
  54. package/dist/lib/file-operations/glob-helpers.d.ts +0 -18
  55. package/dist/lib/file-operations/glob-helpers.js +0 -23
  56. package/dist/lib/file-operations/list-directory.d.ts +0 -14
  57. package/dist/lib/file-operations/list-directory.js +0 -252
  58. package/dist/lib/file-operations/read-multiple-files.d.ts +0 -25
  59. package/dist/lib/file-operations/read-multiple-files.js +0 -252
  60. package/dist/lib/file-operations/search-files.d.ts +0 -27
  61. package/dist/lib/file-operations/search-files.js +0 -216
  62. package/dist/lib/file-operations/search-matcher.d.ts +0 -10
  63. package/dist/lib/file-operations/search-matcher.js +0 -72
  64. package/dist/lib/file-operations/search-worker.d.ts +0 -2
  65. package/dist/lib/file-operations/search-worker.js +0 -131
  66. package/dist/lib/file-operations/tree.d.ts +0 -28
  67. package/dist/lib/file-operations/tree.js +0 -265
  68. package/dist/lib/option-utils.d.ts +0 -3
  69. package/dist/lib/option-utils.js +0 -15
  70. package/dist/lib/path-format.d.ts +0 -1
  71. package/dist/lib/path-format.js +0 -7
  72. package/dist/lib/path-policy.d.ts +0 -2
  73. package/dist/lib/path-policy.js +0 -100
  74. package/dist/lib/progress-reporting.d.ts +0 -11
  75. package/dist/lib/progress-reporting.js +0 -13
  76. package/dist/lib/type-guards.d.ts +0 -1
  77. package/dist/lib/type-guards.js +0 -3
  78. package/dist/server/capabilities.d.ts +0 -10
  79. package/dist/server/capabilities.js +0 -48
  80. package/dist/server/logging.d.ts +0 -7
  81. package/dist/server/logging.js +0 -41
  82. package/dist/server/types.d.ts +0 -4
  83. package/dist/server/types.js +0 -1
package/dist/cli.js CHANGED
@@ -2,8 +2,8 @@ import * as fs from 'node:fs/promises';
2
2
  import { getSystemErrorMessage, getSystemErrorName } from 'node:util';
3
3
  import { Command, CommanderError, InvalidArgumentError } from 'commander';
4
4
  import { processInParallel } from './lib/fs-helpers.js';
5
- import { getReservedDeviceNameForPath, isWindowsDriveRelativePath, normalizePath, } from './lib/path-validation.js';
6
- import { isRecord } from './lib/type-guards.js';
5
+ import { getReservedDeviceNameForPath, isWindowsDriveRelativePath, normalizePath, } from './lib/paths.js';
6
+ import { isRecord } from './lib/utils.js';
7
7
  import { pkgInfo } from './pkg-info.js';
8
8
  const { version: SERVER_VERSION } = pkgInfo;
9
9
  const IS_WINDOWS = process.platform === 'win32';
@@ -1,9 +1,8 @@
1
1
  import * as fs from 'node:fs/promises';
2
2
  import * as path from 'node:path';
3
3
  import { CompleteRequestSchema } from '@modelcontextprotocol/sdk/types.js';
4
- import { toPosixPath } from './lib/path-format.js';
5
- import { getAllowedDirectories, isPathWithinDirectories, normalizePath, } from './lib/path-validation.js';
6
- import { isRecord } from './lib/type-guards.js';
4
+ import { getAllowedDirectories, isPathWithinDirectories, normalizePath, toPosixPath, } from './lib/paths.js';
5
+ import { isRecord } from './lib/utils.js';
7
6
  const MAX_COMPLETION_ITEMS = 100;
8
7
  const COMPLETION_RATE_LIMIT_MS = 100;
9
8
  // WeakMap keyed by McpServer instance so that each HTTP session gets isolated
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import process from 'node:process';
3
- import { CliExitError, parseArgs } from './cli.js';
4
3
  import { DEFAULT_SEARCH_TIMEOUT_MS } from './lib/constants.js';
5
4
  import { formatUnknownErrorMessage } from './lib/errors.js';
6
5
  import { createTimedAbortSignal } from './lib/fs-helpers.js';
7
- import { setAllowedDirectoriesResolved } from './lib/path-validation.js';
6
+ import { setAllowedDirectoriesResolved } from './lib/paths.js';
7
+ import { CliExitError, parseArgs } from './cli.js';
8
8
  import { createServer, startHttpServer, startServer } from './server.js';
9
9
  const SHUTDOWN_TIMEOUT_MS = 5000;
10
10
  let activeServer;
@@ -1,3 +1,4 @@
1
+ import { type Ignore } from 'ignore';
1
2
  export declare function needsStatsForSort(sortBy: string): boolean;
2
3
  export declare function withOptionalStoppedReason<T extends object, R extends string>(summary: T, stoppedReason: R | undefined): T | (T & {
3
4
  stoppedReason: R;
@@ -44,3 +45,8 @@ export interface EntryAccessDependencies {
44
45
  }>;
45
46
  }
46
47
  export declare function isEntryAccessibleByType(entryPath: string, entryType: EntryType, rootDirectories: readonly string[], signal: AbortSignal, deps: EntryAccessDependencies): Promise<boolean>;
48
+ export declare function loadRootGitignore(root: string, signal?: AbortSignal): Promise<Ignore | null>;
49
+ export declare function isIgnoredByGitignore(matcher: Ignore, root: string, absolutePath: string, options?: {
50
+ isDirectory?: boolean;
51
+ relativePath?: string;
52
+ }): boolean;
@@ -1,3 +1,8 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import ignore, {} from 'ignore';
4
+ import { isNodeError } from '../errors.js';
5
+ import { toPosixPath } from '../paths.js';
1
6
  export function needsStatsForSort(sortBy) {
2
7
  return sortBy === 'size' || sortBy === 'modified';
3
8
  }
@@ -94,3 +99,43 @@ export async function isEntryAccessibleByType(entryPath, entryType, rootDirector
94
99
  return false;
95
100
  }
96
101
  }
102
+ function parseGitignoreLines(contents) {
103
+ const lines = [];
104
+ for (const line of contents.split(/\r?\n/u)) {
105
+ const trimmed = line.trim();
106
+ if (trimmed.length > 0) {
107
+ lines.push(trimmed);
108
+ }
109
+ }
110
+ return lines;
111
+ }
112
+ export async function loadRootGitignore(root, signal) {
113
+ const gitignorePath = path.join(root, '.gitignore');
114
+ let contents;
115
+ try {
116
+ contents = await fs.readFile(gitignorePath, {
117
+ encoding: 'utf-8',
118
+ signal,
119
+ });
120
+ }
121
+ catch (error) {
122
+ if (isNodeError(error) && error.code === 'ENOENT') {
123
+ return null;
124
+ }
125
+ throw error;
126
+ }
127
+ const matcher = ignore();
128
+ matcher.add(parseGitignoreLines(contents));
129
+ return matcher;
130
+ }
131
+ export function isIgnoredByGitignore(matcher, root, absolutePath, options = {}) {
132
+ let relative = options.relativePath;
133
+ relative ??= path.relative(root, absolutePath);
134
+ if (relative.length === 0)
135
+ return false;
136
+ const normalized = toPosixPath(relative);
137
+ if (options.isDirectory) {
138
+ return matcher.ignores(normalized.endsWith('/') ? normalized : `${normalized}/`);
139
+ }
140
+ return matcher.ignores(normalized);
141
+ }
@@ -0,0 +1,73 @@
1
+ import type { FileInfo, GetMultipleFileInfoResult, ListDirectoryResult } from '../../config.js';
2
+ import type { EntryType } from './core.js';
3
+ interface FileInfoOptions {
4
+ includeMimeType?: boolean | undefined;
5
+ signal?: AbortSignal | undefined;
6
+ onProgress?: () => void;
7
+ }
8
+ export declare function getFileInfo(filePath: string, options?: FileInfoOptions): Promise<FileInfo>;
9
+ type GetMultipleFileInfoOptions = FileInfoOptions;
10
+ export declare function getMultipleFileInfo(paths: readonly string[], options?: GetMultipleFileInfoOptions): Promise<GetMultipleFileInfoResult>;
11
+ interface ListDirectoryOptions {
12
+ includeHidden?: boolean;
13
+ excludePatterns?: readonly string[];
14
+ maxDepth?: number;
15
+ maxEntries?: number;
16
+ sortBy?: 'name' | 'size' | 'modified' | 'type';
17
+ includeSymlinkTargets?: boolean;
18
+ pattern?: string;
19
+ timeoutMs?: number;
20
+ signal?: AbortSignal;
21
+ }
22
+ export declare function listDirectory(dirPath: string, options?: ListDirectoryOptions): Promise<ListDirectoryResult>;
23
+ interface TreeEntry {
24
+ name: string;
25
+ type: EntryType;
26
+ relativePath: string;
27
+ children?: TreeEntry[];
28
+ }
29
+ interface TreeOptions {
30
+ maxDepth?: number;
31
+ maxEntries?: number;
32
+ includeHidden?: boolean;
33
+ includeIgnored?: boolean;
34
+ timeoutMs?: number;
35
+ signal?: AbortSignal;
36
+ onProgress?: (progress: {
37
+ total?: number;
38
+ current: number;
39
+ }) => void;
40
+ }
41
+ interface TreeResult {
42
+ root: string;
43
+ tree: TreeEntry;
44
+ truncated: boolean;
45
+ totalEntries: number;
46
+ }
47
+ export declare function formatTreeAscii(tree: TreeEntry): string;
48
+ export declare function treeDirectory(dirPath: string, options?: TreeOptions): Promise<TreeResult>;
49
+ interface ReadMultipleResult {
50
+ path: string;
51
+ content?: string;
52
+ truncated?: boolean;
53
+ totalLines?: number;
54
+ readMode?: 'full' | 'head' | 'range';
55
+ head?: number;
56
+ startLine?: number;
57
+ endLine?: number;
58
+ linesRead?: number;
59
+ hasMoreLines?: boolean;
60
+ error?: string;
61
+ }
62
+ interface ReadMultipleOptions {
63
+ encoding?: BufferEncoding;
64
+ maxSize?: number;
65
+ maxTotalSize?: number;
66
+ head?: number;
67
+ startLine?: number;
68
+ endLine?: number;
69
+ signal?: AbortSignal;
70
+ onReadComplete?: () => void;
71
+ }
72
+ export declare function readMultipleFiles(filePaths: readonly string[], options?: ReadMultipleOptions): Promise<ReadMultipleResult[]>;
73
+ export {};