Skip to main content

Review Commands

mcpproxy review is the one CLI entry point for the review decisions that the Web UI Review queue and the macOS Review Queue also offer. It reads the same review payload as GET /api/v1/review and GET /api/v1/servers/{id}/review, and every decision goes through the scan gate: it never calls the legacy unquarantine endpoint.

For the concepts behind quarantine and the four review verbs see Security Quarantine. For scanner setup and scan reports see Security Scanner Commands.

Overview​

mcpproxy review
├── list Servers that need review
├── show <server> [--full] Captured tool definitions and scan verdicts
├── fetch <server> [--wait 30s] Capture tool definitions (does not approve)
├── approve <server> [flags] Approve a server, or approve tools on a trusted server
└── reject <server> [flags] Keep a server quarantined, or block tools

All subcommands accept the global -o table|json|yaml flag. With -o json the output is the data object of the REST response.

review list​

mcpproxy review list
SERVER KIND QUARANTINED ENABLED PENDING CHANGED TIERS SCAN
filesystem server_review true true 0 0 map[destructive:1] map[verdict:clean]

ENABLED is the server's configured state. A disabled quarantined server stays in the queue (its review is still owed) but no live agent is waiting on it, so ENABLED=false rows are deferred reviews, while ENABLED=true rows are active blockers. The Home attention list covers enabled servers only; the queue counts every row.

review show​

mcpproxy review show filesystem --full
Server: filesystem
TOOL TIER APPROVAL SCAN DESCRIPTION
delete_0 destructive pending clean from the server, not verified:
Delete a file
This cannot be undone
Input schema:
{"type":"object"}

When the review payload carries scan coverage, a Scan: line follows Server:. It says whether the baseline scan describes the definitions shown, in the same words as the Web UI and the macOS app:

Server: notes
Scan: out of date (1 tool changed or added after the last scan: notes); run: mcpproxy security rescan notes

A scan that covers every captured tool reads Scan: clean · risk 0/100 · covers all 5 tools. When definitions have not been captured, the line says so and tells you to run mcpproxy review fetch <server> (the same capture as Fetch tool definitions on the Web or macOS review screen).

Tools held as changed​

A trusted server whose tool definition changed after approval holds that tool as changed. review show lists, under the table, what differs from the approved definition (description, input schema, output schema and the safety hints), then how to approve the update and the opt-out for servers you trust:

Changed since approval: create_issue
Description:
@@ -1 +1 @@
-Create an issue
+Create an issue and email the reporter
Safety hints:
@@ -1 +1 @@
-{"readOnlyHint":true}
+{"readOnlyHint":false}

