Skip to main content
Glama

Paddock

Give AI agents room to run, not the whole farm.

Paddock is a persistent Linux MCP workbench for ChatGPT, Claude, IDE agents, and other MCP clients. It provides files, Bash, SSH/SFTP, and 100 GB of durable storage while fencing the workload away from the host, private networks, and unbounded resources.

MCP client
   |
   | SSH/stdio, OpenAI tunnel, Tailscale, or Cloudflare
   v
+------------------------ Ubuntu host -------------------------+
|  optional ingress --> private MCP API --> /workspace (100 GB)|
|                         |                                    |
|  SSH :30222 ----------> | isolated containers, 4 CPU / 16 GB |
|                         v                                    |
|                    filtered web proxy --> public HTTP(S)     |
+--------------------------------------------------------------+

There is no published MCP port. The server listens only on an internal Docker bridge; ingress is either the existing key-only SSH path or an explicit, outbound connector profile. Commands can reach the web only through a filtered HTTP/HTTPS proxy.

WARNING

Paddock grants an AI arbitrary Bash access inside its workspace. It can overwrite files, delete data, download software, and send workspace data to public websites. Paddock limits the blast radius; it does not make an untrusted command harmless. Read thethreat model.

What is in the paddock?

Tool

What it does

workspace_status

Reports capacity and enforced compute limits

list_workspace

Lists bounded directory trees without following symlinked directories

read_workspace_file

Reads text or base64 in chunks

write_workspace_file

Creates or atomically replaces bounded files

delete_workspace_path

Deletes a file or an explicitly requested directory tree

run_workspace_command

Runs Bash with time, output, process, CPU, and memory limits

The same workspace is available over key-only SSH/SFTP for human inspection, large transfers, and recovery when a chat takes an unfortunate turn.

Related MCP server: MCP Files

Requirements

Paddock currently targets one specific, inspectable deployment:

  • Ubuntu 24.04 with systemd

  • Rootful Docker Engine and the Compose v2 plugin

  • nftables, ext4 tools, util-linux, OpenSSH client tools, and sudo

  • A readable Ed25519 or RSA public key, defaulting to ~/.ssh/id_ed25519.pub

  • Three unused Docker subnets: 10.88.0.0/24, 10.89.0.0/24, and 10.90.0.0/24

  • Enough disk for a sparse 100 GB workspace image as it fills

  • At least one supported ingress path from Ingress options

Docker Desktop, rootless Docker, non-systemd hosts, and hosts where UID 11000 is already assigned are intentionally rejected rather than partially secured.

Quick start

1. Install Paddock

Install Docker Engine using Docker's Ubuntu instructions, then install the host tools:

sudo apt-get update
sudo apt-get install -y e2fsprogs nftables openssh-client util-linux

Clone and install:

git clone https://github.com/AnishDe12020/paddock.git
cd paddock
./scripts/install.sh --ssh-host paddock.example.com

Use --ssh-key /path/to/key.pub when your public key is elsewhere. The installer:

  1. checks the host and key before changing anything;

  2. creates a sparse ext4 workspace at /var/lib/paddock/workspace.ext4;

  3. installs the systemd slice, nftables boundary, and SSH socket;

  4. builds and starts the containers; and

  5. prints the SSH command when the stack is healthy.

The SSH listener is 30222/tcp. The installer adds a rate-limited UFW rule only when UFW is already active. With another host firewall, allow that port yourself, preferably from trusted source addresses only.

2. Choose an ingress

Paddock starts with no remote MCP connector enabled. Choose the narrowest path your client supports:

Ingress

Best for

Exposure and authority

SSH/stdio

Claude Code/Desktop, Cursor, VS Code, local MCP clients

Reuses key-only SSH; no new listener

OpenAI Secure Tunnel

ChatGPT

Outbound-only; authorized by OpenAI workspace permissions

Tailscale Serve

Private devices and IDEs

Tailnet-only HTTPS; authorized by tailnet policy

Cloudflare Tunnel

Clients that support Cloudflare Access

Public edge URL; Access policy is mandatory

External HTTPS + OAuth

Hosted, standards-compliant MCP clients

Operator-supplied TLS and MCP OAuth 2.1

See Ingress options for compatibility and security details.

SSH/stdio

Every install can expose MCP over the existing SSH connection without another daemon or credential:

{
  "mcpServers": {
    "paddock": {
      "command": "ssh",
      "args": ["-T", "-p", "30222", "ai@paddock.example.com", "paddock-mcp-stdio"]
    }
  }
}

The SSH key grants both shell and MCP authority over the workspace.

OpenAI Secure Tunnel

Create a tunnel in OpenAI Platform tunnel settings. Associate it with both the Platform organization and the ChatGPT workspace that should see it.

Create a restricted runtime API key in Runtime API keys with only Tunnels: Read + Use. Do not use an admin key or an unrestricted model API key for the daemon.

