File system·续2

List the waiting calls with workspace.runtime.pending(), and answer one with respond():

for (const call of await this.workspace.runtime.pending()) {
    await this.workspace.runtime.respond(call.id, call.callId, {
        approved: true,
    });
}
for (const call of await this.workspace.runtime.pending()) {
    await this.workspace.runtime.respond(call.id, call.callId, {
        approved: true,
    });
}

Once none of its calls are waiting, the run replays to the call, and the function runs again with the same callId. This time, ctx.interrupt() returns the answer straight away. To notify someone when a call starts waiting, pass an onWait function to the backend. It receives the same fields as pending(), at most once per wait. killExec() ends a waiting run.

  • A call can interrupt once. A second ctx.interrupt() in the same call throws.
  • Only a run with onInterrupt: "replay" can wait. In any other run, ctx.interrupt() throws.
  • respond() throws an ENOTWAITING error for a call that is not waiting, such as one already answered.

Current limitations

These limitations apply to the experimental release and may change in future releases.

  • A replay must take the same path as the first attempt. A run fails if it calls or prints something different. Keys from crypto.subtle.generateKey(), node:crypto randomness, node:timers, and cloudflare:sockets are not replayed.
  • A replayable run buffers fetch responses instead of streaming them, and each body must fit in 1 MiB by default. Requests go through the Durable Object, so they are slower than in other runs. A request in flight at the restart is sent again.
  • A host module function runs again once its answer arrives, so any work before ctx.interrupt() must be safe to repeat. Every answer replays the run from the beginning.
  • A run gets three attempts, counted again each time it journals a call. It must finish within its original timeout, counted from when it first started.
  • A run resumes only on the same runtime. A new compatibility date or flags, new size limits on the backend, or a package upgrade that changes how runs replay fails the runs it interrupted.
  • Interrupted runs restart four at a time, because a Durable Object can run up to ten Dynamic Workers at once.
  • Until a run finishes, its journal uses Durable Object storage of roughly the size of every response, plus the code of the run.

Limits

  • Each workspace shares the storage of its Durable Object. For storage limits, refer to Durable Objects limits. Size workspaces for an agent's working files, not for full monorepos or large dependency trees.
  • The JavaScript backend runs ECMAScript modules, not shell commands or native binaries. When an agent needs a Linux environment, use a sandbox.
  • Each JavaScript run is bounded in CPU time, wall-clock time, output size, and the number and size of file operations. Completed runs are kept for 60 minutes by default.

Security considerations

The model reads everything that the file tools and exec return. A file can contain text written to steer the model, such as an instruction to delete other files. Check tool results before the agent acts on them outside the workspace, and require approval for tools with side effects.

Code that the JavaScript backend runs cannot read the environment variables, bindings, or storage of the agent. It reaches only the files under root, the modules you configure, and the network when you pass a globalOutbound. Host modules run with the full access of the agent, so expose only the functions that model-written code needs.

Every user who talks to the same agent instance shares its workspace. Give each user their own agent instance when their files must stay apart.

API reference

Workspace

new Workspace(options) from @cloudflare/computer creates a workspace. It accepts the following options:

Option Description
storage Required. The storage of the Durable Object, this.ctx.storage.
backends Execution backends, such as WorkerJavaScriptBackend. The first backend is the default.
mounts Read-only content mounted at a path, from an R2 bucket (R2Bucket()) or the Worker bundle (WorkerBundle()).
git A Git client from createGitClient() in @cloudflare/computer/git, which turns on workspace.git.
defaultGitIdentity The { name, email } that Git commits use.
artifacts An Artifacts binding, as { binding }.
output Where long command output is saved, and how much result() keeps.

workspace.fs

Every path is absolute. Every method returns a promise.

Method Description
readFile(path, encoding?) Reads a file. Returns a string with "utf8", or a ReadableStream without an encoding. Accepts { byteOffset, byteLength } to read part of a file.
writeFile(path, content, options?) Writes a string, Uint8Array, or ReadableStream. Set options.mode for permissions.
mkdir(path, options?) Creates a directory. Set recursive: true to create parents.
readdir(path) Lists a directory as entries with name, parentPath, isFile, and isDirectory.
stat(path) Returns name, mode, mtime, size, isFile, and isDirectory, following symbolic links.
lstat(path) Like stat, but reports a symbolic link itself, with isSymbolicLink.
rm(path, options?) Removes a file or directory. Set recursive: true for a non-empty directory, and force: true to ignore a missing path.
rename(oldPath, newPath) Moves a file, directory, or symbolic link in one transaction.
symlink(target, path) Creates a symbolic link at path that points to target.
readlink(path) Returns the target of a symbolic link.
chmod(path, mode) Changes the permission bits of a path.
find(directory, pattern?, options?) Finds paths that match a glob, relative to directory. Accepts exclude, limit, and offset.
ls(prefix) Lists every file at or under prefix.
grep(pattern, path, options?) Searches file contents. Accepts regex, ignoreCase, context, include, exclude, limit, and offset.

