Claude Agent SDK
Expose a configured Files instance to the Claude Agent SDK as an in-process MCP server with allowedTools and canUseTool wired up.
The files-sdk/claude subpath exposes a configured Files instance to the Claude Agent SDK (@anthropic-ai/claude-agent-sdk, the renamed Claude Code SDK). The Agent SDK consumes tools as an in-process MCP server plus an allowedTools allow-list and a canUseTool approval callback, so createClaudeFileTools returns a bundle of all three - pass them straight into query().
@anthropic-ai/claude-agent-sdk and zod are optional peer dependencies - only install them if you're consuming this subpath.
Installation
npm install @anthropic-ai/claude-agent-sdk zodQuick start
createClaudeFileTools returns { mcpServers, allowedTools, canUseTool, needsApproval, server, serverName }. The first three slot directly into query()'s options; the rest are escape hatches for callers that want to compose with existing MCP servers or wire their own approval UX.
import { query } from "@anthropic-ai/claude-agent-sdk";
import { Files } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { createClaudeFileTools } from "files-sdk/claude";
const files = new Files({ adapter: s3({ bucket: "uploads" }) });
const tools = createClaudeFileTools({ files });
for await (const message of query({
prompt: "Find every CSV under reports/ and summarize the latest one.",
options: {
mcpServers: tools.mcpServers,
allowedTools: tools.allowedTools,
canUseTool: tools.canUseTool,
},
})) {
// handle messages
}Approval control
The bundled canUseTool denies any tool whose needsApproval resolves to true with a "requires approval" message, and allows everything else. requireApproval accepts a boolean for the all-or-nothing case, or an object keyed by write tool name for fine-grained control.
// All writes require approval (default) - denied by the bundled canUseTool.
createClaudeFileTools({ files });
// Disable the approval gate entirely.
createClaudeFileTools({ files, requireApproval: false });
// Granular: only destructive operations need approval.
createClaudeFileTools({
files,
requireApproval: {
deleteFile: true,
signUploadUrl: true,
uploadFile: false,
copyFile: false,
},
});For real human-in-the-loop UX, compose your own canUseTool on top of tools.needsApproval(). The helper accepts both bare names ("uploadFile") and the MCP-prefixed form ("mcp__files__uploadFile") that the SDK passes in, so the callback is symmetric whichever shape you receive.
import type { CanUseTool } from "@anthropic-ai/claude-agent-sdk";
const tools = createClaudeFileTools({ files });
// Compose your own canUseTool - needsApproval accepts both bare
// names ("uploadFile") and the mcp-prefixed form passed in by the SDK.
const canUseTool: CanUseTool = async (name, input) => {
if (tools.needsApproval(name)) {
const approved = await askUser(name, input);
return approved
? { behavior: "allow", updatedInput: input }
: { behavior: "deny", message: "User rejected the call." };
}
return { behavior: "allow", updatedInput: input };
};Read-only mode
Pass readOnly: true to drop every write tool from the bundled MCP server. The model cannot mutate the bucket regardless of how requireApproval is configured.
// Strip every write tool. The model can browse but cannot mutate
// the bucket regardless of approval configuration.
createClaudeFileTools({ files, readOnly: true });
// allowedTools → ["mcp__files__listFiles", "mcp__files__getFileMetadata",
// "mcp__files__downloadFile", "mcp__files__getFileUrl"]Server name
Claude addresses each MCP tool as mcp__<server-name>__<tool-name>. The default server name is "files"; override it via serverName when you need to namespace alongside another MCP server or just prefer a different label in transcripts.
// Override the MCP server name - affects the mcp__<server>__<tool>
// prefix the model sees, and the mcpServers map key.
const tools = createClaudeFileTools({ files, serverName: "storage" });
// tools.allowedTools → ["mcp__storage__listFiles", ...]
// tools.mcpServers → { storage: <McpSdkServerConfigWithInstance> }Cherry-picking tools
Each tool factory is exported individually as a SdkMcpToolDefinition - bundle them into your own createSdkMcpServer call when you want full control over the MCP server shape or want to mix files-sdk tools with your own.
import { createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
import { Files } from "files-sdk";
import {
claudeDownloadFile,
claudeListFiles,
claudeUploadFile,
} from "files-sdk/claude";
const files = new Files({ adapter });
// Compose your own MCP server with just the tools you want.
const server = createSdkMcpServer({
name: "files",
version: "1.0.0",
tools: [
claudeListFiles(files),
claudeDownloadFile(files),
claudeUploadFile(files),
],
});