Open Harness provides the sandbox; you choose the harness. It's a Docker-based workspace, agent-tended over time: clone-and-own the repo, set one harness.yaml, and make sandbox boots a long-lived container where the coding agent of your choice β Claude Code, Codex, Pi (Hermes, Grok, and more opt-in) β works on its own branch and identity. Because it's just Docker, it runs identically on your laptop or a remote VM β and remote is the default: deployed on a VM, Open Harness becomes a lights-out software factory, where the agent works unattended, on a schedule and reachable over Slack, fanning out across isolated git worktrees β parallel branches, delegated sub-agents, even other cloned repos β while you're away and your laptop stays clean.
- One project, one sandbox. A single container scoped to a single repo. The agent owns its branch and its workspace; you keep your laptop clean.
- Parallel by design. The worktrees skill fans one sandbox into isolated git worktrees β parallel branches, delegated sub-agents, even other cloned repos.
- Remote-first, lights-out. Runs the same on your laptop or a cloud VM; on a VM it's an unattended software factory β agents build on a schedule, reachable over Slack.
- Agents that work while you sleep. A tiny croner runtime reads
.oh/crons/*.mdmarkdown and wakes the agent on a schedule. - Host dependencies: Docker, Git, and make. No Node, no Python, no toolchain rot on your laptop. (
makeruns themake sandbox/make shellwrappers β see Prerequisites.) - Composable infra. Cherry-pick Cloudflare tunnels, SSH, Caddy gateway, or pack-supplied services via Compose overlays.
- Slack-ready. The
pi-messenger-bridgepackage bridges Slack (and other messengers) to a Pi agent β see .oh/docs/integrations/slack.md. - Multiple harnesses, one sandbox. Claude, Codex, and Pi ship by default (Hermes, Grok, and more are opt-in); bridge them to Slack with
pi-messenger-bridge.
π Read the docs β https://oh.mifune.dev Rendered, searchable docs, guides, and blog. New here? Start with the Start Here hub.
Open Harness runs one project in one Docker sandbox. The recommended path is
clone-and-own: clone upstream, then make your own private repo the origin and keep
mifunedev/openharness as upstream so you can pull framework updates and contribute back.
Host prerequisites: Docker with the Compose plugin,
Git, and make (build-essential) β full list in
Prerequisites.
# a. Clone upstream:
git clone https://github.com/mifunedev/openharness.git ~/.openharness && cd ~/.openharness
# b. Materialize local config, then edit it BEFORE building β set sandbox.name,
# sandbox.timezone, git.user_name, git.user_email, and any optional installs
# (Hermes, agent-browser, β¦). Secrets stay in .devcontainer/.env.
make harness-config
nano harness.yaml
# c. Build the image and open a shell inside the sandbox:
make sandbox && make shellThat is already a working sandbox. To make it yours (private origin + upstream) and
authenticate the agents, continue with the optional full setup.
Run these inside the sandbox (make shell). Per-step depth + troubleshooting:
quickstart β End-to-end setup walkthrough.
# GitHub auth over SSH β pick SSH, generate a key, paste a token
# (SSH remotes use the key directly, so `gh auth setup-git` isn't needed):
gh auth login
# Create your own PRIVATE repo, point origin at it, add upstream β all over SSH:
gh repo create <your-user>/openharness --private
git remote set-url origin git@github.com:<your-user>/openharness.git
git remote add upstream git@github.com:mifunedev/openharness.git
git push -u origin HEAD
# Authenticate the agents you'll use. Simplest cross-provider path: launch the agent,
# run /login, and pick DEVICE MODE (a code + URL that works headless/remote). The
# one-liners below are equivalents where a provider exposes them:
claude auth login # Claude Code (or /login in-session)
codex login --device-auth # Codex (device mode; or /login in-session)
pi # Pi (first run walks provider auth; /login in-session)
hermes setup # Hermes (optional; needs install.hermes: true)
# Configure Slack, then run + verify the gateways (sandbox-only):
# config: .oh/docs/integrations/slack.md Β· .oh/docs/harnesses/hermes.md
gateway pi && gateway hermes
gateway status
tmux attach -r -t client-slack-pi # read-only view; detach with Ctrl-b dOptional β DebugMCP. If you attach to the sandbox from VS Code (Dev Containers β Attach to Running Container) after
make sandbox, you can install themicrosoft/DebugMCPextension to expose a debugging MCP server that any MCP-capable harness (Claude Code, Codex, β¦) can drive. It's optional and not tied to any single agent β see the DebugMCP runbook.
Other install methods (one-line installer Β· fork-and-clone)
One-line installer (upstream):
curl -fsSL https://oh.mifune.dev/install.sh | bashReview-first alternative (no extra dependency):
curl -fsSL -o openharness-install.sh https://oh.mifune.dev/install.sh
# Review openharness-install.sh in your editor or pager before running it.
bash openharness-install.shOpen Harness requires Docker with the Compose plugin, Git, and make on the host. The installer clones into ~/.openharness, offers to share your host gh token, writes .devcontainer/.env, and builds the image (~10 min cold, ~30s warm).
Fork and clone (self-hosting):
# Fork on GitHub, then clone YOUR fork; the installer auto-detects the local clone:
git clone https://github.com/<your-org>/<your-fork>.git && cd <your-fork>
bash .oh/scripts/install.shInstall directly from your fork without cloning first:
OH_GITHUB_REPO=<your-org>/<your-fork> curl -fsSL \
https://raw.githubusercontent.com/<your-org>/<your-fork>/main/.oh/scripts/install.sh | bashReview-first fork install:
curl -fsSL -o openharness-install.sh \
https://raw.githubusercontent.com/<your-org>/<your-fork>/main/.oh/scripts/install.sh
# Review openharness-install.sh, then run it against your fork.
OH_GITHUB_REPO=<your-org>/<your-fork> bash openharness-install.shIf your fork uses a default branch other than main, set OH_GITHUB_REF=<branch> and replace main in the URL. See Installation docs for all environment overrides.
Get the standalone oh CLI (equip an existing project repo):
The installer above builds the harness sandbox. To instead put the oh command on your host β so you can run oh init inside any project β bootstrap it once:
curl -fsSL https://oh.mifune.dev/get-oh.sh | bashReview-first alternative (no extra dependency):
curl -fsSL -o get-oh.sh https://oh.mifune.dev/get-oh.sh
# Review get-oh.sh in your editor or pager before running it.
bash get-oh.shUse oh immediately in the current shell (installs and puts oh on your PATH now β no new terminal or re-login):
source <(curl -fsSL https://oh.mifune.dev/get-oh.sh)Or install from npm β if you already have Node.js β₯ 20 on your host, skip the bootstrap script entirely:
npm install -g @mifune/openharness # puts `oh` on your PATH
oh init
# ...or zero-install, no global install:
npx @mifune/openharness initUnlike get-oh.sh, npm does not install Node for you β Node β₯ 20 must already be on your PATH.
If you already ran the plain piped form and oh isn't found yet, just add its dir to the current shell's PATH: export PATH="$HOME/.local/bin:$PATH".
get-oh.sh installs the single self-contained oh binary to ~/.local/bin/oh β no repo clone, and it leaves any existing ~/.openharness sandbox config untouched. It needs Node.js β₯ 20 to run oh; if Node is missing it offers to install nvm + Node 22 (and sources it so it works in the same shell). oh init fetches its scaffold payload on demand. Override the install dir with OH_BIN_DIR. Then:
cd <your-project>
oh init # equip the repo with Open Harness
oh sandbox # provision + start the sandboxOpen Harness vendors the shared skills/agents/hooks primitive pack directly into the .oh/ control plane: .oh/skills/, .oh/agents/, .oh/hooks/, and .oh/skills.lock are tracked as ordinary files in this repo. The oh CLI lays them down during oh init/oh update, so a fresh checkout has the skills immediately β no submodule, no recursive clone, no network step.
Provider surfaces are symlinks into .oh/: .pi/skills, .claude/skills, and .codex/skills point at .oh/skills; .claude/agents β .oh/agents; .claude/hooks β .oh/hooks. .pi/ itself remains the Pi provider surface in v1.
cd ~/.openharness
make shell # enter the isolated sandbox
# inside the sandbox, launch any core agent:
# claude # Claude Code (default)
# codex # OpenAI Codex CLI
# opencode # OpenCode (optional: set install.opencode: true in harness.yaml and rebuild)
# pi # Pi Coding Agent
# deepagents # LangChain DeepAgents (optional: set install.deepagents: true in harness.yaml and rebuild)
# hermes # Nous Research Hermes (optional: set install.hermes: true in harness.yaml and rebuild)
# grok # xAI Grok Build (optional: set install.grok_build: true in harness.yaml and rebuild)
make destroy # stop and remove the sandbox
make help # all targets- Property-based testing convention: .oh/docs/property-testing.md
Prefer VS Code or remote SSH? Use the Dev Containers extension's "Attach to Running Container" against openharness, or SSH into your host first and then attach.
harness.yaml is local gitignored config for shared non-secret settings, generated
from tracked harness.yaml.example by make harness-config (also run by
make sandbox). It holds sandbox.*, git.*, optional installs, paths.*
(overrides like paths.worktrees), Slack allowlists, and compose overlays. Secrets stay in the gitignored .devcontainer/.env
(GH_TOKEN, PI_SLACK_APP_TOKEN, PI_SLACK_BOT_TOKEN) β never in
harness.yaml. Active keys in harness.yaml override .devcontainer/.env; apply
changes with make destroy && make sandbox.
Full key reference: Quickstart β Configuration.
Manual setup (no installer)
git clone https://github.com/mifunedev/openharness.git && cd openharness
make sandbox
make shell| Core agents | Defaults: Claude Code, Codex, Pi. Optional: OpenCode, DeepAgents, Hermes, Grok Build |
| Runtimes | Node 22, pnpm, Bun, uv (Python) |
| DevOps | Docker CLI + Compose, GitHub CLI, cloudflared, tmux, croner |
| Browser | agent-browser + Chromium (headless) |
| One project, one sandbox | A single container scoped to a single repo and branch |
| Worktrees | One sandbox β many isolated git worktrees: parallel branches, delegated sub-agents, satellite project clones under .oh/worktrees/ |
| Crons | Markdown-defined schedules in .oh/crons/*.md driven by the in-container croner runtime |
| Multi-agent | Claude, Codex, Pi by default (Hermes/Grok opt-in); Slack bridging via pi-messenger-bridge |
- Read the docs β oh.mifune.dev β the rendered, searchable documentation site (start here)
- Docs index β GitHub-readable docs kept with the core repo
- Quickstart β full step-by-step
- DeepWiki β generated codebase map
- Docs site source β Docusaurus source repo that builds oh.mifune.dev (contribute doc edits here)
make destroyOpen Harness is maintained under the mifunedev org β the canonical repo is github.com/mifunedev/openharness. To run your own, use the clone-and-own setup above (or fork it β see Other install methods) and open PRs back upstream. Issues and PRs welcome; if Open Harness is useful to you, please give us a star.
MIT.