Failed operations reject with an error whose code is a POSIX error code, such as ENOENT for a missing path.

workspace.runtime

Method Description
exec(source, options?) Runs source on a backend and returns a handle. Call result() on the handle for the final result.
getExec(id, options?) Reattaches to a run by ID.
killExec(id, options?) Stops a run.
disposeExec(id, options?) Discards a completed run.
backends() Lists the backends and the description that each gives to the model.
recover() Resumes interrupted runs. Call it from an alarm. Experimental.
pending() Lists the host module calls that are waiting for an answer. Experimental.
respond(id, callId, answer, options?) Answers a waiting call. Experimental.

exec() accepts the following options:

Option Description
backend The backend ID to run on. Defaults to the first backend.
input JSON-compatible data passed to the default export of a JavaScript module.
encoding Set to "utf8" to receive stdout and stderr as strings instead of bytes.
cwd The working directory, and the base for relative imports.
env Environment variables for this run, available to JavaScript as process.env.
stdin Standard input, as a string or Uint8Array.
timeoutMs How long the run can take, up to the backend's maxTimeoutMs.
onInterrupt What happens to this run if a restart interrupts it. Overrides the backend's default.

The result contains status ("completed", "failed", or "cancelled"), exitCode, stdout, stderr, and value, the return value of a JavaScript module. When output is too long, truncated names the workspace file that holds all of it.

Declare handles from exec() with using so they are disposed when they go out of scope.

Tool functions

Function Entry point Returns
createAITools() @cloudflare/computer/tools/ai-sdk An AI SDK ToolSet.
createPiTools() @cloudflare/computer/tools/pi-ai Pi AI tool declarations and an execute function.
createTanStackTools() @cloudflare/computer/tools/tanstack-ai A list of TanStack AI ↗︎ tools.

Host modules

Pass these to the modules option of WorkerJavaScriptBackend:

Function Entry point Module Description
createGitModule() @cloudflare/computer/modules/git ws:git Git operations on the workspace. Requires the git workspace option. Pass { allowNetwork: true } to clone, fetch, and push.
createArtifactsModule() @cloudflare/computer/modules/artifacts ws:artifacts Artifacts repositories. Requires the artifacts workspace option.
createToolBindings() @cloudflare/computer/modules/tools ws:tools The agent's own tools, callable from code. Build the bindings with forAISDKTools() or forPiTools().

For the full interfaces, refer to the Computer design documentation ↗︎.

Cloudflare Computer

Source code, examples, and design documentation for @cloudflare/computer.

Sandbox

Give an agent a Linux sandbox to run shell commands, scripts, and tests.

Think tools

Built-in workspace tools, custom tools, and approvals for Think agents.

Dynamic Workers

Load and run Workers on demand from another Worker.

Was this helpful?

YesNo

On this page

File system·续2 - 图1Docs

{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/agents/tools/filesystem/#page","headline":"File system","description":"Give an agent a virtual file system stored in its Durable Object, with file tools for the model and an optional JavaScript runtime.","url":"https://developers.cloudflare.com/agents/tools/filesystem/","inLanguage":"en","image":"https://developers.cloudflare.com/agents/tools/filesystem/og.png?v=d015b763134c08dd","dateModified":"2026-10-23","publisher":{"@type":"Organization","name":"Cloudflare","description":"One platform for your apps, agents, and workforce. Build, secure, and scale without managing infrastructure","url":"https://www.cloudflare.com/","sameAs":["https://github.com/cloudflare","https://www.linkedin.com/company/cloudflare","https://x.com/cloudflare"],"logo":{"@type":"ImageObject","url":"https://developers.cloudflare.com/logo.svg"},"address":{"@type":"PostalAddress","streetAddress":"101 Townsend St","addressLocality":"San Francisco","addressRegion":"CA","postalCode":"94107","addressCountry":"US"},"contactPoint":[{"@type":"ContactPoint","contactType":"Customer Support","url":"https://support.cloudflare.com/","availableLanguage":["English"]},{"@type":"ContactPoint","contactType":"Sales","url":"https://www.cloudflare.com/contact/","availableLanguage":["English"]}]},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"}}


description: Connect agents to external Model Context Protocol servers and use their tools in model calls. title: MCP image: https://developers.cloudflare.com/agents/tools/mcp/og.png?v=45c87f178d28710a


Skip to content

Documentation Index
Fetch the complete documentation index at: https://developers.cloudflare.com/agents/llms.txt
Use this file to discover all available pages before exploring further.