@j0hanz/filesystem-mcp 1.19.0 → 2.0.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 +333 -838
- package/dist/cli-help.d.ts +3 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +169 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +168 -123
- package/dist/cli.js.map +1 -0
- package/dist/core/concurrency.d.ts +70 -0
- package/dist/core/concurrency.d.ts.map +1 -0
- package/dist/core/concurrency.js +173 -0
- package/dist/core/concurrency.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +11 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/cursor.d.ts +23 -0
- package/dist/core/cursor.d.ts.map +1 -0
- package/dist/core/cursor.js +62 -0
- package/dist/core/cursor.js.map +1 -0
- package/dist/core/errors.d.ts +96 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +356 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/file-uri.d.ts +24 -0
- package/dist/core/file-uri.d.ts.map +1 -0
- package/dist/core/file-uri.js +52 -0
- package/dist/core/file-uri.js.map +1 -0
- package/dist/core/fmt.d.ts +38 -0
- package/dist/core/fmt.d.ts.map +1 -0
- package/dist/core/fmt.js +109 -0
- package/dist/core/fmt.js.map +1 -0
- package/dist/core/fs.d.ts +108 -0
- package/dist/core/fs.d.ts.map +1 -0
- package/dist/core/fs.js +243 -0
- package/dist/core/fs.js.map +1 -0
- package/dist/core/glob.d.ts +41 -0
- package/dist/core/glob.d.ts.map +1 -0
- package/dist/core/glob.js +399 -0
- package/dist/core/glob.js.map +1 -0
- package/dist/core/input-required.d.ts +147 -0
- package/dist/core/input-required.d.ts.map +1 -0
- package/dist/core/input-required.js +261 -0
- package/dist/core/input-required.js.map +1 -0
- package/dist/core/mime.d.ts +15 -0
- package/dist/core/mime.d.ts.map +1 -0
- package/dist/core/mime.js +188 -0
- package/dist/core/mime.js.map +1 -0
- package/dist/core/observability.d.ts +10 -0
- package/dist/core/observability.d.ts.map +1 -0
- package/dist/core/observability.js +76 -0
- package/dist/core/observability.js.map +1 -0
- package/dist/core/page-store.d.ts +41 -0
- package/dist/core/page-store.d.ts.map +1 -0
- package/dist/core/page-store.js +74 -0
- package/dist/core/page-store.js.map +1 -0
- package/dist/core/path-completer.d.ts +10 -0
- package/dist/core/path-completer.d.ts.map +1 -0
- package/dist/core/path-completer.js +227 -0
- package/dist/core/path-completer.js.map +1 -0
- package/dist/core/path-discovery.d.ts +8 -0
- package/dist/core/path-discovery.d.ts.map +1 -0
- package/dist/core/path-discovery.js +105 -0
- package/dist/core/path-discovery.js.map +1 -0
- package/dist/core/path-utils.d.ts +9 -0
- package/dist/core/path-utils.d.ts.map +1 -0
- package/dist/core/path-utils.js +121 -0
- package/dist/core/path-utils.js.map +1 -0
- package/dist/core/path.d.ts +148 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/path.js +674 -0
- package/dist/core/path.js.map +1 -0
- package/dist/core/primitives.d.ts +23 -0
- package/dist/core/primitives.d.ts.map +1 -0
- package/dist/core/primitives.js +54 -0
- package/dist/core/primitives.js.map +1 -0
- package/dist/core/read.d.ts +74 -0
- package/dist/core/read.d.ts.map +1 -0
- package/dist/core/read.js +562 -0
- package/dist/core/read.js.map +1 -0
- package/dist/core/schema.d.ts +139 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +345 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/search.d.ts +100 -0
- package/dist/core/search.d.ts.map +1 -0
- package/dist/core/search.js +248 -0
- package/dist/core/search.js.map +1 -0
- package/dist/core/sensitive.d.ts +6 -0
- package/dist/core/sensitive.d.ts.map +1 -0
- package/dist/core/sensitive.js +142 -0
- package/dist/core/sensitive.js.map +1 -0
- package/dist/core/store.d.ts +57 -0
- package/dist/core/store.d.ts.map +1 -0
- package/dist/core/store.js +162 -0
- package/dist/core/store.js.map +1 -0
- package/dist/core/util.d.ts +26 -0
- package/dist/core/util.d.ts.map +1 -0
- package/dist/core/util.js +66 -0
- package/dist/core/util.js.map +1 -0
- package/dist/core/watcher-registry.d.ts +68 -0
- package/dist/core/watcher-registry.d.ts.map +1 -0
- package/dist/core/watcher-registry.js +312 -0
- package/dist/core/watcher-registry.js.map +1 -0
- package/dist/http-policy.d.ts +121 -0
- package/dist/http-policy.d.ts.map +1 -0
- package/dist/http-policy.js +340 -0
- package/dist/http-policy.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +77 -41
- package/dist/index.js.map +1 -0
- package/dist/instructions.d.ts +12 -0
- package/dist/instructions.d.ts.map +1 -0
- package/dist/instructions.js +71 -0
- package/dist/instructions.js.map +1 -0
- package/dist/prompts.d.ts +8 -6
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +74 -168
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +73 -9
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +392 -163
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +62 -1
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +139 -1
- package/dist/server.js.map +1 -0
- package/dist/tools/batch.d.ts +89 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +157 -0
- package/dist/tools/batch.js.map +1 -0
- package/dist/tools/create.d.ts +2 -0
- package/dist/tools/create.d.ts.map +1 -0
- package/dist/tools/create.js +142 -0
- package/dist/tools/create.js.map +1 -0
- package/dist/tools/define.d.ts +110 -0
- package/dist/tools/define.d.ts.map +1 -0
- package/dist/tools/define.js +394 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/delete-file.d.ts +2 -4
- package/dist/tools/delete-file.d.ts.map +1 -0
- package/dist/tools/delete-file.js +330 -87
- package/dist/tools/delete-file.js.map +1 -0
- package/dist/tools/diff.d.ts +2 -0
- package/dist/tools/diff.d.ts.map +1 -0
- package/dist/tools/diff.js +94 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/edit.d.ts +2 -0
- package/dist/tools/edit.d.ts.map +1 -0
- package/dist/tools/edit.js +442 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/index.d.ts +26 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +52 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list.d.ts +2 -0
- package/dist/tools/list.d.ts.map +1 -0
- package/dist/tools/list.js +291 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/move.d.ts +2 -0
- package/dist/tools/move.d.ts.map +1 -0
- package/dist/tools/move.js +321 -0
- package/dist/tools/move.js.map +1 -0
- package/dist/tools/patch.d.ts +2 -0
- package/dist/tools/patch.d.ts.map +1 -0
- package/dist/tools/patch.js +155 -0
- package/dist/tools/patch.js.map +1 -0
- package/dist/tools/progress.d.ts +52 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +172 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/read.d.ts +2 -4
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +398 -152
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/replace-in-files.d.ts +2 -4
- package/dist/tools/replace-in-files.d.ts.map +1 -0
- package/dist/tools/replace-in-files.js +435 -264
- package/dist/tools/replace-in-files.js.map +1 -0
- package/dist/tools/roots.d.ts +2 -4
- package/dist/tools/roots.d.ts.map +1 -0
- package/dist/tools/roots.js +29 -52
- package/dist/tools/roots.js.map +1 -0
- package/dist/tools/search-content.d.ts +2 -4
- package/dist/tools/search-content.d.ts.map +1 -0
- package/dist/tools/search-content.js +262 -228
- package/dist/tools/search-content.js.map +1 -0
- package/dist/tools/search-files.d.ts +2 -4
- package/dist/tools/search-files.d.ts.map +1 -0
- package/dist/tools/search-files.js +162 -161
- package/dist/tools/search-files.js.map +1 -0
- package/dist/tools/stat.d.ts +2 -4
- package/dist/tools/stat.d.ts.map +1 -0
- package/dist/tools/stat.js +202 -62
- package/dist/tools/stat.js.map +1 -0
- package/dist/transport/http.d.ts +5 -0
- package/dist/transport/http.d.ts.map +1 -0
- package/dist/transport/http.js +276 -0
- package/dist/transport/http.js.map +1 -0
- package/dist/transport/shared.d.ts +45 -0
- package/dist/transport/shared.d.ts.map +1 -0
- package/dist/transport/shared.js +65 -0
- package/dist/transport/shared.js.map +1 -0
- package/dist/transport/stdio.d.ts +32 -0
- package/dist/transport/stdio.d.ts.map +1 -0
- package/dist/transport/stdio.js +279 -0
- package/dist/transport/stdio.js.map +1 -0
- package/dist/transport.d.ts +5 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +4 -0
- package/dist/transport.js.map +1 -0
- package/package.json +37 -46
- package/dist/assets/logo.svg +0 -35
- package/dist/completions.d.ts +0 -2
- package/dist/completions.js +0 -572
- package/dist/config.d.ts +0 -119
- package/dist/config.js +0 -31
- package/dist/lib/abort.d.ts +0 -7
- package/dist/lib/abort.js +0 -81
- package/dist/lib/constants.d.ts +0 -42
- package/dist/lib/constants.js +0 -313
- package/dist/lib/errors.d.ts +0 -28
- package/dist/lib/errors.js +0 -301
- package/dist/lib/file-operations/core.d.ts +0 -53
- package/dist/lib/file-operations/core.js +0 -144
- package/dist/lib/file-operations/metadata.d.ts +0 -77
- package/dist/lib/file-operations/metadata.js +0 -878
- package/dist/lib/file-operations/search.d.ts +0 -46
- package/dist/lib/file-operations/search.js +0 -1194
- package/dist/lib/file-operations/traversal.d.ts +0 -40
- package/dist/lib/file-operations/traversal.js +0 -310
- package/dist/lib/fs-helpers.d.ts +0 -46
- package/dist/lib/fs-helpers.js +0 -606
- package/dist/lib/globs.d.ts +0 -2
- package/dist/lib/globs.js +0 -19
- package/dist/lib/logger.d.ts +0 -27
- package/dist/lib/logger.js +0 -91
- package/dist/lib/observability.d.ts +0 -33
- package/dist/lib/observability.js +0 -373
- package/dist/lib/paths.d.ts +0 -35
- package/dist/lib/paths.js +0 -634
- package/dist/lib/resource-store.d.ts +0 -28
- package/dist/lib/resource-store.js +0 -195
- package/dist/lib/utils.d.ts +0 -7
- package/dist/lib/utils.js +0 -37
- package/dist/lib/zod-codecs.d.ts +0 -2
- package/dist/lib/zod-codecs.js +0 -18
- package/dist/pkg-info.d.ts +0 -7
- package/dist/pkg-info.js +0 -9
- package/dist/resources/generated-instructions.d.ts +0 -1
- package/dist/resources/generated-instructions.js +0 -105
- package/dist/resources/tool-catalog.d.ts +0 -2
- package/dist/resources/tool-catalog.js +0 -78
- package/dist/resources/tool-info.d.ts +0 -9
- package/dist/resources/tool-info.js +0 -206
- package/dist/resources/workflows.d.ts +0 -1
- package/dist/resources/workflows.js +0 -72
- package/dist/schemas.d.ts +0 -505
- package/dist/schemas.js +0 -676
- package/dist/server/bootstrap.d.ts +0 -6
- package/dist/server/bootstrap.js +0 -563
- package/dist/server/event-store.d.ts +0 -18
- package/dist/server/event-store.js +0 -71
- package/dist/server/roots-manager.d.ts +0 -28
- package/dist/server/roots-manager.js +0 -227
- package/dist/server/task-store.d.ts +0 -10
- package/dist/server/task-store.js +0 -91
- package/dist/tools/apply-patch.d.ts +0 -4
- package/dist/tools/apply-patch.js +0 -235
- package/dist/tools/calculate-hash.d.ts +0 -4
- package/dist/tools/calculate-hash.js +0 -187
- package/dist/tools/contract.d.ts +0 -50
- package/dist/tools/contract.js +0 -1
- package/dist/tools/create-directory.d.ts +0 -4
- package/dist/tools/create-directory.js +0 -68
- package/dist/tools/diff-files.d.ts +0 -4
- package/dist/tools/diff-files.js +0 -136
- package/dist/tools/edit-file.d.ts +0 -4
- package/dist/tools/edit-file.js +0 -256
- package/dist/tools/icons.d.ts +0 -15
- package/dist/tools/icons.js +0 -24
- package/dist/tools/list-directory.d.ts +0 -4
- package/dist/tools/list-directory.js +0 -218
- package/dist/tools/move-file.d.ts +0 -4
- package/dist/tools/move-file.js +0 -178
- package/dist/tools/read-multiple.d.ts +0 -4
- package/dist/tools/read-multiple.js +0 -207
- package/dist/tools/shared.d.ts +0 -172
- package/dist/tools/shared.js +0 -599
- package/dist/tools/stat-many.d.ts +0 -4
- package/dist/tools/stat-many.js +0 -104
- package/dist/tools/task-support.d.ts +0 -29
- package/dist/tools/task-support.js +0 -472
- package/dist/tools/tree.d.ts +0 -4
- package/dist/tools/tree.js +0 -102
- package/dist/tools/write-file.d.ts +0 -4
- package/dist/tools/write-file.js +0 -60
- package/dist/tools.d.ts +0 -5
- package/dist/tools.js +0 -54
package/dist/lib/logger.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { channel } from 'node:diagnostics_channel';
|
|
3
|
-
export const SessionContext = new AsyncLocalStorage();
|
|
4
|
-
const LOG_CHANNEL = channel('filesystem-mcp:log');
|
|
5
|
-
const MCP_LOGGER_NAME = 'filesystem-mcp';
|
|
6
|
-
const LOG_LEVEL_ORDER = {
|
|
7
|
-
debug: 0,
|
|
8
|
-
info: 1,
|
|
9
|
-
notice: 2,
|
|
10
|
-
warning: 3,
|
|
11
|
-
error: 4,
|
|
12
|
-
critical: 5,
|
|
13
|
-
alert: 6,
|
|
14
|
-
emergency: 7,
|
|
15
|
-
};
|
|
16
|
-
export function createLoggingState(minimumLevel = 'debug') {
|
|
17
|
-
return { minimumLevel };
|
|
18
|
-
}
|
|
19
|
-
function canSendMcpLogs(server) {
|
|
20
|
-
const capabilities = server.server.getClientCapabilities();
|
|
21
|
-
if (!capabilities || typeof capabilities !== 'object')
|
|
22
|
-
return false;
|
|
23
|
-
return 'logging' in capabilities && Boolean(capabilities.logging);
|
|
24
|
-
}
|
|
25
|
-
export function logToMcp(server, level, data, minLevel = 'debug') {
|
|
26
|
-
if (LOG_LEVEL_ORDER[level] < LOG_LEVEL_ORDER[minLevel]) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
if (!server || !canSendMcpLogs(server)) {
|
|
30
|
-
console.error(`[${level.toUpperCase()}] ${data}`);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
const params = {
|
|
34
|
-
level,
|
|
35
|
-
logger: MCP_LOGGER_NAME,
|
|
36
|
-
data,
|
|
37
|
-
};
|
|
38
|
-
void server.sendLoggingMessage(params).catch((error) => {
|
|
39
|
-
console.error(`Failed to send MCP log: ${level} | ${data}`, formatTransportError(error));
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
function formatTransportError(error) {
|
|
43
|
-
if (error instanceof Error)
|
|
44
|
-
return error.message;
|
|
45
|
-
if (typeof error === 'string')
|
|
46
|
-
return error;
|
|
47
|
-
try {
|
|
48
|
-
return JSON.stringify(error);
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
51
|
-
return String(error);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
export const Logger = {
|
|
55
|
-
emit(level, message, data) {
|
|
56
|
-
const session = SessionContext.getStore();
|
|
57
|
-
const event = {
|
|
58
|
-
level,
|
|
59
|
-
message,
|
|
60
|
-
...(data !== undefined ? { data } : {}),
|
|
61
|
-
...(session?.sessionId !== undefined
|
|
62
|
-
? { sessionId: session.sessionId }
|
|
63
|
-
: {}),
|
|
64
|
-
};
|
|
65
|
-
if (LOG_CHANNEL.hasSubscribers) {
|
|
66
|
-
LOG_CHANNEL.publish(event);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
// Fallback if no subscribers
|
|
70
|
-
console.error(`[${level.toUpperCase()}] ${message}`, data ?? '');
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
debug(message, data) {
|
|
74
|
-
this.emit('debug', message, data);
|
|
75
|
-
},
|
|
76
|
-
info(message, data) {
|
|
77
|
-
this.emit('info', message, data);
|
|
78
|
-
},
|
|
79
|
-
notice(message, data) {
|
|
80
|
-
this.emit('notice', message, data);
|
|
81
|
-
},
|
|
82
|
-
warn(message, data) {
|
|
83
|
-
this.emit('warning', message, data);
|
|
84
|
-
},
|
|
85
|
-
error(message, data) {
|
|
86
|
-
this.emit('error', message, data);
|
|
87
|
-
},
|
|
88
|
-
critical(message, data) {
|
|
89
|
-
this.emit('critical', message, data);
|
|
90
|
-
},
|
|
91
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
interface OpsTraceContext {
|
|
2
|
-
op: string;
|
|
3
|
-
engine?: string;
|
|
4
|
-
tool?: string;
|
|
5
|
-
path?: string | undefined;
|
|
6
|
-
[key: string]: unknown;
|
|
7
|
-
}
|
|
8
|
-
export interface TraceContext {
|
|
9
|
-
traceparent: string;
|
|
10
|
-
tracestate?: string;
|
|
11
|
-
baggage?: string;
|
|
12
|
-
}
|
|
13
|
-
interface ToolMetrics {
|
|
14
|
-
calls: number;
|
|
15
|
-
errors: number;
|
|
16
|
-
totalDurationMs: number;
|
|
17
|
-
}
|
|
18
|
-
export declare const globalMetrics: Map<string, ToolMetrics>;
|
|
19
|
-
export declare function shouldPublishOpsTrace(): boolean;
|
|
20
|
-
export declare function publishOpsTraceStart(context: OpsTraceContext): void;
|
|
21
|
-
export declare function publishOpsTraceEnd(context: OpsTraceContext): void;
|
|
22
|
-
export declare function publishOpsTraceError(context: OpsTraceContext, error: unknown): void;
|
|
23
|
-
export declare function getToolContextSnapshot(): {
|
|
24
|
-
tool: string;
|
|
25
|
-
path?: string;
|
|
26
|
-
} | undefined;
|
|
27
|
-
export declare function getTraceContext(): TraceContext | undefined;
|
|
28
|
-
export declare function startPerfMeasure(name: string, detail?: Record<string, unknown>): ((ok?: boolean) => void) | undefined;
|
|
29
|
-
export declare function withToolDiagnostics<T>(tool: string, run: () => Promise<T>, options?: {
|
|
30
|
-
path?: string;
|
|
31
|
-
traceContext?: TraceContext;
|
|
32
|
-
}): Promise<T>;
|
|
33
|
-
export {};
|
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { hash } from 'node:crypto';
|
|
3
|
-
import { channel, tracingChannel } from 'node:diagnostics_channel';
|
|
4
|
-
import { monitorEventLoopDelay, performance, PerformanceObserver, } from 'node:perf_hooks';
|
|
5
|
-
import { parseTrueEnvFlag } from './constants.js';
|
|
6
|
-
import { Logger } from './logger.js';
|
|
7
|
-
import { isRecord } from './utils.js';
|
|
8
|
-
// --- Configuration ---
|
|
9
|
-
const ENV = process.env;
|
|
10
|
-
let _cachedConfig;
|
|
11
|
-
function readConfig() {
|
|
12
|
-
_cachedConfig ??= {
|
|
13
|
-
enabled: parseTrueEnvFlag(ENV['FS_CONTEXT_DIAGNOSTICS']),
|
|
14
|
-
detail: parseDetail(ENV['FS_CONTEXT_DIAGNOSTICS_DETAIL']),
|
|
15
|
-
logToolErrors: parseTrueEnvFlag(ENV['FS_CONTEXT_TOOL_LOG_ERRORS']),
|
|
16
|
-
};
|
|
17
|
-
return _cachedConfig;
|
|
18
|
-
}
|
|
19
|
-
function parseDetail(val) {
|
|
20
|
-
if (val === '2')
|
|
21
|
-
return 2;
|
|
22
|
-
if (val === '1')
|
|
23
|
-
return 1;
|
|
24
|
-
return 0;
|
|
25
|
-
}
|
|
26
|
-
export const globalMetrics = new Map();
|
|
27
|
-
function updateMetrics(tool, ok, durationMs) {
|
|
28
|
-
const current = globalMetrics.get(tool) ?? {
|
|
29
|
-
calls: 0,
|
|
30
|
-
errors: 0,
|
|
31
|
-
totalDurationMs: 0,
|
|
32
|
-
};
|
|
33
|
-
current.calls++;
|
|
34
|
-
if (!ok)
|
|
35
|
-
current.errors++;
|
|
36
|
-
current.totalDurationMs += durationMs;
|
|
37
|
-
globalMetrics.set(tool, current);
|
|
38
|
-
}
|
|
39
|
-
// --- Channels & Observability State ---
|
|
40
|
-
const CHANNELS = {
|
|
41
|
-
tool: channel('filesystem-mcp:tool'),
|
|
42
|
-
perf: channel('filesystem-mcp:perf'),
|
|
43
|
-
ops: tracingChannel('filesystem-mcp:ops'),
|
|
44
|
-
};
|
|
45
|
-
const toolContext = new AsyncLocalStorage({
|
|
46
|
-
name: 'filesystem-mcp:tool',
|
|
47
|
-
});
|
|
48
|
-
let perfObserver;
|
|
49
|
-
let traceCounter = 0;
|
|
50
|
-
// --- Helpers: Result Analysis ---
|
|
51
|
-
function extractOutcome(result) {
|
|
52
|
-
if (!isRecord(result)) {
|
|
53
|
-
return { ok: true };
|
|
54
|
-
}
|
|
55
|
-
if (result['isError'] === true) {
|
|
56
|
-
const err = extractErrorMessage(result);
|
|
57
|
-
return { ok: false, error: err };
|
|
58
|
-
}
|
|
59
|
-
if (typeof result['ok'] === 'boolean') {
|
|
60
|
-
if (result['ok'])
|
|
61
|
-
return { ok: true };
|
|
62
|
-
return { ok: false, error: extractErrorMessage(result) };
|
|
63
|
-
}
|
|
64
|
-
const content = result['structuredContent'];
|
|
65
|
-
if (isRecord(content) && typeof content['ok'] === 'boolean') {
|
|
66
|
-
if (content['ok'])
|
|
67
|
-
return { ok: true };
|
|
68
|
-
const err = extractResultError(content);
|
|
69
|
-
return err ? { ok: false, error: err } : { ok: false };
|
|
70
|
-
}
|
|
71
|
-
return { ok: true };
|
|
72
|
-
}
|
|
73
|
-
function extractErrorMessage(source) {
|
|
74
|
-
if (typeof source === 'string')
|
|
75
|
-
return source;
|
|
76
|
-
if (source instanceof Error)
|
|
77
|
-
return source.message;
|
|
78
|
-
if (isRecord(source)) {
|
|
79
|
-
const struct = source['structuredContent'];
|
|
80
|
-
if (isRecord(struct)) {
|
|
81
|
-
const err = struct['error'];
|
|
82
|
-
if (isRecord(err) && typeof err['message'] === 'string')
|
|
83
|
-
return err['message'];
|
|
84
|
-
}
|
|
85
|
-
if (typeof source['message'] === 'string')
|
|
86
|
-
return source['message'];
|
|
87
|
-
const errObj = source['error'];
|
|
88
|
-
if (isRecord(errObj) && typeof errObj['message'] === 'string') {
|
|
89
|
-
return errObj['message'];
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
try {
|
|
93
|
-
return String(source);
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
return 'Unknown error';
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function extractResultError(structured) {
|
|
100
|
-
const err = structured['error'];
|
|
101
|
-
return isRecord(err) && typeof err['message'] === 'string'
|
|
102
|
-
? err['message']
|
|
103
|
-
: undefined;
|
|
104
|
-
}
|
|
105
|
-
function sanitizePathForDiagnostics(path) {
|
|
106
|
-
const { detail } = readConfig();
|
|
107
|
-
if (!path || detail === 0)
|
|
108
|
-
return undefined;
|
|
109
|
-
if (detail === 2)
|
|
110
|
-
return path;
|
|
111
|
-
return hash('sha256', path, 'hex').slice(0, 16);
|
|
112
|
-
}
|
|
113
|
-
function enrichWithToolContext(detail) {
|
|
114
|
-
const current = toolContext.getStore();
|
|
115
|
-
if (!current)
|
|
116
|
-
return detail;
|
|
117
|
-
const merged = { ...(detail ?? {}) };
|
|
118
|
-
if (!Object.hasOwn(merged, 'tool')) {
|
|
119
|
-
merged.tool = current.tool;
|
|
120
|
-
}
|
|
121
|
-
const normalizedPath = sanitizePathForDiagnostics(current.path);
|
|
122
|
-
if (normalizedPath && !Object.hasOwn(merged, 'path')) {
|
|
123
|
-
merged.path = normalizedPath;
|
|
124
|
-
}
|
|
125
|
-
return merged;
|
|
126
|
-
}
|
|
127
|
-
// --- Perf Helpers ---
|
|
128
|
-
function toMs(nanos) {
|
|
129
|
-
return nanos / 1_000_000;
|
|
130
|
-
}
|
|
131
|
-
function getDelayStats(h) {
|
|
132
|
-
if (h.count === 0)
|
|
133
|
-
return undefined;
|
|
134
|
-
return {
|
|
135
|
-
min: toMs(h.min),
|
|
136
|
-
max: toMs(h.max),
|
|
137
|
-
mean: toMs(h.mean),
|
|
138
|
-
p50: toMs(h.percentile(50)),
|
|
139
|
-
p95: toMs(h.percentile(95)),
|
|
140
|
-
p99: toMs(h.percentile(99)),
|
|
141
|
-
exceeds: h.exceeds,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
function clearPublishedMeasures(entries) {
|
|
145
|
-
if (entries.length === 0)
|
|
146
|
-
return;
|
|
147
|
-
const names = new Set();
|
|
148
|
-
for (const entry of entries) {
|
|
149
|
-
names.add(entry.name);
|
|
150
|
-
}
|
|
151
|
-
for (const name of names) {
|
|
152
|
-
performance.clearMeasures(name);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
function ensureObserver() {
|
|
156
|
-
if (perfObserver)
|
|
157
|
-
return;
|
|
158
|
-
perfObserver = new PerformanceObserver((list) => {
|
|
159
|
-
const entries = list.getEntries();
|
|
160
|
-
for (const entry of entries) {
|
|
161
|
-
CHANNELS.perf.publish({
|
|
162
|
-
phase: 'measure',
|
|
163
|
-
name: entry.name,
|
|
164
|
-
durationMs: entry.duration,
|
|
165
|
-
detail: entry.detail,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
try {
|
|
169
|
-
// Keep the global timeline bounded while preserving published events.
|
|
170
|
-
clearPublishedMeasures(entries);
|
|
171
|
-
}
|
|
172
|
-
catch {
|
|
173
|
-
// Never allow observability cleanup to affect tool execution.
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
perfObserver.observe({ entryTypes: ['measure'] });
|
|
177
|
-
}
|
|
178
|
-
// --- Public API ---
|
|
179
|
-
export function shouldPublishOpsTrace() {
|
|
180
|
-
return readConfig().enabled && CHANNELS.ops.hasSubscribers;
|
|
181
|
-
}
|
|
182
|
-
export function publishOpsTraceStart(context) {
|
|
183
|
-
CHANNELS.ops.start.publish(normalizeContext(applyToolContext(context)));
|
|
184
|
-
}
|
|
185
|
-
export function publishOpsTraceEnd(context) {
|
|
186
|
-
CHANNELS.ops.end.publish(normalizeContext(applyToolContext(context)));
|
|
187
|
-
}
|
|
188
|
-
export function publishOpsTraceError(context, error) {
|
|
189
|
-
CHANNELS.ops.error.publish({
|
|
190
|
-
...normalizeContext(applyToolContext(context)),
|
|
191
|
-
error,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
function applyToolContext(context) {
|
|
195
|
-
const current = toolContext.getStore();
|
|
196
|
-
if (!current)
|
|
197
|
-
return context;
|
|
198
|
-
const merged = { ...context };
|
|
199
|
-
merged.tool ??= current.tool;
|
|
200
|
-
merged.path ??= current.path;
|
|
201
|
-
return merged;
|
|
202
|
-
}
|
|
203
|
-
export function getToolContextSnapshot() {
|
|
204
|
-
return toolContext.getStore();
|
|
205
|
-
}
|
|
206
|
-
export function getTraceContext() {
|
|
207
|
-
return toolContext.getStore()?.traceContext;
|
|
208
|
-
}
|
|
209
|
-
function normalizeContext(ctx) {
|
|
210
|
-
if (!ctx.path)
|
|
211
|
-
return ctx;
|
|
212
|
-
const normalized = sanitizePathForDiagnostics(ctx.path);
|
|
213
|
-
if (!normalized) {
|
|
214
|
-
const copy = { ...ctx };
|
|
215
|
-
delete copy.path;
|
|
216
|
-
return copy;
|
|
217
|
-
}
|
|
218
|
-
return { ...ctx, path: normalized };
|
|
219
|
-
}
|
|
220
|
-
function clearMeasureMarks(startMark, endMark) {
|
|
221
|
-
performance.clearMarks(startMark);
|
|
222
|
-
performance.clearMarks(endMark);
|
|
223
|
-
}
|
|
224
|
-
export function startPerfMeasure(name, detail) {
|
|
225
|
-
if (!readConfig().enabled || !CHANNELS.perf.hasSubscribers)
|
|
226
|
-
return undefined;
|
|
227
|
-
ensureObserver();
|
|
228
|
-
const id = ++traceCounter;
|
|
229
|
-
const startMark = `${name}:start:${id}`;
|
|
230
|
-
const endMark = `${name}:end:${id}`;
|
|
231
|
-
const runInCapturedContext = AsyncLocalStorage.snapshot();
|
|
232
|
-
let finished = false;
|
|
233
|
-
performance.mark(startMark);
|
|
234
|
-
return (ok) => {
|
|
235
|
-
if (finished)
|
|
236
|
-
return;
|
|
237
|
-
finished = true;
|
|
238
|
-
try {
|
|
239
|
-
runInCapturedContext(() => {
|
|
240
|
-
try {
|
|
241
|
-
performance.mark(endMark);
|
|
242
|
-
let meta = enrichWithToolContext(detail);
|
|
243
|
-
if (ok !== undefined) {
|
|
244
|
-
meta = { ...(meta ?? {}), ok };
|
|
245
|
-
}
|
|
246
|
-
performance.measure(name, {
|
|
247
|
-
start: startMark,
|
|
248
|
-
end: endMark,
|
|
249
|
-
detail: meta,
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
finally {
|
|
253
|
-
clearMeasureMarks(startMark, endMark);
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
catch {
|
|
258
|
-
clearMeasureMarks(startMark, endMark);
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
function publishToolStart(tool, pathVal, traceparent) {
|
|
263
|
-
const event = { phase: 'start', tool };
|
|
264
|
-
if (pathVal)
|
|
265
|
-
event.path = pathVal;
|
|
266
|
-
if (traceparent)
|
|
267
|
-
event.traceparent = traceparent;
|
|
268
|
-
CHANNELS.tool.publish(event);
|
|
269
|
-
}
|
|
270
|
-
function publishToolEnd(tool, ok, durationMs, errorMsg, traceparent) {
|
|
271
|
-
const event = { phase: 'end', tool, ok, durationMs };
|
|
272
|
-
if (errorMsg)
|
|
273
|
-
event.error = errorMsg;
|
|
274
|
-
if (traceparent)
|
|
275
|
-
event.traceparent = traceparent;
|
|
276
|
-
CHANNELS.tool.publish(event);
|
|
277
|
-
}
|
|
278
|
-
function publishPerfEnd(tool, durationMs, eluStart, loopMonitor) {
|
|
279
|
-
const elu = performance.eventLoopUtilization(eluStart);
|
|
280
|
-
const event = {
|
|
281
|
-
phase: 'end',
|
|
282
|
-
tool,
|
|
283
|
-
durationMs,
|
|
284
|
-
elu: { idle: elu.idle, active: elu.active, utilization: elu.utilization },
|
|
285
|
-
};
|
|
286
|
-
if (loopMonitor) {
|
|
287
|
-
const delays = getDelayStats(loopMonitor);
|
|
288
|
-
if (delays)
|
|
289
|
-
event.eventLoopDelay = delays;
|
|
290
|
-
}
|
|
291
|
-
CHANNELS.perf.publish(event);
|
|
292
|
-
}
|
|
293
|
-
async function runAndObserve(tool, run, pubTool, pubPerf, logErrors, pathVal, traceparent) {
|
|
294
|
-
const startMs = performance.now();
|
|
295
|
-
const eluStart = pubPerf ? performance.eventLoopUtilization() : undefined;
|
|
296
|
-
const loopMonitor = pubPerf ? monitorEventLoopDelay() : undefined;
|
|
297
|
-
loopMonitor?.enable();
|
|
298
|
-
if (pubTool)
|
|
299
|
-
publishToolStart(tool, pathVal, traceparent);
|
|
300
|
-
let result;
|
|
301
|
-
const obs = { ok: false, errorMsg: undefined };
|
|
302
|
-
try {
|
|
303
|
-
result = await run();
|
|
304
|
-
const { ok, error } = extractOutcome(result);
|
|
305
|
-
obs.ok = ok;
|
|
306
|
-
obs.errorMsg = error;
|
|
307
|
-
}
|
|
308
|
-
catch (err) {
|
|
309
|
-
obs.errorMsg = extractErrorMessage(err);
|
|
310
|
-
throw err;
|
|
311
|
-
}
|
|
312
|
-
finally {
|
|
313
|
-
const durationMs = performance.now() - startMs;
|
|
314
|
-
loopMonitor?.disable();
|
|
315
|
-
if (pubPerf && eluStart)
|
|
316
|
-
publishPerfEnd(tool, durationMs, eluStart, loopMonitor);
|
|
317
|
-
if (pubTool)
|
|
318
|
-
publishToolEnd(tool, obs.ok, durationMs, obs.errorMsg, traceparent);
|
|
319
|
-
updateMetrics(tool, obs.ok, durationMs);
|
|
320
|
-
if (logErrors && !obs.ok)
|
|
321
|
-
logError(tool, durationMs, obs.errorMsg);
|
|
322
|
-
}
|
|
323
|
-
return result;
|
|
324
|
-
}
|
|
325
|
-
export async function withToolDiagnostics(tool, run, options) {
|
|
326
|
-
const config = readConfig();
|
|
327
|
-
const normalizedPath = sanitizePathForDiagnostics(options?.path);
|
|
328
|
-
const context = {
|
|
329
|
-
tool,
|
|
330
|
-
...(options?.path ? { path: options.path } : {}),
|
|
331
|
-
...(options?.traceContext ? { traceContext: options.traceContext } : {}),
|
|
332
|
-
};
|
|
333
|
-
return toolContext.run(context, async () => {
|
|
334
|
-
if (!config.enabled) {
|
|
335
|
-
if (!config.logToolErrors)
|
|
336
|
-
return run();
|
|
337
|
-
const start = performance.now();
|
|
338
|
-
try {
|
|
339
|
-
const res = await run();
|
|
340
|
-
const { ok, error } = extractOutcome(res);
|
|
341
|
-
if (!ok)
|
|
342
|
-
logError(tool, performance.now() - start, error);
|
|
343
|
-
return res;
|
|
344
|
-
}
|
|
345
|
-
catch (e) {
|
|
346
|
-
logError(tool, performance.now() - start, extractErrorMessage(e));
|
|
347
|
-
throw e;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
const pubTool = CHANNELS.tool.hasSubscribers;
|
|
351
|
-
const pubPerf = CHANNELS.perf.hasSubscribers;
|
|
352
|
-
if (!pubTool && !pubPerf) {
|
|
353
|
-
const start = performance.now();
|
|
354
|
-
try {
|
|
355
|
-
const res = await run();
|
|
356
|
-
const duration = performance.now() - start;
|
|
357
|
-
const { ok } = extractOutcome(res);
|
|
358
|
-
updateMetrics(tool, ok, duration);
|
|
359
|
-
return res;
|
|
360
|
-
}
|
|
361
|
-
catch (e) {
|
|
362
|
-
const duration = performance.now() - start;
|
|
363
|
-
updateMetrics(tool, false, duration);
|
|
364
|
-
throw e;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
return runAndObserve(tool, run, pubTool, pubPerf, config.logToolErrors, normalizedPath, options?.traceContext?.traceparent);
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
function logError(tool, durationMs, msg) {
|
|
371
|
-
const suffix = msg ? `: ${msg}` : '';
|
|
372
|
-
Logger.error(`[ToolError] ${tool} failed in ${durationMs.toFixed(1)}ms${suffix}`);
|
|
373
|
-
}
|
package/dist/lib/paths.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { Root } from '@modelcontextprotocol/server';
|
|
2
|
-
export declare function toPosixPath(value: string): string;
|
|
3
|
-
export declare function isSensitivePath(requestedPath: string, resolvedPath?: string): boolean;
|
|
4
|
-
export declare function assertAllowedFileAccess(requestedPath: string, resolvedPath?: string): void;
|
|
5
|
-
export interface AllowedDirectoriesState {
|
|
6
|
-
primary: string[];
|
|
7
|
-
expanded: string[];
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Normalizes any path-like input to an absolute path suitable for comparisons.
|
|
11
|
-
* - Expands "~" home directory shorthand.
|
|
12
|
-
* - Resolves against process CWD if relative.
|
|
13
|
-
* - Lowercases Windows drive letter for stable comparisons.
|
|
14
|
-
*/
|
|
15
|
-
export declare function normalizePath(p: string): string;
|
|
16
|
-
export declare function withAllowedDirectoriesState<T>(state: AllowedDirectoriesState, run: () => T): T;
|
|
17
|
-
export declare function setAllowedDirectoriesStateResolved(state: AllowedDirectoriesState): void;
|
|
18
|
-
export declare function getAllowedDirectories(): string[];
|
|
19
|
-
export declare function isAllowedDirectoryRoot(normalizedPath: string): boolean;
|
|
20
|
-
export declare function isPathWithinDirectories(normalizedPath: string, allowedDirs: readonly string[]): boolean;
|
|
21
|
-
export declare function resolveAllowedDirectoriesState(dirs: readonly string[], signal?: AbortSignal): Promise<AllowedDirectoriesState>;
|
|
22
|
-
export declare function setAllowedDirectoriesResolved(dirs: readonly string[], signal?: AbortSignal): Promise<void>;
|
|
23
|
-
export declare function getReservedDeviceNameForPath(requestedPath: string): string | undefined;
|
|
24
|
-
export declare function isWindowsDriveRelativePath(requestedPath: string): boolean;
|
|
25
|
-
interface ValidatedPathDetails {
|
|
26
|
-
requestedPath: string;
|
|
27
|
-
resolvedPath: string;
|
|
28
|
-
isSymlink: boolean;
|
|
29
|
-
}
|
|
30
|
-
export declare function validateExistingPathDetailed(requestedPath: string, signal?: AbortSignal): Promise<ValidatedPathDetails>;
|
|
31
|
-
export declare function validateExistingPath(requestedPath: string, signal?: AbortSignal): Promise<string>;
|
|
32
|
-
export declare function validateExistingDirectory(requestedPath: string, signal?: AbortSignal): Promise<string>;
|
|
33
|
-
export declare function validatePathForWrite(requestedPath: string, signal?: AbortSignal): Promise<string>;
|
|
34
|
-
export declare function getValidRootDirectories(roots: Root[], signal?: AbortSignal): Promise<string[]>;
|
|
35
|
-
export {};
|