Tools
Plugin Claude Code
OpenClaw Plugin - Run Claude Code asynchronous in Podman (or Docker) containers
Install
npm install
```
Configuration Example
{
"plugins": {
"enabled": true,
"load": {
"paths": ["path/to/dist/index.js"]
},
"entries": {
"claude-code": {
"enabled": true,
"config": {
"image": "ghcr.io/13rac1/openclaw-claude-code:latest",
"runtime": "podman",
"startupTimeout": 30,
"idleTimeout": 120,
"memory": "512m",
"cpus": "1.0",
"network": "bridge",
"sessionsDir": "~/.openclaw/claude-sessions",
"workspacesDir": "~/.openclaw/workspaces",
"sessionIdleTimeout": 3600
}
}
}
}
}
README
# OpenClaw Plugin: Claude Code
[](https://github.com/13rac1/openclaw-plugin-claude-code/actions/workflows/ci.yml)
[](https://codecov.io/gh/13rac1/openclaw-plugin-claude-code)
[](https://www.npmjs.com/package/@13rac1/openclaw-plugin-claude-code)
[](https://opensource.org/licenses/Apache-2.0)
[](https://nodejs.org/)
[](https://www.typescriptlang.org/)
An [OpenClaw](https://openclaw.ai) plugin that runs Claude Code CLI sessions in isolated Podman (or Docker) containers. This enables OpenClaw agents to delegate complex coding tasks to Claude Code while maintaining security through containerization.
## Features
- **Isolated Execution**: Each Claude Code session runs in its own container with dropped capabilities
- **Session Persistence**: Sessions maintain state across multiple interactions
- **Dual Authentication**: Supports both API key and OAuth/Claude Max credentials
- **Resource Limits**: Configurable memory, CPU, and PID limits
- **AppArmor Support**: Optional AppArmor profile for additional security hardening
- **Automatic Cleanup**: Idle sessions are automatically cleaned up
## Requirements
- [OpenClaw](https://openclaw.ai) >= 2025.1.0
- [Podman](https://podman.io) (recommended) or Docker
- Node.js >= 22
## Installation
### From npm
```bash
openclaw plugins install @13rac1/openclaw-plugin-claude-code
```
### From GitHub Release
Download the release zip from [GitHub Releases](https://github.com/13rac1/openclaw-plugin-claude-code/releases) and extract to your plugins directory:
```bash
# Download latest release
curl -LO https://github.com/13rac1/openclaw-plugin-claude-code/releases/latest/download/openclaw-plugin-claude-code-1.0.0.zip
# Extract to plugins directory
unzip openclaw-plugin-claude-code-1.0.0.zip -d ~/.openclaw/plugins/openclaw-plugin-claude-code
```
### Container Image
The plugin requires a container image with Claude Code CLI installed. Pull the pre-built image:
```bash
podman pull ghcr.io/13rac1/openclaw-claude-code:latest
```
Or build it yourself:
```bash
podman build -t ghcr.io/13rac1/openclaw-claude-code:latest .
```
## Configuration
Add to your `openclaw.json`:
```json
{
"plugins": {
"enabled": true,
"load": {
"paths": ["path/to/dist/index.js"]
},
"entries": {
"claude-code": {
"enabled": true,
"config": {
"image": "ghcr.io/13rac1/openclaw-claude-code:latest",
"runtime": "podman",
"startupTimeout": 30,
"idleTimeout": 120,
"memory": "512m",
"cpus": "1.0",
"network": "bridge",
"sessionsDir": "~/.openclaw/claude-sessions",
"workspacesDir": "~/.openclaw/workspaces",
"sessionIdleTimeout": 3600
}
}
}
}
}
```
### Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `image` | string | `ghcr.io/13rac1/openclaw-claude-code:latest` | Container image for Claude Code |
| `runtime` | string | `podman` | Container runtime (`podman` or `docker`) |
| `startupTimeout` | number | `30` | Seconds to wait for container to produce first output |
| `idleTimeout` | number | `120` | Kill container after this many seconds of no output |
| `memory` | string | `512m` | Memory limit for containers |
| `cpus` | string | `1.0` | CPU limit for containers |
| `network` | string | `bridge` | Network mode (`none`, `bridge`, `host`) |
| `sessionsDir` | string | `~/.openclaw/claude-sessions` | Directory for session metadata |
| `workspacesDir` | string | `~/.openclaw/workspaces` | Directory for session workspaces |
| `sessionIdleTimeout` | number | `3600` | Cleanup idle sessions after this many seconds |
| `apparmorProfile` | string | `""` | AppArmor profile name (empty = disabled) |
| `maxOutputSize` | number | `10485760` | Maximum output size in bytes (10MB default, 0 = unlimited) |
## Authentication
The plugin supports two authentication methods:
### 1. OAuth / Claude Max (Recommended)
If you have Claude Max or enterprise OAuth credentials, place your credentials file at:
```
~/.claude/.credentials.json
```
The plugin will automatically copy this file into each container session.
### 2. API Key
Set the `ANTHROPIC_API_KEY` environment variable:
```bash
export ANTHROPIC_API_KEY=sk-ant-...
```
**Note**: If both are available, OAuth credentials take precedence.
## Registered Tools
### `claude_code_start`
Start a Claude Code task in the background. Returns immediately with a job ID.
**Parameters:**
- `prompt` (required): The task or prompt to send to Claude Code
- `session_id` (optional): Session ID to continue a previous session
**Returns:** `{ jobId: string, sessionId: string }`
### `claude_code_status`
Check the status of a running or completed job.
**Parameters:**
- `job_id` (required): Job ID returned from `claude_code_start`
- `session_id` (optional): Session ID
**Returns:** Status, elapsed time, output size, resource metrics, exit code, errors
### `claude_code_output`
Read or tail output from a job.
**Parameters:**
- `job_id` (required): Job ID
- `session_id` (optional): Session ID
- `offset` (optional): Byte offset to start reading from (for tailing)
- `limit` (optional): Maximum bytes to read (default 64KB)
**Returns:** Output content with `hasMore` flag for pagination
### `claude_code_cancel`
Cancel a running job and stop its container.
**Parameters:**
- `job_id` (required): Job ID
- `session_id` (optional): Session ID
### `claude_code_cleanup`
Clean up idle sessions and their jobs.
### `claude_code_sessions`
List all active sessions with age, last activity, message count, and active job info.
## Security
The plugin implements multiple layers of security:
1. **Rootless Containers**: Uses Podman rootless mode by default
2. **Capability Dropping**: All Linux capabilities are dropped (`--cap-drop ALL`)
3. **Resource Limits**: Memory, CPU, and PID limits prevent resource exhaustion
4. **tmpfs with noexec**: `/tmp` is mounted as tmpfs with `noexec,nosuid`
5. **Network Isolation**: Configurable network mode (can be set to `none`)
6. **AppArmor**: Optional AppArmor profile support for MAC enforcement
## Development
### Setup
```bash
git clone https://github.com/13rac1/openclaw-plugin-claude-code.git
cd openclaw-plugin-claude-code
npm install
```
### Build
```bash
npm run build
```
### Test
```bash
# Unit tests (mocked)
npm test
# Integration tests (requires Podman)
npm run test:integration
# All tests
npm run test:all
```
### Local Development
Link the plugin for development:
```bash
openclaw plugins install -l ./path/to/openclaw-plugin-claude-code
```
## Container Image
The included Dockerfile creates a Debian Bookworm-based image with:
- Node.js 22
- Claude Code CLI (npm global)
- Go 1.22.5 + TinyGo 0.32.0
- Python 3 with venv
- Common dev tools: git, ripgrep, jq, curl
### Building Multi-arch Images
```bash
# Single architecture (current)
podman build -t ghcr.io/13rac1/openclaw-claude-code:latest .
# Multi-architecture (arm64 + amd64)
GITHUB_USERNAME=13rac1 ./scripts/build-and-push.sh --multi-arch
```
## Releasing
Releases are automated via GitHub Actions when a version tag is pushed.
### Prerequisites
1. Configure `NPM_TOKEN` secret in GitHub repository settings
2. Ensure you have push access to the repository
### Release Process
1. Update version in `package.json`
2. Update `CHANGELOG.md` with release notes
3. Commit the changes:
```bash
git add package.json CHANGELOG.md
git commit -m "chore: release v1.x.x"
```
4. Create and push a version tag:
```bash
git tag v1.x.x
git push origin main --tags
```
The release workflow will automatically:
- Run tests
- Publish to npm with provenance
- Build and push multi-arch container images to ghcr.io
## Troubleshooting
### Container image not found
```
Error: Container image not found: ghcr.io/13rac1/openclaw-claude-code:latest
```
Pull or build the container image:
```bash
podman pull ghcr.io/13rac1/openclaw-claude-code:latest
```
### No authentication available
```
Error: No authentication available. Set ANTHROPIC_API_KEY or have ~/.claude/.credentials.json
```
Either:
1. Set `ANTHROPIC_API_KEY` environment variable, or
2. Place OAuth credentials at `~/.claude/.credentials.json`
### Startup timeout
```
Error: startup_timeout - No output within 30 seconds
```
The container failed to start or produce output. Check:
- Container image is valid
- Sufficient system resources
- Network connectivity (if `network: bridge`)
Increase `startupTimeout` if needed.
### Idle timeout
```
Error: idle_timeout - No output for 120 seconds
```
Claude Code stopped producing output. This may indicate:
- Task completed but output wasn't captured
- Claude Code is stuck
- Task requires more time (increase `idleTimeout`)
## FAQ
### Why Podman?
The primary reason is rootless. Podman runs containers without root privileges by default, which is essential for a tool that executes arbitrary code from AI agents. Docker can run rootless too, but it requires additional setup and isn't the default mode.
## License
Apache-2.0 - see [LICENSE](LICENSE)
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md)
tools
Comments
Sign in to leave a comment