KrabbyKrabby

Bring Your Own Infrastructure

Automatically provision and tear down remote workspaces for each task using your own infrastructure

Contact us to get started:

Plug in custom shell scripts that create and destroy remote environments on demand. When a developer creates a task, Krabby runs your provision script, connects the terminal via SSH, and runs coding agents inside the workspace. When the task is deleted, Krabby runs your teardown script to clean up.

This works with any infrastructure backend: cloud VMs, Kubernetes pods, container-based dev environments, or internal workspace platforms. You just provide the scripts.

AWSHetznerAzureDocker

How It Works

  1. Developer creates a task with "Remote workspace" enabled
  2. Krabby runs your provision script as a child process
  3. Script progress (stderr) streams live in the UI
  4. Script outputs JSON (stdout) with SSH connection details
  5. Krabby connects the terminal to the workspace via SSH
  6. Coding agents run inside the remote workspace
  7. When the task is deleted, Krabby runs your teardown script

Compared to Remote Projects

Remote ProjectsWorkspace Provider
LifecyclePersistent server, shared across tasksPer-task, provisioned on demand
SetupManual connection in SettingsAutomated via scripts
Infra managementYou manage the serverScripts handle create/destroy
Use caseDedicated dev serverEphemeral, isolated workspaces

Both features share the same remote capabilities once connected: terminal access, coding agents, Git operations, and file browsing all work identically.

Setup

Step 1: Create Your Scripts

Create two shell scripts in your project root (or anywhere accessible from the project directory).

Provision Script

The provision script creates a workspace and outputs SSH connection details as JSON to stdout. All log messages must go to stderr.

Environment variables provided by Krabby:

VariableDescription
KRABBY_TASK_IDUnique identifier for the task
KRABBY_REPO_URLRepository URL (e.g., git@github.com:org/repo.git)
KRABBY_BRANCHBranch name for this task
KRABBY_BASE_REFBase branch (e.g., main)

Required output (JSON to stdout):

{
  "host": "workspace-hostname-or-ip",
  "id": "optional-external-id",
  "port": 22,
  "username": "dev",
  "worktreePath": "/path/to/repo/on/workspace"
}
FieldRequiredDescription
hostYesHostname, IP address, or SSH config alias
idNoExternal identifier (passed to teardown as KRABBY_INSTANCE_ID)
portNoSSH port (default: 22)
usernameNoSSH username (default: current user)
worktreePathNoPath to the repository on the workspace

Example provision script:

#!/bin/bash
set -euo pipefail

echo "[$(date)] Creating workspace for $KRABBY_BRANCH..." >&2

# Replace this section with your infrastructure commands
WORKSPACE_ID="ws-$(date +%s)"
HOST="dev-${WORKSPACE_ID}.internal.example.com"

echo "[$(date)] Provisioning VM..." >&2
# your-cli create-workspace --id "$WORKSPACE_ID" \
#   --repo "$KRABBY_REPO_URL" --branch "$KRABBY_BRANCH"

echo "[$(date)] Ready!" >&2

# Output JSON to stdout (this is what Krabby parses)
cat <<EOF
{
  "id": "$WORKSPACE_ID",
  "host": "$HOST",
  "port": 22,
  "username": "dev",
  "worktreePath": "/workspace/repo"
}
EOF

Important rules:

  • All log output must go to stderr (>&2) — Krabby streams these lines live in the UI
  • Only the JSON object goes to stdout — this is parsed for connection details
  • Exit with code 0 on success, non-zero on failure
  • Timeout: 5 minutes

Teardown Script

The teardown script destroys the workspace when the task is deleted.

Environment variables provided by Krabby:

VariableDescription
KRABBY_INSTANCE_IDThe id from your provision output (or host if no id was provided)
KRABBY_TASK_IDThe task identifier (same value passed to the provision script)

Example teardown script:

#!/bin/bash
set -euo pipefail

echo "[$(date)] Destroying workspace $KRABBY_INSTANCE_ID..." >&2
# your-cli delete-workspace "$KRABBY_INSTANCE_ID"
echo "[$(date)] Done." >&2

Make both scripts executable:

chmod +x provision.sh teardown.sh

Step 2: Configure .krabby.json

Add the workspace provider configuration to .krabby.json in your project root:

{
  "workspaceProvider": {
    "type": "script",
    "provisionCommand": "./provision.sh",
    "terminateCommand": "./teardown.sh"
  }
}

Alternatively, configure via the Krabby UI:

  1. Open your project
  2. Click the gear icon (Project Settings)
  3. Scroll to the Workspace Provider section
  4. Enter your provision and terminate commands
  5. Save

