@j0hanz/filesystem-mcp 1.13.1 → 1.14.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 +117 -100
- package/dist/completions.d.ts +0 -11
- package/dist/completions.js +1 -1
- package/dist/config.d.ts +0 -1
- package/dist/lib/constants.d.ts +0 -1
- package/dist/lib/constants.js +0 -1
- package/dist/lib/errors.d.ts +0 -1
- package/dist/lib/errors.js +5 -9
- package/dist/lib/file-operations/core.d.ts +3 -2
- package/dist/lib/file-operations/metadata.js +9 -3
- package/dist/lib/file-operations/search.d.ts +1 -59
- package/dist/lib/file-operations/search.js +9 -22
- package/dist/lib/file-operations/traversal.d.ts +2 -2
- package/dist/lib/fs-helpers.d.ts +1 -2
- package/dist/lib/fs-helpers.js +10 -12
- package/dist/lib/globs.d.ts +2 -0
- package/dist/lib/globs.js +19 -0
- package/dist/lib/paths.d.ts +0 -3
- package/dist/lib/paths.js +1 -4
- package/dist/lib/utils.d.ts +4 -4
- package/dist/lib/utils.js +1 -10
- package/dist/lib/zod-codecs.d.ts +2 -0
- package/dist/lib/zod-codecs.js +18 -0
- package/dist/pkg-info.d.ts +1 -0
- package/dist/pkg-info.js +2 -2
- package/dist/prompts.js +3 -3
- package/dist/resources/generated-instructions.js +3 -12
- package/dist/resources/tool-catalog.js +10 -41
- package/dist/resources/tool-info.d.ts +0 -1
- package/dist/resources/tool-info.js +24 -39
- package/dist/resources/workflows.js +8 -1
- package/dist/schemas.d.ts +179 -481
- package/dist/schemas.js +156 -169
- package/dist/server/bootstrap.d.ts +0 -10
- package/dist/server/bootstrap.js +3 -3
- package/dist/server/roots-manager.js +1 -1
- package/dist/tools/apply-patch.js +19 -8
- package/dist/tools/calculate-hash.js +3 -5
- package/dist/tools/create-directory.d.ts +1 -4
- package/dist/tools/create-directory.js +2 -2
- package/dist/tools/delete-file.js +2 -4
- package/dist/tools/diff-files.js +1 -3
- package/dist/tools/edit-file.d.ts +1 -7
- package/dist/tools/edit-file.js +6 -3
- package/dist/tools/list-directory.js +10 -15
- package/dist/tools/move-file.d.ts +1 -4
- package/dist/tools/move-file.js +15 -27
- package/dist/tools/read-multiple.js +12 -7
- package/dist/tools/read.js +1 -2
- package/dist/tools/replace-in-files.d.ts +1 -10
- package/dist/tools/replace-in-files.js +62 -97
- package/dist/tools/roots.js +2 -6
- package/dist/tools/search-content.js +152 -188
- package/dist/tools/search-files.js +10 -13
- package/dist/tools/shared.d.ts +10 -3
- package/dist/tools/shared.js +53 -12
- package/dist/tools/stat-many.js +6 -4
- package/dist/tools/stat.js +2 -2
- package/dist/tools/task-support.d.ts +0 -7
- package/dist/tools/task-support.js +7 -6
- package/dist/tools/tree.js +1 -1
- package/dist/tools/write-file.js +1 -5
- package/dist/tools.d.ts +0 -1
- package/dist/tools.js +0 -1
- package/package.json +5 -5
package/dist/tools/shared.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createDetailedError, ErrorCode, formatDetailedError, getSuggestion, Mcp
|
|
|
6
6
|
import { createTimedAbortSignal } from '../lib/fs-helpers.js';
|
|
7
7
|
import { withToolDiagnostics } from '../lib/observability.js';
|
|
8
8
|
import { getAllowedDirectories } from '../lib/paths.js';
|
|
9
|
+
import { createBase64JsonCodec } from '../lib/zod-codecs.js';
|
|
9
10
|
export {} from './contract.js';
|
|
10
11
|
const MAX_INLINE_CONTENT_CHARS = parseInt(process.env['FS_CONTEXT_MAX_INLINE_CHARS'] ?? '', 10) || 20_000;
|
|
11
12
|
const MAX_INLINE_PREVIEW_CHARS = 4_000;
|
|
@@ -64,7 +65,7 @@ function normalizeToolExecution(tool) {
|
|
|
64
65
|
}
|
|
65
66
|
return normalized;
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
+
function shouldStripStructuredOutput() {
|
|
68
69
|
return parseTrueEnvFlag(process.env['FS_CONTEXT_STRIP_STRUCTURED']);
|
|
69
70
|
}
|
|
70
71
|
export function maybeStripStructuredContentFromResult(result) {
|
|
@@ -133,19 +134,48 @@ function resolveDetailedError(error, defaultCode, path) {
|
|
|
133
134
|
}
|
|
134
135
|
return detailed;
|
|
135
136
|
}
|
|
137
|
+
export function buildStructuredError(error, defaultCode, path) {
|
|
138
|
+
const detailed = resolveDetailedError(error, defaultCode, path);
|
|
139
|
+
return {
|
|
140
|
+
code: detailed.code,
|
|
141
|
+
message: detailed.message,
|
|
142
|
+
...(detailed.path !== undefined ? { path: detailed.path } : {}),
|
|
143
|
+
...(detailed.suggestion !== undefined
|
|
144
|
+
? { suggestion: detailed.suggestion }
|
|
145
|
+
: {}),
|
|
146
|
+
};
|
|
147
|
+
}
|
|
136
148
|
export function buildToolResponse(text, structuredContent, extraContent = []) {
|
|
137
149
|
return {
|
|
138
150
|
content: [{ type: 'text', text }, ...extraContent],
|
|
139
151
|
structuredContent,
|
|
140
152
|
};
|
|
141
153
|
}
|
|
154
|
+
function validateStructuredContent(toolName, outputSchema, structuredContent) {
|
|
155
|
+
const parsed = outputSchema.safeParse(structuredContent);
|
|
156
|
+
if (parsed.success) {
|
|
157
|
+
return parsed.data;
|
|
158
|
+
}
|
|
159
|
+
throw new McpError(ErrorCode.E_UNKNOWN, `Tool "${toolName}" returned invalid structuredContent.`, undefined, { errors: z.treeifyError(parsed.error) });
|
|
160
|
+
}
|
|
161
|
+
function validateToolResponse(toolName, result, outputSchema) {
|
|
162
|
+
if (!outputSchema)
|
|
163
|
+
return result;
|
|
164
|
+
if (!Object.hasOwn(result, 'structuredContent')) {
|
|
165
|
+
throw new McpError(ErrorCode.E_UNKNOWN, `Tool "${toolName}" returned success without structuredContent.`);
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
...result,
|
|
169
|
+
structuredContent: validateStructuredContent(toolName, outputSchema, result.structuredContent),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
142
172
|
function parseToolArgs(schema, args) {
|
|
143
173
|
const candidate = args === undefined ? {} : args;
|
|
144
174
|
const parsed = schema.safeParse(candidate);
|
|
145
175
|
if (parsed.success) {
|
|
146
176
|
return parsed.data;
|
|
147
177
|
}
|
|
148
|
-
throw new McpError(ErrorCode.E_INVALID_INPUT, `Invalid tool arguments
|
|
178
|
+
throw new McpError(ErrorCode.E_INVALID_INPUT, `Invalid tool arguments:\n${z.prettifyError(parsed.error)}`, undefined, { errors: z.treeifyError(parsed.error) });
|
|
149
179
|
}
|
|
150
180
|
export function withValidatedArgs(schema, handler) {
|
|
151
181
|
return async (args, extra) => {
|
|
@@ -222,7 +252,7 @@ export async function executeToolWithDiagnostics(options) {
|
|
|
222
252
|
return withToolDiagnostics(options.toolName, () => withToolErrorHandling(async () => {
|
|
223
253
|
const { signal, cleanup } = getToolSignal(options.extra.signal, options.timedSignal);
|
|
224
254
|
try {
|
|
225
|
-
return await options.run(signal);
|
|
255
|
+
return validateToolResponse(options.toolName, await options.run(signal), options.outputSchema);
|
|
226
256
|
}
|
|
227
257
|
finally {
|
|
228
258
|
cleanup();
|
|
@@ -461,19 +491,16 @@ export function resolvePathOrRoot(pathValue) {
|
|
|
461
491
|
}
|
|
462
492
|
return root;
|
|
463
493
|
}
|
|
494
|
+
const OffsetCursorSchema = z.strictObject({
|
|
495
|
+
offset: z.int().min(0),
|
|
496
|
+
});
|
|
497
|
+
const OffsetCursorCodec = createBase64JsonCodec(OffsetCursorSchema);
|
|
464
498
|
export function encodeOffsetCursor(offset) {
|
|
465
|
-
return
|
|
499
|
+
return z.encode(OffsetCursorCodec, { offset });
|
|
466
500
|
}
|
|
467
501
|
export function decodeOffsetCursor(cursor) {
|
|
468
502
|
try {
|
|
469
|
-
|
|
470
|
-
if (typeof parsed === 'object' &&
|
|
471
|
-
parsed !== null &&
|
|
472
|
-
typeof parsed.offset === 'number') {
|
|
473
|
-
const { offset } = parsed;
|
|
474
|
-
if (Number.isInteger(offset) && offset >= 0)
|
|
475
|
-
return offset;
|
|
476
|
-
}
|
|
503
|
+
return OffsetCursorCodec.parse(cursor).offset;
|
|
477
504
|
}
|
|
478
505
|
catch {
|
|
479
506
|
// fall through to throw
|
|
@@ -488,6 +515,20 @@ export function buildBatchPathContext(paths, unitLabel = 'paths') {
|
|
|
488
515
|
: '';
|
|
489
516
|
return `${paths.length} ${normalizedLabel} [${first}${extraPaths}]`;
|
|
490
517
|
}
|
|
518
|
+
export function truncateProgressPattern(pattern, maxLength = 40) {
|
|
519
|
+
if (pattern.length <= maxLength)
|
|
520
|
+
return pattern;
|
|
521
|
+
if (pattern.includes('|')) {
|
|
522
|
+
const segments = pattern.split('|');
|
|
523
|
+
const first = segments[0] ?? '';
|
|
524
|
+
const second = segments[1];
|
|
525
|
+
const preview = second !== undefined ? `${first}|${second}` : first;
|
|
526
|
+
return preview.length <= maxLength
|
|
527
|
+
? `${preview}…`
|
|
528
|
+
: `${preview.slice(0, maxLength)}…`;
|
|
529
|
+
}
|
|
530
|
+
return `${pattern.slice(0, maxLength)}…`;
|
|
531
|
+
}
|
|
491
532
|
export function buildBatchCompletionSuffix(summary, successWord, singularWord) {
|
|
492
533
|
const total = summary?.total ?? 0;
|
|
493
534
|
const failed = summary?.failed ?? 0;
|
package/dist/tools/stat-many.js
CHANGED
|
@@ -3,7 +3,7 @@ import { ErrorCode } from '../lib/errors.js';
|
|
|
3
3
|
import { getMultipleFileInfo } from '../lib/file-operations/metadata.js';
|
|
4
4
|
import { formatBytes, joinLines } from '../config.js';
|
|
5
5
|
import { GetMultipleFileInfoInputSchema, GetMultipleFileInfoOutputSchema, } from '../schemas.js';
|
|
6
|
-
import { buildBatchCompletionSuffix, buildBatchPathContext, buildFileInfoPayload, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, withDefaultIcons, withValidatedArgs, wrapToolHandler, } from './shared.js';
|
|
6
|
+
import { buildBatchCompletionSuffix, buildBatchPathContext, buildFileInfoPayload, buildStructuredError, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, withDefaultIcons, withValidatedArgs, wrapToolHandler, } from './shared.js';
|
|
7
7
|
import { registerToolTaskIfAvailable } from './task-support.js';
|
|
8
8
|
export const GET_MULTIPLE_FILE_INFO_TOOL = {
|
|
9
9
|
name: 'stat_many',
|
|
@@ -14,7 +14,6 @@ export const GET_MULTIPLE_FILE_INFO_TOOL = {
|
|
|
14
14
|
outputSchema: GetMultipleFileInfoOutputSchema,
|
|
15
15
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
16
16
|
taskSupport: 'optional',
|
|
17
|
-
nuances: ['Use before read/search when file size/type uncertainty exists.'],
|
|
18
17
|
};
|
|
19
18
|
function formatFileInfoDetail(info) {
|
|
20
19
|
const lines = [
|
|
@@ -38,11 +37,13 @@ async function handleGetMultipleFileInfo(args, signal, onProgress) {
|
|
|
38
37
|
const structuredResults = result.results.map((entry) => ({
|
|
39
38
|
path: entry.path,
|
|
40
39
|
info: entry.info ? buildFileInfoPayload(entry.info) : undefined,
|
|
41
|
-
error: entry.error
|
|
40
|
+
error: entry.error
|
|
41
|
+
? buildStructuredError(entry.error, ErrorCode.E_NOT_FOUND, entry.path)
|
|
42
|
+
: undefined,
|
|
42
43
|
}));
|
|
43
44
|
const text = result.results
|
|
44
45
|
.map((entry) => entry.error
|
|
45
|
-
? `${entry.path}: ${entry.error}`
|
|
46
|
+
? `${entry.path}: ${buildStructuredError(entry.error, ErrorCode.E_NOT_FOUND, entry.path).message}`
|
|
46
47
|
: entry.info
|
|
47
48
|
? formatFileInfoDetail(entry.info)
|
|
48
49
|
: entry.path)
|
|
@@ -64,6 +65,7 @@ export function registerGetMultipleFileInfoTool(server, options = {}) {
|
|
|
64
65
|
return executeToolWithDiagnostics({
|
|
65
66
|
toolName: 'stat_many',
|
|
66
67
|
extra,
|
|
68
|
+
outputSchema: GetMultipleFileInfoOutputSchema,
|
|
67
69
|
timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
|
|
68
70
|
context: { path: primaryPath },
|
|
69
71
|
run: async (signal) => {
|
package/dist/tools/stat.js
CHANGED
|
@@ -15,7 +15,6 @@ export const GET_FILE_INFO_TOOL = {
|
|
|
15
15
|
outputSchema: GetFileInfoOutputSchema,
|
|
16
16
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
17
17
|
taskSupport: 'forbidden',
|
|
18
|
-
nuances: ['Use before read/search when file size/type uncertainty exists.'],
|
|
19
18
|
};
|
|
20
19
|
function formatFileInfoDetails(info) {
|
|
21
20
|
const lines = [
|
|
@@ -45,6 +44,7 @@ export function registerGetFileInfoTool(server, options = {}) {
|
|
|
45
44
|
const handler = (args, extra) => executeToolWithDiagnostics({
|
|
46
45
|
toolName: 'stat',
|
|
47
46
|
extra,
|
|
47
|
+
outputSchema: GetFileInfoOutputSchema,
|
|
48
48
|
timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
|
|
49
49
|
context: { path: args.path },
|
|
50
50
|
run: (signal) => handleGetFileInfo(args, signal),
|
|
@@ -58,7 +58,7 @@ export function registerGetFileInfoTool(server, options = {}) {
|
|
|
58
58
|
if (result.isError)
|
|
59
59
|
return `🕮 stat: ${name} • failed`;
|
|
60
60
|
const sc = result.structuredContent;
|
|
61
|
-
if (!sc.
|
|
61
|
+
if (!sc.info)
|
|
62
62
|
return `🕮 stat: ${name} • failed`;
|
|
63
63
|
return `🕮 stat: ${sc.info.name} • ${sc.info.type}, ${formatBytes(sc.info.size)}`;
|
|
64
64
|
},
|
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
1
|
import type { ToolTaskHandler } from '@modelcontextprotocol/sdk/experimental/tasks/interfaces.js';
|
|
3
2
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
3
|
import type { AnySchema, SchemaOutput, ShapeOutput, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js';
|
|
5
4
|
import type { RequestTaskStore } from '@modelcontextprotocol/sdk/shared/protocol.js';
|
|
6
5
|
import type { IconInfo, ToolExtra, ToolResult } from './shared.js';
|
|
7
|
-
export interface TaskContext {
|
|
8
|
-
taskId: string;
|
|
9
|
-
toolName?: string | undefined;
|
|
10
|
-
startTime: number;
|
|
11
|
-
}
|
|
12
|
-
export declare const taskContext: AsyncLocalStorage<TaskContext>;
|
|
13
6
|
type TaskToolExtra = ToolExtra & {
|
|
14
7
|
taskId?: string;
|
|
15
8
|
taskStore?: RequestTaskStore;
|
|
@@ -7,13 +7,16 @@ import { DEFAULT_TASK_TTL_MS, MAX_CONCURRENT_TASKS, MAX_TASK_TTL_MS, } from '../
|
|
|
7
7
|
import { ErrorCode, McpError } from '../lib/errors.js';
|
|
8
8
|
import { isRecord } from '../lib/utils.js';
|
|
9
9
|
import { buildToolErrorResponse, maybeStripStructuredContentFromResult, withDefaultIcons, } from './shared.js';
|
|
10
|
-
|
|
10
|
+
const taskContext = new AsyncLocalStorage();
|
|
11
11
|
const TASK_DIAGNOSTICS_CHANNEL = channel('filesystem-mcp:tasks');
|
|
12
12
|
function publishTaskDiagnostics(event) {
|
|
13
13
|
if (TASK_DIAGNOSTICS_CHANNEL.hasSubscribers) {
|
|
14
14
|
TASK_DIAGNOSTICS_CHANNEL.publish(event);
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
function getDynamicProperty(target, key) {
|
|
18
|
+
return Reflect.get(target, key);
|
|
19
|
+
}
|
|
17
20
|
// --- Type Guards & Helpers ---
|
|
18
21
|
function isExperimentalTaskRegistration(value) {
|
|
19
22
|
if (!isRecord(value))
|
|
@@ -22,8 +25,7 @@ function isExperimentalTaskRegistration(value) {
|
|
|
22
25
|
return (registerToolTask === undefined || typeof registerToolTask === 'function');
|
|
23
26
|
}
|
|
24
27
|
function getExperimentalTaskRegistration(server) {
|
|
25
|
-
const
|
|
26
|
-
const { experimental } = serverWithExperimental;
|
|
28
|
+
const experimental = getDynamicProperty(server, 'experimental');
|
|
27
29
|
if (!isRecord(experimental))
|
|
28
30
|
return undefined;
|
|
29
31
|
const { tasks } = experimental;
|
|
@@ -32,11 +34,10 @@ function getExperimentalTaskRegistration(server) {
|
|
|
32
34
|
return tasks;
|
|
33
35
|
}
|
|
34
36
|
function hasTaskToolCapability(server) {
|
|
35
|
-
const
|
|
36
|
-
const { server: serverRuntime } = serverRecord;
|
|
37
|
+
const serverRuntime = getDynamicProperty(server, 'server');
|
|
37
38
|
if (!isRecord(serverRuntime))
|
|
38
39
|
return true; // Assume capability if runtime structure is opaque
|
|
39
|
-
const
|
|
40
|
+
const getCapabilities = getDynamicProperty(serverRuntime, 'getCapabilities');
|
|
40
41
|
if (typeof getCapabilities !== 'function')
|
|
41
42
|
return true;
|
|
42
43
|
const capabilities = getCapabilities.call(serverRuntime);
|
package/dist/tools/tree.js
CHANGED
|
@@ -14,7 +14,6 @@ export const TREE_TOOL = {
|
|
|
14
14
|
outputSchema: TreeOutputSchema,
|
|
15
15
|
annotations: READ_ONLY_TOOL_ANNOTATIONS,
|
|
16
16
|
taskSupport: 'optional',
|
|
17
|
-
gotchas: ['`maxDepth=0` returns only the root node.'],
|
|
18
17
|
};
|
|
19
18
|
async function handleTree(args, signal, onProgress) {
|
|
20
19
|
const basePath = resolvePathOrRoot(args.path);
|
|
@@ -45,6 +44,7 @@ export function registerTreeTool(server, options = {}) {
|
|
|
45
44
|
return executeToolWithDiagnostics({
|
|
46
45
|
toolName: 'tree',
|
|
47
46
|
extra,
|
|
47
|
+
outputSchema: TreeOutputSchema,
|
|
48
48
|
timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
|
|
49
49
|
context: { path: targetPath },
|
|
50
50
|
run: async (signal) => {
|
package/dist/tools/write-file.js
CHANGED
|
@@ -14,9 +14,6 @@ export const WRITE_FILE_TOOL = {
|
|
|
14
14
|
inputSchema: WriteFileInputSchema,
|
|
15
15
|
outputSchema: WriteFileOutputSchema,
|
|
16
16
|
annotations: DESTRUCTIVE_WRITE_TOOL_ANNOTATIONS,
|
|
17
|
-
gotchas: [
|
|
18
|
-
'`write` replaces ALL existing content — use `edit` for partial updates.',
|
|
19
|
-
],
|
|
20
17
|
taskSupport: 'forbidden',
|
|
21
18
|
};
|
|
22
19
|
async function handleWriteFile(args, signal) {
|
|
@@ -35,6 +32,7 @@ export function registerWriteFileTool(server, options = {}) {
|
|
|
35
32
|
const handler = (args, extra) => executeToolWithDiagnostics({
|
|
36
33
|
toolName: 'write',
|
|
37
34
|
extra,
|
|
35
|
+
outputSchema: WriteFileOutputSchema,
|
|
38
36
|
timedSignal: {},
|
|
39
37
|
context: { path: args.path },
|
|
40
38
|
run: (signal) => handleWriteFile(args, signal),
|
|
@@ -48,8 +46,6 @@ export function registerWriteFileTool(server, options = {}) {
|
|
|
48
46
|
if (result.isError)
|
|
49
47
|
return `🛠 write: ${name} • failed`;
|
|
50
48
|
const sc = result.structuredContent;
|
|
51
|
-
if (!sc.ok)
|
|
52
|
-
return `🛠 write: ${name} • failed`;
|
|
53
49
|
return `🛠 write: ${name} • ${formatBytes(sc.bytesWritten ?? 0)}`;
|
|
54
50
|
},
|
|
55
51
|
});
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { type ToolContract } from './tools/contract.js';
|
|
3
3
|
import type { ToolRegistrationOptions } from './tools/shared.js';
|
|
4
|
-
export { buildToolErrorResponse, buildToolResponse } from './tools/shared.js';
|
|
5
4
|
export declare const ALL_TOOLS: ToolContract[];
|
|
6
5
|
export declare function registerAllTools(server: McpServer, options?: ToolRegistrationOptions): void;
|
package/dist/tools.js
CHANGED
|
@@ -17,7 +17,6 @@ import { GET_MULTIPLE_FILE_INFO_TOOL, registerGetMultipleFileInfoTool, } from '.
|
|
|
17
17
|
import { GET_FILE_INFO_TOOL, registerGetFileInfoTool } from './tools/stat.js';
|
|
18
18
|
import { registerTreeTool, TREE_TOOL } from './tools/tree.js';
|
|
19
19
|
import { registerWriteFileTool, WRITE_FILE_TOOL } from './tools/write-file.js';
|
|
20
|
-
export { buildToolErrorResponse, buildToolResponse } from './tools/shared.js';
|
|
21
20
|
const TOOL_ENTRIES = [
|
|
22
21
|
{
|
|
23
22
|
contract: LIST_ALLOWED_DIRECTORIES_TOOL,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j0hanz/filesystem-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"mcpName": "io.github.j0hanz/filesystem-mcp",
|
|
5
5
|
"description": "A local filesystem MCP server that lets LLMs and AI agents read, write, search, diff, patch, and manage files safely and efficiently. Built for reliable, structured, and controlled filesystem interaction.",
|
|
6
6
|
"type": "module",
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"test": "node scripts/tasks.mjs test",
|
|
41
41
|
"test:fast": "node --test --import tsx/esm src/__tests__/**/*.test.ts node-tests/**/*.test.ts",
|
|
42
42
|
"test:coverage": "node scripts/tasks.mjs test --coverage",
|
|
43
|
+
"inspector:smoke": "node scripts/inspector-smoke.mjs",
|
|
43
44
|
"knip": "knip",
|
|
44
45
|
"knip:fix": "knip --fix",
|
|
45
46
|
"inspector": "npm run build && npx -y @modelcontextprotocol/inspector node dist/index.js ${workspaceFolder}",
|
|
@@ -86,17 +87,16 @@
|
|
|
86
87
|
"@eslint/js": "^10.0.1",
|
|
87
88
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
88
89
|
"@types/node": "^24",
|
|
89
|
-
"eslint": "^10.0.
|
|
90
|
+
"eslint": "^10.0.3",
|
|
90
91
|
"eslint-config-prettier": "^10.1.8",
|
|
91
92
|
"eslint-plugin-de-morgan": "^2.1.1",
|
|
92
93
|
"eslint-plugin-depend": "^1.5.0",
|
|
93
94
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
94
|
-
"
|
|
95
|
-
"knip": "^5.85.0",
|
|
95
|
+
"knip": "^5.86.0",
|
|
96
96
|
"prettier": "^3.8.1",
|
|
97
97
|
"tsx": "^4.21.0",
|
|
98
98
|
"typescript": "^5.9.3",
|
|
99
|
-
"typescript-eslint": "^8.
|
|
99
|
+
"typescript-eslint": "^8.57.0"
|
|
100
100
|
},
|
|
101
101
|
"engines": {
|
|
102
102
|
"node": ">=24"
|