Skip to main content
Glama

read_many

Read multiple text files simultaneously to retrieve contents and metadata, supporting partial reads by line ranges or head/tail sections.

Instructions

Read multiple text files in one request with contents and metadata. For a single file, use read.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathsYesFiles to read. e.g. ["src/index.ts"]
headNoRead first N lines of each file
tailNoRead last N lines of each file
startLineNoStart line (1-based, inclusive) per file. Defaults to 1 when endLine is set.
endLineNoEnd line (1-based, inclusive) per file. Defaults to last line when startLine is set.

Implementation Reference

  • The core handler function `handleReadMultipleFiles` that processes multiple files for the `read_many` tool.
    async function handleReadMultipleFiles(
      args: ReadManyInput,
      signal?: AbortSignal,
      resourceStore?: ToolRegistrationOptions['resourceStore'],
      onReadComplete?: () => void
    ): Promise<ToolResponse<ReadManyOutput>> {
      const options = buildReadMultipleOptions(args, signal, onReadComplete);
      const results = await readMultipleFiles(args.paths, options);
      const payload = buildReadManyResponsePayload(results, resourceStore);
    
      const structured: ReadManyOutput = {
        ok: true,
        results: payload.structuredResults,
        summary: payload.summary,
      };
    
      return buildToolResponse(payload.text, structured, payload.resourceLinks);
    }
  • The `registerReadMultipleFilesTool` function that registers the `read_many` tool with the MCP server.
    export function registerReadMultipleFilesTool(
      server: McpServer,
      options: ToolRegistrationOptions = {}
    ): void {
      const handler = (
        args: ReadManyInput,
        extra: ToolExtra
      ): Promise<ToolResult<ReadManyOutput>> => {
        const primaryPath = args.paths[0] ?? '';
        return executeToolWithDiagnostics({
          toolName: READ_MANY_TOOL_NAME,
          extra,
          outputSchema: ReadMultipleFilesOutputSchema,
          timedSignal: { timeoutMs: DEFAULT_SEARCH_TIMEOUT_MS },
          context: { path: primaryPath },
          run: async (signal) => {
            const context = buildBatchPathContext(args.paths, 'files');
            const { progress, onItemComplete } = createBatchProgressCallbacks(
              extra,
              {
                toolLabel: READ_MANY_TOOL_LABEL,
                context,
                totalItems: args.paths.length,
                itemVerb: 'read',
              }
            );
    
            try {
              const result = await handleReadMultipleFiles(
                args,
                signal,
                options.resourceStore,
                onItemComplete
              );
    
              const sc = result.structuredContent;
              const suffix = buildBatchCompletionSuffix(
                sc.summary,
                'files read',
                'file read'
              );
              const total = sc.summary?.total ?? 0;
    
              const finalCurrent = resolveFinalProgressCurrent(progress, total);
              progress.complete(
                `${READ_MANY_TOOL_LABEL}: ${context} • ${suffix}`,
                finalCurrent
              );
              return result;
            } catch (error) {
              progress.fail(`${READ_MANY_TOOL_LABEL}: ${context} • failed`);
              throw error;
            }
          },
          onError: (error) =>
            buildToolErrorResponse(error, ErrorCode.E_NOT_FILE, primaryPath),
        });
      };
    
      const wrappedHandler = wrapToolHandler(handler, {
        guard: options.isInitialized,
      });
    
      const validatedHandler = withValidatedArgs(
        ReadMultipleFilesInputSchema,
        wrappedHandler
      );
    
      if (
        registerToolTaskIfAvailable(
          server,
          READ_MANY_TOOL_NAME,
          READ_MANY_TOOL,
          validatedHandler,
          options.iconInfo,
          options.isInitialized
        )
      )
        return;
      server.registerTool(
        READ_MANY_TOOL_NAME,
        withDefaultIcons({ ...READ_MANY_TOOL }, options.iconInfo),
        validatedHandler
      );
    }
  • The `READ_MANY_TOOL` contract definition, which includes name, title, description, and input/output schemas for the `read_many` tool.
    export const READ_MANY_TOOL: ToolContract = {
      name: READ_MANY_TOOL_NAME,
      title: 'Read Multiple Files',
      description:
        'Read multiple text files in one request with contents and metadata. ' +
        'For a single file, use `read`.',
      inputSchema: ReadMultipleFilesInputSchema,
      outputSchema: ReadMultipleFilesOutputSchema,
      annotations: READ_ONLY_TOOL_ANNOTATIONS,
      taskSupport: 'optional',
    } as const;

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