
HAI-MCP
io.github.smlfgPublished by GitHub account smlfgv0.1.0Updated Oct 24, 2026
Model-agnostic MCP control plane for HAI: bounded missions, owner-gated actions, drift checks.
Overview
A local MCP control plane that lets an assistant open bounded missions, request session leases, check activity against a contract, and record evidence.
- What you can do
- Open, recontract and close bounded missions with versioned contracts and done criteria, and read the current contract or status with focus lanes set to at most two active lanes. Authorize time-bounded session leases bound to a mission, contract version, role and criterion set. Classify planned or observed activity as on-contract or off-contract with a deterministic drift check. Record proofs and evidence, checkpoint context and recover the smallest next action. Handle an inbox with intake, distill and park items, and bind a project id to a device-local directory behind an owner acknowledgement.
- When to use it
- Use it when you want an agent's work to stay observable, bounded and owner-gated: missions with explicit non-goals and done criteria, leases that expire, drift checks before acting, and evidence recorded before closing. It suits teams that switch between LLM clients and want the same governance regardless of model.
- Requirements
- Runs locally as a Python package (Python 3.12 or later, uv) over stdio by default, or streamable-http when HAI_TRANSPORT is set. Optional settings: HAI_HOME (default ~/.hai), HAI_OWNER_HOME (default ~/.hai-owner), HAI_HTTP_HOST, HAI_HTTP_PORT and HAI_HTTP_TOKEN for non-loopback HTTP. No account or external service is required.
Installation
In SourceWeft
- Open HAI-MCP in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
HAI-MCP · Model-agnostic MCP control-plane for the Human Agent Interface (HAI) approach
[License: MIT] [Python ≥ 3.12] [MCP] [Issues]
Why this repo exists
Agents are now driving shells, editors, browsers, and CI. Most of them work without a human in the loop long enough for the human to lose the thread. HAI — the Human Agent Interface — is an opinionated, evidence-based way to keep agentic work observable, bounded, owner-gated, and recoverable so a human can still own the work even when an agent is doing it.
HAI-MCP is the open-source, model-agnostic implementation of that approach. It is one of the pieces of Samuel Fleig's HAI stack — the part that any Model-Context-Protocol-speaking client can talk to, regardless of which LLM sits behind it.
Canonical site: https://www.human-agent-interface.com/ · About Samuel: https://www.human-agent-interface.com/samuel/
What "MCP control-plane" means here
MCP — the Model Context Protocol — is a standard JSON-RPC interface that lets a tool server expose tools, resources, and prompts to an LLM-backed client (Claude Code, Codex, Cursor, Grok, OpenCode, Hermes, …). The client discovers the server's tools and calls them during a conversation; the server stays stateless from the model's point of view.
A control-plane server is one that does not do the work itself — it governs how work is authorised, scoped, recorded, and handed back to the human. Concretely, an MCP control-plane:
HAI-MCP is deliberately not an agent runtime. It never calls an LLM, never runs shell, never pushes to git, and never deletes files. It is the judge — agents call it to ask "may I?" and to record "I did".
Features
- One state engine, 23 tools — three surfaces (legacy control plane, mission lifecycle, daily-loop wrappers) sharing one hardened core.
- Strict fail-closed boundary — inputs are typed and rejected, not
coerced. A
String "2"is refused for anIntegerfield; the server stays reachable instead of silently mangling types. - Versioned mission contracts — every mission has a contract with a monotonic version. Recontracting produces a visible field-level diff and revokes every existing lease.
- Time-bounded session leases —
hai_authorize_sessionbinds a lease to a mission id, a contract version, a duration, a role, a contribution, and a claimed criterion set. - Deterministic drift check —
hai_check_activityclassifies planned or observed activity against the contract without ever calling an LLM. - Two-principal owner gate:
- Default (nonce): the server delivers a one-time code to the owner
channel (
HAI_OWNER_HOME/file, or ntfy). The client never sees the code. The code is bound to the exact change, single-use, expiring; only the hash is stored inHAI_HOME. touchid(macOS): the server process shows a Touch ID prompt for that exact change. There is no code. The agent's follow-up call applies it; the client cannot approve itself.ack_legacy: the old self-assertedowner_ackflag — an honor system, surfaced as such byhai_health.
- Default (nonce): the server delivers a one-time code to the owner
channel (
- Mount table —
hai_bind_projectjoins a logicalproject_idto a device-local directory behindowner_ack + reason. - Model-agnostic — same binary, same tools, same contract. Switch LLMs without rewriting governance.
- Two transports — stdio (default) and
streamable-httpwith optional bearer-token binding (loopback only by default). - Checkpoint & recover —
hai_checkpointsnapshots context;hai_recoverreturns the smallest recovery next action. - 203 tests green — the engine is covered; the slice remains open for the learning-budget and owner-instrument follow-ups.
Install & run
Requires Python ≥ 3.12 and uv.
Streamable-HTTP transport:
HTTP binding to non-loopback hosts is refused unless
HAI_HTTP_TOKENis set. Seedocs/OWNER_GATE.mdand the--helpoutput.
Sample usage — wiring the server into a client
The server is transport-agnostic; every MCP client gets the same 23 tools. Drop the snippet into the client's MCP config and restart.
Claude Code / Claude Desktop
Cursor
Cursor plugin: this repo is also a Cursor plugin (.cursor-plugin/plugin.json +
mcp.json). It starts the server from PyPI with uvx hai-mcp, state goes to
~/.hai and ~/.hai-owner by default. Requires uv.
Manual config:
Codex / Hermes / any MCP stdio client
Same shape — point at the uv run --directory … hai-mcp command and pass
the two env vars. More snippets live in docs/client-snippets/.
Sample usage — driving the protocol
A typical agent loop calls HAI-MCP before it acts and after it acts.
1. Open a bounded mission
2. Authorise a session lease
3. Check an activity before running it
4. Close with evidence
5. Owner-gated promotion
For hai_accept_next_step, hai_recontract, or abandoning a mission, the
first call without owner_code asks the owner out of band.
file/ntfy: a one-time code is delivered toHAI_OWNER_HOMEor an ntfy topic. Relaying it back asowner_code=<code>completes the action. The client never sees the code; only its hash is stored inHAI_HOME.touchid(macOS): setHAI_OWNER_CHANNEL=touchidon the server. The server shows a Touch ID prompt and returnsstatus: owner_approved. Call the same tool again with the same arguments (no code) to apply that exact change. Optional:HAI_OWNER_TOUCHID_TIMEOUT(default 60),HAI_OWNER_TOUCHID_HELPER(a compiled binary), andHAI_OWNER_TOUCHID_FALLBACK=fileonly when Touch ID cannot run.
The approval is bound to the exact change and is single-use. On a Mac,
uv run python scripts/manual_touchid.py prompt and … gate exercise the
real sensor; CI mocks the helper. Detail:
docs/OWNER_GATE.md.
State layout
- Global:
$HAI_HOME— default~/.hai - Owner channel:
$HAI_OWNER_HOME— default~/.hai-owner(deliberately outsideHAI_HOMEso the agent cannot read it) - Per-project:
<project_path>/Projek-Managment/(legacy) or device mount + relative prefixes when aproject_idis bound - Mount table:
HAI_HOME/core/projects.json
All writes are resolved and confined to these roots.
Project layout
Limitations
HAI-MCP is intentionally narrow. It does not:
- Call any LLM. The server is dumb on purpose — governance is a separate concern from generation.
- Execute code, run shells, push git, or delete files. It refuses tools
like "commit & push", "run pytest", "rm -rf". Agents are expected to
do those things and report back via
hai_check_activity/hai_proof. - Merge with
hai-intakepackages. The intake pipeline is a separate stack; coexistence is fine, fusion is not. - Provide a UI. There is no dashboard. The control plane speaks MCP and writes JSON; visualisation is the client's job.
- Multi-mission concurrency. Exactly one active mission globally. Open a new one only after the previous is closed (completed or abandoned).
- Cross-device writes. Each device sees only its own mounts. The mount table is per-device; the contract is global.
- Forward compatibility for major MCP bumps. The server pins
mcp>=1.9.0,<2; a v2 of MCP will require a separate migration slice. - No revocation list / no kill-switch API. Lease invalidation happens
via recontract, mission close, or
hai_stop; there is no out-of-band "revoke everything right now" tool. - No automatic recovery from a corrupted
HAI_HOME. If the global state directory is corrupted, the server fails closed — by design, but recovery is manual (seehai_recover).
See docs/TOOL_CONTRACT.md for the full
gate matrix and docs/OWNER_GATE.md for the
owner-gate contract.
Tests
The repo carries 203 green tests as of the Touch ID owner-channel slice. CI status lives on the GitHub Actions page of the repository.
Contributing
The control plane is small on purpose — additions go through a contract slice:
- Read
docs/TOOL_CONTRACT.md. - Open an issue describing the tool / gate / state change.
- Land it behind a
fail-closedslice with tests + plan indocs/plans/.
Pull requests that change gates, schemas, or the mount table without a matching plan will be asked to follow the same path.
License
MIT — see LICENSE. Copyright © 2026 Samuel Fleig.
Acknowledgements
HAI-MCP is one piece of Samuel Fleig's HAI stack. It stands on:
- the Model Context Protocol specification,
- the
mcpPython SDK (mcp>=1.9.0,<2), - and the legacy
~/.config/hai-agent-mcpHermes bridge that this server replaces for control-plane work. Coexistence is supported; the bridge is not required.
Canonical HAI site: https://www.human-agent-interface.com/ · About Samuel Fleig: https://www.human-agent-interface.com/samuel/
Source: README.md at commit 30bc0f4
Tools
0Version history
1- v0.1.0LatestOct 13, 2026
Score
50% of the applicable checks met
How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.
- Reached in the last 30 days25 pts
Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.
- Auth declared10 pts
Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.
- Tools listed15 pts
Answer tools/list without a credential, or ship a package that starts in a sandbox without one.
- DescriptionRequired15 pts
- Logo10 pts
- Documentation15 pts
- License10 pts