@j0hanz/filesystem-mcp 1.14.0 → 1.14.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.
Files changed (66) hide show
  1. package/README.md +47 -47
  2. package/dist/cli.js +2 -2
  3. package/dist/completions.js +54 -51
  4. package/dist/config.d.ts +13 -13
  5. package/dist/config.js +12 -12
  6. package/dist/index.js +1 -1
  7. package/dist/lib/abort.d.ts +7 -0
  8. package/dist/lib/abort.js +81 -0
  9. package/dist/lib/constants.d.ts +3 -1
  10. package/dist/lib/constants.js +8 -2
  11. package/dist/lib/errors.d.ts +7 -3
  12. package/dist/lib/errors.js +59 -39
  13. package/dist/lib/file-operations/core.d.ts +3 -3
  14. package/dist/lib/file-operations/core.js +23 -20
  15. package/dist/lib/file-operations/metadata.d.ts +2 -2
  16. package/dist/lib/file-operations/metadata.js +60 -19
  17. package/dist/lib/file-operations/search.js +83 -84
  18. package/dist/lib/file-operations/traversal.js +13 -15
  19. package/dist/lib/fs-helpers.d.ts +3 -10
  20. package/dist/lib/fs-helpers.js +20 -98
  21. package/dist/lib/globs.js +1 -1
  22. package/dist/lib/logger.d.ts +28 -0
  23. package/dist/lib/logger.js +91 -0
  24. package/dist/lib/observability.d.ts +7 -0
  25. package/dist/lib/observability.js +19 -9
  26. package/dist/lib/paths.js +55 -55
  27. package/dist/lib/resource-store.js +4 -4
  28. package/dist/lib/utils.d.ts +0 -12
  29. package/dist/lib/utils.js +0 -13
  30. package/dist/resources/generated-instructions.js +40 -31
  31. package/dist/resources/tool-catalog.js +32 -26
  32. package/dist/resources/tool-info.js +34 -29
  33. package/dist/resources/workflows.js +39 -18
  34. package/dist/resources.d.ts +1 -1
  35. package/dist/resources.js +4 -4
  36. package/dist/schemas.d.ts +66 -66
  37. package/dist/schemas.js +21 -44
  38. package/dist/server/bootstrap.d.ts +12 -11
  39. package/dist/server/bootstrap.js +95 -86
  40. package/dist/server/roots-manager.d.ts +5 -2
  41. package/dist/server/roots-manager.js +8 -6
  42. package/dist/server/task-store.d.ts +10 -0
  43. package/dist/server/task-store.js +73 -0
  44. package/dist/tools/apply-patch.js +26 -18
  45. package/dist/tools/calculate-hash.js +11 -22
  46. package/dist/tools/create-directory.js +10 -8
  47. package/dist/tools/delete-file.js +17 -15
  48. package/dist/tools/diff-files.js +15 -15
  49. package/dist/tools/edit-file.js +7 -4
  50. package/dist/tools/list-directory.js +6 -6
  51. package/dist/tools/move-file.js +98 -81
  52. package/dist/tools/read-multiple.js +4 -4
  53. package/dist/tools/read.js +5 -5
  54. package/dist/tools/replace-in-files.js +20 -23
  55. package/dist/tools/roots.js +1 -1
  56. package/dist/tools/search-content.js +32 -41
  57. package/dist/tools/search-files.js +54 -41
  58. package/dist/tools/shared.d.ts +3 -0
  59. package/dist/tools/shared.js +70 -28
  60. package/dist/tools/stat-many.js +11 -7
  61. package/dist/tools/stat.js +4 -4
  62. package/dist/tools/task-support.d.ts +10 -9
  63. package/dist/tools/task-support.js +94 -23
  64. package/dist/tools/tree.js +3 -3
  65. package/dist/tools/write-file.js +10 -7
  66. package/package.json +9 -9
@@ -28,52 +28,61 @@ function buildToolsOverview() {
28
28
  .join('\n');
29
29
  }
