Atlas / MCP servers / sekera-radim / impri

impriBLOCK

mcp/sekera-radim/impri

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).

Verdict
BLOCK
Grade
F
Trust score
42 /100
Exposed tools
7 4r · 3w · 0d
Transport
stdio · streamable-http
License
MIT
Stars
5
01

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 ──────────┘

Watch as MP4

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
Read from source at commit 482b9a65ae5aOBSERVED · 2026-10-11
02

Connect

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-code (npm)
claude mcp add mcp --env IMPRI_API_KEY=${IMPRI_API_KEY} -- npx -y @impri/[email protected]
03

Exposed tools (7)

4 read · 3 write · 0 destructive.

ToolRiskDescription
impri_await_decisionreadPoll 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_presetwriteCreate 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_statusreadCheck 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_watchersreadList 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_actionwriteSubmit an action to the Impri human-approval inbox. The action appears in the operator
impri_report_resultreadReport whether you successfully executed an approved action. Closes the audit loop — the operator sees
send_emailwriteSend an email
04

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.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeWARN
L2Instruction surface (what it tells the agent)FAIL
L3Class-specific surfacePASS
L4Behavioural (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)

HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
docs/the-risks-of-autonomous-ai-agents-taking-actions.md: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
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
HIGHPrompt injection · prompt.override · CWE-94, CWE-1427
www/docs/prevent-prompt-injection-from-executing-actions.html:149
<p>A support agent reads a customer&#39;s message, summarizes it, and drafts a reply. Nothing wrong there. The failure mode people call &quot;prompt injection&quot; shows up one step later: the custom
Why it matters. asks the agent to drop prior instructions or safety
Fix. remove the instruction
MEDIUMInventory / provenance · inv.binary · CWE-1104
status/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite
metadata.sqlite
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInventory / provenance · inv.binary · CWE-1104
status/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm
metadata.sqlite-shm
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInventory / provenance · inv.binary · CWE-1104
status/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal
metadata.sqlite-wal
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInventory / provenance · inv.binary · CWE-1104
status/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite
7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInventory / provenance · inv.binary · CWE-1104
status/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite-shm
7fc88c6b70e65bdf613cab7a6bd166bc11ececaa2b726d56a93921761e7e37b0.sqlite-shm
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
integrations/claude-agent-sdk/src/types.ts:62
callback_url?: string;
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
integrations/claude-agent-sdk/src/types.ts:79
callback_url?: string;
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
integrations/crewai/impri_crewai/_client.py:162
callback_url: Optional[str] = None,
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
integrations/crewai/impri_crewai/_client.py:182
if callback_url is not None:
MEDIUMNetwork egress · net.beacon_words · CWE-200, CWE-319
integrations/crewai/impri_crewai/_client.py:183
body["callback_url"] = callback_url
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
scripts/serve-ui.mjs:17
const API = (process.env.IMPRI_API ?? 'http://127.0.0.1:8484').replace(/\/$/, '');
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
mcp/test/webhook.test.ts:7
const SECRET = "test_webhook_secret_abc123";
MEDIUMHard-coded secrets · secret.slack · CWE-798, CWE-321
server/test/slack-approval.test.ts:43
const BOT_TOKEN      = 'xoxb-1234567890-abcdef-testtoken';
MEDIUMHard-coded secrets · secret.slack · CWE-798, CWE-321
server/test/slack-approval.test.ts:263
bot_token: 'xoxa-invalid-token-format',
MEDIUMHard-coded secrets · secret.slack · CWE-798, CWE-321
server/test/slack-shared-oauth.test.ts:30
const BOT_TOKEN           = 'xoxb-shared-app-testtoken-1234567890';
LOWInventory / provenance · inv.hidden_file · CWE-1104
.gitlab-ci.yml
.gitlab-ci.yml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
www/use-cases/.manifest.json
.manifest.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
server/test/notifications.test.ts:227
config: { bot_token: '../../etc/passwd', chat_id: '-100123' },
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
server/test/notifications.test.ts:241
config: { url: VALID_NTFY_URL, topic: '../../../etc' },
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
server/test/watcher-presets.test.ts:273
const r = buildConfig('github-releases', { owner: 'org', repo: 'foo/../../etc' });
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
server/test/watcher-presets.test.ts:324
const r = buildConfig('npm-package', { package: '../../../etc/passwd' });
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
server/test/cloud-scale.test.ts:29
await expect(fetchGuarded('http://169.254.169.254/latest/')).rejects.toThrow(/private/i);
Why it matters. cloud metadata endpoint: the classic SSRF credential grab
LOWNetwork egress · net.metadata_ip · CWE-200, CWE-319
server/test/net-guard.test.ts:7
'127.0.0.1', '0.0.0.0', '169.254.169.254', '100.64.0.1']) {
Why it matters. cloud metadata endpoint: the classic SSRF credential grab

Gates applied: instruction_override, no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 482b9a65ae5afull audit observations/trust-audit/mcp-server/sekera-radim__impri.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11482b9a65ae5aBLOCKF42first audit
06

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.

Advertisement