hitl
Reads a project's git status, diffs and history so the agent's work can be browsed and reviewed with context: files, folders and changes are viewable alongside the repository state, and review items can be compared against a branch (e.g. "against": "main").
Sends push notifications to your phone (via ntfy, or a configured webhook) whenever an agent asks a question, shows something for review, or is waiting at an approval gate, so blocking requests can be answered away from the machine.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
hitl — Human In The Loop
hitl is where an AI agent and its human meet. The agent asks you questions, shows you things, asks you to review its work, and waits at a gate for your OK. You answer, review, mark up pictures and browse the project's files, on your phone or your computer. Everything you say lands in one feed the agent reads a little at a time.
The npm package is hitloop; once installed (npm i -g hitloop) the command is hitl.
npx hitloop init # once per project: the .hitl folder, the MCP server for Claude Code, a note in CLAUDE.md
npx hitloop # the page, for every project, with links for your phoneSite: https://clickermonkey.github.io/hitloop/ (the commands, and a Claude skill to copy or download).
|
|
|
|
Inbox | Review | Before / after | Approve |
"Human in the loop" means a person stays part of what an automated system does: it checks with them, they decide, and it carries on. hitl gives that person somewhere to do it, instead of a chat scrolling past.
It grew from two smaller tools, and does everything both did:
questionme: an agent's questions, answered on your phone.
folderview: browse, search and comment on any folder, with git.
What you can do
Inbox | Everything waiting on you across every project, most urgent first: approvals (an agent is waiting), blocking questions, reviews, things to look at. What's done folds away. |
Answer questions | Dozens at a time, with recommendations, why each one matters, and pictures, diffs and mockups to decide from. Take the recommendations and change the few you disagree with. Text answers grow and wrap as you type. |
Review | Each thing the agent shows you gets Looks good, Needs changes or No. Comment on a line (tap its number; tap another for a range), on selected text, or on an area of a picture you draw around. Attach photos. Finish with Approve or Request changes. |
One at a time | Swipe through a review: right for looks good, left for needs changes. Good for thirty screenshots. |
Before and after | Pictures with a slider (or side by side); code and text as after, before, and the changes between them. |
Approve | An agent asks "Deploy 2.4.0 to production?" and waits. You get a notification, read what it will do, and tap Approve or Refuse. |
Browse the files | Everything folderview does: highlighted code, rendered markdown with Mermaid and math, images, CSV, JSON, notebooks, git status, diffs and history, search, downloads. Big files and big folders open quickly. |
Notes for the agent | Write on any file, line or picture area, or about anything, with photos from your phone. The agent picks them up and resolves each with a reply. |
Decisions | Everything you answered, approved or gave a verdict on, searchable. Agents check it before asking again. |
Who's asking | Each request says which agent session or branch made it. |
Notifications | Your phone buzzes when an agent asks, shows or waits (ntfy or a webhook). Approvals go out at once. |
It works on phones (sections along the bottom, big touch targets, the page scrolls), tablets and desktops (the file tree, the folder and the file side by side).
Related MCP server: Pingfusi
For agents
npx hitloop init adds the MCP server to Claude Code (claude mcp add --scope user hitl -- npx -y hitloop@latest mcp) and
a short section to the project's CLAUDE.md (or AGENTS.md) on when to use it.
MCP tools
Tool | |
| Everything the human said since you last read, across every question set, review and note, one line each. Start here. |
| Block until the human says something ( |
| Put files, code, text, diffs, pictures, diagrams, mockups or links in front of the human. |
| Ask yes or no before doing something, and wait for it. Returns APPROVED, REFUSED or "not yet" with their note. |
| Questions in a set (questionme's format): options, a recommendation, why it matters, follow-ups that open on an answer. |
| One review's feedback, one set's answers, the notes. |
| Mark answers and verdicts as dealt with, resolve comments and notes saying what you did, write back. |
| What the human decided before. |
| What's open; the links to send. |
| Change things. |
The CLI does the same
npx hitloop news # what's new (marks it read; --peek doesn't)
npx hitloop wait --any # exit once the human says something, printing it
npx hitloop wait --done <review> # exit once they've finished a review (or answered an approval)
npx hitloop show src/login.ts screens/*.png --title "Login, round 2" # a review of files
git diff | npx hitloop show - --title "The change" # stdin: a diff, code or text
npx hitloop approve "Deploy 2.4.0?" --details "Restarts the API" --timeout 30m && ./deploy.sh
npx hitloop ask <set> --file questions.json # questions (or write .hitl/questions/<set>.json)
npx hitloop feedback <review> npx hitloop answers <set> --new npx hitloop notes --open
npx hitloop ack <set|review> <id…> --note "Done in src/x.ts"
npx hitloop resolve [<review>] <id…> --note "Fixed: …"
npx hitloop reply <review> c12 "Because the API bills per call."
npx hitloop decisions auth # what was decided about auth
npx hitloop status # every request, with countshitl approve exits 0 when approved, 1 when refused (or changes are asked for), 2 when there's no answer yet, so a
script can stop at a real yes or no.
npx hitloop --help lists every command and option; a mistyped option is refused rather than ignored.
Claude Code hooks (optional)
Off unless you turn them on, per project (hitl hooks on, hitl hooks on --stop, or Settings on the page):
News: whenever you send Claude a message, it's told if you've said something in hitl it hasn't read.
Stop: Claude can't finish while an approval or a blocking question is waiting, or while there's news it hasn't read. (It only holds Claude once, so it can't loop.)
Where things live
<project>/.hitl/
questions/<id>.json question sets the agent writes
reviews/<id>.json reviews, showings and approvals the agent writes
answers/<id>.json, .md what you said about each one hitl writes
notes/notes.json, NOTES.md, images/, photos/ hitl writes
media/ pictures passed as data, snapshots of shown files, marked-up pictures, photos
config.json optional: exclude, hide, showSecrets, maxFileMb, git, watch for this projectEvery request is its own file, and a new review always gets a fresh id, so one agent's request never replaces
another's. Every write is locked and atomic, so the page, the MCP server and the CLI can all write at once.
Formats: npx hitloop schema questions, npx hitloop schema reviews (or schema/ in the package).
npx hitloop import brings in a project's .questionme/ (questions and answers) and .review/ (folderview's comments,
as notes).
A review
{
"title": "Login screen, round 2",
"intro": "I moved the button and fixed the spacing. **The error text** is the part I'm least sure of.",
"mode": "review",
"from": "Claude · branch login-v2",
"items": [
{ "file": "src/login.tsx", "note": "The form", "ask": "Is the error text clear?" },
{ "file": "src/api.ts", "against": "main", "title": "What changed in the API" },
{ "image": "screens/login.png", "before": "screens/login-old.png" },
{ "code": "{ \"retries\": 3 }", "before": "{}", "lang": "json", "name": "config.json" },
{ "diff": "--- a/x\n+++ b/x\n@@ …" },
{ "md": "## Left out\n- Password reset" },
{ "mermaid": "flowchart LR\n A --> B" },
{ "html": "<button>Sign in</button>", "height": 120 },
{ "link": "https://example.com/preview" }
]
}A file item keeps a copy of the file as it was shown; if it changes later, the page says so and shows what changed.
One server for every project
npx hitloop starts one shared server (the hub) on port 4199 for every project you've used it in, so your phone needs
one bookmark. The MCP server starts it in the background when an agent needs a link.
npx hitloop # the hub (adds this folder); prints the links
npx hitloop url [review|set] # the links (starts the hub if needed)
npx hitloop stop # stop the hub
npx hitloop projects # what it serves; --forget <folder> to drop one
npx hitloop --solo [folder] # just this folder, on its own serverOption | Environment | Default | |
|
|
| The port to try first; the next free one is used. |
|
|
| Where to listen. The default lets your phone reach it. |
|
|
| Serve under a URL path (behind a proxy). |
| Only this computer ( | ||
|
| made once | Open a link with |
| Anyone on your network can open it. | ||
| Accept this host name too (a tunnel's). | ||
| Never show, serve, search or zip these. Also | ||
| File browsing, as in folderview. | ||
| Open it in your browser. | ||
| Look, don't answer. |
Settings can also go in ~/.config/hitl/config.json (port, host, base, token, allowHosts, notify,
exclude, hide, showSecrets, maxFileMb, git, watch). HITL_HOME moves that folder.
The links include every address your phone might use: your Wi-Fi or LAN address, and a Tailscale address if you have one. Add the page to your phone's home screen and it opens like an app.
Notifications on your phone
npx hitloop notify ntfy # makes a private ntfy topic, saves it, and sends a test
npx hitloop notify webhook <url> # or POST JSON anywhere: Pushover, Discord, Home Assistant, …
npx hitloop notify link http://100.100.4.74:4199 # where the tap should open
npx hitloop notify test | offInstall the ntfy app and subscribe to the topic it prints. Questions and reviews are batched (one notification once the agent has been quiet for 20 seconds); approvals go out within a couple of seconds, at high priority. Notifications say what's waiting, never your answers.
Safety
A token by default: the server listens on your network so your phone can reach it, so every request needs the token (in the link once, then a cookie).
--locallistens on this computer only.Project files are served only from inside the project, never
.gitor secret-looking files (.env,*.key,*.pem,id_rsa), never through a link that points outside, and never excluded ones.What an agent writes is untrusted: markdown is sanitised, HTML runs in a sandbox with no scripts, SVGs and files are served so they can't run script, diagrams are drawn as images.
DNS rebinding is refused (unknown host names), and so are writes from other sites.
It writes only in
.hitl/and its own config folder;initalso writesCLAUDE.md, and the hooks.claude/settings.json.
Development
npm install
npm test # builds, then runs the tests
node scripts/demo.mjs .demo/trailhead # a demo project with everything in it
HITL_HOME=.demo/home node dist/cli.js --solo .demo/trailhead --local
node scripts/shots.mjs http://localhost:4199/ .demo/shots # phone and desktop screenshots of every pageThe server is TypeScript in
src/, no runtime dependencies, Node 20 or newer.The page is plain JavaScript in
client/, bundled by esbuild; Shiki's grammars, Mermaid and the math renderer load only when needed.
Releasing: bump the version in package.json, commit, push to main. The Release workflow publishes a version that
isn't on npm yet (trusted publishing), tags it and makes a GitHub release.
License
MIT
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
This server cannot be deployed
Maintenance
Related MCP Connectors
Give any AI agent a way to ask a person — for approval, a decision, an answer or a review.
Ask people questions, get approvals and keep team decisions, from any AI agent.
Human-in-the-loop for AI coding agents — ask questions, get approvals via Slack.
Human approvals, notifications, inbound webhooks, wake-ups for headless agents. Free trial: /try
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to request human approvals with customizable forms, webhooks, and team features.68 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI coding agents to publish work mid-task and request review from real human reviewers, who return pinned comments anchored to the exact elements that are off along with an approval verdict. The agent then iterates on that human feedback until the work is approved, keeping users out of the revision loop.38 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI coding agents to call real human reviewers for mid-task feedback, publishing work artifacts so reviewers can pin issues and return verdicts that guide iterative revisions until approval.38 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI coding agents to publish their work mid-task and hand it to a real human reviewer, who pins comments to the exact elements that are off and returns an approval verdict. The agent then iterates on that human feedback until the work is signed off.38 npmMIT