Step 3: Create a Task

  1. Click New Task
  2. In the task creation dialog, expand Advanced Settings
  3. Check "Remote workspace (provision via script)"
  4. Create the task

Krabby will:

  1. Show a provisioning overlay with live progress from your script's stderr
  2. Parse the JSON output to get connection details
  3. Connect the terminal to the workspace via SSH
  4. Start your coding agent inside the workspace

Workspace Requirements

For the best experience, ensure your provisioned workspaces have these tools installed:

Required

  • SSH server — Krabby connects via your system's ssh command
  • Git — For repository operations, configured with user.name and user.email
  • A coding agent — At least one CLI agent (Claude Code, Codex, etc.)
  • GitHub CLI (gh) — For PR creation and GitHub operations from the Krabby UI
  • tmux — Krabby automatically uses tmux for workspace sessions to preserve state across reconnects

GitHub Access (for push/pull)

If your workflow involves pushing code, configure SSH access to GitHub on the workspace:

ssh-keygen -t ed25519 -C "workspace" -f ~/.ssh/id_github -N ""
# Add ~/.ssh/id_github.pub to GitHub (deploy key or user key)
git config --global core.sshCommand "ssh -i /home/dev/.ssh/id_github"
ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null

SSH Authentication

Krabby connects to workspaces using your local system's ssh command, which means:

  • SSH config aliases work — Your provision script can return an SSH config Host alias as the host field
  • SSH agent works — Keys in your local SSH agent (including macOS Keychain) are available
  • ~/.ssh/config works — ProxyJump, custom ports, identity files, and other SSH config directives are respected

No additional SSH configuration is needed in Krabby itself.

Task Lifecycle

Creating a Task

When you create a task with remote workspace enabled:

  1. Provision script runs (progress streams in the UI)
  2. On success: SSH connection is established, agent starts in the workspace
  3. On failure: error is shown in the UI with a retry option

Deleting a Task

When you delete a workspace-backed task:

  1. Teardown script runs with KRABBY_INSTANCE_ID
  2. On success: workspace is destroyed, database is cleaned up
  3. On failure: instance is marked as error, task is kept for retry

App Restart

If Krabby is restarted while workspaces are active:

  • Provisioning instances are marked as error (the child process is gone)
  • Ready instances remain — the SSH connection is re-established when you open the task

Troubleshooting

Provision Script Fails

Symptoms: Error overlay with script output

Solutions:

  1. Check the error message in the overlay — it includes the last 500 chars of stderr
  2. Run the script manually to debug:
    KRABBY_TASK_ID=test KRABBY_REPO_URL=git@github.com:org/repo.git \
    KRABBY_BRANCH=test-branch KRABBY_BASE_REF=main \
    ./provision.sh
  3. Verify the JSON output is valid: pipe stdout through jq
  4. Ensure log output goes to stderr, not stdout

SSH Connection Fails After Provisioning

Symptoms: Terminal shows SSH error after provision succeeds

Solutions:

  1. Verify you can SSH manually: ssh <host> (using the host from your script output)
  2. Check your ~/.ssh/config for the host
  3. Verify your SSH agent has the right key loaded: ssh-add -l
  4. If using an SSH config alias, ensure the alias is configured on the machine running Krabby

Script Times Out

Provision scripts have a 5-minute timeout and teardown scripts have a 2-minute timeout. If your infrastructure takes longer, optimize the provisioning pipeline or pre-warm environments.

"Invalid JSON" Error

Symptoms: "Provision script output is not valid JSON"

Solutions:

  1. Ensure only JSON is printed to stdout — all log messages must use >&2
  2. Check for stray echo or printf statements without >&2
  3. Validate your output: ./provision.sh 2>/dev/null | jq .

Script Contract Reference

Provision Script

AspectDetails
Executionbash -c <provisionCommand>
Working directoryProject root
Env varsKRABBY_TASK_ID, KRABBY_REPO_URL, KRABBY_BRANCH, KRABBY_BASE_REF
StdoutJSON object with at least host field
StderrLog lines (streamed to UI)
Exit code0 = success, non-zero = failure
Timeout5 minutes

Teardown Script

AspectDetails
Executionbash -c <terminateCommand>
Working directoryProject root
Env varsKRABBY_INSTANCE_ID, KRABBY_TASK_ID
Stdout(ignored)
StderrLog lines
Exit code0 = success, non-zero = failure
Timeout2 minutes
Last updated on April 2, 2026