30
30
  function buildInstructionsHeader() {
31
- return `<role>
32
- Filesystem agent. Scope: allowed roots only. Discover paths before acting — never guess.
33
- </role>
31
+ return `## Role
32
+
33
+ Secure filesystem agent. Operate strictly within allowed roots. Resolve paths before acting — never assume.
34
+
35
+ ## Tools Overview
34
36
 
35
- <tools_overview>
36
37
  | Category | Tools |
37
- |----------|-------|
38
+ | -------- | ----- |
39
+
38
40
  ${buildToolsOverview()}
39
- </tools_overview>
40
41
 
41
- <resources>
42
- - \`internal://instructions\`: Full usage reference.
43
- - \`internal://tool-catalog\`: Tool routing and data flow.
44
- - \`internal://workflows\`: Standard execution sequences.
45
- - \`internal://tool-info/{name}\`: Per-tool nuances (e.g. \`internal://tool-info/read\`).
46
- - \`filesystem-mcp://result/{id}\`: Cached large output — call \`resources/read\` immediately when \`resourceUri\` is returned.
47
- - \`filesystem-mcp://metrics\`: Per-tool runtime metrics.
48
- </resources>
42
+ ## Resources
43
+
44
+ | URI | Purpose |
45
+ | -------------------------------- | -------------------------------------------------------------- |
46
+ | \`internal://instructions\` | Full usage reference (this document) |
47
+ | \`internal://tool-catalog\` | Tool routing, data flow, and selection guide |
48
+ | \`internal://workflows\` | Step-by-step execution sequences |
49
+ | \`internal://tool-info/{name}\` | Per-tool contract (e.g. \`internal://tool-info/read\`) |
50
+ | \`filesystem-mcp://result/{id}\` | Cached large output — fetch via \`resources/read\` immediately |
51
+ | \`filesystem-mcp://metrics\` | Per-tool call count, error rate, and avg duration |
49
52
 
50
- <task_protocol>
51
- Task execution: Check \`execution.taskSupport\` per tool — \`forbidden\` (default): never send \`task\`; \`optional\`: send \`task\` only when durable polling or deferred results are needed; \`required\`: always send \`task\`.
52
- Task results: Poll via \`tasks/get\`, then retrieve the final payload via \`tasks/result\`.
53
- Progress: Pass \`_meta.progressToken\` in \`tools/call\` to receive \`notifications/progress\`.
54
- </task_protocol>
53
+ ## Task Protocol
54
+
55
+ - Check \`execution.taskSupport\` before sending task metadata.
56
+ - \`forbidden\` (default): Do not send \`task\`.
57
+ - \`optional\`: Send \`task\` only when durable polling or deferred retrieval is needed.
58
+ - \`required\`: Always send \`task\`.
59
+ - Poll status via \`tasks/get\`, retrieve final payload via \`tasks/result\`.
60
+ - Pass \`_meta.progressToken\` in \`tools/call\` to receive \`notifications/progress\`.
55
61
  `;
56
62
  }
57
- const INSTRUCTIONS_FOOTER = `<constraints>
63
+ const INSTRUCTIONS_FOOTER = `## Constraints
64
+
58
65
  ${getSharedConstraints()
59
66
  .map((c) => `- ${c}`)
60
67
  .join('\n')}
61
- </constraints>
62
68
 
63
- <error_handling>
64
- - \`E_ACCESS_DENIED\` => call \`roots\`, use an allowed path.
65
- - \`E_NOT_FOUND\` => call \`ls\` or \`find\`, verify spelling.
66
- - \`E_TOO_LARGE\` => use \`head\`, line ranges, or \`read_many\`.
67
- - \`E_TIMEOUT\` => reduce scope or result limits.
68
- </error_handling>
69
+ ## Error Recovery
70
+
71
+ | Error Code | Action |
72
+ | ------------------- | ------------------------------------------------------------------------- |
73
+ | \`ACCESS_DENIED\` | Run \`roots\` to list allowed directories, retry with a valid path. |
74
+ | \`NOT_FOUND\` | Run \`ls\` or \`find\` to verify the path. |
75
+ | \`TOO_LARGE\` | Use \`head\`/\`tail\`, line ranges, or split across \`read_many\`. |
76
+ | \`TIMEOUT\` | Reduce scope, depth, or maxResults. |
77
+ | \`INVALID_INPUT\` | Re-read tool contract via \`internal://tool-info/{name}\`. |
69
78
  `;
70
79
  function formatToolSection(tool) {
71
80
  const parts = [`### ${tool.name}\n${tool.description}`];
72
81
  if (tool.nuances && tool.nuances.length > 0) {
73
- parts.push(...tool.nuances.map((n) => `- Nuance: ${n}`));
82
+ parts.push(...tool.nuances.map((n) => `- ${n}`));
74
83
  }
75
84
  if (tool.gotchas && tool.gotchas.length > 0) {
76
- parts.push(...tool.gotchas.map((g) => `- Gotcha: ${g}`));
85
+ parts.push(...tool.gotchas.map((g) => `- ⚠ ${g}`));
77
86
  }
78
87
  return parts.join('\n');
79
88
  }
