推出 openrouter:shell 服务器工具和 Files API:OpenRouter 上的任何模型现在都可以在托管的 Linux 容器中运行命令。Files API 支持上传文件供模型使用,并可下载输出结果。这两项功能今天起以 beta 版本提供。
Shell 和 Files 加入了我们不断扩充的 服务器工具 列表,让你能够创建可在不同模型之间切换的服务器端智能体行为。例如,你可以让任何模型搜索网络、编写一个将结果转化为图表的脚本,并完全使用服务器端算力来运行它。


在 聊天室 中开启 shell 工具即可试用,并阅读 shell、容器 和 Files API 指南了解 API 详情。沙箱时间按每秒 $0.0001 计费,作为请求的一部分计费,并包含 Files API 的使用。详情见 定价 部分。
shell 的工作原理
要使用 openrouter:shell,请将其发送到任何支持工具调用的模型的 tools 数组中。这让模型能够自行决定何时需要终端以及何时调用它:
curl https://openrouter.ai/api/v1/responses \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro-0813",
"input": "Check the Python version, then write a script that prints the first 20 primes and run it.",
"tools": [
{ "type": "openrouter:shell", "parameters": { "engine": "openrouter" } }
]
}' 我们推出了三项协同工作的能力,以提供服务器端命令执行和文件功能:
- Shell 与 Bash:我们在 Responses API 和 Anthropic Messages API 上支持兼容 OpenAI 的 Shell 工具,并在 Messages API 上支持
openrouter:bash(兼容 Anthropic 的 Bash 工具)。两者均可与任何模型配合使用。 - Files API:位于
/api/v1/files下的工作区存储。上传文件、按 ID 将文件附加到容器,并保留运行产生的文件。 - 容器:这些是 shell 命令运行的沙箱。写入其中的文件会在共享同一容器 ID 的请求之间持久保留。你可以通过
/api/v1/containersAPI 访问容器的内容。
当模型调用该工具时,它会发出一批命令。这些命令在容器内执行,每条命令各自独立调用,并将 stdout、stderr 和退出码返回给模型。这使得模型能够对收到的输出做出反应。例如,如果它编写了一个脚本来解析你的 CSV,而解析失败,它可以在 stderr 上看到问题,并在回答前修复脚本。
日志页面上的生成详情视图将请求显示为时间线。模型轮次和沙箱运行显示为单独的行,每行都有各自的持续时间和成本:

