How Agents Access Parlel
Agents reach Parlel services in a hosted sandbox with just a pk_ API key —
no install, no npm package, and no Parlel code in your application. There
are two ways in:
- The
parlel/bridgeDocker sidecar (recommended) — your app connects to plain hostnames; the sidecar does all the Parlel-specific work. - The raw HTTP API — provision a sandbox and connect your drivers yourself.
Both are documented below.
Remote Sandbox Access
When the services run in a Parlel sandbox (not in your local process), an agent reaches them with just an API key — no install, no infra, and no Parlel code in your application.
Recommended: the parlel/bridge sidecar
Add the published bridge image to your stack. It provisions a sandbox from a
pk_ key and exposes every dependency on a plain hostname, so your app connects
to parlel-bridge:<port> exactly as it would to a real service in production.
# docker-compose.test.yml
include:
- path: parlel-bridge.yml # image: parlel/bridge
services:
app:
build: .
env_file: test.env
depends_on:
parlel-bridge: { condition: service_healthy }
PARLEL_API_KEY=pk_... docker compose -f docker-compose.test.yml up
import psycopg, redis # unmodified, real wire protocol
db = psycopg.connect("postgres://parlel:parlel@parlel-bridge:5432/parlel")
cache = redis.Redis(host="parlel-bridge", port=6379)
The bridge sidecar is configured entirely by env:
| Env | Default | Notes |
|---|---|---|
PARLEL_API_KEY | (required) | your pk_ key |
PARLEL_API_URL | https://api.parlel.com | control-plane base URL |
PARLEL_SERVICES | postgres,redis,jira,stripe | catalog slugs to provision + bridge |
PARLEL_SANDBOX_ID | (unset) | attach to an existing sandbox instead |
The raw API (if you're not using the sidecar)
- Provision a sandbox:
POST /api/sandboxeswith apk_key. With noservicesspecified it defaults to Postgres + Redis; otherwise pass any catalog slugs (postgres,redis,kafka,rabbitmq,mysql,mongodb,cassandra, plus 240+ HTTP services). - Connect:
GET /api/sandboxes/{id}/connectionreturns atargetURL andpreview_tokenfor every service. HTTP services are reached at their preview URL with thex-daytona-preview-tokenheader. TCP services additionally include abridge_url— a WebSocket endpoint that tunnels raw bytes over the preview proxy (raw TCP can't cross the HTTPS-only proxy directly).
The parlel/bridge sidecar simply automates this: it terminates each
bridge_url as a local TCP listener and reverse-proxies the HTTP services with
the token injected — so unmodified psycopg / redis-py / kafkajs /
amqplib / CQL connect with no SSH tunnel and no daytona CLI. (For Kafka the
bridge binds 9092 so metadata-advertised reconnects land back on the bridge.)
The Flask CRUD example
runs the whole sidecar flow end-to-end from a single PARLEL_API_KEY.
Driving services in a sandbox (MCP)
Every sandbox exposes an MCP endpoint (mcp_url in the connection payload) for
AI coding agents. Use parlel_execute to run commands against any service —
handy for seeding data or inspecting state without a driver:
{
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {
"name": "parlel_execute",
"arguments": {
"service": "postgres",
"command": "CREATE TABLE users (id serial, email text); INSERT INTO users (email) VALUES ('a@b.com'); SELECT * FROM users;"
}
}
}
The same tool seeds Redis (SET session:1 active), runs Kafka/AMQP operations,
and so on. Pair it with the bridge sidecar (drivers for your app) for a complete
loop: provision once, drive setup over MCP, exercise your code over real wire
protocols, tear down.
Lifecycle
| Action | Call |
|---|---|
| Provision | POST /api/sandboxes (body: { "name", "services": [...] }) |
| Connection details | GET /api/sandboxes/{id}/connection |
| Status | GET /api/sandboxes/{id} |
| Tear down | DELETE /api/sandboxes/{id} |
State is ephemeral — deleting the sandbox removes everything. No cleanup of production data, because nothing ever touched production.