One Config,
Every Harness

One canonical source of truth for skills, agents, MCP servers, LLM endpoints, and global instructions across every LLM harness on your machine.

Version License Go Report

The Problem

Seven harnesses. Seven copies of the same config. They drift.

Without harness-sync

Same skill markdown, duplicated seven ways
Same agent definitions, rewritten per harness
Same MCP registry, seven different key names (mcpServers, mcp, context_servers...)
Same gateway URL, hand-copied into seven config files
Edit once. Forget the others. Things break.

With harness-sync

One canonical tree under git version control
Per-harness adapters render native config formats
3-way merge via git for conflict resolution
Secrets via ${VAR} env-var substitution, never stored
Git rollback on every apply

Features

Everything you need to manage LLM harness config at scale

Canonical Tree

Profiles, skills, agents, MCP servers, and instructions — one git-managed directory

Native Adapters

Each harness gets its correct native format — right keys, right types, right paths

3-Way Merge

Git merge-file semantics — disjoint changes merge cleanly, conflicts produce .rej files

Profiles

Bundle gateway URL, model allowlist, and upstream keys — switch with one command

Secret Safety

Env-var substitution at render time — secrets never stored in canonical tree

Auto-Detection

Detects which harnesses are installed and only touches what's relevant

Dry-Run Preview

See exactly what will change before writing — diff every file without touching disk

Git Rollback

Revert the last N applies — full version history preserved in local git

Self-Update

Pulls latest release in place with SHA-256 verification

Non-Destructive

Only overlays managed keys — your hooks, permissions, and editor settings survive

Import from Any

harness-sync init picks the best source harness and imports everything

Extensible

Add a harness: drop a Go package under internal/adapters/

Supported Harnesses

Each adapter grounded against real config files and official docs

claude-code

MCP · Skills · Instructions

Built-in subscription — provider config managed by Anthropic directly.

crush

MCP · Skills · Providers · Models

Full gateway rendering with provider map and default model support.

kilo

MCP · Skills · Providers · Models

Kilo CLI with provider map, model, and small model configuration.

opencode

MCP · Skills · Providers · Models · Instructions

Full rendering with JSONC config support and instructions merging.

goose

MCP · Skills · Providers · Models

YAML config with extensions map and custom provider JSON files.

cagent

MCP · Providers · Models · Instructions

Starter YAML config with per-agent model selection.

zed

MCP · Providers · Models

Context servers and language model configuration in settings.json.

Install

One binary, zero dependencies, every platform

One-liner

Recommended
$ curl -fsSL https://raw.githubusercontent.com/
  lukaszraczylo/harness-sync/main/install.sh | bash

Picks the right artefact for OS/arch, verifies SHA-256, drops binary in ~/.local/bin.

Homebrew

$ brew install lukaszraczylo/taps/harness-sync

macOS and Linux via Homebrew tap.

From Source

$ git clone https://github.com/
  lukaszraczylo/harness-sync
$ make build && make install

Requires Go 1.24+ and git on $PATH.

Usage

Three commands to get going

01

Detect

$ harness-sync detect

Lists which harnesses are installed on your machine.

02

Init

$ harness-sync init

Imports config from detected harnesses into the canonical tree.

03

Apply

$ harness-sync apply

Renders and writes native config to every detected harness.

Full Command Reference

$ harness-sync detect                       # list adapters + detection status
$ harness-sync show [harness...]            # print files each adapter manages
$ harness-sync init                         # import from detected harnesses
                --from a,b              # pick adapters, skip prompt
                --no-prompt             # take all detected
                --force                 # allow re-init
$ harness-sync apply [harness...]           # render + write
                --dry-run               # show plan, write nothing
                --force                 # overwrite without merge
                --yes                   # skip confirmation prompt
$ harness-sync diff [harness...]            # apply --dry-run shorthand
$ harness-sync profile list                 # list canonical profiles
$ harness-sync profile use <name>           # switch active profile
                --apply                 # reapply after switching
$ harness-sync rollback [n]                 # git revert last N applies
$ harness-sync update                       # reinstall latest release

Architecture

Single Go binary, ~5000 LOC, 18 packages, 93 tests

harness-sync architecture

Canonical Tree

~/.config/harness-sync/  (git)
├── profiles/<name>.yaml
├── skills/<name>/SKILL.md
├── agents/<name>.md
├── mcp.yaml
└── instructions/global.md

3-Way Merge

base   ← state/  (last render)
ours   ← rendered (what we'd write now)
theirs ← on disk  (what's actually there)

disjoint → clean merge, write
overlap  → .rej file, exit non-zero