Shell 与 bash
我们推出了两个用于沙箱命令执行的工具,以便同时兼容 OpenAI 和 Anthropic 的规范。最显著的区别在于,bash 工具的默认行为是请求你的应用在本地运行命令。在 OpenRouter 上,你可以更改引擎来覆盖此行为,改为在服务器端执行。
openrouter:shell | openrouter:bash | |
|---|---|---|
| 兼容 | OpenAI 的 shell 工具 | Anthropic 的 bash 工具 |
| API | Responses、Messages | Messages |
| 默认运行命令的位置 | 在 OpenRouter 沙箱内 | 在你的应用中 |
在任一工具上使用 engine: "openrouter" 均可保证在任何模型下于 OpenRouter 沙箱内执行服务器端命令。
容器
容器是 OpenRouter 基础设施上隔离的 Linux 环境,限定在你的工作空间范围内。容器可以根据你的应用需求进行配置:
- 网络:默认关闭出站访问。对于
pip3 install这类任务,可将network_policy设置为白名单,例如{ "type": "allowlist", "allowed_domains": ["pypi.org", "files.pythonhosted.org"] },或设为{ "type": "allowlist", "allowed_domains": ["*"] }以允许不受限的出站流量。白名单中的主机可通过 80 和 443 端口访问;对白名单之外域名的请求会以 HTTP 520 错误失败,而非连接错误。该策略在容器启动后无法更改。 - 文件:仅捕获主目录(
/workspace/home)下的文件。每次 shell 执行结果还会返回命令创建或修改的文件 id 列表(以cfile_为前缀)。容器文件端点 列出容器中保存的所有内容,而 Files API 用于将文件移入和移出容器。 - 跨请求复用:默认情况下,一次对话会获得全新的容器。如果请求中包含
session_id或带有可识别容器的先前 shell 结果,则会复用该容器。若要显式指定容器,请在工具的{ "type": "container_reference", "container_id": "my-project" }字段中传入environment。 - 生命周期:容器在空闲 5 分钟后进入休眠状态。此设置不可配置。
文件与 Shell 协同工作
Files API 是与容器并行的工作区存储。你可以将输入文件上传到其中供 shell 处理,也可以将 shell 的输出移回该存储中。
为 shell 上传文件
使用 POST /api/v1/files 上传输入文件。响应中会包含一个以 or_file_ 开头的文件 id:
curl https://openrouter.ai/api/v1/files \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-F "file=@data/sales.csv" 然后在工具的 environment 中通过该 id 附加文件:
{
"type": "openrouter:shell",
"parameters": {
"engine": "openrouter",
"environment": {
"type": "container_auto",
"file_ids": ["or_file_011CNha8iCJcU1wXNR6q4V8w"]
}
}
} 附加的文件会以可写副本的形式出现在主目录中,每个容器最多 20 个。每个副本的文件名由文件 id 的最后 8 个字符加上原始文件名组成,因此使用上述 id 附加的 data/sales.csv 会变成 ~/NR6q4V8w-sales.csv。容器内的更改不会影响原始工作区文件。容器启动时只包含你附加到其中的文件。
下载 shell 生成的文件
每次 shell 运行结果都会列出该命令所触及的文件,并为每个文件提供一个 cfile_ id。使用 容器文件内容端点 下载这些文件:
curl "https://openrouter.ai/api/v1/containers/$CONTAINER_ID/files/$FILE_ID/content" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-o output.txt 容器文件会保留 30 天。如需长期保留某个文件,可以将其提升:
curl -X POST "https://openrouter.ai/api/v1/containers/$CONTAINER_ID/files/$FILE_ID/promote" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" Promoting(提升)会将容器文件复制到你的工作区,并返回一个新的 or_file_ id,你可以像上传文件一样,在后续运行中附加该 id。与上传不同,被提升的文件可以通过 Files API 下载。
Files API 详情
你可以在 工作区文件页面查看你的所有文件。直接上传的文件无法下载,但从容器中提升的文件则可以下载。
同时使用多个服务器工具
Shell 是我们提供的众多 服务器工具之一,这些工具协同工作时功能强大。下面这个例子中,模型使用网络搜索查找资料,再用 shell 将其转换为文件:
curl https://openrouter.ai/api/v1/responses \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro-0813",
"input": "Look up the three biggest open-source AI releases this week, then write ~/out/releases.md with one paragraph each and a source link.",
"tools": [
{ "type": "openrouter:web_search" },
{ "type": "openrouter:shell", "parameters": { "engine": "openrouter" } }
]
}' 生成的 ~/out/releases.md 会出现在 shell 结果的文件列表中,你可以通过上述的容器文件内容端点下载它。
如果你不想让容器拥有网络访问权限,这种组合也很重要。网络搜索在容器外部运行,因此模型可以获取网络内容并将其传入自己的命令中,而容器则保持默认网络策略,自身无法访问互联网。
在 聊天室中,开启 shell 和网络搜索开关后,同样的组合也能生效。运行产生的文件会以下载的形式出现在对话中。
定价
Shell 和 Bash 的使用按沙箱时长计费。价格为 每活动秒 $0.0001,从请求首次运行沙箱命令的那一刻起计费,直到最后一条沙箱命令结束。请求结束后容器空闲的时间不计费。
当请求启动一个冷容器(无论是新建的还是已进入空闲状态的)时,我们按最低 30 秒计费。如果智能体连续向同一容器发出多个请求,只有第一个请求需要支付最低时长费用。
按请求计费让查找运行某个特定请求的成本变得很容易。一个请求的成本等于其 token 成本加上沙箱时长,而沙箱时长会在日志页面的请求时间线中作为单独一行显示。
Files API 的使用不单独收费,但总存储空间限制为 10 GiB。
为工作区禁用工具
服务器工具默认启用。工作区管理员可以从工作区的 Server Tools 页面关闭其中任意工具,每个工具都有一个显示“可用”或“已阻止”的开关。该设置适用于工作区发出的每一个请求,无论是通过 API 密钥、聊天室还是预设配置发出的。
Shell、Bash、Files API 和容器目前处于测试阶段,现已可用。API 在测试期间可能会发生变化。如果有任何功能不符合你的预期,请在我们的 Discord 的 #feedback 频道告诉我们。
Introducing the openrouter:shell server tool and the Files API: any model on OpenRouter can now run commands in a hosted Linux container. The Files API enables upload of files for models to work with and the download of outputs. Both are available today in beta.
Shell and Files join our growing list of server tools, enabling you to create server-side agentic behaviors you can swap across models. For example, you can ask any model to search the web, write a script that turns the results into a chart, and run it entirely with server-side compute.


