Run shell commands in hosted containers or your own local runtime.
The shell tool gives models the ability to work inside a complete terminal environment. We support shell for local execution and for hosted execution through the Responses API.
The shell tool lets models run commands through either:
Shell is available through the Responses API. It’s not available via the Chat Completions API.
Running arbitrary shell commands can be dangerous. Always sandbox execution,
apply allowlists or denylists where possible, and log tool activity for
auditing.
Hosted shell quickstart
Hosted shell is a native and streamlined option for tasks that need richer, deterministic processing, from running calculations to working with multimedia.
Use container_auto when you want OpenAI to provision and manage a container for the request.
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.2",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_reference",
"container_id": "cntr_08f3d96c87a585390069118b594f7481a088b16cda7d9415fe"
}
}
],
"input": "List files in the container and show disk usage."
}'
import OpenAI from"openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5.2",
tools: [
{
type: "shell",
environment: {
type: "container_reference",
container_id: "cntr_08f3d96c87a585390069118b594f7481a088b16cda7d9415fe",
},
},
],
input: "List files in the container and show disk usage.",
});
console.log(response.output_text);
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.2",
tools=[
{
"type": "shell",
"environment": {
"type": "container_reference",
"container_id": "cntr_08f3d96c87a585390069118b594f7481a088b16cda7d9415fe",
},
}
],
input="List files in the container and show disk usage.",
)
print(response.output_text)
Attach skills
Skills are reusable, versioned bundles that you can mount in hosted shell environments. This defines the available skills, and at shell execution time the model decides whether to invoke them.
Use the Skills guide for upload and versioning details.
Allowlisting domains introduces security risks such as prompt
injection-driven data exfiltration. Only allowlist domains you trust and that
attackers cannot use to receive exfiltrated data. Carefully review the Risks
and safety section below before using this tool.
Network policy precedence
When multiple controls are present:
Your org allow list defines the full set of allowed_domains.
Request-level network_policy further restricts access.
Requests fail if allowed_domains includes domains outside your org allow list.
Domain secrets
Use domain_secrets when a domain in your allowed_domains list requires private authorization headers, such as Authorization: Bearer <token>.
Each secret entry includes:
Target domain
Friendly secret name
Secret value
At runtime:
The model and runtime see placeholder names (for example, $API_KEY) instead of raw credentials.
The auth-translation sidecar applies raw secret values only for approved destinations.
Raw secret values don’t persist on API servers and don’t appear in model-visible context.
This lets the assistant call protected services while reducing leakage risk.
Shell tool with domain_secrets
Select...
curl -L 'https://api.openai.com/v1/responses' \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.2",
"input": [
{
"role": "user",
"content": "Use curl to call https://httpbin.org/headers with header Authorization: Bearer $API_KEY. Tell me what you see in the final text response."
}
],
"tool_choice": "required",
"tools": [
{
"type": "shell",
"environment": {
"type": "container_auto",
"network_policy": {
"type": "allowlist",
"allowed_domains": ["httpbin.org"],
"domain_secrets": [
{
"domain": "httpbin.org",
"name": "API_KEY",
"value": "debug-secret-123"
}
]
}
}
}
]
}'
import OpenAI from"openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5.2",
input: [
{
role: "user",
content:
"Use curl to call https://httpbin.org/headers with header Authorization: Bearer $API_KEY. Tell me what you see in the final text response.",
},
],
tool_choice: "required",
tools: [
{
type: "shell",
environment: {
type: "container_auto",
network_policy: {
type: "allowlist",
allowed_domains: ["httpbin.org"],
domain_secrets: [
{
domain: "httpbin.org",
name: "API_KEY",
value: "debug-secret-123",
},
],
},
},
},
],
});
console.log(response.output_text);
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.2",
input=[
{
"role": "user",
"content": "Use curl to call https://httpbin.org/headers with header Authorization: Bearer $API_KEY. Tell me what you see in the final text response.",
}
],
tool_choice="required",
tools=[
{
"type": "shell",
"environment": {
"type": "container_auto",
"network_policy": {
"type": "allowlist",
"allowed_domains": ["httpbin.org"],
"domain_secrets": [
{
"domain": "httpbin.org",
"name": "API_KEY",
"value": "debug-secret-123",
}
],
},
},
}
],
)
print(response.output_text)
Multi-turn workflows
To continue work in the same hosted environment, reuse the container and pass previous_response_id.
You can also run shell commands in your own local runtime by executing shell_call actions and sending shell_call_output back to the model.
Use this mode when you need full control over execution environment, filesystem access, or existing internal tooling.
Local shell request
Select...
curl -L 'https://api.openai.com/v1/responses' \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "gpt-5.2",
"instructions": "The local bash shell environment is on Mac.",
"input": "find me the largest pdf file in ~/Documents",
"tools": [{ "type": "shell", "environment": { "type": "local" } }]
}'
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.2",
instructions="The local bash shell environment is on Mac.",
input="find me the largest pdf file in ~/Documents",
tools=[{"type": "shell", "environment": {"type": "local"}}],
)
print(response)
import OpenAI from"openai";
const client = new OpenAI();
const response = await client.responses.create({
model: "gpt-5.2",
instructions: "The local bash shell environment is on Mac.",
input: "find me the largest pdf file in ~/Documents",
tools: [{ type: "shell", environment: { type: "local" } }],
});
console.log(response);
When you receive shell_call output items:
Execute requested commands in your runtime.
Capture stdout, stderr, and outcome.
Return results as shell_call_output in the next request.
If a command exceeds your execution timeout, return a timeout outcome and include partial captured output.
If max_output_length is present on shell_call, include it in shell_call_output.
Don’t rely on interactive commands; shell tool execution should be non-interactive.
Preserve non-zero exit outputs so the model can reason about recovery steps.
Risks and safety
Enabling network access in the Containers API is a powerful capability, and it introduces meaningful security and data-governance risk. By default, network access is not enabled. When enabled, outbound access should remain tightly scoped to trusted domains needed for the task.
Network-enabled containers can interact with third-party services and package registries. That creates risks including data exfiltration, prompt-injection-driven tool misuse, and accidental access beyond intended boundaries. These risks increase when policies are broad, static, or inconsistently enforced.
Understand prompt injection risks from network-retrieved content
Any external content fetched over the network may contain hidden instructions intended to manipulate model behavior. Treat untrusted network content as potentially adversarial, and require additional caution for actions that can modify data or systems.
Connect only to trusted destinations
Allow only domains you trust and actively maintain. Be cautious with intermediaries and aggregators that proxy to other services, and review their data handling and retention practices before allowlisting.
Build in reviews before and after requests are executed
Review the shell tool command and execution output, which are provided in the Responses API response. Capture requested hosts and actual outbound destinations for each session. Periodically review logs to verify access patterns match expectations, detect drift, and identify suspicious behavior.
Validate data residency and retention requirements
OpenAI data controls apply within OpenAI boundaries. However, data transmitted to third-party services over network connections is subject to their data retention policies. Ensure external endpoints meet your residency, retention, and compliance requirements.