hmesh-mcp
Integrates with Google Antigravity CLI as a coding harness, enabling ticket execution via agy, model discovery, plan/read-only or write modes, and conversation resume.
Integrates with OpenAI Codex CLI as a coding harness, enabling ticket execution via codex exec, model discovery, sandbox/read-only or full-auto modes, and session resume.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hmesh-mcp Dispatch a ticket to fix the login bug and monitor it"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Harness-Mesh
Run one coding ticket across Claude Code, OpenAI Codex, DeepSeek Harness, Google Antigravity and ZCode. A ticket owns one isolated Git worktree; individual assignments may fail over between harnesses, models and sessions while the worktree and partial work stay in place.
中文文档 · Security · Docs · Contributing · MIT License
What the product is
Harness-Mesh is a local orchestration layer, shipped as:
a Python package (
harness_mesh) with a typed data model and SQLite ledger;a CLI,
hmesh, for status, model discovery, dispatch, context and patches;an stdio MCP server,
hmesh-mcp, exposing 18 tools to a controller harness;a local runtime directory,
.harness-mesh/, holding state, worktrees and paged resources.
It does not provide a model, a hosted service, a web UI or a multi-user scheduler. It orchestrates the harness CLIs you already have installed and authenticated on the machine. Prompts and code are sent to those CLIs; the mesh process itself keeps a local ledger and bounded summaries.
Related MCP server: agentbus
Who it is for
Developers who use more than one coding harness and want one task queue instead of copying prompts between terminals.
Platform and agent-infrastructure engineers who need quota-aware routing, worktree isolation and auditable assignment history.
Researchers and reviewers evaluating cross-harness scheduling, failover and shared-context behaviour.
It is not a replacement for a harness's permission model, sandbox, or vendor terms. It assumes you have legitimate access to each CLI and its models.
Scope
In scope | Out of scope |
Dynamic discovery of locally authorised models from configuration, environment, live model endpoints and CLI enumeration | Maintaining a fixed or hosted model catalogue |
Difficulty tiers plus market-aware routing by task kind, and skill/plugin injection | Training or hosting models |
Ticket/Assignment failover on quota exhaustion, unauthorised models, credential failures and transient errors | Multi-tenant authentication, RBAC or billing |
Git worktree isolation, dirty-workspace sync, dependency pre-apply and explicit patch application | Merging worktrees automatically without review |
Shared project instructions, a cross-harness memory blackboard and dependency context | Uploading project data to a remote service |
Claude Code, Codex, DSH, Antigravity and ZCode adapters | Changing a vendor CLI's own protocol beyond the configured template |
Requirements
Python 3.11+.
One or more supported harness CLIs installed and logged in. A harness that Harness-Mesh runs as a worker needs its own command-line login; see Logins: controller versus worker.
Git available on
PATHfor isolated worktrees.macOS is the primary target for the shipped App Bundle paths. Linux/WSL works with binaries on
PATH; real-machine tests skip when the macOS bundles are absent.
Install
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"Two entry points are installed:
hmesh— operator CLI.hmesh-mcp— MCP stdio server.
Optional Antigravity Python SDK support:
.venv/bin/pip install -e ".[antigravity]"One-command install into desktop harnesses
After installing the Python package, register Harness-Mesh in every detected desktop harness with one command:
cd /path/to/your/project
hmesh installWhat it installs:
Harness | Integration |
Claude Code |
|
OpenAI Codex / ChatGPT desktop |
|
Google Antigravity |
|
ZCode | Generates a local MCP plugin + marketplace, registers/installs it through |
DeepSeek Harness | Adds an |
Useful options:
hmesh install --dry-run # print planned commands/files, change nothing
hmesh install --yes # non-interactive install
hmesh install --approve read # pre-approve 11 read-only MCP tools
hmesh install --harness zcode # one harness only (repeatable)
hmesh install --workspace /path/project # pin the MCP workspace explicitly
hmesh install --uninstall # remove integrationsWithout --dry-run, hmesh install prints the planned files and commands and asks for confirmation. A non-interactive shell must pass --yes.
MCP tool pre-approvals
Interactive sessions ask before an MCP tool runs. Headless commands such as codex exec and agy -p cannot answer that prompt, so hmesh install writes per-tool allow rules:
hmesh install --approve dispatch # default: 14 read and dispatch tools
hmesh install --approve read # 11 read-only tools
hmesh install --approve all # 16 tools; apply_task_patch and install_integration stay manual
hmesh install --approve none # write nothing and remove rules written by hmeshdispatch, the default, approves the eleven read tools plus dispatch_task, parallel_dispatch and cancel_task. Dispatched work runs in an isolated worktree; its changes reach the primary checkout only through apply_task_patch. The four write tools stay manual: apply_task_patch, report_quota_status, update_project_context and install_integration change the primary workspace, shared state or another application's configuration. --approve all pre-approves report_quota_status and update_project_context as well, but apply_task_patch and install_integration are always manual and are never written into a harness allow rule. Independently of harness approvals, the MCP server refuses every write tool under HARNESS_MESH_READ_ONLY=1 and refuses workers the controller-only write tools; hmesh apply and hmesh install apply the same gate.
Harness | File | Rule |
Claude Code |
|
|
Codex |
| A managed block holds |
Antigravity |
|
|
ZCode, DeepSeek Harness | none | Workers call MCP tools without approval settings |
The installer is idempotent. It keeps a <file>.harness-mesh.bak copy before the first edit, writes through a temporary file, re-parses the result and restores the previous bytes if validation fails. Lowering the level or uninstalling removes only entries with the mcp__harness-mesh__ or mcp(harness-mesh/ prefix, plus the Codex managed block; other rules stay in place. --dry-run prints the approval count and each entry without touching files. hmesh doctor reports approved and missing tools against the default dispatch level and changes no files; on Codex, a service-wide default_tools_approval_mode = "approve" counts as covering every tool.
Headless runs cannot answer approval prompts. Measured on the real harnesses (2026-11-01): codex exec denies the MCP call with "approval policy is never" unless the server is approved; agy -p auto-denies it unless permissions.allow holds a matching rule such as mcp(harness-mesh/list_harnesses). The per-tool rules above cover the selected level; the service-wide Codex setting -c 'mcp_servers.harness-mesh.default_tools_approval_mode="approve"' remains a manual alternative that approves every tool. ZCode and DeepSeek Harness workers call the tools without extra configuration, and Claude Code shows the server as connected. Interactive sessions prompt as usual.
ZCode's --scope project still records the marketplace and plugin in the global state files ~/.zcode/cli/plugins/known_marketplaces.json and installed_plugins.json, even though the plugin and its cache are project-scoped. hmesh install --uninstall removes both entries; the matching zcode plugins uninstall and zcode plugins marketplace remove commands do the same by hand.
Restart the desktop application after installation and start a new chat/task. Existing chats may keep a cached tool list. The installer is idempotent; editing an existing DSH entry or re-adding an MCP server replaces the previous registration rather than duplicating it.
When another harness arrives later
Claude Code and Codex are often installed first; ZCode or another supported harness may follow. The two roles need different handling.
Worker. No action. Dispatch re-resolves the binary for every assignment and routing re-checks adapter runnability, so the next ticket can use the new harness. Only the model inventory is cached, for five minutes.
Controller. The harness must have the Mesh MCP server or plugin registered before it can call these tools. Mesh reports the gap and leaves the decision to you:
hmesh integrationslists every configured harness asintegrated,detected_not_integrated,stale(registered but the command no longer runs),not_detectedorignored.hmesh doctorandhmesh statusend with one line naming the detected harness and the install command.Inside a controller conversation,
list_harnessesaddsintegration_hints. The agent explains the hint, callsplan_integrationto show the files, approval entries and commands, and callsinstall_integrationonly after you agree.
plan_integration returns a plan_id: the first 16 hex characters of a SHA-256 over the normalised plan and the current content of the target files. install_integration recomputes the plan and refuses any id that no longer matches, so editing a config file between review and install forces a new review. It is a write tool; the default dispatch level leaves it for manual approval. Workers are refused through the same lineage resolution as nested dispatch, HARNESS_MESH_READ_ONLY=1 blocks it, and the target harness must restart before its tool list appears.
hmesh integrations ignore zcode stops the reminder and unignore restores it. The command writes only integration.ignore in the Mesh config; it never edits another application's configuration.
Logins: controller versus worker
A harness can play two roles, and each role uses a different login.
Role | Who calls the model | Login it needs |
Controller | You, inside the harness, for example the Claude Code desktop app calling the harness-mesh tools | The login the harness application already has |
Worker | Harness-Mesh starts the harness command-line tool as a subprocess to run a ticket | The command-line tool's own credentials |
The two logins can differ. Measured on macOS with the Claude Code desktop app (2026-11-01): the app was logged in and called every harness-mesh tool as a controller, while the bundled claude command reported loggedIn: false and Not logged in · Please run /login. The desktop app hands credentials to the sessions it hosts through its own channel; no keychain item, credentials file or API key existed for a separately started claude to read. A command-line Claude Code used as a controller is itself the command line, so it needs the command-line login too.
When a worker is not logged in, Harness-Mesh does not fail the ticket. The first attempt returns not_logged_in, the harness circuit opens (hmesh quota shows claude_code/*: state=open reason=not_logged_in), routing skips that harness and the ticket moves to another one, for example Claude models served through Antigravity. Probes run automatically and the circuit closes once the login works.
To use the Claude Code command line as a worker, log in once in a terminal and confirm it:
claude auth login # or set ANTHROPIC_API_KEY
claude auth status # loggedIn must be trueThe same rule applies to every harness: a worker uses that tool's own login. hmesh status and hmesh quota show which harnesses are usable. Not verified: whether a worker started by a Harness-Mesh server hosted inside the desktop app can inherit the desktop login; on the test machine it could not.
Quick start
# Discover installed harnesses, real CLI versions and authorised models.
hmesh status
# Force the three-layer model discovery and the tier mapping.
hmesh models --refresh
# Inspect quota circuits and waiting tickets.
hmesh quota --probe
# Fetch market prices and evaluation scores, then preview a route.
hmesh market refresh
hmesh market show --unmatched
hmesh route --objective "Design the migration plan" --kind plan
# List indexed SKILL.md files and MCP/plugin manifests.
hmesh skills
# Write and read a shared project fact.
hmesh context set arch.overview "Federated Harness Mesh" --category architecture
hmesh context list
# Print the MCP configuration for a controller harness.
hmesh init-mcp --print
# Dispatch a ticket and inspect the result.
hmesh dispatch --harness deepseek \
--objective "Create a short design note in docs/mesh.md" \
--difficulty medium --fallback codex --fallback zcode
hmesh tasks
hmesh read <task_id> diff --limit 4000
hmesh apply <task_id> --strategy patch
hmesh apply <task_id> --strategy copy --force-copy
hmesh doctorStart the MCP server with background recovery, effects consumption and market refresh (the default):
hmesh-mcpDisable every background worker for a pure request/response server:
hmesh-mcp --no-monitorThe server reads HARNESS_MESH_WORKSPACE for the primary project root and HARNESS_MESH_CONFIG for an optional YAML configuration. Without that variable the loader reads $XDG_CONFIG_HOME/harness-mesh/config.yaml (usually ~/.config/harness-mesh/config.yaml) and then ~/.harness-mesh/config.yaml.
Supported harnesses
The defaults target the real macOS installations observed on a developer machine. All paths and command templates are configuration, not code.
Harness | Default binary search | Real non-interactive protocol | Model discovery |
Claude Code |
|
|
|
OpenAI Codex |
|
|
|
DeepSeek Harness |
|
|
|
Google Antigravity |
|
|
|
ZCode |
| wrapper runs the Electron binary with the CJS entry and provider config; `zcode -p --cwd --json --mode plan | yolo |
hmesh status returns available: true only when the binary resolves and its version command succeeds. Model lists are runtime data and are never hard-coded.
How it works
Ticket, Assignment and failover
Ticket task_x (one Git worktree)
├── Assignment #1 claude_code/claude-opus-<version> ended_quota
├── Assignment #2 codex/gpt-<version>-<variant> completed
└── failover_history: quota_exhausted:rate_limit_429dispatchcreates a ticket and an isolated worktree. If the primary checkout has uncommitted files,sync_uncommittedcopies them into the worktree and records a baseline commit.The router selects an authorised, quota-healthy model for the task's difficulty tier and runs one adapter.
On quota exhaustion, an unauthorised model, a harness-wide login failure, or a transient error, it records a
ContinuationCheckpointand creates a new assignment on the next harness/model. The worktree is reused.Recovery Notes force the next agent to inspect
git statusandgit diffbefore continuing. The final diff is measured against the baseline commit, so only the ticket's net changes are returned.Outputs are capped: summary, diff preview and raw logs are bounded; full content is saved as
diff,transcriptandassignmentsresources and read page by page withread_task_resource.
Quota policies:
failover(default): create a new assignment on the next healthy candidate.wait_and_resume: suspend the ticket aswaiting_for_quotaand resume it after a real provider probe succeeds.fail: fail immediately.
Circuits are CLOSED / OPEN / HALF_OPEN. A probe makes one deliberately tiny real model call; local configuration alone never closes a quota circuit. A successful assignment also closes it.
Shared project context
ProjectContextManagerscansAGENTS.md,CLAUDE.md,.harness-mesh/PROJECT_CONTEXT.md,.cursorrulesand.github/copilot-instructions.md, with a character budget.update_project_contextwrites architecture notes, conventions, API contracts, decisions, pitfalls and notes to a SQLite blackboard. Later tickets receive<project_shared_memory>.context_filesare rendered as bounded<context_file_previews>so the child agent does not start with a blind search.depends_oninjects upstream summaries, modified files and diffs as<upstream_task_outputs>and pre-applies the upstream diff into the downstream worktree baseline.auto_record_contextrecords a completed ticket's summary as a shared note.
These blocks are project data, not instructions that override the ticket objective or the security policy.
Sessions and permissions
TaskRequest.session_id flows through MCP and AdapterCall. Adapters map it to --resume (Claude/ZCode), codex exec resume <id>, --session-id (DSH) or --conversation (Antigravity). Write-mode templates inject each CLI's approval bypass; read-only tickets use plan/read-only modes and run in a disposable worktree.
Market data and model routing
The mesh can rank models by published price and evaluation score instead of relying only on the four difficulty tiers. The data layer is read-only and separate from dispatch.
Sources
Source | Authentication | Fields used |
OpenRouter | none | list price per token, context window, reasoning and tool flags |
models.dev | none | list price per million tokens, context window, release date |
Epoch AI | none | reasoning and coding benchmark percentiles, benchmark dates |
Artificial Analysis |
| intelligence index, list price, output speed |
models.dev lists the same model once per provider, including hundreds of resale gateways. Those rows fold onto one canonical model per name. The price comes from the model vendor's own entry (listed in market.first_party_providers), then from OpenRouter, then from the median of every priced offer. An entry that prices input and output at zero counts as unknown, not free.
Epoch AI publishes the CC BY 4.0 "Capabilities & benchmarking" archive and needs no key, so it is the default evaluation source. Each benchmark contributes one percentile computed inside a 540-day reference window (market.epoch.reference_window_days); an axis with fewer than three scored benchmarks stays empty (market.epoch.min_benchmarks). The two axes are intelligence_reasoning and intelligence_coding, and intelligence is the equal-weight mean of the axes a model has. Artificial Analysis takes precedence when ARTIFICIAL_ANALYSIS_API_KEY is set. Without either source the mesh computes a labelled heuristic from the existing discovery score, the price percentile, the reasoning flag and the release date.
The heuristic is not an evaluation. Every score carries intelligence_source: epoch_ai, artificial_analysis, override or heuristic. hmesh market show and the get_model_market MCP tool print that field.
Epoch AI data is CC BY 4.0 and requires attribution. hmesh market show ends with Benchmark data: Epoch AI, 'Capabilities & benchmarking', https://epoch.ai/benchmarks (CC BY 4.0); --json carries the same string in attribution, and every routing decision includes it.
hmesh market refresh writes a snapshot to .harness-mesh/state.db. The default lifetime is six hours. Epoch AI and Artificial Analysis are cached for at least twelve hours; Artificial Analysis is also limited to 20 requests per process per day. A failed refresh keeps the previous snapshot and marks it stale. Cached data older than seven days still works and is flagged expired.
market.enabled: false or HARNESS_MESH_OFFLINE=1 stops every outbound request.
Hands-off refresh
The cache stays current without a manual step. The MCP server refreshes in the background at start-up when a source is missing or past its TTL, then on a TTL cadence. The first dispatch that finds no market data at all waits at most market.wait_seconds (8 s) and then continues with the local tiers while the refresh finishes in the background. One-shot commands (dispatch, route, status, models, market show) run the same refresh synchronously under the same 8 s bound and fall back to the previous snapshot or the heuristic when a source is slow or down. A failed refresh only logs a warning.
The controller sends an objective, nothing else. dispatch_task over MCP and hmesh dispatch default target_harness to auto, so the mesh routes across every installed harness and picks the model. The MCP initialize response states the same rule to every client. Passing model or target_harness explicitly keeps the previous behaviour.
On a machine with only some of the five harnesses, hmesh status, hmesh models and list_harnesses report a missing harness as not installed with the reason and leave its models and tier map empty; hmesh doctor ends with N of 5 harnesses installed. hmesh install --dry-run returns skipped for a missing binary, and ZCode is skipped as ZCode not found without writing a plugin when neither its CLI nor its app is present.
The market score also drives discovery: when a harness model matches the catalogue, its capability_score, assigned_tiers and tier map come from the market intelligence instead of the local heuristic. hmesh models, hmesh status and list_harnesses show each model's intelligence, intelligence_source and blended price, so the tier a user reads, the model dispatch picks and the route preview agree. hmesh doctor adds a read-only market row with the sources, the last successful refresh, staleness, the match rate and the unmatched models.
Task kinds and tiers
task_kind is plan, audit, review, implement, refactor, debug, test, docs or auto. auto reads the objective (Chinese and English keywords) and otherwise follows evaluate_difficulty.
Tier | Task kinds and difficulty | Rule |
|
| highest intelligence; ties go to the lower blended price |
|
| highest intelligence per blended dollar among candidates at or above 85% of the best score |
|
| cheapest candidate at or above a difficulty floor (0.55 for low, 0.70 for medium) |
blended_price = (3 * input + output) / 4 in USD per million tokens. A model with no known price is left out of price comparisons and used only when nothing else qualifies.
routing.axis_weights decides which evaluation axis a task kind is scored on: plan, audit and review use reasoning 0.7 / coding 0.3; implement, refactor, debug and test use coding 0.7 / reasoning 0.3; docs uses reasoning 1.0. When a model has only one axis, that axis carries full weight.
Claude Code and Codex bill through a subscription quota rather than per token. The router uses the API list price as a proxy for quota consumption and states that in every decision record.
Routing modes
routing.mode defaults to auto. manual keeps the model you pass; off uses the four difficulty tiers. HARNESS_MESH_ROUTING overrides the configured default, and a request-level routing_mode wins over both.
routing.pins fixes {harness, model} for one task kind. routing.premium_hints and routing.value_hints add weight to matching models; routing.strict_hints: true turns them into a hard filter. The example configuration uses exact glm-5.3, so it does not match glm-5.3-flash.
When no market snapshot exists, no harness model matches the catalogue, or the planner returns no choice, dispatch falls back to discovery.resolve_model(harness, difficulty). The decision record keeps the reason.
Decision record
Every result carries a routing object: mode, task kind, tier, chosen harness/model/effort, intelligence and its source, axis_scores (both axis scores with the weights used), benchmarks_used, the attribution string, list prices, the top three alternatives with scores, the data sources, fetched_at, stale, expired and the match confidence. The same block appears at the top of the transcript.
Not connected
The Aider polyglot leaderboard has no data after 2025-10. The community LMArena snapshot (oolong-tea-2026/arena-ai-leaderboards) has returned empty leaderboards every day since 2026-10-20. api.llm-stats.com returns vendor-reported scores marked verified: false, only four models carry an AA-Index, and its terms page returns 404. None of the three is used.
MCP tools (18)
Tool | Purpose |
| Installed harnesses, real binary, version, authorised models, tier map and quota state |
| Force three-layer discovery for one or all harnesses |
| Read cached list prices, context windows and intelligence scores; |
| Rank a task without dispatching: task kind, tier, chosen model and alternatives |
| Search indexed |
| Create a ticket, choose a model and run assignments with failover |
| Dispatch several tickets concurrently |
| Ticket status plus assignments and failover history |
| Page through |
| Circuits, waiting queue; |
| Five-state integration report for every enabled harness; read-only |
| Reviewable install plan and |
| Write tool: installs only when |
| Manual |
| Apply a completed isolated worktree to the primary workspace with |
| Cancel a running or waiting ticket; child processes are killed |
| Read shared memory entries and scanned instruction files |
| Write or update one shared project fact/contract |
CLI
hmesh install [--dry-run] [--yes] [--approve LEVEL] [--harness H]... [--uninstall]
hmesh doctor [--harness H] [--json]
hmesh status [--refresh] [--json]
hmesh integrations [--json]
hmesh integrations ignore|unignore NAME [--json]
hmesh models [--refresh] [--harness H]
hmesh quota [--probe]
hmesh route --objective O [--kind K] [--difficulty D] [--harness H] [--json]
hmesh market refresh [--source S]... [--json]
hmesh market show [--model GLOB] [--axis reasoning|coding] [--unmatched] [--json]
hmesh skills [--query Q]
hmesh dispatch --objective O [--harness H] [--difficulty D] [--kind K] [--routing-mode M] [--fallback H]...
hmesh tasks [--status S]
hmesh read <task_id> [diff|transcript|assignments] [--offset N] [--limit N]
hmesh apply <task_id> [--strategy patch|merge|copy] [--force-copy]
hmesh context list [--category C] [--json]
hmesh context set <key> <content> [--category C] [--author A] [--task-id T]
hmesh init-mcp [--print] [--target PATH]
hmesh versionConfiguration
The template lives at config/harnesses.example.yaml. Copy it to ~/.config/harness-mesh/config.yaml (or any path passed via --config / HARNESS_MESH_CONFIG). Files inside the checkout (config/harnesses.yaml, .harness-mesh/config.yaml) are treated as untrusted repository content and are ignored by default: a cloned repository must not be able to choose which binary runs or where credentials are sent. HARNESS_MESH_TRUST_WORKSPACE_CONFIG=1 merges only non-executable fields (market, routing, sizes, quotas) from the workspace file; --config and HARNESS_MESH_CONFIG are always trusted because the operator named them explicitly. Resolution order is: the command name on PATH (for example claude, codex, dsh, agy, zcode), then the configured binary_paths (built-in macOS app-bundle locations plus any you add), then the macOS ZCode shim. A standard CLI install that lands on PATH therefore needs no configuration and no absolute path; the bundled paths only help desktop-app installs that do not put their CLI on PATH. If a harness lives outside PATH, add it to binary_paths in the user-level config file. Binary search supports ~ and * globs and selects the newest version. ZCode on macOS is wrapped automatically into .harness-mesh/bin/zcode.
The ledger lives under state_dir: the directory is created/tightened to 0700, and state.db plus its -wal/-shm side files to 0600. Transcripts, diffs and checkpoints are redacted before they are stored; the transcript resource is capped by transcript_max_chars (default 200000). If you upgrade from 0.4.1, the first 0.4.2 process rewrites legacy credential-shaped provider rows and vacuums the ledger; restart every harness that runs hmesh-mcp so the hardened server is the one in use.
Templates support {prompt}, {system_prompt}, {system_prompt_file}, {model}, {effort}, {workdir}, {mcp_config}, {task_id} and {assignment_id}. Empty flag/value pairs are dropped, so <cli_active_default> means "use the harness's own active model".
Key settings:
Setting | Default | Meaning |
|
| Ledger, worktrees, generated MCP configs |
| service workspace | Optional allowlist for request-level |
|
| Refuse a non-Git workspace unless it is explicitly enabled |
|
| Injection of approval-bypass flags when |
ZCode |
| Mode used when approval is withheld ( |
|
| Global cap on simultaneously running assignments |
|
| Summary returned to the controller |
|
| Diff preview returned to the controller |
|
| Cap for the paged transcript resource; head and tail are kept |
|
| Nested dispatch depth limit |
|
| Maximum failovers per ticket |
|
| Background recovery probe interval |
|
| Per-tier assignment timeout |
|
| Read-only market data and its snapshot cache |
|
| Snapshot lifetime for OpenRouter and models.dev |
|
| Longest automatic refresh before dispatch or a command continues |
| four sources | Providers to refresh |
|
| Vendors whose own models.dev entry sets the list price |
| six benchmarks | Benchmarks that feed the reasoning axis |
| nine benchmarks | Benchmarks that feed the coding axis |
|
| Percentile window before a benchmark's latest release |
|
| Minimum scored benchmarks before an axis counts |
|
| Map a harness model id or glob to a market key |
|
| Glob-keyed intelligence and price overrides |
|
|
|
|
| Value-tier intelligence floor by difficulty |
| per task kind | Reasoning/coding weights used to score a task |
|
| Model globs weighted per tier |
|
| Turn hint weighting into a filter |
|
| Fixed harness/model per task kind |
|
| Harness names whose integration hints are suppressed |
Testing
.venv/bin/ruff check src tests
.venv/bin/python -m compileall -q src tests
.venv/bin/pytest -vThe fast suite uses mocked adapters, temporary Git repositories, httpx.MockTransport market providers and cached snapshots. It opens no sockets. Live HTTP checks live in tests/test_real_machine_market.py and run only with HARNESS_MESH_REAL_MACHINE=1; the Artificial Analysis branch also needs ARTIFICIAL_ANALYSIS_API_KEY. tests/test_local_machine_harnesses.py additionally exercises the real locally installed harnesses when the macOS bundles are present; it asserts real binary resolution, real model inventories, and a real DeepSeek ticket that creates a file in a worktree and applies it back. See CONTRIBUTING.md for the development workflow.
Operational notes
The mesh state directory may contain source excerpts and prompts. Keep it out of commits and shared archives.
Approval-bypass flags make a disposable worktree convenient, not safe. Built-in harnesses default to
auto_approve: truefor isolated worktrees;shared_writesuppresses bypass unlessauto_approve_shared_write: true. Use isolated worktrees, review diffs, and respect provider terms.The DeepSeek built-in runtime strips credential-shaped environment variables from its shell tool. That reduces accidental key exposure but does not create a sandbox.
A one-shot
hmesh dispatch --policy wait_and_resumeexits after scheduling the suspension; the long-lived MCP server runs the background monitor and effects consumer. Usehmesh quota --probeor the MCP tool to resume manually.Antigravity SDK timeouts cancel waiting but cannot kill a third-party worker thread.
Codex CLI versions differ in accepted approval flags. The built-in default injects
--full-auto; the example YAML overrides it with--dangerously-bypass-approvals-and-sandboxfor codex-cli 0.166. Adjustexecute_templateorextra.auto_approve_argsfor your version.
Workspace and context boundaries
The MCP server and CLI require a Git workspace; startup fails from
$HOME,/, or a directory without Git.Request-level
workspace_rootmust resolve (including symlinks) insideallowed_workspace_roots, which defaults to the service workspace.Sensitive filtering covers
.envand real credential/key files, plus.ssh,.aws,.gnupg, and.gitpath segments..env.example,.env.sample,.env.template,.env.dist, ordinarycredentials_service.py-style source, and public*.pubkeys stay visible. Every skipped path is reported inskipped_sensitiveand warnings; Mesh no longer edits the user's.git/info/exclude.Worktree symlinks are rewritten as relative links into the worktree. Escaping or dangling links are reported; apply rejects symlink diffs that leave the target root.
Approval bypass flags are suppressed for
shared_writeunlessauto_approve_shared_write: true; the DeepSeek built-in shell drops credential-shaped environment variables, cloud key names, SSH agent sockets, and URLs containing passwords.Shared memory is capped at 128 characters per key, 4,000 per entry and 6,000 rendered characters. Only
controllerentries render as verified; worker and auto entries render in a separate unverified block. Author validation checks the name only.Mesh Git commands disable hooks, fsmonitor, pager, external diff and protocol.ext, record a per-task metadata guard once, and reject apply or abort the ticket when metadata changes after task start.
MCP call depth can be recovered from the worktree cwd or lineage marker when inherited environment variables are unavailable;
max_active_assignmentscaps running assignments.
Trademarks and independence
Harness-Mesh is an independent open-source project. It is not affiliated with, sponsored by, or endorsed by Anthropic, OpenAI, DeepSeek, Google, or ZCode. Claude, Codex, DeepSeek Harness, Google Antigravity, and ZCode are names or trademarks of their respective owners, used here only to describe interoperability. Each harness remains governed by its own licence, acceptable-use policy, and data terms.
License
MIT. See LICENSE.
Available Tools
18 toolsapply_task_patchB
Apply the isolated worktree changes back into the primary workspace.
Only patch and merge are exposed over MCP. The copy
strategy is destructive and remains a CLI-only operation.
Inputs: task_id (required), strategy. Returns: object
cancel_taskB
Cancel a running or waiting ticket. The worktree is retained for inspection.
Inputs: task_id (required). Returns: object
discover_harness_modelsC
Run the three-layer model discovery waterfall for one or all harnesses.
Inputs: harness, force_refresh. Returns: object
dispatch_taskB
Dispatch a ticket.
Only the objective is required. Leave target_harness at "auto" and model unset to let the mesh choose; pass task_kind when it is known. Quota exhaustion creates a new Assignment on another harness and resumes in the same worktree.
Inputs: objective (required), model, skills, plugins, +25 more. Returns: object
get_integration_statusA
Report whether each installed harness can reach Mesh as a controller.
States are integrated, detected_not_integrated, stale,
not_detected and ignored. Read-only: detection never writes.
Inputs: no named parameters. Returns: object
get_model_marketB
Read cached model prices, context windows and intelligence scores.
intelligence_source says whether a score came from Artificial
Analysis, a user override or the local heuristic. This tool never
refreshes the cache and never performs a network request.
Inputs: limit, query. Returns: object
get_project_contextC
Read the cross-harness project memory blackboard and instruction files.
Inputs: category, include_instructions. Returns: object
get_quota_statusA
Show quota circuits and the waiting_for_quota queue.
probe_now triggers recovery probes and resumes waiting tickets.
Inputs: probe_now. Returns: object
get_task_statusC
Return ticket status plus every assignment and failover hop.
Inputs: task_id (required). Returns: object
install_integrationA
Install one harness after the user approved the reviewed plan.
This is a write tool: it refuses workers and HARNESS_MESH_READ_ONLY=1,
and it refuses any plan_id that no longer matches a freshly computed
plan. The target harness must restart before the tools appear.
Inputs: harness (required), plan_id, approve_level. Returns: object
list_harnessesC
List locally available harnesses, discovered authorised models, tier bindings and quota state.
Inputs: refresh_models. Returns: object
list_skills_and_pluginsC
Search indexed SKILL.md files and MCP/plugin manifests.
Inputs: query. Returns: object
parallel_dispatchA
Dispatch multiple tickets concurrently.
Every task accepts the same fields as dispatch_task, including
task_kind, routing_mode, max_price_per_mtok and
min_intelligence. target_harness is optional and defaults to
auto.
Inputs: tasks (required), max_concurrency. Returns: object
plan_integrationA
Return the exact installation plan and plan_id without writing.
harness must be an enabled configured name and approve_level
one of read, dispatch, all or none. Show this plan to
the user and ask for consent before calling install_integration.
Inputs: harness (required), approve_level. Returns: object
preview_routingB
Preview the routing decision for an objective without dispatching it.
Inputs: objective (required), task_kind, difficulty, target_harness. Returns: object
read_task_resourceB
Page through a large diff/transcript/assignments payload to protect the controller context window.
Inputs: task_id (required), limit, offset, resource. Returns: object
report_quota_statusC
Manually reset or mark a quota circuit (actions: reset, open, half_open).
Inputs: harness (required), model, action, cooldown_seconds. Returns: object
update_project_contextC
Write or update one shared project fact or interface contract.
Inputs: key (required), content (required), task_id, category, +1 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 18 tools
Most tools map to a distinct resource+action, and the three-phase integration flow (status → plan → install) is explicitly separated by read/write semantics. Minor ambiguity remains between get_quota_status and report_quota_status, since 'report' sounds like a read but actually mutates the circuit, and the model-information trio (discover_harness_models, list_harnesses, get_model_market) requires reading descriptions to separate cache reads from live discovery.
The surface is overwhelmingly verb_noun snake_case (get_task_status, cancel_task, update_project_context) with clear read/write prefixes. Deviations are cosmetic: parallel_dispatch inverts the verb order, preview_routing lacks an explicit object, and discover_harness_models/get_model_market stretch the pattern without breaking it.
18 tools sit at the high end of comfortable but each corresponds to a real operation across dispatch, quota, integration, model discovery and project context. Nothing looks like filler, though the set is broad enough that a controller may need a session to build a mental map.
Core lifecycle is well covered: routing preview, dispatch (single and parallel), status, cancel, patch application, quota read/write and integration detect/plan/install. Gaps are real but workaroundable: there is no list_tasks to enumerate tickets before calling get_task_status, no uninstall/ignore integration despite the 'ignored' state, and no tool to edit tier bindings that list_harnesses reports.
Maintenance
Related MCP Connectors
Workflow planning, recovery checkpoints, coordination, fixtures, and compatibility tools for agents.
Shared control plane for AI coding agents — tasks, memory, decisions, file locks. 12 tools.
Hosted coding agent: start, follow up on and stop tasks that can open GitHub pull requests.
A hosted backlog coding agents claim work from: one ticket per agent, finished work back to review.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables repository-aware lifecycle management and controlled delegation of coding tasks to trusted worker harnesses via MCP, with execution isolation, recovery, and verified handoff.36 npm8Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables coordinating Claude Code and Codex on one machine by fanning out tasks to multiple agents in isolated Git worktrees, comparing results, picking a winning candidate, and handing off work between harnesses. It provides MCP stdio tools, a CLI, and a local loopback web cockpit.Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables AI coding providers to run structured multi-agent workflows with shared documents, tracked tasks, handoffs, and health-gated completion evidence. It integrates with multiple coding tools while keeping task state, actions, and health results in the harness.29 npmMIT
- AlicenseAqualityCmaintenanceEnables a planning agent to delegate research and implementation to lower-cost worker models in isolated git worktrees, monitor job progress, respond to blocked jobs, and land verified changes for review.6MIT