Harness for Engineer Role Management via Interactive Tasks
A simple multi-agent development automation harness leveraging Claude Code's native features (Agent tool and MCP).
Automatically picks up GitHub Issues, spawns Agents in parallel, and autonomously handles implementation, PR creation, and merging.
The software is provided "as is", without warranty of any kind.
"Claude Code is the star. HERMIT is just the toolbox for domain operations."
- AI reasoning, orchestration, and context management are fully delegated to Claude Code
- HERMIT only provides a thin wrapper for GitHub/Git operations as an MCP server
- Code volume ~700 lines (for reference: an equivalent Go binary implementation would be ~5,000 lines)
curl -sSL https://raw.githubusercontent.com/ytnobody/HERMIT/refs/heads/main/install.sh | shPlaces the binary at ~/.local/bin/hermit and automatically registers it as a Claude Code MCP server.
- Claude Code must be installed
- Authenticated with gh CLI (
gh auth login), orGITHUB_TOKENenvironment variable must be set gitcommand must be available
# 1. Install HERMIT (downloads the binary and auto-registers it as a Claude Code MCP server)
curl -sSL https://raw.githubusercontent.com/ytnobody/HERMIT/refs/heads/main/install.sh | sh
# 2. Initialize your project
cd your-project
hermit init
# 3. Commit the generated files (including hermit's slash commands) to version control
git add harness.toml CLAUDE.md .github/ISSUE_TEMPLATE/hermit-task.md .claude/
git commit -m "chore: initialize HERMIT"
# 4. Start Claude Code and launch the Superintendent loop
claude
# Inside Claude Code:
# /hermit
# 5. Create a GitHub Issue — HERMIT picks it up automatically and handles everythingOnce /hermit is running, just open GitHub Issues in your repository. HERMIT will automatically:
- Pick up the Issue
- Spawn an Engineer agent to implement it
- Create a Pull Request
- Evaluate risk and merge if safe
Note:
install.shcallshermit installautomatically, so the MCP server registration happens as part of the one-liner install command.
Version control: The files generated in
.claude/commands/(hermit.md,hermit-pause.md,hermit-resume.md) should be committed to git. They are project-scoped slash commands — similar toCLAUDE.md— and allow all contributors using Claude Code on the same project to access/hermit,/hermit-pause, and/hermit-resumewithout runninghermit installthemselves.
cd your-project
hermit initEnter the following interactively:
| Field | Description |
|---|---|
| GitHub owner | Org name or username |
| GitHub repo | Repository name |
| Language | ja or en (language for Claude instructions) |
| Max Engineers | Maximum number of Engineers to spawn in parallel (default: 4) |
| Model preset | Claude model combination to use (default: claude) |
Generated files:
harness.toml— Project configuration (shared with the team)CLAUDE.md— Role definitions for Superintendent / Engineer.github/ISSUE_TEMPLATE/hermit-task.md— GitHub Issue template for well-structured tasks.claude/settings.json— Claude Code permission settings for autonomous operation
Edit the "Coding Guidelines" section in CLAUDE.md to match your project.
Since hermit install registers it as an MCP server in ~/.claude/settings.json, Claude Code automatically starts hermit serve on launch. No need to start it manually in another terminal.
Claude Code starts
└─ hermit serve auto-started (MCP subprocess)
↓ list_issues / assign_issue / create_worktree
↓ Agent spawn → Engineer × N
↓ evaluate_risk / merge_pr / close_worktree
↓ (repeat)
cd your-project # directory where hermit init was run
claudeThis step is required. Autonomous development does not begin until you run
/hermitinside Claude Code.
/hermit
/hermit internally calls /loop 120s, resetting context every 120 seconds while continuing the Superintendent cycle. If there are no Issues it waits for the next loop; if there are Issues it automatically handles everything through implementation and merge.
With /hermit running, simply open an Issue in your GitHub repository:
GitHub Issue created
└─ HERMIT picks it up on the next cycle
└─ Engineer agent spawned automatically
└─ Implementation committed → PR created
└─ Risk evaluated → auto-merged (if LOW/MEDIUM)
No further action is needed. HERMIT handles the entire development workflow autonomously.
- Retrieve open Issues with
list_issues - Mark as in-progress with
assign_issue - Spawn Engineers in parallel with the Agent tool (up to
max_engineers) - Risk evaluation with
evaluate_risk - If LOW/MEDIUM, auto-merge with
merge_pr(skip HIGH with comment) - Clean up worktrees with
close_worktree - Return to step 1
| Tool | Description |
|---|---|
list_issues |
Returns a list of open Issues (supports multi-repo mode) |
assign_issue |
Marks an Issue as in-progress by adding a label and assigning |
create_worktree |
Creates a branch and git worktree for an Issue |
evaluate_risk |
Returns LOW/MEDIUM/HIGH based on PR change volume and impact area |
merge_pr |
Merges after CI passes; posts a risk comment and records a lesson |
close_worktree |
Removes the worktree and branch |
check_ci_status |
Checks CI/CD status for a PR; auto-posts a comment if checks are failing |
add_issue_comment |
Posts a comment on an Issue or PR |
get_issue_comments |
Returns comments on an Issue, optionally filtered by timestamp |
get_recent_pr_comments |
Returns inline review comments on a PR, optionally filtered by timestamp |
close_issue |
Closes a GitHub Issue, optionally posting a comment first |
list_prs |
Returns a list of open pull requests, optionally filtered by Issue number |
review_pr |
Posts a structured automated review comment based on static diff analysis |
get_lessons |
Returns lessons learned from past merges to avoid repeating mistakes |
get_config |
Returns current HERMIT configuration values (e.g. loop_interval) |
notify |
Sends a notification to the configured webhook (Slack, Discord, or generic) |
get_default_branch |
Returns the repository's default branch name |
| Condition | Level |
|---|---|
20+ changed files / 500+ changed lines / changes in cmd/, go.mod, .github/ |
HIGH |
10+ changed files / 200+ changed lines / changes in internal/ |
MEDIUM |
| Otherwise | LOW |
[github]
owner = "your-org"
repo = "your-repo"
rate_limit_threshold = 10 # pause when remaining API calls drop to this level
default_branch = "main" # base branch for new worktrees
[agent]
max_engineers = 4 # maximum number of parallel Engineers
language = "en" # "ja" | "en"
# loop_interval = 270 # Superintendent cycle interval in seconds (default: 270)
# branch_prefix = "hermit/your-login" # defaults to hermit/<gh_login> if omitted
# trigger_comment = "/hermit" # only process Issues that have this comment
[model]
superintendent = "claude-sonnet-4-5" # model used for the Superintendent role
engineer = "claude-sonnet-4-5" # model used for Engineer roles
# [notification]
# webhook_url = "https://hooks.slack.com/services/..." # Slack, Discord, or generic webhook
# type = "slack" # "slack" | "discord" | "generic" (auto-detected from URL if omitted)Pass GITHUB_TOKEN as an environment variable. Do not write it in harness.toml.
HERMIT automatically monitors the GitHub API rate limit before each operation. When remaining calls drop to rate_limit_threshold (default: 10), it waits until the limit resets. If the reset time is more than 10 minutes away, the current cycle is skipped rather than blocking.
When trigger_comment is set in harness.toml, the Superintendent will only pick up Issues that have at least one comment containing the specified string (case-insensitive). This lets you control which Issues HERMIT handles without relying solely on labels or assignment.
Example: set trigger_comment = "/hermit" and comment /hermit on any Issue you want HERMIT to process.
The [model] section lets you specify which Claude model each role uses. You can also apply a preset with hermit use:
hermit use claude # Sonnet for both Superintendent and Engineer (balanced)
hermit use claude-cheap # Sonnet for Superintendent, Haiku for Engineers (cost-optimized)HERMIT can send notifications to Slack, Discord, or any generic webhook when key events occur (issue assigned, PR merged, high risk detected, etc.). Set webhook_url in [notification]. The webhook type is auto-detected from the URL; set type explicitly if needed.
To monitor multiple repositories from a single HERMIT instance, replace [github] with a [[repos]] array:
[[repos]]
owner = "your-org"
repo = "repo-one"
[[repos]]
owner = "your-org"
repo = "repo-two"
label = "hermit" # optional: only pick up Issues with this label in this repoWhen [[repos]] is present, list_issues queries all configured repositories and returns issues from all of them in a single call.
hermit pause # pause autonomous operation (creates .hermit-paused)
hermit resume # resume autonomous operation (removes .hermit-paused)
hermit status # check current state (running / paused)The Superintendent checks for .hermit-paused at the start of each cycle. Running hermit pause stops it after the current cycle completes; hermit resume resumes it immediately.
After each PR is merged, HERMIT scores the Issue's instruction quality (0–100) based on:
- PR risk level (HIGH: −30, MEDIUM: −15)
- CI was failing before merge (−20)
- Multiple PRs were created for the same Issue (−15)
- A clarification comment was present (−20)
When the score drops below 70, a lesson is generated and saved to .hermit/lessons.txt. The Superintendent reads these lessons at the start of each cycle via get_lessons to avoid repeating the same mistakes. Up to 15 lessons are kept; high-risk lessons are always retained.
hermit serve # Start the MCP server (stdio) — Claude Code auto-starts this, manual execution normally not needed
hermit install # Register MCP server in ~/.claude/settings.json and install slash commands
hermit init # Initialize a project (generate harness.toml, CLAUDE.md, issue template, settings)
hermit pause # Pause autonomous operation
hermit resume # Resume autonomous operation
hermit status # Show autonomous operation status (running / paused)
hermit use # Apply a model preset to harness.toml (e.g. hermit use claude-cheap)
hermit version # Print the current hermit version
hermit upgrade # Download and install the latest hermit release
hermit cleanup # Remove legacy branches and zombie worktrees left by older versions
hermit doctor # Check prerequisites (git, gh CLI, GITHUB_TOKEN, harness.toml, Claude Code)
hermit dry-run # Preview what the Superintendent would do without making any changes
Runs a series of environment checks and reports pass/fail for each:
gitis available in PATHghCLI is installed and authenticatedGITHUB_TOKENis available (from environment orgh auth token)harness.tomlexists withownerandrepofilled inclaude(Claude Code) is installed
Exits with a non-zero status if any check fails.
Shows which open Issues the Superintendent would pick up on the next cycle, along with the branch name and worktree path it would create for each. No GitHub API writes are performed and no files are modified.
Fetches the latest release from GitHub, verifies the SHA-256 checksum (when a checksums.txt asset is present), and replaces the running binary in-place. The binary is written atomically via a temporary file.
Detects and removes:
- Legacy branches — branches matching the old
hermit/issue-Nformat that were not cleaned up - Zombie worktrees — git worktrees whose directories no longer exist on disk
Run this once after upgrading from an older version if you see warnings about legacy resources on hermit serve startup.
MIT