@@ -85,9 +94,9 @@ export function buildServerInstructions() {
85
94
  '',
86
95
  buildToolCatalogDetailsOnly(),
87
96
  '',
88
- '<tool_reference>',
97
+ '## Tool Reference',
98
+ '',
89
99
  toolSections,
90
- '</tool_reference>',
91
100
  '',
92
101
  buildWorkflowGuide(),
93
102
  '',
@@ -15,13 +15,16 @@ function buildCrossToolDataFlow() {
15
15
  }
16
16
  function buildCatalogGuide() {
17
17
  const taskCapable = getTaskCapableToolNames();
18
- return `<tool_selection_guide>
18
+ return `# Tool Selection Guide
19
+
19
20
  ## Primitive Routing
20
21
 
21
- - \`tools\`: model-controlled operations that inspect or mutate the allowed filesystem.
22
- - \`resources\`: application-driven context such as \`internal://instructions\`, \`internal://tool-info/{name}\`, and cached \`filesystem-mcp://result/{id}\` output.
23
- - \`prompts\`: user-controlled workflow templates for help, comparison, and guided inspection.
24
- - \`completion\`: argument suggestions for prompts and resource templates; not a discovery mechanism.
22
+ | Primitive | Purpose |
23
+ | -------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
24
+ | \`tools\` | Model-controlled operations that inspect or mutate the filesystem within allowed roots. |
25
+ | \`resources\` | Application-driven context: \`internal://instructions\`, \`internal://tool-info/{name}\`, cached \`filesystem-mcp://result/{id}\`. |
26
+ | \`prompts\` | User-controlled workflow templates for help, comparison, and guided inspection. |
27
+ | \`completion\` | Argument suggestions for prompts and resource templates (not a discovery mechanism). |
25
28
 
26
29
  ## Cross-Tool Data Flow
27
30
 
@@ -31,37 +34,40 @@ ${buildCrossToolDataFlow()}
31
34
 
32
35
  ## Result Contract
33
36
 
34
- - Successful tools return \`content\` and \`structuredContent\` (when \`outputSchema\` is declared).
35
- - When \`isError: true\`, \`structuredContent\` is omitted — parse the \`content\` text instead.
36
- - Tool/business failures return \`isError: true\` inside the tool result, not a JSON-RPC protocol error.
37
- - When a tool returns \`resourceUri\` or a \`resource_link\`, follow it with \`resources/read\` immediately.
37
+ - Success: returns both \`content\` (JSON text) and \`structuredContent\` (when \`outputSchema\` is declared).
38
+ - Error: \`isError: true\` in tool result, \`structuredContent\` omitted. Parse \`content\` text for error details.
39
+ - Tool/business failures use \`isError: true\` inside the tool result, not JSON-RPC protocol errors.
40
+ - When a response includes \`resourceUri\` or \`resource_link\`, follow up with \`resources/read\` immediately.
41
+
42
+ ## Task Mode
38
43
 
39
- ## Task Mode Routing
44
+ Use inline execution by default. Add task mode only when the caller needs durable polling, deferred retrieval, or cancellation.
40
45
 
41
- - Inline first for fast operations.
42
- - Add task mode only when the caller needs durable polling, deferred retrieval, or cancellation after the initial response.
43
- - Task-capable tools: ${taskCapable.length > 0 ? taskCapable.map((name) => `\`${name}\``).join(', ') : 'none'}.
46
+ Task-capable tools: ${taskCapable.length > 0 ? taskCapable.map((name) => `\`${name}\``).join(', ') : 'none'}.
44
47
 
45
48
  ## Search Strategy
46
49
 
47
- - \`find\`: glob file discovery.
48
- - \`grep\`: text content search.
49
- - \`search_and_replace\`: replacement only, not discovery.
50
+ | Goal | Tool |
51
+ | ----------------------- | ------------------------------------------ |
52
+ | Find files by name/glob | \`find\` |
53
+ | Search file contents | \`grep\` |
54
+ | Replace across files | \`search_and_replace\` (not for discovery) |
50
55
 
51
56
  ## Write Strategy
52
57
 
53
- 1. **Single file, targeted change?** -> \`edit\` (match exact text, replace first occurrence)
54
- 2. **Single file, full rewrite?** -> \`write\` (overwrite entire content)
55
- 3. **Multiple files, same change?** -> \`search_and_replace\` (glob + pattern across files)
56
- 4. **Not sure what to change?** -> \`grep\` first, then decide
58
+ | Scenario | Tool |
59
+ | --------------------------- | ----------------------------------------------------- |
60
+ | Single file, targeted edit | \`edit\` — match exact text, replace first occurrence |
61
+ | Single file, full rewrite | \`write\` — overwrite entire content |
62
+ | Multiple files, same change | \`search_and_replace\` — glob + pattern across files |
63
+ | Unsure what to change | \`grep\` first, then decide |
57
64
 
58
- ## Patch Management
65
+ ## Patch Strategy
59
66
 
60
- - Generate patches with \`diff_files\` first.
61
- - Validate with \`apply_patch(dryRun:true)\` before writing.
62
- - \`apply_patch\` accepts unified diffs - single-file or multi-file.
63
- - Multi-file: \`path\` is base directory; each file is best-effort with per-file \`results[]\`.
64
- </tool_selection_guide>
67
+ 1. Generate with \`diff_files\`.
68
+ 2. Validate with \`apply_patch(dryRun: true)\` before writing.
69
+ 3. Apply with \`apply_patch\`.
70
+ 4. Multi-file patches: set \`path\` to the base directory; results are per-file.
65
71
  `;
66
72
  }
