Steckling
How it works Agents Quickstart MCP Docs GitHub Install
Open source · MIT · macOS & Linux

Every branch gets its own everything.

A git worktree + an isolated Docker stack per branch. Run many branches — or many coding agents — in parallel on one machine, each with its own database, ports, and data.

Get started curl -fsSL steckling.dev/install.sh | sh

Stack-agnostic — your app runs natively, the way it always has. Requires git and Docker.

{{ ln.p }}{{ ln.t }}

Your code switches branches in a second. Your database doesn't.

Work on a feature, get pulled onto a hotfix, and suddenly you're juggling one shared Postgres — migrating it back and forth, wiping data, fighting over port 5432. Running two branches at once is basically off the table.

HOW IT WORKS

Three moving parts, and deliberately nothing more

1

A folder per branch

Via git worktree, each branch lives in its own directory. Switching branches is switching folders.

2

Private services per branch

A separate docker compose project per branch — own containers, own volumes, a free host port picked for you.

3

Env injection

Steckling writes the right DATABASE_URL into a gitignored file your app reads, then runs your normal dev command.

Steckling never runs your app for you and knows nothing about your framework. It works for any language that reads its config from the environment. Read the concepts →

PARALLEL AGENTS

One agent per branch. All at once.

Isolation is what makes agentic coding parallel. Point a separate Claude session at each worktree — every session gets a database, ports, and data that belong to it alone. Agents can migrate, seed, and break things freely; nothing leaks across branches.

claude · feature/checkout
postgres :31140 · own data
migrated + seeded
▸ building checkout flow
claude · feature/search
postgres :44870 · own data
migrated + seeded
▸ rebuilding the indexer
claude · fix/webhooks
postgres :20030 · own data
migrated + seeded
▸ replaying failed deliveries

Merged a branch? steck prune reclaims the whole stack; add --purge to remove the worktree folder and branch too. Want agents to manage the fleet themselves? steck mcp →

QUICKSTART

Add two files to your repo

Run steck init and the wizard writes both files (plus the .gitignore entry) for you — presets for Postgres, MySQL, Redis, Mongo, and RabbitMQ, and your detected run command. Or add them by hand: a services compose file and a steckling.yml. That's the whole integration.

steckling.yml
version: 1
services:
  compose: ./compose.steckling.yml
  expose:
    postgres:
      container: 5432
      env: DATABASE_URL
      url: "postgres://app:app@localhost:{port}/app"
app:
  run: "npm run dev"  # any language
hooks:
  provision: "npm run migrate && npm run seed"
compose.steckling.yml
services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    # Steckling injects the host port
    ports: ["${STECKLING_PORT_POSTGRES}:5432"]
    volumes: [pgdata:/var/lib/postgresql/data]
volumes: { pgdata: {} }
$ steck up        # start this branch: services + provision + run the app
$ steck new feature/x  # a second branch, in its own folder…
$ steck up        # …with its own DB, running in parallel
$ steck list       # every worktree, its status + ports

Full walkthrough → Quickstart · already have a project? → Adopting an existing project

COMMANDS

A small, sharp CLI

steck initSet up a repo interactively — service presets, detected run command, both config files written for you
steck new <branch>Create a worktree + allocate its service ports
steck exec -- <cmd>Run a command wired to this branch's env
steck upServices up, provision on first boot, run the app
steck cockpitCockpit TUI: app pane + live service logs, per branch (via mprocs) — quit stops the services (--keep-up to leave running)
steck rm / pruneReclaim a branch's stack / bulk-reclaim merged ones (--purge: folder + branch too)
steck downStop the containers, keep the data
steck deployShip this branch's agent to Railway
steck list / statusWhat's registered, running, and on which ports
steck mcpRun the MCP server so Claude can drive the fleet
steck doctor / configCheck the environment / validate steckling.yml
steck logs / destroyTail or tear down the deployed agent

Full reference → Commands

STECK MCP

Drive the fleet from Claude

steck mcp exposes the fleet to AI agents as MCP tools, plus a live registry resource. Because branches are fully isolated, you can point a separate Claude session at each one and let them work in parallel.

Plays well with your ticket tracker. Steckling can parse a ticket ID out of your branch name (tim/eng-123-fix-login → ENG-123), remember it, show it in steck list, inject it into every hook as $STECKLING_TICKET, and expose it over MCP — so “one ticket, one branch, one isolated stack, one agent” is a config block, not a platform.

MCP guide →
# tools
steckling_new · steckling_up · steckling_list · steckling_down
# live resource
steckling://registry
# one ticket, one branch, one stack, one agent
ticket:
  pattern: "eng-\\d+"
  url: "https://linear.app/acme/issue/{ticket}"
Steckling

Isolated worktree + Docker stack per git branch, with auto ports and env injection.

DOCS Concepts Install Quickstart
REFERENCE Commands steckling.yml MCP
PROJECT GitHub Contributing Changelog
MIT © Tim Duckett github.com/timd/steckling