Skip to main content
Glama
trivediroshan1-ui

MCP Human Approval Gateway

MCP Human Approval Gateway

A public-safe research prototype for controlling AI-agent tool actions with deterministic policy, risk-based human approval, time-bound authorization and a tamper-evident audit chain.

It speaks the Model Context Protocol (revision 2026-07-28, with 2025-11-25 for older clients) over Streamable HTTP and stdio, so a real MCP client can call its tools and hit the same policy and approval gate. See MCP server. The MCP server runs in the Node server only. The browser demo does not speak MCP.

The project demonstrates a strict separation of responsibility:

  • AI explains and recommends. Its analysis is advisory and cannot change a policy outcome.

  • Deterministic policy decides. Registered tools, actions, scopes, environments and data classifications produce a reproducible decision.

  • Humans authorize high-impact actions. Role-qualified reviewers approve or deny requests with a recorded rationale.

  • The execution guard enforces the result. Approvals expire, can be consumed once and cannot be replayed.

All included names, resources, identities and actions are synthetic. The prototype contains no employer architecture, production credentials, customer data or confidential control implementations.

What the lab demonstrates

The catalog has nine scenarios. Each one states its expected outcome, the app checks the result against it after every run, and tests/scenarios.test.js asserts the same table on both the server and the browser copy.

  1. Public research is auto-approved (low risk, 60 minute authorization).

  2. A private repository read goes to a resource owner.

  3. Restricted credential metadata needs a security lead, and secret values never reach the AI analyst.

  4. A production privilege change needs a security lead.

  5. Prompt-injected context is treated as untrusted data and denied.

  6. Runtime scope expansion is denied and must be submitted as a new request.

  7. A production deployment needs a security lead.

  8. An unregistered tool fails closed.

  9. An agent that hands off without options, a recommendation or a confidence is stopped by the decision-package gate before a person sees it.

Three more behaviours can be tried from the app: replaying a consumed authorization is blocked, an authorization expires (the browser demo has a lab clock you can move forward), and editing a stored audit event makes verification fail at that event.

The Architecture section animates the path each scenario takes and where it stops.

Related MCP server: MCP Permission Guard

Run locally

Prerequisite: Node.js 24 or newer. The prototype uses the built-in node:sqlite API. The tests also pass on Node 22 (SQLite prints an experimental warning there).

npm install
npm run build
npm start

Open http://localhost:4174.

For frontend development:

npm run dev:server
npm run dev:client

The Vite client runs on http://localhost:5174 and proxies API calls to port 4174.

Verify

npm run check

The suite (210 tests under Node 22) covers policy outcomes, reviewer authorization, request-hash binding, atomic decision commits, expiry, single-use execution, audit tamper detection, HTTP hardening, server and browser-copy parity, the animated paths, and the MCP server (raw JSON-RPC over HTTP and a stdio child process).

To run every use case in one go against real copies of the gateway, with a results file at the end (about ten seconds, Node 22 or newer):

node scripts/run-use-cases.mjs              # add --real-wait for the real 11-minute expiry
node scripts/run-gap-cases.mjs                # G1 to G32 (add --full for the one-minute wait)
node scripts/run-change-cases.mjs             # policy and tool definition changes
node scripts/run-second-client.mjs            # a client with the older handshake
node scripts/run-binding-profiles.mjs         # prototype of fields that may vary, and attempts to abuse it
node scripts/run-conformance.mjs --label mine # 15 approval-binding checks
node scripts/run-coverage-cases.mjs           # round three: permit and receipt, identity plane, 20 test-only domain tools (46 checks)

It covers changed requests after approval, text and encoding variants, time, people and abuse, lost replies, restarts, every tool tier, protocol hygiene, database tampering and approval fatigue. Each case records what was expected and what happened. Results go to results/ (not committed). Everything is synthetic.

MCP server

npm start            # web UI, REST API and POST /mcp on 127.0.0.1:4174
npm run mcp:stdio    # the same server over stdin and stdout

An MCP client sees the seven registered tools and check_approval_status. A low-risk call runs at once. A risky one returns pending_approval with an id, a person approves it in the web UI, and the agent calls again with the same arguments plus approvalId so the guard can consume the single-use approval. Denied calls return isError: true, and unknown tools return a JSON-RPC -32602 error. Every call, including refusals, lands in the audit chain with source mcp.

It is unauthenticated demo mode: the caller is a configured agent id plus a self-declared clientInfo. A real deployment needs the MCP authorization flow (OAuth) in front. The connection snippets, a recorded session and the list of what is not implemented are in docs/MCP.md.

Optional AI analyst

The lab works fully offline with a deterministic analyst. An OpenAI-compatible chat-completions endpoint can be configured through environment variables:

cp .env.example .env

The offline analyst is a rule-based simulation and the app labels it that way. The external analyst receives a fixed list of metadata fields, never context, arguments or the resource path, and credential-shaped text is redacted from the justification. Provider failure falls back to the offline analyst. In every mode the output is advisory: it cannot change a decision or pass the gate.

Three other settings: AUDIT_HMAC_KEY signs audit events, REVIEWER_ALLOWLIST="name:role,..." limits which typed reviewer names count (it is not authentication), and ALLOW_RESET=false removes the unauthenticated reset route.

Limits and honest caveats

Data is synthetic, reviewers are simulated (no authentication), the analyst is rule-based unless you configure a model, injection detection is a phrase heuristic, reviewer names are typed in and not proven, the hash chain is tamper-evident but not tamper-proof without a key or an outside anchor, and none of this is a production control. Details are in Workflows and SECURITY.md. What changed in the latest review is in the changelog.

Design documents

Standards and research basis

The control design is informed by:

These references inform the design; they do not constitute certification or formal compliance.

GitHub Pages browser demonstration

The GitHub Pages edition is a browser-only synthetic simulation. It allows visitors to explore deterministic policy decisions, human approval, time-limited authorization, guarded execution, replay blocking and audit-chain verification without connecting to real systems.

Each visitor has independent demonstration state stored only in their browser. Use Reset Lab to remove that state.

The browser demonstration does not provide enterprise identity proofing, shared approval queues, server-side policy enforcement, durable audit storage, multi-user coordination or cross-tab transaction locking. The Node.js and SQLite implementation remains the reference full-stack research prototype.

No production systems, company information, customer data, credentials or API keys are used by the demonstration.

Important scope boundary

This is an educational security prototype, not a production authorization service. It simulates tool execution and intentionally omits enterprise identity proofing, durable key management, multi-node transaction coordination and append-only external audit storage. See SECURITY.md before adapting any part of it.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Local zero-trust permission gateway for AI agents. Enforces policy-based tool authorization, human approvals, scoped permissions, and cryptographically verifiable audit logs.
    4
    66 PyPI
    5
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    A pre-action authorization server for AI agents that classifies tool calls into 14 intent categories, scores risk 0-100, and produces deterministic allow/deny/ask decisions with full audit trail.
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables controlled AI-agent access to enterprise-shaped tools with a deny-by-default gated write path, human approval, dry-run execution, and append-only audit logging.
    1
    -