67
73
  export function buildToolCatalog() {
@@ -63,14 +63,14 @@ export function buildCoreContextPack() {
63
63
  const annotations = e.annotations ? ` ${e.annotations.join(' ')}` : '';
64
64
  return `| \`${e.name}\` | ${e.description}${annotations} |`;
65
65
  });
66
- return `<core_context>\n| Tool | Purpose |\n|------|---------|\n${rows.join('\n')}\n</core_context>`;
66
+ return `## Tool Summary\n\n| Tool | Purpose |\n|------|---------|\n${rows.join('\n')}`;
67
67
  }
68
68
  export function getSharedConstraints() {
69
69
  return [
70
- 'Use allowed roots only (from CLI negotiation).',
71
- 'Sensitive paths are denylisted by default.',
72
- `Limits enforced: max file size ${Math.floor(MAX_TEXT_FILE_SIZE / 1024 / 1024)}MB; search caps ${MAX_SEARCH_RESULTS} files, ${DEFAULT_SEARCH_CONTENT_RESULTS} content matches.`,
73
- 'If response includes `resourceUri`, call `resources/read` immediately — cached results expire on restart.',
70
+ 'Operate within allowed roots only (negotiated at startup via CLI).',
71
+ 'Sensitive file paths (e.g. .env, *.pem, *id_rsa*) are denied by default.',
72
+ `Enforced limits: max file size ${Math.floor(MAX_TEXT_FILE_SIZE / 1024 / 1024)} MB, file search cap ${MAX_SEARCH_RESULTS} results, content search cap ${DEFAULT_SEARCH_CONTENT_RESULTS} matches.`,
73
+ 'When a response includes `resourceUri`, call `resources/read` immediately — cached results expire on server restart.',
74
74
  ];
75
75
  }
