mcpField
M
mcp-approval-queue

mcp-approval-queue

Local
github.com/opafexAI & Agents0Updated 5d ago

About mcp-approval-queue

mcp-approval-queue is an MCP server that adds human approval checks for AI agents, scoring requests by risk and routing uncovered actions to a person. Only humans can approve or reject requests; the agent has no decision tool.

Key features

  1. 01Scores risk from actions and estimated cost
  2. 02Routes high-risk requests to human review
  3. 03Supports auto-approval rules for low and medium risk
  4. 04Accepts decisions through client forms or CLI
  5. 05Exposes request, rule, and history lookups

Use cases

  1. 01Require review before deleting data
  2. 02Approve actions before sending email
  3. 03Gate deployments or spending behind human review

MCP support

The MCP server provides tools to request approval and inspect request status and pending items, plus resources for statistics, rules, and history. Clients supporting elicitation can present approval forms.

Configuration

Local server config is the same for every client. Copy it into your client’s MCP config file.

mcp.json · Universal config
{
"mcpServers": {
"opafex-mcp-approval-queue": {
"command": "npx",
"args": [
"-y",
"@opafex/mcp-approval-queue"
],
"env": {
"APPROVAL_QUEUE_STATE_DIR": "<APPROVAL_QUEUE_STATE_DIR>",
"APPROVAL_QUEUE_TTL_HOURS": "<APPROVAL_QUEUE_TTL_HOURS>"
}
}
}
}
Run commandnpx -y @opafex/mcp-approval-queue
Environment variables to set
APPROVAL_QUEUE_STATE_DIRDirectory holding state.json; the server and the CLI must share it (default ~/.opafex/approval-queue)
APPROVAL_QUEUE_TTL_HOURSHours before an undecided request expires (default 24)

Local servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.

Packages
npm@opafex/mcp-approval-queue0.2.0

Tools

5

Saved tool list · updated 4d ago

ParameterTypeRequiredDescription
waitbooleanNoAsk the human now and wait for the answer, when the client supports it (default true). False returns at once with a pending request.
actionstringYesThe action you want to take, as a short verb_noun name (e.g. "delete_user", "send_email", "deploy_production")
paramsobjectNoThe parameters you would act with, shown to the human (e.g. { "userId": "123", "estimatedCost": 50 }). estimatedCost raises the risk score.
contextstringNoWhy the action is needed, in one or two sentences, for the human deciding
categoryenumNoOptional category. It can only RAISE the risk inferred from the action name, never lower it.read | compute | file_write | file_system | data_mutation | external_api | payment | delete

Details

From the project README

@opafex/mcp-approval-queue

A human-in-the-loop approval gate for AI agents, as an MCP server.

The agent calls request_approval before doing something risky. The action is risk-scored, and unless a rule you set covers it, you decide — in a form your MCP client shows you (MCP elicitation), or from a terminal. The agent gets a proceed: true|false it can act on.

The agent can ask; only a human can approve. There is no approve, reject or add-rule tool for the model to call. An approval gate the gated agent can open is not a gate.

Requires Node.js 20+.

Quick start

Add to your client's MCP config (for Claude Code, .mcp.json in your project root):

{
  "mcpServers": {
    "approval-queue": {
      "command": "npx",
      "args": ["-y", "@opafex/mcp-approval-queue"]
    }
  }
}

Then tell the agent when to use it, for example in your project instructions:

Before deleting data, sending email, spending money or deploying, call request_approval and only continue if proceed is true.

How a request is decided

  1. Risk is scored from the action name — bulk_delete_users is a delete wherever the word sits — plus params.estimatedCost. The agent may pass a category, but it can only raise the score, never lower it.

  2. A rule may auto-approve it — only low or medium risk, only rules a human created. High and critical risk always go to a person.

  3. Otherwise a person decides:

    • In the client — if the client supports elicitation, the server asks you directly with the action, risk, parameters and the agent's reason, and waits for your answer. The answer goes to the server, not to the model. Approve, reject, or tick Always approve (low/medium risk only) to create a rule. Dismissing the form leaves the request pending.

    • In a terminal — otherwise the request waits, and the agent is told to poll check_status:

      npx @opafex/mcp-approval-queue pending
      npx @opafex/mcp-approval-queue approve appr_3f9c1a2b4d5e --reason "checked the recipient list"
      npx @opafex/mcp-approval-queue reject  appr_3f9c1a2b4d5e
      
  4. Unanswered requests expire after 24 hours (APPROVAL_QUEUE_TTL_HOURS) and can no longer be approved.

After five human approvals of the same action with no rejection, the next form suggests always approve. Auto-approvals do not count towards that — the system agreeing with itself is not evidence.

Tools (what the agent sees)

ToolDescription
request_approvalSubmit an action (action, optional params, context, category, wait). Returns status, proceed, risk, and what to do next.
check_statusRe-read a request by id.
list_pendingRequests still waiting for a human, newest first.
list_rulesThe auto-approval rules a human has set (read-only).

status is one of pending, approved, rejected, auto_approved, expired. Proceed only when proceed is true.

Resources

URIContents
approval://statsCounts by status and the average time a human took to decide
approval://rulesCurrent auto-approval rules
approval://historyLast 50 decisions

CLI

mcp-approval-queue                       start the MCP server (stdio)
mcp-approval-queue pending               list requests waiting for a decision
mcp-approval-queue show <id>             one request in full
mcp-approval-queue approve <id> [--always] [--reason <text>]
mcp-approval-queue reject <id> [--reason <text>]
mcp-approval-queue rules                 list rules
mcp-approval-queue rules add <pattern> --max-risk <low|medium> [--description <text>]
mcp-approval-queue rules remove <id>
mcp-approval-queue history [limit]

Patterns are globs: * matches anything, ? one character, case-insensitive. A rule can never cover high or critical risk.

Configuration

VariableDefaultDescription
APPROVAL_QUEUE_STATE_DIR~/.opafex/approval-queueWhere state.json (requests, rules, history) lives. The server and the CLI must point at the same directory.
APPROVAL_QUEUE_TTL_HOURS24Hours before an undecided request expires

State is one JSON file, written atomically under a lock file, so the server and the CLI can run at the same time.

What it does not protect against

Be clear about this before relying on it:

  • An agent with a shell or file access can reach the terminal channel. The CLI and state.json are a human channel only if the agent cannot run the command or write the file. Coding agents such as Claude Code usually can. In that setup rely on the elicitation channel, and deny the agent the CLI and the state directory in your client's permission settings — for Claude Code, deny Bash(npx @opafex/mcp-approval-queue approve:*), Bash(npx @opafex/mcp-approval-queue rules:*), and edits under ~/.opafex/.
  • It only gates what the agent asks about. The agent has to call request_approval, and has to honour proceed: false. This is a protocol for a cooperative agent and a record of what was allowed, not a sandbox. Pair it with your client's own tool permissions for anything that must be enforced.
  • Elicitation is shown by the client. The guarantee that the answer came from a person is only as good as the client's rendering of the form.

Library use

import { ApprovalQueueService, StateStore, assessRisk } from '@opafex/mcp-approval-queue';

const queue = new ApprovalQueueService(new StateStore('/var/lib/my-app/approvals'));
const { request } = await queue.requestApproval({ action: 'refund_order', params: { estimatedCost: 40 } });

Development

npm install
npm run build
npm test

License

MIT — see LICENSE.

Comments

Markdown supported

New to MCP?

From what the protocol is to installing your first server, these answers cover most first questions.

An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.