Activate it:

./scripts/activate-tunnel.sh tunnel_0123456789abcdef0123456789abcdef

The key prompt is hidden. The script installs it as a root-only file, starts the pinned official tunnel-client image, and waits for an authenticated control-plane handshake.

Add it to ChatGPT:

Open ChatGPT apps, create a developer-mode app, and choose:

  • Connection: Tunnel

  • Tunnel: your Paddock tunnel

  • Authentication: None / No authentication

The runtime API key authenticates the tunnel daemon. Paddock deliberately does not implement user OAuth on the private MCP hop.

Tailscale Serve

After enabling HTTPS for your tailnet and creating an OAuth client authorized to create tag:paddock devices:

./scripts/activate-tailscale.sh paddock.your-tailnet.ts.net OAUTH_CLIENT_ID

Connect tailnet-capable clients to https://paddock.your-tailnet.ts.net/mcp. Restrict that node with Tailscale grants or ACLs; every identity permitted to reach it receives the full advertised MCP authority.

Cloudflare Tunnel

Create a remotely managed tunnel and public hostname with service http://10.89.0.4:8000 and HTTP Host Header 10.89.0.4. Protect it with a tested Cloudflare Access application before activating the connector:

./scripts/activate-cloudflare.sh --access-policy-ready

Cloudflare Tunnel alone is not authentication. Do not enable this profile for an unprotected hostname. It is most useful for MCP clients that can send Access service-token headers; it is not a substitute for standard MCP OAuth.

Try:

Use Paddock. Show its workspace status, create hello.txt, run `uname -a`,
read the file back, and then tell me exactly what you changed.

The fence posts

Paddock relies on several independent boundaries rather than one magic "sandbox" switch:

  • Explicit MCP transport: there is no published container port. Each optional connector receives only the network path required for its job.

  • Unprivileged tools: MCP file and command operations run as UID 11000 with every Linux capability dropped and no-new-privileges enabled.

  • Read-only roots: containers can write only to /workspace and bounded tmpfs mounts.

  • Filtered egress: workloads have internal-only networks and can reach the internet only through Squid on ports 80/443. Private, loopback, link-local, metadata-like, and all IPv6 destinations are denied.

  • Host firewall: nftables blocks sandbox-initiated host/sibling traffic and blocks the proxy from looping back into the host or private networks.

  • Resource boundary: a systemd slice caps aggregate compute at 4 CPUs, 16 GiB RAM, no swap, and 1024 tasks. Commands also have a 300-second maximum and bounded captured output.

  • Dedicated storage: startup fails closed unless /workspace is the expected loop-backed ext4 filesystem.

  • Key-only SSH: password login, root login, forwarding, tunneling, agent forwarding, and user startup hooks are disabled; stdio MCP reuses this path.

See Architecture for the packet paths and Threat model for what these controls do and do not protect.

Operations

# Service state
sudo docker compose ps

# Recent logs
sudo docker compose logs --tail=100

# Host boundaries
sudo systemctl status paddock-firewall.service paddock-ssh.socket
sudo nft list table inet paddock

# Run the live MCP protocol test from this checkout
MCP_URL=http://10.89.0.4:8000/mcp pytest tests/integration

# Redeploy after an update; data and keys are preserved
./scripts/install.sh --ssh-host paddock.example.com

Back up /srv/paddock-workspace like any other live filesystem. The sparse image grows with use; "100 GB sparse" is a capacity limit, not a promise that it consumes no host disk.

Development

python3 -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
ruff check .
ruff format --check .
pytest tests/unit
docker compose config --quiet

The integration suite skips when no private MCP endpoint is reachable. See CONTRIBUTING.md before changing a security boundary.

Project status

Paddock is alpha software and intentionally narrow. It is a useful deployment reference, not a multi-tenant service or a hardened malware-analysis VM. Security reports are welcome through GitHub private vulnerability reporting; see SECURITY.md.

Paddock is licensed under the MIT License. OpenAI's tunnel-client is pulled as a separately licensed, digest-pinned container and is not redistributed in this repository.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

No tool schema history has been recorded yet.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Provides AI coding agents with a secure, sandboxed environment for executing coding tasks including file operations, command execution, and testing. Features session management, policy enforcement, and Docker-based sandboxing for safe code execution and development workflows.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a secure, constrained filesystem workspace for LLM agents to manage files, notes, and code artifacts via stdio or remote HTTP. It features granular access controls, including extension whitelisting, storage quotas, and immutable paths for safe automated file operations.
    BSD 3-Clause
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents to safely read and write files in a sandboxed workspace via natural language, with on-demand connection, CVE-hardened path confinement, injection resistance, and full audit logging.
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AnishDe12020/paddock'

If you have feedback or need assistance with the MCP directory API, please join our Discord server