Skip to main content
Glama

stat_many

Retrieve metadata for multiple files or directories simultaneously to optimize token usage in filesystem operations.

Instructions

Get metadata for multiple files/directories in one request. Use tokenEstimate (size÷4) to pre-screen token cost before reading.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathsYesFile/directory paths. e.g. ["src", "lib"]

Implementation Reference

  • The internal handler function that processes the logic for 'stat_many'.
    async function handleGetMultipleFileInfo(
      args: z.infer<typeof GetMultipleFileInfoInputSchema>,
      signal?: AbortSignal,
      onProgress?: () => void
    ): Promise<ToolResponse<z.infer<typeof GetMultipleFileInfoOutputSchema>>> {
      const result = await getMultipleFileInfo(args.paths, {
        includeMimeType: true,
        ...(signal ? { signal } : {}),
        ...(onProgress ? { onProgress } : {}),
      });
    
      const structuredResults: z.infer<
        typeof GetMultipleFileInfoOutputSchema
      >['results'] = result.results.map((entry) => ({
        path: entry.path,
        info: entry.info ? buildFileInfoPayload(entry.info) : undefined,
        error: entry.error
          ? buildStructuredError(entry.error, ErrorCode.E_NOT_FOUND, entry.path)
          : undefined,
      }));
    
      const text = result.results
        .map((entry) =>
          entry.error
            ? `${entry.path}: ${buildStructuredError(entry.error, ErrorCode.E_NOT_FOUND, entry.path).message}`
            : entry.info
              ? formatFileInfoDetail(entry.info)
              : entry.path
        )
        .join('\n\n');
    
      const structured: z.infer<typeof GetMultipleFileInfoOutputSchema> = {
        ok: true,
        results: structuredResults,
        summary: {
          total: result.summary.total,
          succeeded: result.summary.succeeded,
          failed: result.summary.failed,
        },
      };
    
      return buildToolResponse(text, structured);
    }
  • The definition of the tool 'stat_many' including schema and metadata.
    export const GET_MULTIPLE_FILE_INFO_TOOL: ToolContract = {
      name: 'stat_many',
      title: 'Get Multiple File Info',
      description:
        'Get metadata for multiple files/directories in one request. ' +
        'Use `tokenEstimate` (size\u00f74) to pre-screen token cost before reading.',
      inputSchema: GetMultipleFileInfoInputSchema,
      outputSchema: GetMultipleFileInfoOutputSchema,
      annotations: READ_ONLY_TOOL_ANNOTATIONS,
      taskSupport: 'optional',
    } as const;
  • The registration function that exposes the tool to the MCP server.
    export function registerGetMultipleFileInfoTool(
      server: McpServer,
      options: ToolRegistrationOptions = {}
    ): void {
      const handler = (
        args: z.infer<typeof GetMultipleFileInfoInputSchema>,
        extra: ToolExtra
      ): Promise<ToolResult<z.infer<typeof GetMultipleFileInfoOutputSchema>>> => {
        const primaryPath = args.paths[0] ?? '';
        return executeToolWithDiagnostics({
          toolName: 'stat_many',
          extra,
          outputSchema: GetMultipleFileInfoOutputSchema,
          timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
          context: { path: primaryPath },
          run: async (signal) => {
            const context = buildBatchPathContext(args.paths);
            const { progress, onItemComplete } = createBatchProgressCallbacks(
              extra,
              {
                toolLabel: '🕮 stat_many',
                context,
                totalItems: args.paths.length,
                itemVerb: 'done',
              }
            );
    
            try {
              const result = await handleGetMultipleFileInfo(
                args,
                signal,
                onItemComplete
              );
    
              const sc = result.structuredContent;
              const suffix = buildBatchCompletionSuffix(sc.summary, 'OK');
              const total = sc.summary?.total ?? 0;
    
              const finalCurrent = resolveFinalProgressCurrent(progress, total);
              progress.complete(
                `🕮 stat_many: ${context} • ${suffix}`,
                finalCurrent
              );
              return result;
            } catch (error) {
              progress.fail(`🕮 stat_many: ${context} • failed`);
              throw error;
            }
          },
          onError: (error) =>
            buildToolErrorResponse(error, ErrorCode.E_NOT_FOUND, primaryPath),
        });
      };
    
      const wrappedHandler = wrapToolHandler(handler, {
        guard: options.isInitialized,
      });
    
      const validatedHandler = withValidatedArgs(
        GetMultipleFileInfoInputSchema,
        wrappedHandler
      );
    
      if (
        registerToolTaskIfAvailable(
          server,
          'stat_many',
          GET_MULTIPLE_FILE_INFO_TOOL,
          validatedHandler,
          options.iconInfo,
          options.isInitialized
        )
      )
        return;
      server.registerTool(
        'stat_many',
        withDefaultIcons({ ...GET_MULTIPLE_FILE_INFO_TOOL }, options.iconInfo),
        validatedHandler
      );
    }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/j0hanz/filesystem-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server