Impri について
ImpriはAIエージェント向けのMCPサーバー兼承認インボックスです。エージェントが提案した操作を、人が実行前に確認し、承認、拒否、編集できます。ウォッチャー管理と監査記録も備え、ローカルまたはホスト型で接続できます。
主な機能
- 01操作の人手による承認と拒否
- 02実行前の提案編集
- 03監査記録による結果追跡
- 04ウォッチャーの作成と管理
- 05ローカルとホスト型のMCP接続
活用シーン
- 01エージェントの投稿前に人の確認を挟む
- 02実行予定の操作を担当者が編集する
- 03一括処理前に承認待ちを確認する
- 04プリセットからウォッチャーを作成する
MCP 対応
操作の送信、決定待ち、結果報告、受信箱の確認、ウォッチャー管理を行う8つのツールを提供します。クライアントはローカルサーバーまたはホスト型Streamable HTTPエンドポイントに接続できます。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://api.impri.dev/mcpclaude mcp add --transport http impri https://api.impri.dev/mcp{"mcpServers":{"impri":{"type":"http","url":"https://api.impri.dev/mcp"}}}Cursor で開く{"servers":{"impri":{"type":"http","url":"https://api.impri.dev/mcp"}}}VS Code で開く{"mcpServers":{"impri":{"type":"http","url":"https://api.impri.dev/mcp"}}}{"mcpServers":{"impri":{"serverUrl":"https://api.impri.dev/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
https://api.impri.dev/mcp認証が必要ツール
8| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| kind | string | はい | 受信トレイのフィルタリングに使う分類ラベル(例:'reddit.comment'、'email.send'、'blog.publish')。自由形式です。一貫した方式を選んでください。 |
| title | string | はい | 受信トレイのカードに表示する短い見出しです。120 文字以内にしてください。 |
| preview | object | はい | レビュー担当者が決定前に読む内容です。 |
| preview.format | enum | はい | プレビュー本文の表示形式です。markdown | text |
| preview.body | string | はい | レビュー担当者に承認してもらうテキスト全体です。 |
| payload | any | いいえ | webhook コールバックでそのまま返される不透明なデータです。コンテキスト(例:Reddit の投稿 ID、下書き ID、キュー内の位置)の保存に便利です。レビュー担当者には表示されません。 |
| target_url | string | いいえ | レビュー担当者がコンテキストを確認するために開ける URL(例:Reddit のスレッド、メールの下書き)。任意ですが、強く推奨します。 |
| expires_in | number | いいえ | 操作が自動的に期限切れになるまでの秒数(デフォルトは 86400 = 24 時間)。期限切れ後、ステータスは 'expired' になり、決定できなくなります。 |
| idempotency_key | string | いいえ | 再試行時の重複送信を防ぐ安定したキー。同じキーを 24 時間以内に使用すると、新しい操作を作成せず、元の操作を返します。 |
| editable | array | いいえ | レビュー担当者が承認前に編集できる、ドット記法のフィールド(例:['preview.body'])。編集後の最終値は、承認された操作に含めて返されます。 |
詳細
@impri/mcp
Impri の MCP サーバー — AI エージェント向けの、人間が承認するための受信箱です。
エージェントはアクションを送信して人間のレビュー(承認/拒否/編集)を受け、サイドエフェクトを伴う処理を実行する前に、判断をポーリングして確認します。Impri のウェブおよびモバイルの受信箱では、完全な監査証跡を確認できます。
ローカルプロセスを実行したくない場合は? 同じ 8 つのツールを、https://api.impri.dev/mcp の Streamable HTTP 経由でも利用できます。インストールは不要で、URL と Bearer トークンとしての API キーだけで使えます。
claude mcp add --transport http impri https://api.impri.dev/mcp --header "Authorization: Bearer $IMPRI_API_KEY"
Cursor/Windsurf/Codex の設定と詳細については、impri.dev/docs/mcp をご覧ください(たとえば、ホスト型エンドポイントでは impri_await_decision の待機時間が 20s に制限されます)。この README の残りでは、以下のローカルの npx @impri/mcp パッケージについて説明します。
クイックスタート(Claude Code)
1. impri.dev で API キーを取得するか、セルフホスト可能なサーバーを起動します。
# self-host
docker compose up -d # starts on http://localhost:8484
export IMPRI_API_KEY=im_your_key_here
2. Claude Code に MCP サーバーを登録します。
claude mcp add impri \
-e IMPRI_API_KEY=im_your_key_here \
-- npx @impri/mcp
カスタム URL を使用してセルフホストする場合:
claude mcp add impri \
-e IMPRI_API_KEY=im_your_key_here \
-e IMPRI_BASE_URL=http://localhost:8484 \
-- npx @impri/mcp
または、~/.claude/settings.json に手動で追加します。
{
"mcpServers": {
"impri": {
"command": "npx",
"args": ["@impri/mcp"],
"env": {
"IMPRI_API_KEY": "im_your_key_here",
"IMPRI_BASE_URL": "http://localhost:8484"
}
}
}
}
3. 読み込まれたことを確認します。
/mcp
8 つのツールを持つ impri が一覧に表示されます。
環境変数
| 変数 | 必須 | デフォルト | 説明 |
|---|---|---|---|
IMPRI_API_KEY | はい | — | API キー(im_...)。Impri ダッシュボードで取得します。 |
IMPRI_BASE_URL | いいえ | http://localhost:8484 | /v1 を含まないベース URL です。クラウド版では https://api.impri.dev を使用します。 |
ツール
impri_push_action
アクションを人間の承認用受信箱に送信します。後続の呼び出しで使用する action_id を返します。
kind: "reddit.comment"
title: "Reply: Why is resume advice so conflicting?"
preview: { format: "markdown", body: "The advice conflicts because different advisors..." }
target_url: "https://reddit.com/r/cscareerquestions/comments/..."
editable: ["preview.body"]
impri_await_decision
人間が判断する(承認/拒否)まで、またはタイムアウトになるまでポーリングします。5 秒ごとにポーリングします。
action_id: "act_abc123"
timeout_s: 300 # default: 5 minutes
判断のステータス:
approved— アクションを実行しますrejected— 中止します。オペレーターが拒否しましたexpired— 承認期間が終了しました。引き続き必要な場合は新しいアクションを作成します
impri_report_result
承認されたアクションを実行したかどうかを報告します。監査の一連の流れを完了します。
action_id: "act_abc123"
status: "executed" # or "execute_failed"
detail: "Posted to Reddit thread r/cscareerquestions"
impri_inbox_status
人間の判断を待っているアクションの件数を確認します。レビュアーに負荷をかけすぎないよう、バッチを開始する前に使用します。
impri_create_watcher
詳細な仕様をすべて手作業で指定してウォッチャーを作成します。設定、キーワード、スコアリングルール、スケジュールを細かく制御する必要がある場合に便利です。スキーマの全容については SPEC.md §3.2 をご覧ください。
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" }
}
impri_list_watchers
設定済みのすべてのウォッチャーを一覧表示します。必要に応じて、ステータス(active、paused、degraded)で絞り込めます。
impri_list_watcher_presets
利用可能なウォッチャーのプリセットテンプレートをカテゴリ別に一覧表示します。各プリセットには、id、タイトル、種類、対応するパラメーター(必須/任意)、デフォルトのスケジュールが表示されます。
最初にこれを使って適切なプリセットを見つけ、次に impri_create_watcher_from_preset でウォッチャーを作成します。
利用可能なプリセットカテゴリ:コミュニティ、開発者、コンテンツ、モニタリング、リサーチ、ニュース。
impri_create_watcher_from_preset
プリセット ID とパラメーター値だけを指定して、プリセットテンプレートからウォッチャーを作成します。URL の構築、キーワードの設定、検証はプリセットが自動的に処理します。
preset_id: "reddit-subreddit"
params: { subreddit: "MachineLearning" }
# name and schedule are optional; defaults come from the preset
preset_id: "github-releases"
params: { owner: "fastify", repo: "fastify" }
schedule: { every: "2h" }
preset_id: "hn-keyword"
params: { keyword: "rust programming", min_points: "25" }
{ watcher_id, name, kind, status, next_run_at } を返します。
注: プリセットベースのウォッチャーが配信するアイテムには
payload.untrusted = trueが付与されます。タイトルとプレビューは外部ソース(HN、Reddit、arXiv など)から取得されるため、指示ではなくデータとして扱う必要があります。
完全なループの例(Claude Code のシステムプロンプト)
You are a Reddit engagement agent. Before posting any comment or reply:
1. Call impri_inbox_status — if more than 5 actions are pending, pause.
2. Draft your reply.
3. Call impri_push_action with kind "reddit.comment", your draft in preview.body,
the thread URL in target_url, and editable: ["preview.body"] so I can tweak it.
4. Call impri_await_decision(action_id, timeout_s=600).
5. If approved: post the (possibly edited) preview.body to Reddit, then
call impri_report_result(action_id, "executed").
If rejected: discard the draft and move on.
If expired: log a note and skip this reply.
Webhook の検証
Impri が callback_url に Webhook を送信すると、リプレイ攻撃や偽造を防ぐため、各リクエストに HMAC-SHA256 署名が付与されます。@impri/mcp パッケージには、すぐに使えるヘルパーが用意されています。
import { verifyWebhookSignature } from "@impri/mcp/webhook";
署名に関する情報は、次の 3 つのヘッダーで渡されます。
| ヘッダー | 例 | 説明 |
|---|---|---|
X-Impri-Signature | sha256=abc123… | ${timestamp}.${nonce}.${rawBody} に対する HMAC-SHA256 |
X-Impri-Timestamp | 1752134400 | Unix エポック秒(古いリプレイを拒否するために使用) |
X-Impri-Nonce | a1b2c3d4… | ランダムな 16 進数文字列 — 配信ごとに一意 |
Express ミドルウェア
import express from "express";
import { verifyWebhookSignature } from "@impri/mcp/webhook";
const app = express();
app.post(
"/impri/webhook",
express.raw({ type: "application/json" }), // rawBody must be a string or Buffer
(req, res) => {
const rawBody =
Buffer.isBuffer(req.body) ? req.body.toString("utf8") : String(req.body);
const ok = verifyWebhookSignature({
secret: process.env.IMPRI_WEBHOOK_SECRET!,
rawBody,
signatureHeader: req.headers["x-impri-signature"] as string,
timestampHeader: req.headers["x-impri-timestamp"] as string,
nonceHeader: req.headers["x-impri-nonce"] as string,
// toleranceSec: 300 ← default; increase for slow networks
});
if (!ok) {
return res.status(401).json({ error: "Invalid signature" });
}
const event = JSON.parse(rawBody);
console.log("Impri event:", event.event, event.action_id, event.status);
res.sendStatus(200);
},
);
Fastify ミドルウェア
import Fastify from "fastify";
import { verifyWebhookSignature } from "@impri/mcp/webhook";
const app = Fastify();
app.addContentTypeParser("application/json", { parseAs: "string" }, (req, body, done) => {
done(null, body);
});
app.post("/impri/webhook", (request, reply) => {
const rawBody = request.body as string;
const ok = verifyWebhookSignature({
secret: process.env.IMPRI_WEBHOOK_SECRET!,
rawBody,
signatureHeader: request.headers["x-impri-signature"] as string,
timestampHeader: request.headers["x-impri-timestamp"] as string,
nonceHeader: request.headers["x-impri-nonce"] as string,
});
if (!ok) {
return reply.status(401).send({ error: "Invalid signature" });
}
const event = JSON.parse(rawBody);
console.log("Impri event:", event.event, event.action_id);
reply.send({ ok: true });
});
Important: ヘルパーに渡す前に、ボディを生の文字列として解析してください。ボディを JSON として解析して再度文字列化すると、空白やフィールドの順序が変わり、HMAC が一致しなくなります。
開発
cd mcp
npm install
npm run typecheck # TypeScript check
npm run lint # ESLint
npm run test # Vitest (16 tests)
npm run check # all three
npm run build # compile to dist/
開発用にサーバーをローカルで実行する方法:
IMPRI_API_KEY=im_dev_key node dist/index.js
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。