# Impri

> Impri MCP server — human-in-the-loop approval inbox for AI agents

- name: io.github.sekera-radim/impri
- version: 0.1.3
- connection class: R1 (autonomous)
- trust: 97/100
- quality: 91/100 (strong)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.sekera-radim%2Fimpri
- tools: https://api.protogrid.dev/v1/servers/io.github.sekera-radim%2Fimpri/tools

**An agent can connect on its own if it already holds `api_key`.** Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "impri": {
      "type": "http",
      "url": "https://api.impri.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${api_key}"
      }
    }
  }
}
```

Placeholders to fill: `${api_key}`.

## Trust

- hygiene: 100
- liveness: 99
- freshness: 100
- provenance: 90
- drivers: +repository +namespace-matches-repo +website +reachable +uptime-98% +updated-11d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 91/100 (strong)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-06-18; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 100 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 8 of 8 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- pass `tools.token_cost`: about 2,534 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: deps.dev does not know @impri/mcp@0.1.3

- tools: 8, about 2,534 tokens to load them all
- tool set hash: dc9ccf7c018d74b212ffc30b63b58d53
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.sekera-radim/impri.svg)](https://protogrid.dev/servers/io.github.sekera-radim/impri)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Dependencies

- npm @impri/mcp@0.1.3: unknown

Dependency graphs from deps.dev; advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database; all CC BY 4.0.

## Remotes

- https://api.impri.dev/mcp (streamable-http, auth api_key ${api_key}, reachable true, uptime30d 0.97727275)

## Packages

- npm @impri/mcp@0.1.3 secrets: IMPRI_API_KEY

## Tools (8)

- `impri_await_decision`: 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:
  "approved"  — proceed with the action; any reviewer edits are included in preview/payload
  "rejected"  — abort; respect the decision and do not proceed
  "expired"   — the approval window closed; create a new action if the task is still relevant

On timeout the action stays pending in the inbox. Call impri_inbox_status to check queue depth and consider pausing further submissions.

Typical usage:
  1. impri_push_action → get action_id
  2. impri_await_decision(action_id) → wait for human decision
  3. If approved: execute the action, then impri_report_result(action_id, "executed")
- `impri_create_watcher`: Create a watcher that monitors external sources (RSS feeds, Reddit, URL diffs) and delivers matching items to the approval inbox or a webhook.

The watcher runs on the schedule you specify, deduplicates items by URL/content-hash, and delivers only new matches. The first run establishes a baseline and does not generate alerts.

Example — watch an RSS feed for AI-related news:
  spec: {
    name: "AI launches radar",
    kind: "rss",
    config: { url: "https://openai.com/news/rss.xml" },
    keywords: ["launch", "gpt-", "voice"],
    keywords_none: ["funding", "benchmark"],
    min_score: 1,
    schedule: { every: "8h", jitter: "4h" }
  }

Returns { watcher_id, name, kind, status, next_run_at }.
- `impri_create_watcher_from_preset`: 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's recommended interval but can be overridden. The name defaults to "{preset title}: {primary param value}" if omitted.

Returns { watcher_id, name, kind, status, next_run_at }.

Examples:

  Watch the HN front page (no params needed):
    preset_id: "hn-front-page"
    params: {}

  Watch a subreddit for new posts:
    preset_id: "reddit-subreddit"
    params: { subreddit: "MachineLearning" }

  Watch a GitHub repo for new releases, check every 2 hours:
    preset_id: "github-releases"
    params: { owner: "fastify", repo: "fastify" }
    schedule: { every: "2h" }

  Watch HN for keyword with a custom min_points threshold:
    preset_id: "hn-keyword"
    params: { keyword: "rust programming", min_points: "25" }
- `impri_inbox_status`: 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_watcher_presets`: List all available watcher presets with their parameters.

Presets are pre-configured watcher templates for common sources (Hacker News, Reddit, GitHub, npm, YouTube, arXiv, etc.). Each preset has an id, a human-readable title, required and optional params, and a default schedule.

Call this first to discover which preset fits your monitoring goal, then use impri_create_watcher_from_preset to create the watcher by supplying only the preset_id and param values. No deep knowledge of watcher config schemas is needed.

Example output:
  Community:
    - hn-front-page: "Hacker News Front Page" (rss) — no params required
    - reddit-keyword: "Reddit – Keyword Search" (reddit_search) — params: query, [subreddit]
- `impri_list_watchers`: 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`: Submit an action to the Impri human-approval inbox.

The action appears in the operator's web and mobile inbox as a card with a title, formatted preview, and optional tap-to-edit fields. The operator approves or rejects with one tap; you poll for the decision with impri_await_decision.

Returns { action_id, status: "pending", inbox_url }. Save action_id — you need it for all follow-up calls.

Example — send a draft Reddit reply for review:
  kind: "reddit.comment"
  title: "Reply: Why is resume advice so conflicting?"
  preview: { format: "markdown", body: "The advice conflicts because different advisors optimise for different audiences..." }
  target_url: "https://reddit.com/r/cscareerquestions/comments/..."
  editable: ["preview.body"]   // lets the reviewer tweak wording before approving
- `impri_report_result`: Report whether you successfully executed an approved action.

Closes the audit loop — the operator sees 'executed' or 'execute_failed' in the inbox alongside the original action and decision. Always call this after attempting an approved action, even on failure.

Statuses:
  "executed"       — action was carried out successfully
  "execute_failed" — execution attempt failed (include the error in detail)