Try it in the chatroom by turning on the shell tool, and read the shell, containers, and Files API guides for the API details. Sandbox time costs $0.0001 per second, is billed as part of the request, and includes Files API usage. Details are in the Pricing section.
How shell works
To use openrouter:shell, send it in the tools array for any model that supports tool calling. This lets the model decide when it needs a terminal and when to invoke it:
curl https://openrouter.ai/api/v1/responses \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro-0813",
"input": "Check the Python version, then write a script that prints the first 20 primes and run it.",
"tools": [
{ "type": "openrouter:shell", "parameters": { "engine": "openrouter" } }
]
}' We’ve introduced three capabilities that work together to provide server-side command execution and files:
- Shell and Bash: We support the OpenAI-compatible Shell tool, on the Responses API and the Anthropic Messages API, as well as
openrouter:bash, the Anthropic-compatible Bash tool, on the Messages API. Both work with any model. - Files API: workspace storage under
/api/v1/files. Upload files, attach them to a container by id, and keep the files a run produces. - Containers: these are the sandbox where shell commands run. Files written there persist between requests that share a container id. You can access the container’s contents through the
/api/v1/containersAPI.
When the model calls the tool, it emits a batch of commands. They are executed within the container, each in its own invocation, and return stdout, stderr, and an exit code to the model. This allows the model to react to the output it receives. For example, if it writes a script to parse your CSV and the parse fails, it can see the problem on stderr and fix the script before answering.
The generation details view on the Logs page shows the request as a timeline. The model turns and the sandbox run appear as separate rows, each with its own duration and cost:

