@j0hanz/filesystem-mcp 1.17.1 → 1.19.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.
@@ -1,13 +1,12 @@
1
1
  import { basename } from 'node:path';
2
2
  import { DEFAULT_SEARCH_TIMEOUT_MS } from '../lib/constants.js';
3
- import { ErrorCode } from '../lib/errors.js';
3
+ import { classifyError, ErrorCode } from '../lib/errors.js';
4
4
  import { readMultipleFiles } from '../lib/file-operations/metadata.js';
5
5
  import { ReadMultipleFilesInputSchema, ReadMultipleFilesOutputSchema, } from '../schemas.js';
6
6
  import { FILE_READ_ICONS } from './icons.js';
7
- import { buildBatchCompletionSuffix, buildBatchPathContext, buildResourceLink, buildStructuredError, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, maybeExternalizeTextContent, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, } from './shared.js';
8
- import { registerStandardTool } from './task-support.js';
7
+ import { buildBatchPathContext, buildResourceLink, buildStructuredError, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, maybeExternalizeTextContent, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, } from './shared.js';
8
+ import { registerStandardTool, reportTaskStatus } from './task-support.js';
9
9
  const READ_MANY_TOOL_NAME = 'read_many';
10
- const READ_MANY_TOOL_LABEL = '🕮 read_many';
11
10
  const FULL_FILE_CONTENTS_DESCRIPTION = 'Full file contents';