76
76
  function formatTaskSupportLabel(taskSupport) {
@@ -86,6 +86,14 @@ function formatTaskSupportLabel(taskSupport) {
86
86
  function toJsonSchemaObject(schema, io = 'output') {
87
87
  return z.toJSONSchema(schema, { io });
88
88
  }
89
+ function summarizeArrayType(schema) {
90
+ if (Array.isArray(schema.prefixItems) && schema.prefixItems.length > 0) {
91
+ const itemTypes = schema.prefixItems.map(summarizeSchemaType).join(', ');
92
+ return `tuple<${itemTypes}>`;
93
+ }
94
+ const itemType = schema.items ? summarizeSchemaType(schema.items) : 'unknown';
95
+ return `array<${itemType}>`;
96
+ }
89
97
  function summarizeSchemaType(schema) {
90
98
  if (Array.isArray(schema.enum) && schema.enum.length > 0) {
91
99
  return `enum(${schema.enum.map((value) => JSON.stringify(value)).join(', ')})`;
@@ -100,14 +108,7 @@ function summarizeSchemaType(schema) {
100
108
  return schema.oneOf.map(summarizeSchemaType).join(' | ');
101
109
  }
102
110
  if (schema.type === 'array') {
103
- if (Array.isArray(schema.prefixItems) && schema.prefixItems.length > 0) {
104
- const itemTypes = schema.prefixItems.map(summarizeSchemaType).join(', ');
105
- return `tuple<${itemTypes}>`;
106
- }
107
- const itemType = schema.items
108
- ? summarizeSchemaType(schema.items)
109
- : 'unknown';
110
- return `array<${itemType}>`;
111
+ return summarizeArrayType(schema);
111
112
  }
112
113
  if (schema.type === 'object' && schema.additionalProperties === false) {
113
114
  return 'object (strict)';
@@ -117,16 +118,23 @@ function summarizeSchemaType(schema) {
117
118
  }
118
119
  return 'unknown';
119
120
  }
121
+ function formatFieldLabel(label) {
122
+ return label
123
+ .split('_')
124
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
125
+ .join(' ');
126
+ }
120
127
  function buildSchemaFieldLines(label, schema) {
128
+ const heading = `**${formatFieldLabel(label)}:**`;
121
129
  if (!schema) {
122
- return [`<${label}>`, '- none', `</${label}>`];
130
+ return [heading, '- none'];
123
131
  }
124
132
  const io = label === 'input_fields' ? 'input' : 'output';
125
133
  const jsonSchema = toJsonSchemaObject(schema, io);
126
134
  const properties = jsonSchema.properties ?? {};
127
135
  const required = new Set(jsonSchema.required ?? []);
128
136
  const fieldNames = Object.keys(properties);
129
- const lines = [`<${label}>`];
137
+ const lines = [heading];
130
138
  if (typeof jsonSchema.description === 'string' &&
131
139
  jsonSchema.description.length > 0) {
132
140
  lines.push(`- Schema constraints: ${jsonSchema.description}`);
@@ -135,7 +143,7 @@ function buildSchemaFieldLines(label, schema) {
135
143
  lines.push('- Unknown fields are rejected (`additionalProperties: false`).');
136
144
  }
137
145
  if (fieldNames.length === 0) {
138
- lines.push('- object with no fields', `</${label}>`);
146
+ lines.push('- object with no fields');
139
147
  return lines;
140
148
  }
141
149
  lines.push(...fieldNames.map((fieldName) => {
@@ -147,7 +155,7 @@ function buildSchemaFieldLines(label, schema) {
147
155
  ? fieldSchema.description
148
156
  : 'No description.';
149
157
  return `- ${fieldName} (${type}, ${requiredLabel}): ${description}`;
150
- }), `</${label}>`);
158
+ }));
151
159
  return lines;
152
160
  }
153
161
  export function buildToolInfo(name) {
@@ -165,37 +173,34 @@ export function buildToolInfo(name) {
165
173
  if (contract.annotations?.openWorldHint)
166
174
  annotationLines.push('- openWorldHint: true');
167
175
  const lines = [
168
- `<tool_info name="${entry.name}">`,
169
- `## ${entry.name}`,
176
+ `---`,
177
+ `# ${entry.name}`,
170
178
  '',
171
- `Title: ${entry.title}`,
172
- `Description: ${entry.description}`,
179
+ `**Title:** ${entry.title}`,
180
+ `**Description:** ${entry.description}`,
173
181
  '',
174
- '<execution>',
182
+ '**Execution:**',
175
183
  `- taskSupport: ${formatTaskSupportLabel(contract.taskSupport)}`,
176
- '</execution>',
177
184
  '',
178
185
  ...buildSchemaFieldLines('input_fields', contract.inputSchema),
179
186
  '',
180
187
  ...buildSchemaFieldLines('output_fields', contract.outputSchema),
181
188
  ];
182
189
  if (annotationLines.length > 0) {
183
- lines.push('', '<annotations>', ...annotationLines, '</annotations>');
190
+ lines.push('', '**Behavior:**', ...annotationLines);
184
191
  }
185
192
  if (entry.nuances && entry.nuances.length > 0) {
186
- lines.push('', '<nuances>');
193
+ lines.push('', '**Usage Notes:**');
187
194
  for (const nuance of entry.nuances) {
188
195
  lines.push(`- ${nuance}`);
189
196
  }
190
- lines.push('</nuances>');
191
197
  }
192
198
  if (entry.gotchas && entry.gotchas.length > 0) {
193
- lines.push('', '<gotchas>');
199
+ lines.push('', '**Warnings:**');
194
200
  for (const gotcha of entry.gotchas) {
195
201
  lines.push(`- ${gotcha}`);
196
202
  }
197
- lines.push('</gotchas>');
198
203
  }
199
- lines.push('</tool_info>');
204
+ lines.push('---');
200
205
  return lines.join('\n');
201
206
  }
@@ -18,22 +18,43 @@ export function buildWorkflowGuide() {
18
18
  'rm',
19
19
  'mkdir',
20
20
  ]));
21
- return `<workflows>
22
- ### A: EXPLORE — directory layout or file content
23
- 1. ${exploreTools}.
24
- > **Strict:** Resolve paths first. Never guess.
25
-
26
- ### B: SEARCH — files by pattern or content
27
- 1. ${searchTools}.
28
- > **Strict:** Content search with \`grep\`, not \`find\`.
29
-
30
- ### C: EDIT — modify files or layout
31
- 1. ${editTools}.
32
- 2. Use \`edit\` for targeted changes, \`search_and_replace\` for bulk changes, and \`mv\`/\`rm\`/\`mkdir\` for layout updates.
33
- > **Strict:** Confirm destructive ops (\`write\`, \`mv\`, \`rm\`, bulk replace).
34
-
35
- ### D: PATCH — apply unified diffs
36
- 1. \`diff_files\` → \`apply_patch(dryRun:true)\` → \`apply_patch\`.
37
- > **Tip:** Feed \`diff_files\` output directly. Multi-file patches: \`path\` = base dir, results per file.
38
- </workflows>`;
21
+ return `## Workflows
22
+
23
+ ### A: Explore — Discover directory layout or file content
24
+
25
+ **Tools:** ${exploreTools}
26
+
27
+ 1. Start with \`roots\` to identify allowed directories.
28
+ 2. Use \`ls\` or \`tree\` to map structure, then \`stat\` or \`read\` for details.
29
+
30
+ > Resolve paths before acting. Never assume a path exists.
31
+
32
+ ### B: Search — Find files by name or content
33
+
34
+ **Tools:** ${searchTools}
35
+
36
+ 1. Use \`find\` for file name/glob matching.
37
+ 2. Use \`grep\` for content search (supports regex).
38
+ 3. Use \`read\` to inspect matched files.
39
+
40
+ > Use \`grep\` for content, \`find\` for filenames. Do not conflate them.
41
+
42
+ ### C: Edit — Modify files or directory layout
43
+
44
+ **Tools:** ${editTools}
45
+
46
+ 1. Use \`edit\` for targeted single-file changes (exact text match → replace).
47
+ 2. Use \`search_and_replace\` for bulk changes across multiple files.
48
+ 3. Use \`mv\`, \`rm\`, \`mkdir\` for structural changes.
49
+
50
+ > Confirm destructive operations (\`write\`, \`mv\`, \`rm\`, bulk replace) before executing.
51
+
52
+ ### D: Patch — Generate and apply unified diffs
53
+
54
+ 1. Generate: \`diff_files(original, modified)\`.
55
+ 2. Validate: \`apply_patch(patch, dryRun: true)\`.
56
+ 3. Apply: \`apply_patch(patch)\`.
57
+
58
+ > Multi-file patches: set \`path\` to the base directory. Results are reported per file.
59
+ `;
39
60
  }
@@ -1,4 +1,4 @@
1
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { type McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { ResourceStore } from './lib/resource-store.js';
3
3
  import { type IconInfo } from './tools/shared.js';
4
4
  export declare function registerInstructionResource(server: McpServer, instructions: string, iconInfo?: IconInfo): void;
package/dist/resources.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { ResourceTemplate, } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { ErrorCode, McpError } from './lib/errors.js';
3
3
  import { globalMetrics } from './lib/observability.js';
4
4
  import { buildToolCatalog } from './resources/tool-catalog.js';
@@ -104,7 +104,7 @@ export function registerResultResources(server, store, iconInfo) {
104
104
  }, iconInfo), (uri, variables) => {
105
105
  const { id } = variables;
106
106
  if (typeof id !== 'string' || id.length === 0) {
107
- throw new McpError(ErrorCode.E_NOT_FOUND, 'Cached result has expired — re-run the tool to regenerate.');
107
+ throw new McpError(ErrorCode.NOT_FOUND, 'Cached result expired. Re-run the tool to regenerate.');
108
108
  }
109
109
  const entry = store.getText(uri.toString());
110
110
  return {
@@ -130,11 +130,11 @@ export function registerToolInfoResource(server, iconInfo) {
130
130
  }, iconInfo), (uri, variables) => {
131
131
  const { name } = variables;
132
132
  if (typeof name !== 'string' || name.length === 0) {
133
- throw new McpError(ErrorCode.E_INVALID_INPUT, 'Tool name is required');
133
+ throw new McpError(ErrorCode.INVALID_INPUT, 'Tool name is required');
134
134
  }
135
135
  const content = buildToolInfo(name);
136
136
  if (content === undefined) {
137
- throw new McpError(ErrorCode.E_INVALID_INPUT, `Tool not found: ${name}`);
137
+ throw new McpError(ErrorCode.INVALID_INPUT, `Tool not found: ${name}`);
138
138
  }
139
139
  return {
140
140
  contents: [
package/dist/schemas.d.ts CHANGED
@@ -22,9 +22,9 @@ export declare const ListDirectoryInputSchema: z.ZodObject<{
22
22
  maxDepth: z.ZodOptional<z.ZodInt>;
23
23
  maxEntries: z.ZodDefault<z.ZodOptional<z.ZodInt>>;
24
24
  sortBy: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
25
- name: "name";
26
- size: "size";
27
25
  type: "type";
26
+ size: "size";
27
+ name: "name";
28
28
  modified: "modified";
29
29
  }>>>;
30
30
  pattern: z.ZodOptional<z.ZodString>;
@@ -39,8 +39,8 @@ export declare const SearchFilesInputSchema: z.ZodObject<{
39
39
  includeIgnored: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
40
40
  includeHidden: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
41
41
  sortBy: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
42
- name: "name";
43
42
  size: "size";
43
+ name: "name";
44
44
  path: "path";
45
45
  modified: "modified";
46
46
  }>>>;
@@ -208,18 +208,18 @@ export declare const ReadMultipleFilesOutputSchema: z.ZodObject<{
208
208
  }>>;
209
209
  error: z.ZodOptional<z.ZodObject<{
210
210
  code: z.ZodEnum<{
211
- readonly E_ACCESS_DENIED: "E_ACCESS_DENIED";
212
- readonly E_NOT_FOUND: "E_NOT_FOUND";
213
- readonly E_NOT_FILE: "E_NOT_FILE";
214
- readonly E_NOT_DIRECTORY: "E_NOT_DIRECTORY";
215
- readonly E_TOO_LARGE: "E_TOO_LARGE";
216
- readonly E_TIMEOUT: "E_TIMEOUT";
217
- readonly E_CANCELLED: "E_CANCELLED";
218
- readonly E_INVALID_PATTERN: "E_INVALID_PATTERN";
219
- readonly E_INVALID_INPUT: "E_INVALID_INPUT";
220
- readonly E_PERMISSION_DENIED: "E_PERMISSION_DENIED";
221
- readonly E_SYMLINK_NOT_ALLOWED: "E_SYMLINK_NOT_ALLOWED";
222
- readonly E_UNKNOWN: "E_UNKNOWN";
211
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
212
+ readonly NOT_FOUND: "NOT_FOUND";
213
+ readonly NOT_FILE: "NOT_FILE";
214
+ readonly NOT_DIRECTORY: "NOT_DIRECTORY";
215
+ readonly TOO_LARGE: "TOO_LARGE";
216
+ readonly TIMEOUT: "TIMEOUT";
217
+ readonly CANCELLED: "CANCELLED";
218
+ readonly INVALID_PATTERN: "INVALID_PATTERN";
219
+ readonly INVALID_INPUT: "INVALID_INPUT";
220
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
221
+ readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
222
+ readonly UNKNOWN: "UNKNOWN";
223
223
  }>;
224
224
  message: z.ZodString;
225
225
  path: z.ZodOptional<z.ZodString>;
@@ -279,18 +279,18 @@ export declare const GetMultipleFileInfoOutputSchema: z.ZodObject<{
279
279
  }, z.core.$strict>>;
280
280
  error: z.ZodOptional<z.ZodObject<{
281
281
  code: z.ZodEnum<{
282
- readonly E_ACCESS_DENIED: "E_ACCESS_DENIED";
283
- readonly E_NOT_FOUND: "E_NOT_FOUND";
284
- readonly E_NOT_FILE: "E_NOT_FILE";
285
- readonly E_NOT_DIRECTORY: "E_NOT_DIRECTORY";
286
- readonly E_TOO_LARGE: "E_TOO_LARGE";
287
- readonly E_TIMEOUT: "E_TIMEOUT";
288
- readonly E_CANCELLED: "E_CANCELLED";
289
- readonly E_INVALID_PATTERN: "E_INVALID_PATTERN";
290
- readonly E_INVALID_INPUT: "E_INVALID_INPUT";
291
- readonly E_PERMISSION_DENIED: "E_PERMISSION_DENIED";
292
- readonly E_SYMLINK_NOT_ALLOWED: "E_SYMLINK_NOT_ALLOWED";
293
- readonly E_UNKNOWN: "E_UNKNOWN";
282
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
283
+ readonly NOT_FOUND: "NOT_FOUND";
284
+ readonly NOT_FILE: "NOT_FILE";
285
+ readonly NOT_DIRECTORY: "NOT_DIRECTORY";
286
+ readonly TOO_LARGE: "TOO_LARGE";
287
+ readonly TIMEOUT: "TIMEOUT";
288
+ readonly CANCELLED: "CANCELLED";
289
+ readonly INVALID_PATTERN: "INVALID_PATTERN";
290
+ readonly INVALID_INPUT: "INVALID_INPUT";
291
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
292
+ readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
293
+ readonly UNKNOWN: "UNKNOWN";
294
294
  }>;
295
295
  message: z.ZodString;
296
296
  path: z.ZodOptional<z.ZodString>;
@@ -354,18 +354,18 @@ export declare const MoveFileOutputSchema: z.ZodObject<{
354
354
  source: z.ZodString;
355
355
  error: z.ZodObject<{
356
356
  code: z.ZodEnum<{
357
- readonly E_ACCESS_DENIED: "E_ACCESS_DENIED";
358
- readonly E_NOT_FOUND: "E_NOT_FOUND";
359
- readonly E_NOT_FILE: "E_NOT_FILE";
360
- readonly E_NOT_DIRECTORY: "E_NOT_DIRECTORY";
361
- readonly E_TOO_LARGE: "E_TOO_LARGE";
362
- readonly E_TIMEOUT: "E_TIMEOUT";
363
- readonly E_CANCELLED: "E_CANCELLED";
364
- readonly E_INVALID_PATTERN: "E_INVALID_PATTERN";
365
- readonly E_INVALID_INPUT: "E_INVALID_INPUT";
366
- readonly E_PERMISSION_DENIED: "E_PERMISSION_DENIED";
367
- readonly E_SYMLINK_NOT_ALLOWED: "E_SYMLINK_NOT_ALLOWED";
368
- readonly E_UNKNOWN: "E_UNKNOWN";
357
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
358
+ readonly NOT_FOUND: "NOT_FOUND";
359
+ readonly NOT_FILE: "NOT_FILE";
360
+ readonly NOT_DIRECTORY: "NOT_DIRECTORY";
361
+ readonly TOO_LARGE: "TOO_LARGE";
362
+ readonly TIMEOUT: "TIMEOUT";
363
+ readonly CANCELLED: "CANCELLED";
364
+ readonly INVALID_PATTERN: "INVALID_PATTERN";
365
+ readonly INVALID_INPUT: "INVALID_INPUT";
366
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
367
+ readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
368
+ readonly UNKNOWN: "UNKNOWN";
369
369
  }>;
370
370
  message: z.ZodString;
371
371
  path: z.ZodOptional<z.ZodString>;
@@ -431,18 +431,18 @@ export declare const ApplyPatchOutputSchema: z.ZodObject<{
431
431
  linesRemoved: z.ZodOptional<z.ZodInt>;
432
432
  error: z.ZodOptional<z.ZodObject<{
433
433
  code: z.ZodEnum<{
434
- readonly E_ACCESS_DENIED: "E_ACCESS_DENIED";
435
- readonly E_NOT_FOUND: "E_NOT_FOUND";
436
- readonly E_NOT_FILE: "E_NOT_FILE";
437
- readonly E_NOT_DIRECTORY: "E_NOT_DIRECTORY";
438
- readonly E_TOO_LARGE: "E_TOO_LARGE";
439
- readonly E_TIMEOUT: "E_TIMEOUT";
440
- readonly E_CANCELLED: "E_CANCELLED";
441
- readonly E_INVALID_PATTERN: "E_INVALID_PATTERN";
442
- readonly E_INVALID_INPUT: "E_INVALID_INPUT";
443
- readonly E_PERMISSION_DENIED: "E_PERMISSION_DENIED";
444
- readonly E_SYMLINK_NOT_ALLOWED: "E_SYMLINK_NOT_ALLOWED";
445
- readonly E_UNKNOWN: "E_UNKNOWN";
434
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
435
+ readonly NOT_FOUND: "NOT_FOUND";
436
+ readonly NOT_FILE: "NOT_FILE";
437
+ readonly NOT_DIRECTORY: "NOT_DIRECTORY";
438
+ readonly TOO_LARGE: "TOO_LARGE";
439
+ readonly TIMEOUT: "TIMEOUT";
440
+ readonly CANCELLED: "CANCELLED";
441
+ readonly INVALID_PATTERN: "INVALID_PATTERN";
442
+ readonly INVALID_INPUT: "INVALID_INPUT";
443
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
444
+ readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
445
+ readonly UNKNOWN: "UNKNOWN";
446
446
  }>;
447
447
  message: z.ZodString;
448
448
  path: z.ZodOptional<z.ZodString>;
@@ -458,9 +458,9 @@ export declare const SearchAndReplaceInputSchema: z.ZodObject<{
458
458
  isRegex: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
459
459
  caseSensitive: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
460
460
  dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
461
- includeHidden: z.ZodOptional<z.ZodBoolean>;
462
- includeIgnored: z.ZodOptional<z.ZodBoolean>;
463
- returnDiff: z.ZodOptional<z.ZodBoolean>;
461
+ includeHidden: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
462
+ includeIgnored: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
463
+ returnDiff: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
464
464
  maxFiles: z.ZodOptional<z.ZodInt>;
465
465
  }, z.core.$strict>;
466
466
  export declare const SearchAndReplaceOutputSchema: z.ZodObject<{
@@ -473,18 +473,18 @@ export declare const SearchAndReplaceOutputSchema: z.ZodObject<{
473
473
  path: z.ZodString;
474
474
  error: z.ZodObject<{
475
475
  code: z.ZodEnum<{
476
- readonly E_ACCESS_DENIED: "E_ACCESS_DENIED";
477
- readonly E_NOT_FOUND: "E_NOT_FOUND";
478
- readonly E_NOT_FILE: "E_NOT_FILE";
479
- readonly E_NOT_DIRECTORY: "E_NOT_DIRECTORY";
480
- readonly E_TOO_LARGE: "E_TOO_LARGE";
481
- readonly E_TIMEOUT: "E_TIMEOUT";
482
- readonly E_CANCELLED: "E_CANCELLED";
483
- readonly E_INVALID_PATTERN: "E_INVALID_PATTERN";
484
- readonly E_INVALID_INPUT: "E_INVALID_INPUT";
485
- readonly E_PERMISSION_DENIED: "E_PERMISSION_DENIED";
486
- readonly E_SYMLINK_NOT_ALLOWED: "E_SYMLINK_NOT_ALLOWED";
487
- readonly E_UNKNOWN: "E_UNKNOWN";
476
+ readonly ACCESS_DENIED: "ACCESS_DENIED";
477
+ readonly NOT_FOUND: "NOT_FOUND";
478
+ readonly NOT_FILE: "NOT_FILE";
479
+ readonly NOT_DIRECTORY: "NOT_DIRECTORY";
480
+ readonly TOO_LARGE: "TOO_LARGE";
481
+ readonly TIMEOUT: "TIMEOUT";
482
+ readonly CANCELLED: "CANCELLED";
483
+ readonly INVALID_PATTERN: "INVALID_PATTERN";
484
+ readonly INVALID_INPUT: "INVALID_INPUT";
485
+ readonly PERMISSION_DENIED: "PERMISSION_DENIED";
486
+ readonly SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED";
487
+ readonly UNKNOWN: "UNKNOWN";
488
488
  }>;
489
489
  message: z.ZodString;
490
490
  path: z.ZodOptional<z.ZodString>;