@j0hanz/filesystem-context-mcp 1.1.0 → 1.2.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/README.md +106 -29
- package/dist/__tests__/lib/errors.test.js +3 -23
- package/dist/__tests__/lib/errors.test.js.map +1 -1
- package/dist/__tests__/lib/file-operations.test.js +34 -0
- package/dist/__tests__/lib/file-operations.test.js.map +1 -1
- package/dist/__tests__/lib/path-validation.test.js +8 -0
- package/dist/__tests__/lib/path-validation.test.js.map +1 -1
- package/dist/__tests__/schemas/validators.test.js +101 -122
- package/dist/__tests__/schemas/validators.test.js.map +1 -1
- package/dist/__tests__/security/filesystem-boundary.test.js +1 -1
- package/dist/__tests__/security/filesystem-boundary.test.js.map +1 -1
- package/dist/config/types.d.ts +1 -85
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +0 -2
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/instructions.md +1 -2
- package/dist/lib/constants.d.ts +3 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +73 -259
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/errors.d.ts +25 -3
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +4 -94
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/file-operations/analyze-directory.d.ts +8 -0
- package/dist/lib/file-operations/analyze-directory.d.ts.map +1 -0
- package/dist/lib/file-operations/analyze-directory.js +117 -0
- package/dist/lib/file-operations/analyze-directory.js.map +1 -0
- package/dist/lib/file-operations/directory-helpers.d.ts +35 -0
- package/dist/lib/file-operations/directory-helpers.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-helpers.js +136 -0
- package/dist/lib/file-operations/directory-helpers.js.map +1 -0
- package/dist/lib/file-operations/directory-items.d.ts +20 -0
- package/dist/lib/file-operations/directory-items.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-items.js +85 -0
- package/dist/lib/file-operations/directory-items.js.map +1 -0
- package/dist/lib/file-operations/directory-iteration.d.ts +17 -0
- package/dist/lib/file-operations/directory-iteration.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-iteration.js +55 -0
- package/dist/lib/file-operations/directory-iteration.js.map +1 -0
- package/dist/lib/file-operations/directory-tree.d.ts +9 -0
- package/dist/lib/file-operations/directory-tree.d.ts.map +1 -0
- package/dist/lib/file-operations/directory-tree.js +175 -0
- package/dist/lib/file-operations/directory-tree.js.map +1 -0
- package/dist/lib/file-operations/file-info.d.ts +3 -0
- package/dist/lib/file-operations/file-info.d.ts.map +1 -0
- package/dist/lib/file-operations/file-info.js +56 -0
- package/dist/lib/file-operations/file-info.js.map +1 -0
- package/dist/lib/file-operations/list-directory.d.ts +10 -0
- package/dist/lib/file-operations/list-directory.d.ts.map +1 -0
- package/dist/lib/file-operations/list-directory.js +189 -0
- package/dist/lib/file-operations/list-directory.js.map +1 -0
- package/dist/lib/file-operations/pattern-complexity.d.ts +16 -0
- package/dist/lib/file-operations/pattern-complexity.d.ts.map +1 -0
- package/dist/lib/file-operations/pattern-complexity.js +86 -0
- package/dist/lib/file-operations/pattern-complexity.js.map +1 -0
- package/dist/lib/file-operations/pattern-validator.d.ts +15 -0
- package/dist/lib/file-operations/pattern-validator.d.ts.map +1 -0
- package/dist/lib/file-operations/pattern-validator.js +69 -0
- package/dist/lib/file-operations/pattern-validator.js.map +1 -0
- package/dist/lib/file-operations/read-media-file.d.ts +5 -0
- package/dist/lib/file-operations/read-media-file.d.ts.map +1 -0
- package/dist/lib/file-operations/read-media-file.js +31 -0
- package/dist/lib/file-operations/read-media-file.js.map +1 -0
- package/dist/lib/file-operations/read-multiple-files.d.ts +16 -0
- package/dist/lib/file-operations/read-multiple-files.d.ts.map +1 -0
- package/dist/lib/file-operations/read-multiple-files.js +100 -0
- package/dist/lib/file-operations/read-multiple-files.js.map +1 -0
- package/dist/lib/file-operations/search-content.d.ts +18 -0
- package/dist/lib/file-operations/search-content.d.ts.map +1 -0
- package/dist/lib/file-operations/search-content.js +436 -0
- package/dist/lib/file-operations/search-content.js.map +1 -0
- package/dist/lib/file-operations/search-files.d.ts +11 -0
- package/dist/lib/file-operations/search-files.d.ts.map +1 -0
- package/dist/lib/file-operations/search-files.js +143 -0
- package/dist/lib/file-operations/search-files.js.map +1 -0
- package/dist/lib/file-operations/sorting.d.ts +12 -0
- package/dist/lib/file-operations/sorting.d.ts.map +1 -0
- package/dist/lib/file-operations/sorting.js +24 -0
- package/dist/lib/file-operations/sorting.js.map +1 -0
- package/dist/lib/file-operations.d.ts +9 -57
- package/dist/lib/file-operations.d.ts.map +1 -1
- package/dist/lib/file-operations.js +9 -773
- package/dist/lib/file-operations.js.map +1 -1
- package/dist/lib/fs-helpers/binary-detect.d.ts +3 -0
- package/dist/lib/fs-helpers/binary-detect.d.ts.map +1 -0
- package/dist/lib/fs-helpers/binary-detect.js +54 -0
- package/dist/lib/fs-helpers/binary-detect.js.map +1 -0
- package/dist/lib/fs-helpers/concurrency.d.ts +11 -0
- package/dist/lib/fs-helpers/concurrency.d.ts.map +1 -0
- package/dist/lib/fs-helpers/concurrency.js +95 -0
- package/dist/lib/fs-helpers/concurrency.js.map +1 -0
- package/dist/lib/fs-helpers/fs-utils.d.ts +5 -0
- package/dist/lib/fs-helpers/fs-utils.d.ts.map +1 -0
- package/dist/lib/fs-helpers/fs-utils.js +13 -0
- package/dist/lib/fs-helpers/fs-utils.js.map +1 -0
- package/dist/lib/fs-helpers/readers/head-file.d.ts +2 -0
- package/dist/lib/fs-helpers/readers/head-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/head-file.js +73 -0
- package/dist/lib/fs-helpers/readers/head-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/line-range.d.ts +7 -0
- package/dist/lib/fs-helpers/readers/line-range.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/line-range.js +46 -0
- package/dist/lib/fs-helpers/readers/line-range.js.map +1 -0
- package/dist/lib/fs-helpers/readers/read-file.d.ts +16 -0
- package/dist/lib/fs-helpers/readers/read-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/read-file.js +87 -0
- package/dist/lib/fs-helpers/readers/read-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/stream-lines.d.ts +7 -0
- package/dist/lib/fs-helpers/readers/stream-lines.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/stream-lines.js +61 -0
- package/dist/lib/fs-helpers/readers/stream-lines.js.map +1 -0
- package/dist/lib/fs-helpers/readers/tail-file.d.ts +2 -0
- package/dist/lib/fs-helpers/readers/tail-file.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/tail-file.js +98 -0
- package/dist/lib/fs-helpers/readers/tail-file.js.map +1 -0
- package/dist/lib/fs-helpers/readers/utf8.d.ts +3 -0
- package/dist/lib/fs-helpers/readers/utf8.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers/utf8.js +22 -0
- package/dist/lib/fs-helpers/readers/utf8.js.map +1 -0
- package/dist/lib/fs-helpers/readers.d.ts +4 -0
- package/dist/lib/fs-helpers/readers.d.ts.map +1 -0
- package/dist/lib/fs-helpers/readers.js +4 -0
- package/dist/lib/fs-helpers/readers.js.map +1 -0
- package/dist/lib/fs-helpers.d.ts +4 -25
- package/dist/lib/fs-helpers.d.ts.map +1 -1
- package/dist/lib/fs-helpers.js +4 -327
- package/dist/lib/fs-helpers.js.map +1 -1
- package/dist/lib/path-validation/allowed-directories.d.ts +9 -0
- package/dist/lib/path-validation/allowed-directories.d.ts.map +1 -0
- package/dist/lib/path-validation/allowed-directories.js +94 -0
- package/dist/lib/path-validation/allowed-directories.js.map +1 -0
- package/dist/lib/path-validation/errors.d.ts +5 -0
- package/dist/lib/path-validation/errors.d.ts.map +1 -0
- package/dist/lib/path-validation/errors.js +33 -0
- package/dist/lib/path-validation/errors.js.map +1 -0
- package/dist/lib/path-validation/roots.d.ts +3 -0
- package/dist/lib/path-validation/roots.d.ts.map +1 -0
- package/dist/lib/path-validation/roots.js +49 -0
- package/dist/lib/path-validation/roots.js.map +1 -0
- package/dist/lib/path-validation/validators.d.ts +9 -0
- package/dist/lib/path-validation/validators.d.ts.map +1 -0
- package/dist/lib/path-validation/validators.js +70 -0
- package/dist/lib/path-validation/validators.js.map +1 -0
- package/dist/lib/path-validation.d.ts +3 -7
- package/dist/lib/path-validation.d.ts.map +1 -1
- package/dist/lib/path-validation.js +3 -141
- package/dist/lib/path-validation.js.map +1 -1
- package/dist/lib/performance/monitor.d.ts +25 -0
- package/dist/lib/performance/monitor.d.ts.map +1 -0
- package/dist/lib/performance/monitor.js +84 -0
- package/dist/lib/performance/monitor.js.map +1 -0
- package/dist/schemas/input-helpers.d.ts +27 -0
- package/dist/schemas/input-helpers.d.ts.map +1 -0
- package/dist/schemas/input-helpers.js +176 -0
- package/dist/schemas/input-helpers.js.map +1 -0
- package/dist/schemas/inputs.d.ts +14 -7
- package/dist/schemas/inputs.d.ts.map +1 -1
- package/dist/schemas/inputs.js +56 -228
- package/dist/schemas/inputs.js.map +1 -1
- package/dist/schemas/output-helpers.d.ts +24 -0
- package/dist/schemas/output-helpers.d.ts.map +1 -0
- package/dist/schemas/output-helpers.js +13 -0
- package/dist/schemas/output-helpers.js.map +1 -0
- package/dist/schemas/outputs.d.ts +476 -42
- package/dist/schemas/outputs.d.ts.map +1 -1
- package/dist/schemas/outputs.js +26 -41
- package/dist/schemas/outputs.js.map +1 -1
- package/dist/server.d.ts +9 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +29 -45
- package/dist/server.js.map +1 -1
- package/dist/tools/analyze-directory.d.ts.map +1 -1
- package/dist/tools/analyze-directory.js +115 -53
- package/dist/tools/analyze-directory.js.map +1 -1
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +86 -49
- package/dist/tools/directory-tree.js.map +1 -1
- package/dist/tools/get-file-info.d.ts.map +1 -1
- package/dist/tools/get-file-info.js +71 -37
- package/dist/tools/get-file-info.js.map +1 -1
- package/dist/tools/list-allowed-dirs.d.ts.map +1 -1
- package/dist/tools/list-allowed-dirs.js +48 -35
- package/dist/tools/list-allowed-dirs.js.map +1 -1
- package/dist/tools/list-directory.d.ts.map +1 -1
- package/dist/tools/list-directory.js +129 -58
- package/dist/tools/list-directory.js.map +1 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +70 -56
- package/dist/tools/read-file.js.map +1 -1
- package/dist/tools/read-media-file.d.ts.map +1 -1
- package/dist/tools/read-media-file.js +39 -41
- package/dist/tools/read-media-file.js.map +1 -1
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +58 -50
- package/dist/tools/read-multiple-files.js.map +1 -1
- package/dist/tools/search-content.d.ts.map +1 -1
- package/dist/tools/search-content.js +148 -89
- package/dist/tools/search-content.js.map +1 -1
- package/dist/tools/search-files.d.ts.map +1 -1
- package/dist/tools/search-files.js +123 -50
- package/dist/tools/search-files.js.map +1 -1
- package/dist/tools/tool-response.d.ts +9 -0
- package/dist/tools/tool-response.d.ts.map +1 -0
- package/dist/tools/tool-response.js +7 -0
- package/dist/tools/tool-response.js.map +1 -0
- package/package.json +2 -1
- package/dist/__tests__/errors.test.d.ts +0 -2
- package/dist/__tests__/errors.test.d.ts.map +0 -1
- package/dist/__tests__/errors.test.js +0 -88
- package/dist/__tests__/errors.test.js.map +0 -1
- package/dist/__tests__/file-operations.test.d.ts +0 -2
- package/dist/__tests__/file-operations.test.d.ts.map +0 -1
- package/dist/__tests__/file-operations.test.js +0 -230
- package/dist/__tests__/file-operations.test.js.map +0 -1
- package/dist/__tests__/lib/formatters.test.d.ts +0 -2
- package/dist/__tests__/lib/formatters.test.d.ts.map +0 -1
- package/dist/__tests__/lib/formatters.test.js +0 -248
- package/dist/__tests__/lib/formatters.test.js.map +0 -1
- package/dist/__tests__/lib/image-parsing.test.d.ts +0 -2
- package/dist/__tests__/lib/image-parsing.test.d.ts.map +0 -1
- package/dist/__tests__/lib/image-parsing.test.js +0 -262
- package/dist/__tests__/lib/image-parsing.test.js.map +0 -1
- package/dist/__tests__/path-validation.test.d.ts +0 -2
- package/dist/__tests__/path-validation.test.d.ts.map +0 -1
- package/dist/__tests__/path-validation.test.js +0 -92
- package/dist/__tests__/path-validation.test.js.map +0 -1
- package/dist/lib/directory-helpers.d.ts +0 -4
- package/dist/lib/directory-helpers.d.ts.map +0 -1
- package/dist/lib/directory-helpers.js +0 -36
- package/dist/lib/directory-helpers.js.map +0 -1
- package/dist/lib/formatters.d.ts +0 -10
- package/dist/lib/formatters.d.ts.map +0 -1
- package/dist/lib/formatters.js +0 -202
- package/dist/lib/formatters.js.map +0 -1
- package/dist/lib/image-parsing.d.ts +0 -4
- package/dist/lib/image-parsing.d.ts.map +0 -1
- package/dist/lib/image-parsing.js +0 -124
- package/dist/lib/image-parsing.js.map +0 -1
- package/dist/lib/mcp-logger.d.ts +0 -11
- package/dist/lib/mcp-logger.d.ts.map +0 -1
- package/dist/lib/mcp-logger.js +0 -49
- package/dist/lib/mcp-logger.js.map +0 -1
- package/dist/lib/roots-utils.d.ts +0 -7
- package/dist/lib/roots-utils.d.ts.map +0 -1
- package/dist/lib/roots-utils.js +0 -39
- package/dist/lib/roots-utils.js.map +0 -1
- package/dist/lib/search-helpers.d.ts +0 -16
- package/dist/lib/search-helpers.d.ts.map +0 -1
- package/dist/lib/search-helpers.js +0 -169
- package/dist/lib/search-helpers.js.map +0 -1
- package/dist/lib/sorting.d.ts +0 -12
- package/dist/lib/sorting.d.ts.map +0 -1
- package/dist/lib/sorting.js +0 -41
- package/dist/lib/sorting.js.map +0 -1
- package/dist/lib/types.d.ts +0 -6
- package/dist/lib/types.d.ts.map +0 -1
- package/dist/lib/types.js +0 -2
- package/dist/lib/types.js.map +0 -1
- package/dist/prompts/analyze-codebase.d.ts +0 -3
- package/dist/prompts/analyze-codebase.d.ts.map +0 -1
- package/dist/prompts/analyze-codebase.js +0 -144
- package/dist/prompts/analyze-codebase.js.map +0 -1
- package/dist/prompts/filesystem-query.d.ts +0 -3
- package/dist/prompts/filesystem-query.d.ts.map +0 -1
- package/dist/prompts/filesystem-query.js +0 -168
- package/dist/prompts/filesystem-query.js.map +0 -1
- package/dist/prompts/find-duplicates.d.ts +0 -3
- package/dist/prompts/find-duplicates.d.ts.map +0 -1
- package/dist/prompts/find-duplicates.js +0 -77
- package/dist/prompts/find-duplicates.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -3
- package/dist/prompts/index.d.ts.map +0 -1
- package/dist/prompts/index.js +0 -13
- package/dist/prompts/index.js.map +0 -1
- package/dist/prompts/project-overview.d.ts +0 -3
- package/dist/prompts/project-overview.d.ts.map +0 -1
- package/dist/prompts/project-overview.js +0 -122
- package/dist/prompts/project-overview.js.map +0 -1
- package/dist/prompts/search-and-replace.d.ts +0 -3
- package/dist/prompts/search-and-replace.d.ts.map +0 -1
- package/dist/prompts/search-and-replace.js +0 -130
- package/dist/prompts/search-and-replace.js.map +0 -1
- package/dist/prompts/shared.d.ts +0 -11
- package/dist/prompts/shared.d.ts.map +0 -1
- package/dist/prompts/shared.js +0 -32
- package/dist/prompts/shared.js.map +0 -1
- package/dist/resources/index.d.ts +0 -3
- package/dist/resources/index.d.ts.map +0 -1
- package/dist/resources/index.js +0 -54
- package/dist/resources/index.js.map +0 -1
- package/dist/schemas/validators.d.ts +0 -12
- package/dist/schemas/validators.d.ts.map +0 -1
- package/dist/schemas/validators.js +0 -35
- package/dist/schemas/validators.js.map +0 -1
- package/dist/utils/index.d.ts +0 -2
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -2
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/response-helpers.d.ts +0 -22
- package/dist/utils/response-helpers.d.ts.map +0 -1
- package/dist/utils/response-helpers.js +0 -24
- package/dist/utils/response-helpers.js.map +0 -1
|
@@ -1,59 +1,96 @@
|
|
|
1
1
|
import { createErrorResponse, ErrorCode } from '../lib/errors.js';
|
|
2
2
|
import { getDirectoryTree } from '../lib/file-operations.js';
|
|
3
|
-
import { formatOperationSummary, formatTreeEntry } from '../lib/formatters.js';
|
|
4
3
|
import { DirectoryTreeInputSchema, DirectoryTreeOutputSchema, } from '../schemas/index.js';
|
|
4
|
+
import { buildToolResponse } from './tool-response.js';
|
|
5
|
+
const BYTE_UNIT_LABELS = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
6
|
+
function formatBytes(bytes) {
|
|
7
|
+
if (bytes === 0)
|
|
8
|
+
return '0 B';
|
|
9
|
+
const unitIndex = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
10
|
+
const unit = BYTE_UNIT_LABELS[unitIndex] ?? 'B';
|
|
11
|
+
const value = bytes / Math.pow(1024, unitIndex);
|
|
12
|
+
return `${parseFloat(value.toFixed(2))} ${unit}`;
|
|
13
|
+
}
|
|
14
|
+
function formatTreeEntry(entry, indent = '') {
|
|
15
|
+
const lines = [];
|
|
16
|
+
const icon = entry.type === 'directory' ? '[DIR]' : '[FILE]';
|
|
17
|
+
const size = entry.size !== undefined ? ` (${formatBytes(entry.size)})` : '';
|
|
18
|
+
lines.push(`${indent}${icon} ${entry.name}${size}`);
|
|
19
|
+
for (const child of entry.children ?? []) {
|
|
20
|
+
lines.push(formatTreeEntry(child, `${indent} `));
|
|
21
|
+
}
|
|
22
|
+
return lines.join('\n');
|
|
23
|
+
}
|
|
24
|
+
function formatOperationSummary(summary) {
|
|
25
|
+
const lines = [];
|
|
26
|
+
if (summary.truncated) {
|
|
27
|
+
lines.push(`\n\n!! PARTIAL RESULTS: ${summary.truncatedReason ?? 'results truncated'}`);
|
|
28
|
+
if (summary.tip)
|
|
29
|
+
lines.push(`Tip: ${summary.tip}`);
|
|
30
|
+
}
|
|
31
|
+
const note = (count, msg) => {
|
|
32
|
+
if (count && count > 0)
|
|
33
|
+
lines.push(`Note: ${count} ${msg}`);
|
|
34
|
+
};
|
|
35
|
+
note(summary.skippedTooLarge, 'file(s) skipped (too large).');
|
|
36
|
+
note(summary.skippedBinary, 'file(s) skipped (binary).');
|
|
37
|
+
note(summary.skippedInaccessible, 'item(s) were inaccessible and skipped.');
|
|
38
|
+
note(summary.symlinksNotFollowed, 'symlink(s) were not followed (security).');
|
|
39
|
+
note(summary.linesSkippedDueToRegexTimeout, 'line(s) skipped (regex timeout).');
|
|
40
|
+
return lines.join('\n');
|
|
41
|
+
}
|
|
42
|
+
function buildStructuredResult(result) {
|
|
43
|
+
return {
|
|
44
|
+
ok: true,
|
|
45
|
+
tree: result.tree,
|
|
46
|
+
summary: result.summary,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function buildTextResult(result) {
|
|
50
|
+
let textOutput = formatTreeEntry(result.tree);
|
|
51
|
+
textOutput += formatOperationSummary({
|
|
52
|
+
truncated: result.summary.truncated,
|
|
53
|
+
truncatedReason: 'tree was truncated',
|
|
54
|
+
tip: 'Increase maxDepth or maxFiles, or add excludePatterns to narrow scope.',
|
|
55
|
+
skippedInaccessible: result.summary.skippedInaccessible,
|
|
56
|
+
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
57
|
+
});
|
|
58
|
+
return textOutput;
|
|
59
|
+
}
|
|
60
|
+
async function handleDirectoryTree({ path, maxDepth, excludePatterns, includeHidden, includeSize, maxFiles, }) {
|
|
61
|
+
const result = await getDirectoryTree(path, {
|
|
62
|
+
maxDepth,
|
|
63
|
+
excludePatterns,
|
|
64
|
+
includeHidden,
|
|
65
|
+
includeSize,
|
|
66
|
+
maxFiles,
|
|
67
|
+
});
|
|
68
|
+
const structured = buildStructuredResult(result);
|
|
69
|
+
const textOutput = buildTextResult(result);
|
|
70
|
+
return buildToolResponse(textOutput, structured);
|
|
71
|
+
}
|
|
72
|
+
const DIRECTORY_TREE_TOOL = {
|
|
73
|
+
title: 'Directory Tree',
|
|
74
|
+
description: 'Generate a hierarchical JSON tree structure of a directory. ' +
|
|
75
|
+
'More efficient for AI parsing than flat file lists. ' +
|
|
76
|
+
'Ideal for understanding project layout and structure at a glance. ' +
|
|
77
|
+
'Use maxDepth to limit traversal depth and excludePatterns to skip folders like node_modules. ' +
|
|
78
|
+
'Optionally include file sizes with includeSize=true.',
|
|
79
|
+
inputSchema: DirectoryTreeInputSchema,
|
|
80
|
+
outputSchema: DirectoryTreeOutputSchema,
|
|
81
|
+
annotations: {
|
|
82
|
+
readOnlyHint: true,
|
|
83
|
+
idempotentHint: true,
|
|
84
|
+
openWorldHint: true,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
5
87
|
export function registerDirectoryTreeTool(server) {
|
|
6
|
-
server.registerTool('directory_tree', {
|
|
7
|
-
title: 'Directory Tree',
|
|
8
|
-
description: 'Generate a hierarchical JSON tree structure of a directory. ' +
|
|
9
|
-
'More efficient for AI parsing than flat file lists. ' +
|
|
10
|
-
'Ideal for understanding project layout and structure at a glance. ' +
|
|
11
|
-
'Use maxDepth to limit traversal depth and excludePatterns to skip folders like node_modules. ' +
|
|
12
|
-
'Optionally include file sizes with includeSize=true.',
|
|
13
|
-
inputSchema: DirectoryTreeInputSchema,
|
|
14
|
-
outputSchema: DirectoryTreeOutputSchema,
|
|
15
|
-
annotations: {
|
|
16
|
-
readOnlyHint: true,
|
|
17
|
-
idempotentHint: true,
|
|
18
|
-
openWorldHint: true,
|
|
19
|
-
},
|
|
20
|
-
}, async ({ path, maxDepth, excludePatterns, includeHidden, includeSize, maxFiles, }) => {
|
|
88
|
+
server.registerTool('directory_tree', DIRECTORY_TREE_TOOL, async (args) => {
|
|
21
89
|
try {
|
|
22
|
-
|
|
23
|
-
maxDepth,
|
|
24
|
-
excludePatterns,
|
|
25
|
-
includeHidden,
|
|
26
|
-
includeSize,
|
|
27
|
-
maxFiles,
|
|
28
|
-
});
|
|
29
|
-
let textOutput = formatTreeEntry(result.tree);
|
|
30
|
-
const structured = {
|
|
31
|
-
ok: true,
|
|
32
|
-
tree: result.tree,
|
|
33
|
-
summary: {
|
|
34
|
-
totalFiles: result.summary.totalFiles,
|
|
35
|
-
totalDirectories: result.summary.totalDirectories,
|
|
36
|
-
maxDepthReached: result.summary.maxDepthReached,
|
|
37
|
-
truncated: result.summary.truncated,
|
|
38
|
-
skippedInaccessible: result.summary.skippedInaccessible,
|
|
39
|
-
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
// Add truncation notice for better error recovery feedback
|
|
43
|
-
textOutput += formatOperationSummary({
|
|
44
|
-
truncated: result.summary.truncated,
|
|
45
|
-
truncatedReason: 'tree was truncated',
|
|
46
|
-
tip: 'Increase maxDepth or maxFiles, or add excludePatterns to narrow scope.',
|
|
47
|
-
skippedInaccessible: result.summary.skippedInaccessible,
|
|
48
|
-
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
49
|
-
});
|
|
50
|
-
return {
|
|
51
|
-
content: [{ type: 'text', text: textOutput }],
|
|
52
|
-
structuredContent: structured,
|
|
53
|
-
};
|
|
90
|
+
return await handleDirectoryTree(args);
|
|
54
91
|
}
|
|
55
92
|
catch (error) {
|
|
56
|
-
return createErrorResponse(error, ErrorCode.E_NOT_DIRECTORY, path);
|
|
93
|
+
return createErrorResponse(error, ErrorCode.E_NOT_DIRECTORY, args.path);
|
|
57
94
|
}
|
|
58
95
|
});
|
|
59
96
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-tree.js","sourceRoot":"","sources":["../../src/tools/directory-tree.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"directory-tree.js","sourceRoot":"","sources":["../../src/tools/directory-tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-file-info.d.ts","sourceRoot":"","sources":["../../src/tools/get-file-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"get-file-info.d.ts","sourceRoot":"","sources":["../../src/tools/get-file-info.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8FzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAQ/D"}
|
|
@@ -1,47 +1,81 @@
|
|
|
1
1
|
import { createErrorResponse, ErrorCode } from '../lib/errors.js';
|
|
2
2
|
import { getFileInfo } from '../lib/file-operations.js';
|
|
3
|
-
import { formatFileInfo } from '../lib/formatters.js';
|
|
4
3
|
import { GetFileInfoInputSchema, GetFileInfoOutputSchema, } from '../schemas/index.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
import { buildToolResponse } from './tool-response.js';
|
|
5
|
+
const BYTE_UNIT_LABELS = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
6
|
+
function formatBytes(bytes) {
|
|
7
|
+
if (bytes === 0)
|
|
8
|
+
return '0 B';
|
|
9
|
+
const unitIndex = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
10
|
+
const unit = BYTE_UNIT_LABELS[unitIndex] ?? 'B';
|
|
11
|
+
const value = bytes / Math.pow(1024, unitIndex);
|
|
12
|
+
return `${parseFloat(value.toFixed(2))} ${unit}`;
|
|
13
|
+
}
|
|
14
|
+
function formatDate(date) {
|
|
15
|
+
return date.toISOString();
|
|
16
|
+
}
|
|
17
|
+
function formatFileInfo(info) {
|
|
18
|
+
const lines = [
|
|
19
|
+
`Name: ${info.name}`,
|
|
20
|
+
`Path: ${info.path}`,
|
|
21
|
+
`Type: ${info.type}`,
|
|
22
|
+
`Size: ${formatBytes(info.size)}`,
|
|
23
|
+
`Created: ${formatDate(info.created)}`,
|
|
24
|
+
`Modified: ${formatDate(info.modified)}`,
|
|
25
|
+
`Accessed: ${formatDate(info.accessed)}`,
|
|
26
|
+
`Permissions: ${info.permissions}`,
|
|
27
|
+
`Hidden: ${info.isHidden ? 'Yes' : 'No'}`,
|
|
28
|
+
];
|
|
29
|
+
if (info.mimeType)
|
|
30
|
+
lines.push(`MIME Type: ${info.mimeType}`);
|
|
31
|
+
if (info.symlinkTarget)
|
|
32
|
+
lines.push(`Symlink Target: ${info.symlinkTarget}`);
|
|
33
|
+
return lines.join('\n');
|
|
34
|
+
}
|
|
35
|
+
function buildStructuredResult(info) {
|
|
36
|
+
return {
|
|
37
|
+
ok: true,
|
|
38
|
+
info: {
|
|
39
|
+
name: info.name,
|
|
40
|
+
path: info.path,
|
|
41
|
+
type: info.type,
|
|
42
|
+
size: info.size,
|
|
43
|
+
created: info.created.toISOString(),
|
|
44
|
+
modified: info.modified.toISOString(),
|
|
45
|
+
accessed: info.accessed.toISOString(),
|
|
46
|
+
permissions: info.permissions,
|
|
47
|
+
isHidden: info.isHidden,
|
|
48
|
+
mimeType: info.mimeType,
|
|
49
|
+
symlinkTarget: info.symlinkTarget,
|
|
18
50
|
},
|
|
19
|
-
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async function handleGetFileInfo({ path, }) {
|
|
54
|
+
const info = await getFileInfo(path);
|
|
55
|
+
const structured = buildStructuredResult(info);
|
|
56
|
+
return buildToolResponse(formatFileInfo(info), structured);
|
|
57
|
+
}
|
|
58
|
+
const GET_FILE_INFO_TOOL = {
|
|
59
|
+
title: 'Get File Info',
|
|
60
|
+
description: 'Retrieve detailed metadata about a file or directory without reading its contents. ' +
|
|
61
|
+
'Returns: name, path, type, size, timestamps (created/modified/accessed), permissions, ' +
|
|
62
|
+
'MIME type (for files), hidden status, and symlink target (if applicable). ' +
|
|
63
|
+
'Use this to check file properties before reading large files.',
|
|
64
|
+
inputSchema: GetFileInfoInputSchema,
|
|
65
|
+
outputSchema: GetFileInfoOutputSchema,
|
|
66
|
+
annotations: {
|
|
67
|
+
readOnlyHint: true,
|
|
68
|
+
idempotentHint: true,
|
|
69
|
+
openWorldHint: true,
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
export function registerGetFileInfoTool(server) {
|
|
73
|
+
server.registerTool('get_file_info', GET_FILE_INFO_TOOL, async (args) => {
|
|
20
74
|
try {
|
|
21
|
-
|
|
22
|
-
const structured = {
|
|
23
|
-
ok: true,
|
|
24
|
-
info: {
|
|
25
|
-
name: info.name,
|
|
26
|
-
path: info.path,
|
|
27
|
-
type: info.type,
|
|
28
|
-
size: info.size,
|
|
29
|
-
created: info.created.toISOString(),
|
|
30
|
-
modified: info.modified.toISOString(),
|
|
31
|
-
accessed: info.accessed.toISOString(),
|
|
32
|
-
permissions: info.permissions,
|
|
33
|
-
isHidden: info.isHidden,
|
|
34
|
-
mimeType: info.mimeType,
|
|
35
|
-
symlinkTarget: info.symlinkTarget,
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
return {
|
|
39
|
-
content: [{ type: 'text', text: formatFileInfo(info) }],
|
|
40
|
-
structuredContent: structured,
|
|
41
|
-
};
|
|
75
|
+
return await handleGetFileInfo(args);
|
|
42
76
|
}
|
|
43
77
|
catch (error) {
|
|
44
|
-
return createErrorResponse(error, ErrorCode.E_NOT_FOUND, path);
|
|
78
|
+
return createErrorResponse(error, ErrorCode.E_NOT_FOUND, args.path);
|
|
45
79
|
}
|
|
46
80
|
});
|
|
47
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-file-info.js","sourceRoot":"","sources":["../../src/tools/get-file-info.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"get-file-info.js","sourceRoot":"","sources":["../../src/tools/get-file-info.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-allowed-dirs.d.ts","sourceRoot":"","sources":["../../src/tools/list-allowed-dirs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"list-allowed-dirs.d.ts","sourceRoot":"","sources":["../../src/tools/list-allowed-dirs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAyFzE,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAM1E"}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import * as fs from 'node:fs/promises';
|
|
2
|
-
import { formatAllowedDirectories } from '../lib/formatters.js';
|
|
3
2
|
import { getAllowedDirectories } from '../lib/path-validation.js';
|
|
4
3
|
import { ListAllowedDirectoriesOutputSchema } from '../schemas/index.js';
|
|
4
|
+
import { buildToolResponse } from './tool-response.js';
|
|
5
|
+
function formatAllowedDirectories(dirs) {
|
|
6
|
+
if (dirs.length === 0) {
|
|
7
|
+
return 'No directories are currently allowed.';
|
|
8
|
+
}
|
|
9
|
+
const lines = ['Allowed Directories:', ''];
|
|
10
|
+
for (const dir of dirs) {
|
|
11
|
+
lines.push(` - ${dir}`);
|
|
12
|
+
}
|
|
13
|
+
return lines.join('\n');
|
|
14
|
+
}
|
|
5
15
|
async function checkDirectoryAccess(dirPath) {
|
|
6
16
|
try {
|
|
7
17
|
await fs.access(dirPath, fs.constants.R_OK);
|
|
@@ -17,40 +27,43 @@ async function checkDirectoryAccess(dirPath) {
|
|
|
17
27
|
}
|
|
18
28
|
}
|
|
19
29
|
}
|
|
30
|
+
function buildHint(count) {
|
|
31
|
+
if (count === 0) {
|
|
32
|
+
return 'No directories configured. Server cannot access any files.';
|
|
33
|
+
}
|
|
34
|
+
if (count === 1) {
|
|
35
|
+
return 'Single directory configured. All operations are sandboxed here.';
|
|
36
|
+
}
|
|
37
|
+
return `${count} directories configured. Operations work across all of them.`;
|
|
38
|
+
}
|
|
39
|
+
async function handleListAllowedDirectories() {
|
|
40
|
+
const dirs = getAllowedDirectories();
|
|
41
|
+
const count = dirs.length;
|
|
42
|
+
const hint = buildHint(count);
|
|
43
|
+
const accessStatus = await Promise.all(dirs.map(checkDirectoryAccess));
|
|
44
|
+
const structured = {
|
|
45
|
+
ok: true,
|
|
46
|
+
allowedDirectories: dirs,
|
|
47
|
+
count,
|
|
48
|
+
accessStatus,
|
|
49
|
+
hint,
|
|
50
|
+
};
|
|
51
|
+
return buildToolResponse(formatAllowedDirectories(dirs), structured);
|
|
52
|
+
}
|
|
53
|
+
const LIST_ALLOWED_DIRECTORIES_TOOL = {
|
|
54
|
+
title: 'List Allowed Directories',
|
|
55
|
+
description: 'Returns the list of directories this server is permitted to access. ' +
|
|
56
|
+
'Call this FIRST to understand the scope of available file operations. ' +
|
|
57
|
+
'All other tools will only work within these directories for security.',
|
|
58
|
+
inputSchema: {},
|
|
59
|
+
outputSchema: ListAllowedDirectoriesOutputSchema,
|
|
60
|
+
annotations: {
|
|
61
|
+
readOnlyHint: true,
|
|
62
|
+
idempotentHint: true,
|
|
63
|
+
openWorldHint: false,
|
|
64
|
+
},
|
|
65
|
+
};
|
|
20
66
|
export function registerListAllowedDirectoriesTool(server) {
|
|
21
|
-
server.registerTool('list_allowed_directories',
|
|
22
|
-
title: 'List Allowed Directories',
|
|
23
|
-
description: 'Returns the list of directories this server is permitted to access. ' +
|
|
24
|
-
'Call this FIRST to understand the scope of available file operations. ' +
|
|
25
|
-
'All other tools will only work within these directories for security.',
|
|
26
|
-
inputSchema: {},
|
|
27
|
-
outputSchema: ListAllowedDirectoriesOutputSchema,
|
|
28
|
-
annotations: {
|
|
29
|
-
readOnlyHint: true,
|
|
30
|
-
idempotentHint: true,
|
|
31
|
-
openWorldHint: false,
|
|
32
|
-
},
|
|
33
|
-
}, async () => {
|
|
34
|
-
const dirs = getAllowedDirectories();
|
|
35
|
-
const count = dirs.length;
|
|
36
|
-
const hint = count === 0
|
|
37
|
-
? 'No directories configured. Server cannot access any files.'
|
|
38
|
-
: count === 1
|
|
39
|
-
? 'Single directory configured. All operations are sandboxed here.'
|
|
40
|
-
: `${count} directories configured. Operations work across all of them.`;
|
|
41
|
-
// Check access status for each directory
|
|
42
|
-
const accessStatus = await Promise.all(dirs.map(checkDirectoryAccess));
|
|
43
|
-
const structured = {
|
|
44
|
-
ok: true,
|
|
45
|
-
allowedDirectories: dirs,
|
|
46
|
-
count,
|
|
47
|
-
accessStatus,
|
|
48
|
-
hint,
|
|
49
|
-
};
|
|
50
|
-
return {
|
|
51
|
-
content: [{ type: 'text', text: formatAllowedDirectories(dirs) }],
|
|
52
|
-
structuredContent: structured,
|
|
53
|
-
};
|
|
54
|
-
});
|
|
67
|
+
server.registerTool('list_allowed_directories', LIST_ALLOWED_DIRECTORIES_TOOL, async () => await handleListAllowedDirectories());
|
|
55
68
|
}
|
|
56
69
|
//# sourceMappingURL=list-allowed-dirs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-allowed-dirs.js","sourceRoot":"","sources":["../../src/tools/list-allowed-dirs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"list-allowed-dirs.js","sourceRoot":"","sources":["../../src/tools/list-allowed-dirs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-directory.d.ts","sourceRoot":"","sources":["../../src/tools/list-directory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"list-directory.d.ts","sourceRoot":"","sources":["../../src/tools/list-directory.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmMzE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAQjE"}
|
|
@@ -1,75 +1,146 @@
|
|
|
1
1
|
import * as pathModule from 'node:path';
|
|
2
2
|
import { createErrorResponse, ErrorCode } from '../lib/errors.js';
|
|
3
3
|
import { listDirectory } from '../lib/file-operations.js';
|
|
4
|
-
import { formatDirectoryListing, formatOperationSummary, } from '../lib/formatters.js';
|
|
5
4
|
import { ListDirectoryInputSchema, ListDirectoryOutputSchema, } from '../schemas/index.js';
|
|
5
|
+
import { buildToolResponse } from './tool-response.js';
|
|
6
6
|
function getExtension(name, isFile) {
|
|
7
7
|
if (!isFile)
|
|
8
8
|
return undefined;
|
|
9
9
|
const ext = pathModule.extname(name);
|
|
10
10
|
return ext ? ext.slice(1) : undefined;
|
|
11
11
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
const BYTE_UNIT_LABELS = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
13
|
+
function formatBytes(bytes) {
|
|
14
|
+
if (bytes === 0)
|
|
15
|
+
return '0 B';
|
|
16
|
+
const unitIndex = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
17
|
+
const unit = BYTE_UNIT_LABELS[unitIndex] ?? 'B';
|
|
18
|
+
const value = bytes / Math.pow(1024, unitIndex);
|
|
19
|
+
return `${parseFloat(value.toFixed(2))} ${unit}`;
|
|
20
|
+
}
|
|
21
|
+
function formatDirectoryListing(entries, basePath) {
|
|
22
|
+
if (entries.length === 0)
|
|
23
|
+
return 'Directory is empty';
|
|
24
|
+
const dirs = entries.filter((e) => e.type === 'directory');
|
|
25
|
+
const files = entries.filter((e) => e.type !== 'directory');
|
|
26
|
+
const lines = [
|
|
27
|
+
`Contents of ${basePath}:`,
|
|
28
|
+
'',
|
|
29
|
+
...(dirs.length
|
|
30
|
+
? [
|
|
31
|
+
'Directories:',
|
|
32
|
+
...dirs.map((dir) => {
|
|
33
|
+
const symlink = dir.symlinkTarget ? ` -> ${dir.symlinkTarget}` : '';
|
|
34
|
+
return ` [DIR] ${dir.relativePath}${symlink}`;
|
|
35
|
+
}),
|
|
36
|
+
'',
|
|
37
|
+
]
|
|
38
|
+
: []),
|
|
39
|
+
...(files.length
|
|
40
|
+
? [
|
|
41
|
+
'Files:',
|
|
42
|
+
...files.map((file) => {
|
|
43
|
+
const size = file.size !== undefined ? ` (${formatBytes(file.size)})` : '';
|
|
44
|
+
const tag = file.type === 'symlink' ? '[LINK]' : '[FILE]';
|
|
45
|
+
const symlink = file.symlinkTarget
|
|
46
|
+
? ` -> ${file.symlinkTarget}`
|
|
47
|
+
: '';
|
|
48
|
+
return ` ${tag} ${file.relativePath}${size}${symlink}`;
|
|
49
|
+
}),
|
|
50
|
+
]
|
|
51
|
+
: []),
|
|
52
|
+
'',
|
|
53
|
+
`Total: ${dirs.length} directories, ${files.length} files`,
|
|
54
|
+
];
|
|
55
|
+
return lines.join('\n');
|
|
56
|
+
}
|
|
57
|
+
function formatOperationSummary(summary) {
|
|
58
|
+
const lines = [];
|
|
59
|
+
if (summary.truncated) {
|
|
60
|
+
lines.push(`\n\n!! PARTIAL RESULTS: ${summary.truncatedReason ?? 'results truncated'}`);
|
|
61
|
+
if (summary.tip) {
|
|
62
|
+
lines.push(`Tip: ${summary.tip}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const note = (count, msg) => {
|
|
66
|
+
if (count && count > 0)
|
|
67
|
+
lines.push(`Note: ${count} ${msg}`);
|
|
68
|
+
};
|
|
69
|
+
note(summary.skippedTooLarge, 'file(s) skipped (too large).');
|
|
70
|
+
note(summary.skippedBinary, 'file(s) skipped (binary).');
|
|
71
|
+
note(summary.skippedInaccessible, 'item(s) were inaccessible and skipped.');
|
|
72
|
+
note(summary.symlinksNotFollowed, 'symlink(s) were not followed (security).');
|
|
73
|
+
note(summary.linesSkippedDueToRegexTimeout, 'line(s) skipped (regex timeout).');
|
|
74
|
+
return lines.join('\n');
|
|
75
|
+
}
|
|
76
|
+
const LIST_DIRECTORY_TOOL = {
|
|
77
|
+
title: 'List Directory',
|
|
78
|
+
description: 'List files and subdirectories in a specified path with optional recursive traversal. ' +
|
|
79
|
+
'Returns names, types (file/directory/symlink), sizes, and modification dates. ' +
|
|
80
|
+
'Use recursive=true with maxDepth to explore nested structures. ' +
|
|
81
|
+
'For a visual tree structure, use directory_tree instead.',
|
|
82
|
+
inputSchema: ListDirectoryInputSchema,
|
|
83
|
+
outputSchema: ListDirectoryOutputSchema,
|
|
84
|
+
annotations: {
|
|
85
|
+
readOnlyHint: true,
|
|
86
|
+
idempotentHint: true,
|
|
87
|
+
openWorldHint: true,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
function buildStructuredResult(result) {
|
|
91
|
+
return {
|
|
92
|
+
ok: true,
|
|
93
|
+
path: result.path,
|
|
94
|
+
entries: result.entries.map((e) => ({
|
|
95
|
+
name: e.relativePath,
|
|
96
|
+
type: e.type,
|
|
97
|
+
extension: getExtension(e.relativePath, e.type === 'file'),
|
|
98
|
+
size: e.size,
|
|
99
|
+
modified: e.modified?.toISOString(),
|
|
100
|
+
symlinkTarget: e.symlinkTarget,
|
|
101
|
+
})),
|
|
102
|
+
summary: {
|
|
103
|
+
totalEntries: result.summary.totalEntries,
|
|
104
|
+
totalFiles: result.summary.totalFiles,
|
|
105
|
+
totalDirectories: result.summary.totalDirectories,
|
|
106
|
+
maxDepthReached: result.summary.maxDepthReached,
|
|
107
|
+
truncated: result.summary.truncated,
|
|
108
|
+
skippedInaccessible: result.summary.skippedInaccessible,
|
|
109
|
+
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
25
110
|
},
|
|
26
|
-
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function buildTextResult(result) {
|
|
114
|
+
let textOutput = formatDirectoryListing(result.entries, result.path);
|
|
115
|
+
textOutput += formatOperationSummary({
|
|
116
|
+
truncated: result.summary.truncated,
|
|
117
|
+
truncatedReason: `reached max entries limit (${result.summary.totalEntries} returned)`,
|
|
118
|
+
tip: 'Increase maxEntries or reduce maxDepth to see more results.',
|
|
119
|
+
skippedInaccessible: result.summary.skippedInaccessible,
|
|
120
|
+
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
121
|
+
});
|
|
122
|
+
return textOutput;
|
|
123
|
+
}
|
|
124
|
+
async function handleListDirectory({ path: dirPath, recursive, includeHidden, maxDepth, maxEntries, sortBy, includeSymlinkTargets, }) {
|
|
125
|
+
const result = await listDirectory(dirPath, {
|
|
126
|
+
recursive,
|
|
127
|
+
includeHidden,
|
|
128
|
+
maxDepth,
|
|
129
|
+
maxEntries,
|
|
130
|
+
sortBy,
|
|
131
|
+
includeSymlinkTargets,
|
|
132
|
+
});
|
|
133
|
+
const structured = buildStructuredResult(result);
|
|
134
|
+
const textOutput = buildTextResult(result);
|
|
135
|
+
return buildToolResponse(textOutput, structured);
|
|
136
|
+
}
|
|
137
|
+
export function registerListDirectoryTool(server) {
|
|
138
|
+
server.registerTool('list_directory', LIST_DIRECTORY_TOOL, async (args) => {
|
|
27
139
|
try {
|
|
28
|
-
|
|
29
|
-
recursive,
|
|
30
|
-
includeHidden,
|
|
31
|
-
maxDepth,
|
|
32
|
-
maxEntries,
|
|
33
|
-
sortBy,
|
|
34
|
-
includeSymlinkTargets,
|
|
35
|
-
});
|
|
36
|
-
const structured = {
|
|
37
|
-
ok: true,
|
|
38
|
-
path: result.path,
|
|
39
|
-
entries: result.entries.map((e) => ({
|
|
40
|
-
name: e.relativePath,
|
|
41
|
-
type: e.type,
|
|
42
|
-
extension: getExtension(e.relativePath, e.type === 'file'),
|
|
43
|
-
size: e.size,
|
|
44
|
-
modified: e.modified?.toISOString(),
|
|
45
|
-
symlinkTarget: e.symlinkTarget,
|
|
46
|
-
})),
|
|
47
|
-
summary: {
|
|
48
|
-
totalEntries: result.summary.totalEntries,
|
|
49
|
-
totalFiles: result.summary.totalFiles,
|
|
50
|
-
totalDirectories: result.summary.totalDirectories,
|
|
51
|
-
maxDepthReached: result.summary.maxDepthReached,
|
|
52
|
-
truncated: result.summary.truncated,
|
|
53
|
-
skippedInaccessible: result.summary.skippedInaccessible,
|
|
54
|
-
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
// Build text output with truncation notice for better error recovery feedback
|
|
58
|
-
let textOutput = formatDirectoryListing(result.entries, result.path);
|
|
59
|
-
textOutput += formatOperationSummary({
|
|
60
|
-
truncated: result.summary.truncated,
|
|
61
|
-
truncatedReason: `reached max entries limit (${result.summary.totalEntries} returned)`,
|
|
62
|
-
tip: 'Increase maxEntries or reduce maxDepth to see more results.',
|
|
63
|
-
skippedInaccessible: result.summary.skippedInaccessible,
|
|
64
|
-
symlinksNotFollowed: result.summary.symlinksNotFollowed,
|
|
65
|
-
});
|
|
66
|
-
return {
|
|
67
|
-
content: [{ type: 'text', text: textOutput }],
|
|
68
|
-
structuredContent: structured,
|
|
69
|
-
};
|
|
140
|
+
return await handleListDirectory(args);
|
|
70
141
|
}
|
|
71
142
|
catch (error) {
|
|
72
|
-
return createErrorResponse(error, ErrorCode.E_NOT_DIRECTORY,
|
|
143
|
+
return createErrorResponse(error, ErrorCode.E_NOT_DIRECTORY, args.path);
|
|
73
144
|
}
|
|
74
145
|
});
|
|
75
146
|
}
|