Approvals hub
Sends optional Discord notifications when agent-submitted work is waiting for reviewer attention.
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.
Approvals hub
A review queue for AI agents. Agents submit work over MCP or REST: artwork, copy, emails, either-or decisions. You approve it, edit it, or send it back with a note, from your desk or your phone. The agent picks up your decision on its next run and carries on.

Why I built it
I'm the only engineer at FinalPeace. A team of AI agents does the work of a ten-person team across development and marketing: ads, emails, landing pages and product fixes. The bottleneck stopped being the work and became me. Agents would stop mid-task to ask a question in a chat I wasn't looking at, or ship something I'd have changed.
So every agent sends finished work here instead, keeps going on something else, and checks back for my answer. I approve what they ship in about half an hour a day. I've run it since September 2026, and the same hub serves agents across my other projects, each with its own key.
Related MCP server: @quirna/mcp
How it works
sequenceDiagram
participant A as Agent (Claude, script, bot)
participant H as Approvals hub
participant R as You
A->>H: submit_for_review (MCP) or POST /api/items
H-->>R: Waiting on you (web, phone, optional Discord ping)
R->>H: Approve / edit and approve / request changes / reject
H-->>A: Optional signed callback
A->>H: check_decisions (MCP) or GET /api/decisions?ack=1
Note over A: approved: ship it, using your edit if there is one<br/>changes_requested: revise and resubmit with revises=id<br/>rejected: drop itAgents never block on you. They submit and move on. Decisions are pulled with
check_decisions, so an agent that only wakes up on a schedule works the same as one that's always running. Each decision is handed out once, then marked as picked up.Your edits are the decision. For copy and emails you can rewrite the text and approve your version. The agent gets it back as
revised_contentand is told to use it word for word.Revisions keep their history. A resubmission with
revises=<id>replaces the earlier version in your queue and shows your previous note next to the new draft.
Quick start
With Docker:
git clone https://github.com/adamblazer18/approvals-hub && cd approvals-hub
ADMIN_PASSWORD=pick-something-long docker compose up -d
# open http://localhost:3060With Node 22 or later (no native build step; storage is the built-in node:sqlite):
cp .env.example .env # set ADMIN_PASSWORD
npm install
npm run seed:demo # optional: sample items to click through
npm start # http://localhost:3060Connecting an agent
Create one key per agent under Settings → Agent keys (or npm run create-key -- "Website agent" "Website"). A key can be locked to a single project. Keys are stored as SHA-256 hashes and shown once.
Claude Code
claude mcp add --transport http approvals https://your-hub.example.com/mcp/apk_...Claude apps (custom connector): paste https://your-hub.example.com/mcp/apk_... under Settings → Connectors. Any other MCP client can use https://your-hub.example.com/mcp with Authorization: Bearer apk_....
The server sends agents instructions on how to handle each decision. One line in an agent's prompt is usually enough:
When something needs sign-off, submit it with
submit_for_reviewand keep working on other things. At the start of every run, callcheck_decisionsand act on each one.
MCP tool | What it does |
| Adds an item to the queue. Images and files as URLs or base64. |
| Returns new decisions and marks them picked up. Filter by |
| What's already waiting, to avoid duplicates. |
| One item with its earlier versions and notes. |
| Removes an item that's no longer needed. |
| Projects with pending counts. |
REST, for scripts and bots
curl -X POST https://your-hub.example.com/api/items \
-H "Authorization: Bearer $KEY" -H 'content-type: application/json' -d '{
"project": "Website", "kind": "copy", "title": "Homepage headline",
"summary": "Current version is underperforming on signups.",
"body": "# Your week, planned before Monday",
"external_ref": "task-123", "callback_url": "https://your-agent.example.com/hooks/approvals"
}'
curl -H "Authorization: Bearer $KEY" 'https://your-hub.example.com/api/decisions?ack=1'Multipart uploads work too (-F files=@option-a.png). Item fields: project and title are required; kind is design, copy, email, decision or other; plus summary, body, body_format, email_to, email_subject, options, attachments, links, priority, due_at, external_ref, revises, agent and callback_url.
A decision comes back in this shape, over MCP, REST or the callback:
{ "id": "k0xwi87O", "project": "website", "title": "Homepage headline", "status": "approved",
"note": null, "revised_content": "# Your week, planned before Monday", "chosen_option": null,
"external_ref": "task-123", "version": 1, "decided_at": "2026-11-03T18:02:11.000Z", "url": "..." }Reviewing
The queue is sorted by priority, then due date, then age, and filters by project. Each item shows what the agent needs from you, the content itself (image gallery, rendered email, formatted copy, video, PDF), its links and your notes on earlier versions. Approving a multiple-choice item requires picking an option; rejecting or sending back requires a note, because the agent needs something to act on.
It's built to be fast from the keyboard: j/k to move, a approve, c request changes, r reject, 1–9 pick an option, e edit copy, u undo, ? for the rest. It works on a phone.
Security model
This is a single-reviewer tool, meant to sit behind HTTPS on your own server.
One reviewer password, compared in constant time, with a growing delay after failed attempts from the same address. Sessions are HMAC-signed cookies (
httpOnly,sameSite=lax).Agent keys are random 192-bit tokens stored only as hashes. A key can be scoped to one project, and it can submit, read and withdraw but never decide. Only the reviewer can approve.
Uploaded files are served only to the reviewer or a valid key. Images, audio, video and PDFs display inline; anything else, such as HTML, downloads with a sandboxing Content-Security-Policy, so an uploaded file can never act as the reviewer. SVGs get a restrictive policy of their own. Markdown and HTML bodies are sanitized with DOMPurify before rendering.
Decision callbacks are signed:
x-approvals-signature: sha256=<HMAC of the exact body>whenWEBHOOK_SECRETis set. Callback URLs must be http(s).The key-in-URL form (
/mcp/apk_...) exists because some MCP connectors can't set headers. Treat that URL like the key itself. Prefer theAuthorizationheader where your client supports it.
Design notes
SQLite through
node:sqlite. One file, no native build, backups withsqlite3 .backup. It runs as a single process on purpose.Stateless MCP. Each request builds a fresh MCP server over Streamable HTTP with JSON responses, so there's no session state to lose on restart and it sits happily behind any reverse proxy.
Pull, then optionally push. Agents poll
check_decisionswith acknowledgement, which works for scheduled agents that can't receive webhooks. Callbacks are there for the ones that can.Every change is an event. Submissions, decisions, reopenings and pickups are written to an events table, so you can see what an agent did with your answer.
Deploying
docker compose up -d behind any HTTPS proxy is the simplest route. For a plain Linux server with nginx and PM2, deploy/install.sh installs the app, writes .env with generated secrets and adds the nginx site (DOMAIN=approvals.example.com bash deploy/install.sh). deploy/backup.sh keeps 14 days of nightly database and upload backups.
Development
npm testThe tests start the hub on a random port with a throwaway database and cover the full loop over REST and over a real MCP client: submit, decide, pick up once, revisions, option choices, project-scoped keys, revoked keys, upload access, upload sandboxing and callback signatures. CI runs them on Node 22 and 24, and also builds the Docker image and checks that it starts.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Human-in-the-loop review and approval for AI agents. Audit trail, approval policies, native MCP.
Human-in-the-loop for AI agents over MCP: durable approvals with a hosted review page & audit trail
Give any AI agent a way to ask a person — for approval, a decision, an answer or a review.
Set up human approval for your AI agents' tool calls.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceEnables AI agents to submit tasks for human or AI review and receive decisions via MCP tools, adding human review checkpoints to workflows.MIT
@quirna/mcpofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to request human approval before consequential actions, with policy-based routing, phone-based approver decisions, and signed audit evidence.40 npmMIT- AlicenseNot gradedqualityAmaintenanceEnables AI agents to publish work mid-task and call real human reviewers for pinned feedback, second opinions, and approval verdicts, then iterate until the work is approved.38 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to publish work mid-task and request reviews from real human reviewers, who attach pinned comments and return a verdict so the agent can iterate until approved.38 npmMIT