# How to Use the run_script Tool for Sandboxed Python Script Execution in AWS MCP Server

> Learn to use the AWS MCP Server run_script tool for secure, sandboxed Python script execution in isolated micro-VMs. Get stdout, stderr, and exit codes via JSON.

- Repository: [Amazon Web Services/agent-toolkit-for-aws](https://github.com/aws/agent-toolkit-for-aws)
- Tags: how-to-guide
- Published: 2026-06-26

---

**The AWS MCP Server's `run_script` tool executes Python code inside isolated Firecracker micro-VMs with strict resource limits (default 1 vCPU and 512 MiB RAM), returning stdout, stderr, and exit codes via JSON while blocking network access and host filesystem interactions.**

The `aws/agent-toolkit-for-aws` repository provides the AWS MCP (Managed Compute Platform) Server, which exposes the `run_script` tool for secure, isolated execution of user-supplied Python scripts. This capability enables skills to perform complex calculations and data transformations without risking host system security or credential exposure.

## How the run_script Tool Works

The `run_script` tool launches a sandboxed environment for each invocation, ensuring complete isolation between executions and the host system.

### Firecracker Micro-VM Isolation

According to the [`plugins/aws-core/README.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-core/README.md), the AWS MCP Server runs each script inside a **Firecracker micro-VM**. This architecture provides strong tenant isolation by launching a lightweight virtual machine for every script execution. As implemented in the AWS Core plugin, the micro-VM is automatically terminated after the script completes or exceeds its timeout, leaving no residual state on the host.

### Resource and Network Constraints

The sandbox enforces strict boundaries on every execution:

- **CPU and Memory**: Default limits of approximately 1 vCPU and 512 MiB RAM
- **Network Access**: Outbound connections are disabled unless explicitly allowed by the surrounding skill
- **Filesystem Protection**: Scripts operate within an empty temporary filesystem confined to `/tmp`, preventing access to host disks or sensitive system paths

These constraints are documented in [`skills/core-skills/aws-billing-and-cost-management/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-billing-and-cost-management/SKILL.md), which outlines the sandbox contract for deterministic calculations.

## Request Format and Parameters

Skills invoke `run_script` by constructing a JSON payload that specifies the language and script content.

### JSON Payload Structure

The toolkit forwards requests to the MCP server using this format:

```json
{
  "tool": "run_script",
  "input": {
    "language": "python",
    "script": "import json, sys\npayload = json.loads(sys.stdin.read())\nprint(payload['value'] * 2)"
  }
}

```

The `language` field must specify `"python"`, and the `script` field contains the complete Python code to execute. The MCP server validates this payload before launching the micro-VM.

### Reading Input via stdin

Scripts receive input data through standard input as JSON. The pattern shown in [`skills/core-skills/aws-billing-and-cost-management/references/deterministic-calculations.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-billing-and-cost-management/references/deterministic-calculations.md) demonstrates reading and parsing stdin:

```python
import json, sys

data = json.loads(sys.stdin.read())
bytes_val = data["bytes"]
gb = bytes_val / (1024 ** 3)
print(gb)

```

This approach allows skills to pass dynamic data into the sandboxed environment without environment variables or command-line arguments.

## Complete Code Examples

The following patterns demonstrate practical implementations for the `run_script` tool.

### Basic Calculation with Inline Script

For simple arithmetic or data conversions, embed the logic directly in the request:

```json
{
  "tool": "run_script",
  "input": {
    "language": "python",
    "script": "\nimport json, sys\npayload = json.loads(sys.stdin.read())\nbytes_tx = payload[\"bytes_transferred\"]\nprice_per_gb = 0.09\ncost = (bytes_tx / (1024**3)) * price_per_gb\nprint(f\"${cost:.2f}\")\n"
  }
}

```

This example from the billing calculations reference converts bytes to gigabytes and calculates AWS data transfer costs at $0.09 per GB.

### Complex Logic with Helper Functions

When scripts require multiple functions or utilities, concatenate all code into a single self-contained script:

```json
{
  "tool": "run_script",
  "input": {
    "language": "python",
    "script": "\nimport math\nimport json, sys\n\ndef round_two(val):\n    return round(val, 2)\n\npayload = json.loads(sys.stdin.read())\nbytes_val = payload[\"bytes\"]\nGB = bytes_val / (1024 ** 3)\nprint(round_two(GB))\n"
  }
}

```

Since the sandbox lacks a persistent filesystem, all helper code must be included in the `script` field.

### Error Handling and Exit Codes

The MCP server returns a JSON object containing `stdout`, `stderr`, and `exit_code`. Robust skills should validate execution status before processing results:

```python

# Skill-side error handling

result = mcp.call_tool(
    tool="run_script",
    input={
        "language": "python",
        "script": "print(1/0)"
    }
)

if result["exit_code"] != 0:
    raise RuntimeError(f"Script failed: {result['stderr']}")
value = float(result["stdout"].strip())

```

This pattern captures Python exceptions through `stderr` and allows the skill to handle failures gracefully without crashing the execution environment.

## Security Guarantees and Safety Checks

The `aws/agent-toolkit-for-aws` repository implements multiple layers of security around the `run_script` tool.

### Secret Safety Validation

The [`plugins/aws-core/hooks/secret-safety.py`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-core/hooks/secret-safety.py) hook inspects skill code for `run_script` references to enforce secret-safety policies. This validation ensures that scripts do not leak credentials or sensitive environment variables through the tool's input or output streams.

### Filesystem and Network Isolation

As implemented in the AWS Core plugin, the sandbox prevents scripts from:
- Accessing environment variables from the host
- Reading or writing to host filesystem paths outside `/tmp`
- Establishing outbound network connections
- Persisting data between executions

These guarantees ensure that untrusted code supplied by users or generated by agents cannot compromise the MCP host or exfiltrate data.

## Summary

- The `run_script` tool in AWS MCP Server executes Python inside Firecracker micro-VMs with strict isolation guarantees.
- Requests require a JSON payload with `language` set to `"python"` and a `script` field containing the executable code.
- Scripts read input via `sys.stdin` and write results to `stdout`, with the server returning both streams plus an `exit_code`.
- Resource limits default to 1 vCPU and 512 MiB RAM, with no network access and filesystem restricted to `/tmp`.
- The [`secret-safety.py`](https://github.com/aws/agent-toolkit-for-aws/blob/main/secret-safety.py) hook validates skill usage to prevent credential leakage.

## Frequently Asked Questions

### What is the default resource limit for run_script executions?

The AWS MCP Server limits each sandboxed execution to approximately 1 vCPU and 512 MiB of RAM. These boundaries prevent resource exhaustion attacks and ensure fair usage across concurrent skill invocations. The micro-VM automatically terminates if the script exceeds these limits or completes execution.

### Can run_script access external APIs or databases?

No. By default, the sandbox disables outbound network access, preventing scripts from reaching external services, APIs, or databases. This restriction is documented in [`plugins/aws-core/README.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-core/README.md) and ensures that untrusted code cannot exfiltrate data or access remote resources. Skills requiring external data must fetch it before invoking `run_script` and pass the data through stdin.

### How does the MCP Server handle Python exceptions?

When a script raises an exception, the MCP Server captures the traceback in the `stderr` field of the response JSON and sets `exit_code` to a non-zero value. The skill can then inspect these fields to determine failure and handle the error appropriately. The micro-VM is destroyed after capturing the error state, ensuring no residual impact on the host system.

### Where is the run_script tool defined in the source code?

Usage patterns and security contracts for `run_script` are documented in [`skills/core-skills/aws-billing-and-cost-management/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-billing-and-cost-management/SKILL.md) and [`skills/core-skills/aws-billing-and-cost-management/references/deterministic-calculations.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/skills/core-skills/aws-billing-and-cost-management/references/deterministic-calculations.md). The security validation logic resides in [`plugins/aws-core/hooks/secret-safety.py`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-core/hooks/secret-safety.py), while the sandbox capabilities are announced in [`plugins/aws-core/README.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-core/README.md).