12
11
  export const READ_MANY_TOOL = {
13
12
  name: READ_MANY_TOOL_NAME,
@@ -20,6 +19,7 @@ export const READ_MANY_TOOL = {
20
19
  icons: FILE_READ_ICONS,
21
20
  taskSupport: 'optional',
22
21
  };
22
+ const READ_MANY_TOOL_LABEL = READ_MANY_TOOL.title;
23
23
  function buildReadManyResourceName(filePath) {
24
24
  return `read:${basename(filePath)}`;
25
25
  }
@@ -173,23 +173,30 @@ export function registerReadMultipleFilesTool(server, options = {}) {
173
173
  context: { path: primaryPath },
174
174
  run: async (signal) => {
175
175
  const context = buildBatchPathContext(args.paths, 'files');
176
- const { progress, onItemComplete } = createBatchProgressCallbacks(ctx, {
176
+ const { progress, onItemComplete: rawOnItemComplete } = createBatchProgressCallbacks(ctx, {
177
177
  toolLabel: READ_MANY_TOOL_LABEL,
178
178
  context,
179
179
  totalItems: args.paths.length,
180
180
  itemVerb: 'read',
181
181
  });
182
+ let itemsDone = 0;
183
+ const onItemComplete = () => {
184
+ rawOnItemComplete();
185
+ itemsDone++;
186
+ void reportTaskStatus(`${READ_MANY_TOOL_LABEL}: ${context} [${itemsDone}/${args.paths.length} read]`);
187
+ };
182
188
  try {
183
189
  const result = await handleReadMultipleFiles(args, signal, options.resourceStore, onItemComplete);
184
190
  const sc = result.structuredContent;
185
- const suffix = buildBatchCompletionSuffix(sc.summary, 'files read', 'file read');
186
191
  const total = sc.summary?.total ?? 0;
192
+ const failed = sc.summary?.failed ?? 0;
193
+ const suffix = failed ? `${failed} failed` : 'done';
187
194
  const finalCurrent = resolveFinalProgressCurrent(progress, total);
188
195
  progress.complete(`${READ_MANY_TOOL_LABEL}: ${context} • ${suffix}`, finalCurrent);
189
196
  return result;
190
197
  }
191
198
  catch (error) {
192
- progress.fail(`${READ_MANY_TOOL_LABEL}: ${context} • failed`);
199
+ progress.fail(`${READ_MANY_TOOL_LABEL}: ${context} • ${classifyError(error)}`);
193
200
  throw error;
194
201
  }
195
202
  },
@@ -22,7 +22,7 @@ export const READ_FILE_TOOL = {
22
22
  taskSupport: 'forbidden',
23
23
  };
24
24
  const READ_TOOL_NAME = 'read';
25
- const READ_TOOL_LABEL = '🕮 read';
25
+ const READ_TOOL_LABEL = READ_FILE_TOOL.title;
26
26
  const FULL_FILE_CONTENTS_DESCRIPTION = 'Full file contents';
27
27
  function buildReadResourceName(filePath) {
28
28
  return `read:${basename(filePath)}`;
@@ -114,7 +114,7 @@ function buildReadProgressMessage(args) {
114
114
  function buildReadCompletionMessage(args, result) {
115
115
  const name = basename(args.path);
116
116
  if (result.isError)
117
- return `${READ_TOOL_LABEL}: ${name} • failed`;
117
+ return `${READ_TOOL_LABEL}: ${name} • ${result.errorCode}`;
118
118
  const structured = result.structuredContent;
119
119
  const lines = structured.linesRead ?? structured.totalLines;
120
120
  if (structured.startLine !== undefined) {
@@ -4,7 +4,7 @@ import { basename, relative } from 'node:path';
4
4
  import { createTwoFilesPatch } from 'diff';
5
5
  import RE2 from 're2';
6
6
  import { DEFAULT_EXCLUDE_PATTERNS, MAX_TEXT_FILE_SIZE, PARALLEL_CONCURRENCY, } from '../lib/constants.js';
7
- import { ErrorCode, formatUnknownErrorMessage, McpError, } from '../lib/errors.js';
7
+ import { classifyError, ErrorCode, formatUnknownErrorMessage, McpError, } from '../lib/errors.js';
8
8
  import { globEntries } from '../lib/file-operations/traversal.js';
9
9
  import { atomicWriteFile } from '../lib/fs-helpers.js';
10
10
  import { Logger } from '../lib/logger.js';
@@ -340,12 +340,12 @@ export function registerSearchAndReplaceTool(server, options = {}) {
340
340
  const dryLabel = args.dryRun ? ' [dry run]' : '';
341
341
  const truncatedPattern = truncateProgressPattern(args.searchPattern);
342
342
  const context = `"${truncatedPattern}" in ${args.filePattern}${dryLabel}`;
343
- const progress = createToolProgressSession(ctx, `🛠 replace: ${context}`);
343
+ const progress = createToolProgressSession(ctx, `${SEARCH_AND_REPLACE_TOOL.title}: ${context}`);
344
344
  const progressWithMessage = ({ current, total, }) => {
345
345
  progress.update({
346
346
  current,
347
347
  ...(total !== undefined ? { total } : {}),
348
- message: `🛠 replace: ${truncatedPattern} [${current} files]`,
348
+ message: `${SEARCH_AND_REPLACE_TOOL.title}: ${truncatedPattern} [${current} files]`,
349
349
  });
350
350
  };
351
351
  try {
@@ -357,14 +357,14 @@ export function registerSearchAndReplaceTool(server, options = {}) {
357
357
  let endSuffix = `${sc.matches ?? 0} ${matchWord} in ${sc.filesChanged ?? 0} ${fileWord}`;
358
358
  if (sc.failedFiles)
359
359
  endSuffix += `, ${sc.failedFiles} failed`;
360
- progress.complete(`🛠 replace: ${context} • ${endSuffix}`, finalCurrent);
360
+ progress.complete(`${SEARCH_AND_REPLACE_TOOL.title}: ${context} • ${endSuffix}`, finalCurrent);
361
361
  if (!args.dryRun) {
362
362
  void ctx.log?.('info', `search_and_replace: ${String(sc.matches ?? 0)} matches in ${String(sc.filesChanged ?? 0)} files`);
363
363
  }
364
364
  return result;
365
365
  }
366
366
  catch (error) {
367
- progress.fail(`🛠 replace: ${context} • failed`);
367
+ progress.fail(`${SEARCH_AND_REPLACE_TOOL.title}: ${context} • ${classifyError(error)}`);
368
368
  throw error;
369
369
  }
370
370
  },
@@ -41,13 +41,13 @@ export function registerListAllowedDirectoriesTool(server, options = {}) {
41
41
  onError: (error) => buildToolErrorResponse(error, ErrorCode.UNKNOWN),
42
42
  });
43
43
  registerStandardTool(server, LIST_ALLOWED_DIRECTORIES_TOOL, handler, options, {
44
- progressMessage: () => '≣ roots',
44
+ progressMessage: () => LIST_ALLOWED_DIRECTORIES_TOOL.title,
45
45
  completionMessage: (_args, result) => {
46
46
  if (result.isError)
47
- return `≣ roots • failed`;
47
+ return `${LIST_ALLOWED_DIRECTORIES_TOOL.title} • ${result.errorCode}`;
48
48
  const sc = result.structuredContent;
49
49
  const count = sc.directories?.length ?? 0;
50
- return `≣ roots • ${count} ${count === 1 ? 'root' : 'roots'}`;
50
+ return `${LIST_ALLOWED_DIRECTORIES_TOOL.title} • ${count} ${count === 1 ? 'root' : 'roots'}`;
51
51
  },
52
52
  });
53
53
  }
@@ -1,13 +1,13 @@
1
1
  import { relative } from 'node:path';
2
2
  import RE2 from 're2';
3
3
  import { DEFAULT_EXCLUDE_PATTERNS } from '../lib/constants.js';
4
- import { ErrorCode, formatUnknownErrorMessage, McpError, } from '../lib/errors.js';
4
+ import { classifyError, ErrorCode, formatUnknownErrorMessage, McpError, } from '../lib/errors.js';
5
5
  import { searchContent, } from '../lib/file-operations/search.js';
6
6
  import { formatOperationSummary } from '../config.js';
7
7
  import { SearchContentInputSchema, SearchContentOutputSchema, } from '../schemas.js';
8
8
  import { SEARCH_ICONS } from './icons.js';
9
9
  import { buildResourceLink, buildToolErrorResponse, buildToolResponse, createToolProgressSession, executeToolWithDiagnostics, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, resolvePathOrRoot, truncateProgressPattern, } from './shared.js';
10
- import { registerStandardTool } from './task-support.js';
10
+ import { registerStandardTool, reportTaskStatus } from './task-support.js';
11
11
  /**
12
12
  * Configuration constants for the Search Content tool.
13
13
  */
@@ -268,7 +268,7 @@ export function registerSearchContentTool(server, options = {}) {
268
268
  context: { path: args.path ?? '.' },
269
269
  run: async (signal) => {
270
270
  const { pattern, filePattern: scope } = args;
271
- const progressLabel = `🔎︎ grep: ${truncateProgressPattern(pattern)}`;
271
+ const progressLabel = `${SEARCH_CONTENT_TOOL.title}: ${truncateProgressPattern(pattern)}`;
272
272
  const progress = createToolProgressSession(ctx, progressLabel);
273
273
  const progressWithMessage = ({ current, total, }) => {
274
274
  progress.update({
@@ -276,6 +276,7 @@ export function registerSearchContentTool(server, options = {}) {
276
276
  ...(total !== undefined ? { total } : {}),
277
277
  message: `${progressLabel} [${current} files]`,
278
278
  });
279
+ void reportTaskStatus(`${progressLabel} ${current} files`);
279
280
  };
280
281
  try {
281
282
  const result = await handleSearchContent(args, signal, options.resourceStore, progressWithMessage);
@@ -287,7 +288,7 @@ export function registerSearchContentTool(server, options = {}) {
287
288
  return result;
288
289
  }
289
290
  catch (error) {
290
- progress.fail(`${progressLabel} • failed`);
291
+ progress.fail(`${progressLabel} • ${classifyError(error)}`);
291
292
  throw error;
292
293
  }
293
294
  },
@@ -1,6 +1,6 @@
1
1
  import { basename, relative } from 'node:path';
2
2
  import { DEFAULT_EXCLUDE_PATTERNS, DEFAULT_SEARCH_TIMEOUT_MS, } from '../lib/constants.js';
3
- import { ErrorCode } from '../lib/errors.js';
3
+ import { classifyError, ErrorCode } from '../lib/errors.js';
4
4
  import { searchFiles } from '../lib/file-operations/search.js';
5
5
  import { formatOperationSummary, joinLines } from '../config.js';
6
6
  import { SearchFilesInputSchema, SearchFilesOutputSchema } from '../schemas.js';
@@ -126,7 +126,7 @@ export function registerSearchFilesTool(server, options = {}) {
126
126
  let progressCursor = 0;
127
127
  notifyProgress(ctx, {
128
128
  current: 0,
129
- message: `🔎︎ find: ${truncatedPattern}`,
129
+ message: `${SEARCH_FILES_TOOL.title}: ${truncatedPattern}`,
130
130
  });
131
131
  const baseReporter = createProgressReporter(ctx);
132
132
  const progressWithMessage = ({ current, total, }) => {
@@ -135,7 +135,7 @@ export function registerSearchFilesTool(server, options = {}) {
135
135
  baseReporter({
136
136
  current,
137
137
  ...(total !== undefined ? { total } : {}),
138
- message: `🔎︎ find: ${truncatedPattern} [${current} files]`,
138
+ message: `${SEARCH_FILES_TOOL.title}: ${truncatedPattern} [${current} files]`,
139
139
  });
140
140
  };
141
141
  try {
@@ -162,7 +162,7 @@ export function registerSearchFilesTool(server, options = {}) {
162
162
  notifyProgress(ctx, {
163
163
  current: finalCurrent,
164
164
  total: finalCurrent,
165
- message: `🔎︎ find: ${context} • ${suffix}`,
165
+ message: `${SEARCH_FILES_TOOL.title}: ${context} • ${suffix}`,
166
166
  });
167
167
  return result;
168
168
  }
@@ -171,7 +171,7 @@ export function registerSearchFilesTool(server, options = {}) {
171
171
  notifyProgress(ctx, {
172
172
  current: finalCurrent,
173
173
  total: finalCurrent,
174
- message: `🔎︎ find: ${context} • failed`,
174
+ message: `${SEARCH_FILES_TOOL.title}: ${context} • ${classifyError(error)}`,
175
175
  });
176
176
  throw error;
177
177
  }
@@ -1,4 +1,4 @@
1
- import type { ContentBlock, Icon, LoggingLevel, ProgressNotificationParams, ServerContext } from '@modelcontextprotocol/server';
1
+ import type { ContentBlock, Icon, LoggingLevel, Notification, RequestMeta, ServerContext } from '@modelcontextprotocol/server';
2
2
  import { z } from 'zod';
3
3
  import { ErrorCode } from '../lib/errors.js';
4
4
  import type { ResourceStore } from '../lib/resource-store.js';
@@ -56,25 +56,27 @@ export type ToolResponse<T> = ReturnType<typeof buildToolResponse<T>> & {
56
56
  interface ToolErrorResponse extends Record<string, unknown> {
57
57
  content: ContentBlock[];
58
58
  isError: true;
59
- errorCode?: ErrorCode;
59
+ errorCode: ErrorCode;
60
60
  }
61
61
  export type ToolResult<T> = ToolResponse<T> | ToolErrorResponse;
62
62
  export declare function withValidatedArgs<Args, Result>(schema: z.ZodType<Args>, handler: (args: Args, ctx: ToolContext) => Promise<ToolResult<Result>>): (args: unknown, ctx: ToolContext | ServerContext) => Promise<ToolResult<Result>>;
63
- type ProgressToken = string | number;
63
+ /**
64
+ * App-level tracing metadata passed through {@linkcode RequestMeta}.
65
+ * These fields are preserved by the SDK's loose `RequestMeta` type.
66
+ */
67
+ interface TracingMeta {
68
+ traceparent?: string | undefined;
69
+ tracestate?: string | undefined;
70
+ baggage?: string | undefined;
71
+ }
64
72
  export interface ToolContext {
65
73
  signal?: AbortSignal;
66
- _meta?: {
67
- progressToken?: ProgressToken | undefined;
68
- traceparent?: string | undefined;
69
- tracestate?: string | undefined;
70
- baggage?: string | undefined;
71
- } | undefined;
72
- sendNotification?: (notification: {
73
- method: 'notifications/progress';
74
- params: ProgressNotificationParams;
75
- }) => Promise<void>;
74
+ sessionId?: string;
75
+ _meta?: (RequestMeta & TracingMeta) | undefined;
76
+ sendNotification?: (notification: Notification) => Promise<void>;
76
77
  log?: (level: LoggingLevel, data: unknown, logger?: string) => Promise<void>;
77
78
  }
79
+ export declare function toToolContext(ctx?: ToolContext | ServerContext): ToolContext;
78
80
  export interface IconInfo {
79
81
  src: string;
80
82
  mimeType: string;
@@ -168,8 +170,3 @@ export declare function encodeOffsetCursor(offset: number): string;
168
170
  export declare function decodeOffsetCursor(cursor: string): number;
169
171
  export declare function buildBatchPathContext(paths: readonly string[], unitLabel?: string): string;
170
172
  export declare function truncateProgressPattern(pattern: string, maxLength?: number): string;
171
- export declare function buildBatchCompletionSuffix(summary: {
172
- total?: number;
173
- failed?: number;
174
- succeeded?: number;
175
- } | undefined, successWord: string, singularWord?: string): string;
@@ -3,7 +3,7 @@ import { basename } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  import { createTimedAbortSignal } from '../lib/abort.js';
5
5
  import { parseTrueEnvFlag } from '../lib/constants.js';
6
- import { createDetailedError, ErrorCode, formatDetailedError, getSuggestion, McpError, } from '../lib/errors.js';
6
+ import { classifyError, createDetailedError, ErrorCode, formatDetailedError, getSuggestion, McpError, } from '../lib/errors.js';
7
7
  import { Logger } from '../lib/logger.js';
8
8
  import { withToolDiagnostics, } from '../lib/observability.js';
9
9
  import { getAllowedDirectories } from '../lib/paths.js';
@@ -223,20 +223,18 @@ export function withValidatedArgs(schema, handler) {
223
223
  }
224
224
  };
225
225
  }
226
- function toToolContext(ctx) {
226
+ export function toToolContext(ctx) {
227
227
  if (!ctx)
228
228
  return {};
229
229
  if ('mcpReq' in ctx) {
230
230
  return {
231
231
  signal: ctx.mcpReq.signal,
232
+ ...(ctx.sessionId ? { sessionId: ctx.sessionId } : {}),
232
233
  ...(ctx.mcpReq._meta
233
234
  ? { _meta: ctx.mcpReq._meta }
234
235
  : {}),
235
236
  sendNotification: async (notification) => ctx.mcpReq.notify(notification),
236
- log: async (level, data, logger) => ctx.mcpReq.notify({
237
- method: 'notifications/message',
238
- params: { level, data, ...(logger ? { logger } : {}) },
239
- }),
237
+ log: async (level, data, logger) => ctx.mcpReq.log(level, data, logger),
240
238
  };
241
239
  }
242
240
  return ctx;
@@ -509,7 +507,7 @@ async function withProgress(message, ctx, run, getCompletionMessage) {
509
507
  void reportProgress(ctx, {
510
508
  current: total,
511
509
  total,
512
- message: `${message} • failed`,
510
+ message: `${message} • ${classifyError(error)}`,
513
511
  });
514
512
  throw error;
515
513
  }
@@ -599,13 +597,3 @@ export function truncateProgressPattern(pattern, maxLength = 40) {
599
597
  }
600
598
  return `${pattern.slice(0, maxLength)}…`;
601
599
  }
602
- export function buildBatchCompletionSuffix(summary, successWord, singularWord) {
603
- const total = summary?.total ?? 0;
604
- const failed = summary?.failed ?? 0;
605
- const succeeded = summary?.succeeded ?? 0;
606
- if (failed) {
607
- return `${succeeded}/${total} ${successWord}, ${failed} failed`;
608
- }
609
- const word = total === 1 && singularWord ? singularWord : successWord;
610
- return `${total} ${word}`;
611
- }
@@ -1,10 +1,10 @@
1
1
  import { DEFAULT_SEARCH_TIMEOUT_MS } from '../lib/constants.js';
2
- import { ErrorCode } from '../lib/errors.js';
2
+ import { classifyError, ErrorCode } from '../lib/errors.js';
3
3
  import { getMultipleFileInfo } from '../lib/file-operations/metadata.js';
4
4
  import { formatBytes, joinLines } from '../config.js';
5
5
  import { GetMultipleFileInfoInputSchema, GetMultipleFileInfoOutputSchema, } from '../schemas.js';
6
6
  import { FILE_READ_ICONS } from './icons.js';
7
- import { buildBatchCompletionSuffix, buildBatchPathContext, buildFileInfoPayload, buildStructuredError, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, } from './shared.js';
7
+ import { buildBatchPathContext, buildFileInfoPayload, buildStructuredError, buildToolErrorResponse, buildToolResponse, createBatchProgressCallbacks, executeToolWithDiagnostics, READ_ONLY_TOOL_ANNOTATIONS, resolveFinalProgressCurrent, } from './shared.js';
8
8
  import { registerStandardTool } from './task-support.js';
9
9
  export const GET_MULTIPLE_FILE_INFO_TOOL = {
10
10
  name: 'stat_many',
@@ -77,7 +77,7 @@ export function registerGetMultipleFileInfoTool(server, options = {}) {
77
77
  run: async (signal) => {
78
78
  const context = buildBatchPathContext(args.paths);
79
79
  const { progress, onItemComplete } = createBatchProgressCallbacks(ctx, {
80
- toolLabel: '🕮 stat_many',
80
+ toolLabel: GET_MULTIPLE_FILE_INFO_TOOL.title,
81
81
  context,
82
82
  totalItems: args.paths.length,
83
83
  itemVerb: 'done',
@@ -85,14 +85,15 @@ export function registerGetMultipleFileInfoTool(server, options = {}) {
85
85
  try {
86
86
  const result = await handleGetMultipleFileInfo(args, signal, onItemComplete);
87
87
  const sc = result.structuredContent;
88
- const suffix = buildBatchCompletionSuffix(sc.summary, 'OK');
89
88
  const total = sc.summary?.total ?? 0;
89
+ const failed = sc.summary?.failed ?? 0;
90
+ const suffix = failed ? `${failed} failed` : 'done';
90
91
  const finalCurrent = resolveFinalProgressCurrent(progress, total);
91
- progress.complete(`🕮 stat_many: ${context} • ${suffix}`, finalCurrent);
92
+ progress.complete(`${GET_MULTIPLE_FILE_INFO_TOOL.title}: ${context} • ${suffix}`, finalCurrent);
92
93
  return result;
93
94
  }
94
95
  catch (error) {
95
- progress.fail(`🕮 stat_many: ${context} • failed`);
96
+ progress.fail(`${GET_MULTIPLE_FILE_INFO_TOOL.title}: ${context} • ${classifyError(error)}`);
96
97
  throw error;
97
98
  }
98
99
  },
@@ -53,15 +53,15 @@ export function registerGetFileInfoTool(server, options = {}) {
53
53
  onError: (error) => buildToolErrorResponse(error, ErrorCode.NOT_FOUND, args.path),
54
54
  });
55
55
  registerStandardTool(server, GET_FILE_INFO_TOOL, handler, options, {
56
- progressMessage: (args) => `🕮 stat: ${basename(args.path)}`,
56
+ progressMessage: (args) => `${GET_FILE_INFO_TOOL.title}: ${basename(args.path)}`,
57
57
  completionMessage: (args, result) => {
58
58
  const name = basename(args.path);
59
59
  if (result.isError)
60
- return `🕮 stat: ${name} • failed`;
60
+ return `${GET_FILE_INFO_TOOL.title}: ${name} • ${result.errorCode}`;
61
61
  const sc = result.structuredContent;
62
62
  if (!sc.info)
63
- return `🕮 stat: ${name} • failed`;
64
- return `🕮 stat: ${sc.info.name} • ${sc.info.type}, ${formatBytes(sc.info.size)}`;
63
+ return `${GET_FILE_INFO_TOOL.title}: ${name} • failed`;
64
+ return `${GET_FILE_INFO_TOOL.title}: ${sc.info.name} • ${formatBytes(sc.info.size)}`;
65
65
  },
66
66
  });
67
67
  }
@@ -1,5 +1,10 @@
1
1
  import { type McpServer, type RequestTaskStore, type StandardSchemaWithJSON, type ToolTaskHandler } from '@modelcontextprotocol/server';
2
2
  import { type IconInfo, type ToolContext, type ToolContract, type ToolRegistrationOptions, type ToolResult } from './shared.js';
3
+ /**
4
+ * Report an intermediate 'working' status update for the current task.
5
+ * No-op when called outside of a task context.
6
+ */
7
+ export declare function reportTaskStatus(statusMessage: string): Promise<void>;
3
8
  type TaskToolContext = ToolContext & {
4
9
  taskId?: string;
5
10
  taskStore?: RequestTaskStore;