1 tool(s) are held until you approve the update: mcpproxy review approve github --tools create_issue
To let a server you trust update its tools without review, set auto_approve_tool_changes: true on it (https://docs.mcpproxy.app/features/security-quarantine).

Scan mode holds every changed contract; the diff and a one-step approval are what keeps that cheap. The Web review screen shows the same changes and an Approve update (N changed tools) button that approves exactly the changed tools on screen.

Descriptions and schemas come from the upstream server and are shown as plain text; they are not verified. Without --full only the first line of each description is shown and the schemas are left out.

review fetch​

mcpproxy review fetch <server> [--wait 30s]

Asks the daemon to connect to the server and capture its tool definitions, then re-reads the review to confirm they were stored. It is the headless counterpart of Fetch tool definitions, so capture, inspection and approval all work from the CLI:

mcpproxy review fetch notes
mcpproxy review show notes
mcpproxy review approve notes
Captured 12 tool definitions for notes (server remains quarantined; nothing was approved).
Review them with: mcpproxy review show notes

It never approves, unquarantines or enables a server. --wait bounds the whole command (default 30s, maximum 2m). -o json prints {"server","captured","tool_count","quarantined"}; on failure it adds an error field and the exit code is still nonzero.

SituationResult
Unknown serverserver 'x' not found, exit 1
Disabled serverserver 'x' is disabled ... enable it first: mcpproxy upstream enable x, exit 1; the command does not enable it
Unreachable or invalid upstreamThe daemon's connection error plus check connectivity with: mcpproxy upstream logs x, exit 1
Connected but zero toolsno tool definitions captured for 'x', exit 1
Timeouttimed out after 30s ...; retry with a larger --wait, exit 1

Retrying is safe: the command can be run again at any time.

review approve​

mcpproxy review approve <server> [--all | --tools a,b] [--except a,b] [--force] [--yes] [--from-review <file>]

On a quarantined server the command allows the same default selection as the Web and macOS review screens: only read-only tools with a clean scan (default_allowed in the review payload). Every other tool is blocked, meaning approved and disabled, until you enable it on the Tools tab. A core that does not send default_allowed blocks every tool.

FlagMeaning
--allApprove every pending or changed tool (the Web and macOS "Approve all"); tools blocked earlier on a re-quarantined server stay blocked. On a trusted server this is the default and changes nothing
--tools a,bQuarantined server: allow exactly these tools and block the rest. Trusted server: approve only these pending or changed tools
--except a,bQuarantined server only: block these tools as well, whichever base was chosen
--forceApprove although the scan verdict is dangerous (use only after reading the findings)
--yesSkip the confirmation prompt. Without --from-review this approves what the server serves at that moment
--from-review <file>Bind the approval to a review saved with mcpproxy review show <server> -o json; the selection and the binding come from that file

The command picks the right endpoint for you:

Server stateEndpointNotes
QuarantinedPOST /api/v1/servers/{id}/security/approveblock is every tool outside the selection (default, --all or --tools, minus --except); --force is sent as force
Trusted (not quarantined)POST /api/v1/servers/{id}/tools/approve--tools selects tools; without it every pending or changed tool is approved

Using the wrong flag for the state fails with exit code 1 instead of doing something else:

  • --all together with --tools: --all cannot be combined with --tools
  • A tool name that is not in the review (--tools or --except): unknown tool 'x' for server 's'; nothing is written
  • --tools or --except while no tool definitions are captured: no tool definitions captured for server 's'; fetch them first (mcpproxy review fetch s) ...; nothing is written
  • --except on a trusted server: --except applies only while approving a quarantined server

The confirmation prompt reads the review first and names the exact count, for example Approve server 'memory' with 3 of 9 tools? Blocked: a, b, c., Approve server 'memory' with all 9 tools? or Approve server 'memory' without seeing tools? Tools the server lists later will wait for review. when nothing is captured (the approval records the server's tool baseline, so tools it lists later are held for review). In table output one line precedes the result: Allowing 3 of 9 tools; blocking 6: a, b, ...; with --all it reads Allowing all pending or changed tools; previously blocked tools stay blocked. JSON and YAML output stay the REST data object.

After the write the command reports what actually applied. In table output the result line reads, for example, Approved server memory: 6 tools approved, 3 blocked, 0 still pending, 0 changed. If any tool on the server is still pending or changed after the approval, a warning naming those tools is printed to stderr in every output format, for example Warning: 2 tool(s) on server 'memory' still need review (2 pending, 0 changed): a, b. Inspect them with: mcpproxy review show memory. JSON and YAML output carry the same counts (approved_count, blocked_count, still_pending, still_changed, held_tools).

The approval is bound to the review you saw (issue #1566). The command sends the review fingerprint (current_hash) of every reviewed tool as expected_hashes ({} for an empty review). If a tool changed (definition or safety hints) or appeared after that review, the core approves nothing and the command exits 1:

Error: tool review for server 'notes' is out of date (definition changed since review: read_note); nothing was approved — fetch the review again
Run 'mcpproxy review show notes' and approve again.

With -o json the 409 envelope (error_code: "review_out_of_date", stale_tools) is printed to stdout first. Which review is bound:

  • --from-review <file>: the saved review. Save it with mcpproxy review show <server> -o json > review.json, read it, then run mcpproxy review approve <server> --from-review review.json --yes. The file must be the review of <server> (its server.name); a file of another server, a malformed file or an error response exits 1 before anything is sent. This is the path for scripts and headless use.
  • Interactive (no --yes): before asking, the command lists every tool the approval will make callable, with tier, status, the first line of its description and [changed since approval] for a changed tool. The binding is to that listing.
  • --yes without a file: binds to the review fetched at that moment, so it approves what the server serves now and is still refused if a definition changes during the call.

A core that predates review fingerprints reports no current_hash; the command then sends an unbound request, as before.

mcpproxy review approve <server> --yes used to allow every tool. It now allows the default selection, so it matches the review screens; add --all to approve every tool.

mcpproxy review approve filesystem --except delete_0 --force --yes
Allowing 0 of 1 tool; blocking 1: delete_0
Approved server filesystem
mcpproxy review approve trusted --tools write_0 --yes
Approved 1 tool for server trusted

review reject​

mcpproxy review reject <server> [--tools a,b] [--yes]

Without --tools the server stays quarantined (POST /api/v1/servers/{id}/security/reject). With --tools the listed pending or changed tools are blocked (POST /api/v1/servers/{id}/tools/block).

mcpproxy review reject filesystem --yes
Rejected server filesystem
mcpproxy review reject trusted --tools write_0 --yes
Blocked 1 tool for server trusted

Older commands​

These keep working and name the matching mcpproxy review command in their help:

CommandSame as
mcpproxy upstream approve <server> [tools...]mcpproxy review approve <server> --tools ... for a trusted server
mcpproxy tools approve <server:tool>...mcpproxy review approve <server> --tools ...
mcpproxy tools reject <server:tool>...mcpproxy review reject <server> --tools ...
mcpproxy security approve <server>mcpproxy review approve <server>
mcpproxy security reject <server>mcpproxy review reject <server>