Shell and bash
We shipped two different tools for sandbox command execution to provide compatibility with both the OpenAI and Anthropic spec. The most notable difference is that the bash tool’s default is to ask your app to run the command locally. On OpenRouter, you can change the engine to override this behavior and execute on the server.
openrouter:shell | openrouter:bash | |
|---|---|---|
| Compatible with | OpenAI’s shell tool | Anthropic’s bash tool |
| APIs | Responses, Messages | Messages |
| Runs commands by default | In the OpenRouter sandbox | In your application |
engine: "openrouter" on either tool guarantees server-side execution in the OpenRouter sandbox with any model.
Containers
A container is an isolated Linux environment on OpenRouter’s infrastructure scoped to your workspace. Containers can be configured for the needs of your app:
- Network: outbound access is off by default. For jobs like
pip3 install, setnetwork_policyto an allowlist such as{ "type": "allowlist", "allowed_domains": ["pypi.org", "files.pythonhosted.org"] }, or{ "type": "allowlist", "allowed_domains": ["*"] }for unrestricted egress. Allowlisted hosts are reachable on ports 80 and 443; requests to domains outside the allowlist fail with HTTP 520 rather than a connection error. The policy cannot be changed after the container starts. - Files: only files under the home directory (
/workspace/home) are captured. Each shell result also returns a list of ids for the files a command created or changed (prefixed withcfile_). The container files endpoint lists everything saved in the container, and the Files API is for moving files in and out. - Reuse across requests: by default, a conversation gets a fresh container. If a request includes a
session_idor a previous shell result with an identifiable container, that container is reused. To pick a container explicitly, pass{ "type": "container_reference", "container_id": "my-project" }in the tool’senvironmentfield. - Lifetime: a container sleeps after 5 minutes idle. This is not configurable.
Files and shell together
The Files API is workspace storage that sits alongside the container. You upload inputs there for shell to work on, and you move shell’s outputs back into it.
Upload a file for shell
Upload the input with POST /api/v1/files. The response includes a file id that starts with or_file_:
curl https://openrouter.ai/api/v1/files \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-F "file=@data/sales.csv" Then attach it by id in the tool’s environment:
{
"type": "openrouter:shell",
"parameters": {
"engine": "openrouter",
"environment": {
"type": "container_auto",
"file_ids": ["or_file_011CNha8iCJcU1wXNR6q4V8w"]
}
}
} Attached files appear in the home directory as writable copies, up to 20 per container. Each copy is named with the last 8 characters of the file id plus the original filename, so data/sales.csv attached with the id above becomes ~/NR6q4V8w-sales.csv. Changes inside the container won’t affect the original workspace file. A container starts with only the files you attach to it.
Download a file shell generated
Each shell result lists the files the command touched, with a cfile_ id for each. Download the files with the container file content endpoint:
curl "https://openrouter.ai/api/v1/containers/$CONTAINER_ID/files/$FILE_ID/content" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-o output.txt Container files are kept for 30 days. To keep one for the long term, promote it:
curl -X POST "https://openrouter.ai/api/v1/containers/$CONTAINER_ID/files/$FILE_ID/promote" \
-H "Authorization: Bearer $OPENROUTER_API_KEY" Promoting copies the container file into your workspace and returns a new or_file_ id, which you can attach to a later run the same way as an upload. Unlike uploads, promoted files are downloadable through the Files API.
Files API details
You can view all of your files on the workspace files page. Files you upload directly cannot be downloaded, but files promoted from a container can.
Using multiple server tools together
Shell is one of many server tools we offer and are powerful when working together. Here the model uses web search to find material and shell to turn it into a file:
curl https://openrouter.ai/api/v1/responses \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro-0813",
"input": "Look up the three biggest open-source AI releases this week, then write ~/out/releases.md with one paragraph each and a source link.",
"tools": [
{ "type": "openrouter:web_search" },
{ "type": "openrouter:shell", "parameters": { "engine": "openrouter" } }
]
}' The resulting ~/out/releases.md shows up in the shell result’s file list, and you download it with the container file content endpoint above.
This combination also matters if you don’t want to give the container network access. Web search runs outside the container, so the model can pull in web content and pass it into its commands while the container stays on the default network policy with no internet access of its own.
In the chatroom, the same combination works with the shell and web search switches turned on. Files the run creates appear in the conversation as downloads.
Pricing
Shell and Bash usage is billed by sandbox time. The price is $0.0001 per active second, metered from the moment a request first runs a sandbox command until the last sandbox command. Time a container spends idle after the request ends is not billed.
We bill a minimum of 30 seconds when a request starts a cold container, either a new one or one that has gone idle. If an agent makes several requests to the same container in succession, only the first pays the minimum.
Billing per request makes it easy to find the cost to run a specific request. A request’s cost is its token cost plus its sandbox time, and the sandbox time appears as its own row in the request’s timeline on the Logs page.
Files API usage has no separate charge, but total storage is limited to 10 GiB.
Disabling tools for a workspace
Server tools are enabled by default. A workspace admin can turn any of them off from the workspace’s Server Tools page, where each tool has a switch showing Available or Blocked. The setting applies to every request the workspace makes, whether through API keys, the chatroom, or presets.
Shell, Bash, the Files API, and containers are in beta and available now. The API may change during the beta. If something doesn’t work the way you expect, let us know in #feedback on our Discord.