Voice
Ptc
Programmatic Tool Calling plugin for OpenClaw - run multi-step tool workflows in a Docker sandbox
Install
npm install
npm
Configuration Example
{
"plugins": {
"entries": {
"ptc-sandbox": {
"enabled": true,
"config": {
"sandboxImage": "python:3.12-slim",
"timeoutSeconds": 60,
"memoryLimit": "256m",
"cpuLimit": "0.5"
}
}
}
},
"agents": {
"list": [
{
"id": "main",
"tools": {
"allow": ["ptc_execute", "group:openclaw"]
}
}
]
}
}
README
# OpenClaw PTC Plugin
Programmatic Tool Calling for OpenClaw — lets the agent write Python scripts
that orchestrate multiple tool calls in an isolated Docker sandbox.
## How It Works
```
User request
-> OpenClaw agent decides to use ptc_execute
-> Agent generates Python code
-> Code runs in Docker (--network none, memory/CPU limited)
-> Tool stubs in sandbox write requests to /shared/requests.jsonl
-> Host-side polls requests, executes real handlers, writes responses
-> Sandbox reads responses, continues execution
-> print() output returned to agent for summarisation
```
The sandbox has **no network access**. All external calls go through
host-side tool handlers that have full network and system access.
## Installation
```bash
# 1. Clone / download
cd ~/openclaw-ptc
# 2. Install deps and build
npm install
npm run build
# 3. Pull the sandbox image
docker pull python:3.12-slim
# 4. Install into OpenClaw (local link for development)
openclaw plugins install -l ~/openclaw-ptc
# 5. Restart gateway
openclaw gateway --force
# 6. Verify
openclaw plugins list
```
## Configuration
In `openclaw.json`:
```json
{
"plugins": {
"entries": {
"ptc-sandbox": {
"enabled": true,
"config": {
"sandboxImage": "python:3.12-slim",
"timeoutSeconds": 60,
"memoryLimit": "256m",
"cpuLimit": "0.5"
}
}
}
},
"agents": {
"list": [
{
"id": "main",
"tools": {
"allow": ["ptc_execute", "group:openclaw"]
}
}
]
}
}
```
## Adding Your Own Tools
Edit `index.ts` and add to the registry section:
```typescript
registry.register({
name: "my_api_tool",
description: "Call my custom API",
parameters: {
endpoint: "API endpoint path",
params: "Query parameters dict",
},
handler: async (kwargs) => {
const resp = await fetch(`https://api.example.com/${kwargs.endpoint}`, {
headers: { Authorization: `Bearer ${process.env.MY_API_KEY}` },
});
return await resp.json();
},
});
```
The tool automatically becomes available in the sandbox as
`my_api_tool(endpoint="...", params={...})`.
### Real Database Example
```typescript
import pg from "pg";
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
registry.register({
name: "query_database",
description: "Execute a read-only SQL query",
parameters: { sql: "SELECT query" },
handler: async (kwargs) => {
const sql = kwargs.sql.trim();
if (!sql.toUpperCase().startsWith("SELECT")) {
return { error: "Only SELECT queries allowed" };
}
const client = await pool.connect();
try {
const result = await client.query(sql);
return result.rows;
} finally {
client.release();
}
},
});
```
## Docker-in-Docker (TrueNAS / Container Setups)
If your OpenClaw gateway itself runs in Docker, mount the Docker socket:
```bash
docker run ... -v /var/run/docker.sock:/var/run/docker.sock ...
```
## Security
The sandbox enforces:
- `--network none` (no network)
- `--memory 256m` (configurable)
- `--cpus 0.5` (configurable)
- `--pids-limit 50`
- `--read-only` root filesystem
- `/shared` is the only writable mount
Host-side tool handlers should validate input (e.g. block destructive SQL).
## License
MIT
voice
Comments
Sign in to leave a comment