impriBLOCK
Human-in-the-loop approval inbox for AI agents. An agent proposes an action, a human approves or rejects it, then it runs. Watchers + approval inbox, MCP + REST, self-hostable (MIT).
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://m8ven.ai/mcp/sekera-radim-impri-14kdjw)
Human-in-the-loop approval inbox for AI agents.
Your agent wants to send the email, post the reply, run the migration. You want to see it before it happens, from your phone if you're not at a desk. Impri is the inbox in between.
Agent (Claude Code / any MCP client) → Impri inbox → You approve, edit, or reject ↑ | └──────────────── agent executes, reports result ──────────┘
The problem
Agents that only read and draft are safe by construction. The moment one can send an email, post a reply, or run a write against a database, "ask the user first" becomes a system-prompt instruction — and a instruction is something a capable model can reason its way past, forget under load, or misjudge on an edge case you didn't anticipate.
Impri turns that instruction into a data dependency instead. The agent pushes a proposed action to an inbox and polls for a decision; the execution branch is only reachable once the API actually returns status: "approved". There's nothing to talk the model past — the gate lives outside the model, not inside its prompt.
60-second install
No install at all — connect straight to the hosted endpoint if your client supports a remote MCP server:
claude mcp add --transport http impri https://api.impri.dev/mcp --header "Authorization: Bearer $IMPRI_API_KEY"
codex mcp add impri --url https://api.impri.dev/mcp # then add to ~/.codex/config.toml under [mcp_servers.impri]: # bearer_token_env_var = "IM
482b9a65ae5aOBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp --env IMPRI_API_KEY=${IMPRI_API_KEY} -- npx -y @impri/[email protected]Exposed tools (7)
4 read · 3 write · 0 destructive.
| Tool | Risk | Description |
|---|---|---|
impri_await_decision | read | Poll until the human approves, rejects, or the timeout elapses. Checks GET /actions/:id every 5 seconds and returns as soon as the action leaves the pending state. Decision meanings: |
impri_create_watcher_from_preset | write | Create a watcher from a preset template by supplying the preset id and param values. Presets handle all watcher config construction — URL building, keyword setup, SSRF validation — so you only provide the param values listed by impri_list_watcher_presets. The schedule defaults to the preset |
impri_inbox_status | read | Check how many actions are waiting for human decisions. Returns the pending count and a brief list of pending action titles. Call this before starting a large batch of tasks — if the inbox is backed up, pause and let the operator catch up to avoid actions expiring before they are reviewed. |
impri_list_watchers | read | List all configured watchers, optionally filtered by status. Returns the watcher count and a summary line per watcher (id, name, kind, status). Use this to audit what is being monitored, check for degraded watchers, or find a watcher_id for further operations. |
impri_push_action | write | Submit an action to the Impri human-approval inbox. The action appears in the operator |
impri_report_result | read | Report whether you successfully executed an approved action. Closes the audit loop — the operator sees |
send_email | write | Send an email |
Trust audit
BLOCKgrade F · trust 42/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | FAIL |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- declared (8 observation(s))
- Shell
- none-observed
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
The common first instinct is to add a line to the system prompt: "Always ask for confirmation before doing anything irreversible." This fails for a boring reason — it's advisory, not structural. The m
<p>A support agent reads a customer's message, summarizes it, and drafts a reply. Nothing wrong there. The failure mode people call "prompt injection" shows up one step later: the custom
metadata.sqlite
metadata.sqlite-shm
metadata.sqlite-wal
7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite
7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite-shm
callback_url?: string;
callback_url?: string;
callback_url: Optional[str] = None,
if callback_url is not None:
body["callback_url"] = callback_url
const API = (process.env.IMPRI_API ?? 'http://127.0.0.1:8484').replace(/\/$/, '');
const SECRET = "test_webhook_secret_abc123";
const BOT_TOKEN = 'xoxb-1234567890-abcdef-testtoken';
bot_token: 'xoxa-invalid-token-format',
const BOT_TOKEN = 'xoxb-shared-app-testtoken-1234567890';
.gitlab-ci.yml
.manifest.json
config: { bot_token: '../../etc/passwd', chat_id: '-100123' },config: { url: VALID_NTFY_URL, topic: '../../../etc' },const r = buildConfig('github-releases', { owner: 'org', repo: 'foo/../../etc' });const r = buildConfig('npm-package', { package: '../../../etc/passwd' });await expect(fetchGuarded('http://169.254.169.254/latest/')).rejects.toThrow(/private/i);'127.0.0.1', '0.0.0.0', '169.254.169.254', '100.64.0.1']) {Gates applied: instruction_override, no_behavioural_pass.
482b9a65ae5afull audit observations/trust-audit/mcp-server/sekera-radim__impri.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | 482b9a65ae5a | BLOCK | F | 42 | first audit |
Questions
What is the impri MCP server?
Human-in-the-loop approval inbox for AI agents. An agent proposes an action, a human approves or rejects it, then it runs. Watchers + approval inbox, MCP + REST, self-hostable (MIT).
What tools does impri expose?
7 in total: 4 read-only, 3 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.
Is impri safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (42/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does impri need?
It reads IMPRI_API_KEY, METRICS_TOKEN, REDDIT_ACCESS_TOKEN, SIGNUP_SECRET, SLACK_APP_SIGNING_SECRET, SLACK_CLIENT_SECRET, SMTP_PASS, STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, VAPID_PRIVATE_KEY, VAPID_PUBLIC_KEY and WEBHOOK_SECRET from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does impri run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @impri/ui at 0.1.0.
How current is this page?
The grade is for one exact copy of the source (482b9a65ae5a), read on 2026-10-11. The repository is watched and re-audited when it changes.