mcpField
I
Impri

Impri

リモート
impri.devAI・エージェント62 日前に更新

Impri について

ImpriはAIエージェント向けのMCPサーバー兼承認インボックスです。エージェントが提案した操作を、人が実行前に確認し、承認、拒否、編集できます。ウォッチャー管理と監査記録も備え、ローカルまたはホスト型で接続できます。

主な機能

  1. 01操作の人手による承認と拒否
  2. 02実行前の提案編集
  3. 03監査記録による結果追跡
  4. 04ウォッチャーの作成と管理
  5. 05ローカルとホスト型のMCP接続

活用シーン

  1. 01エージェントの投稿前に人の確認を挟む
  2. 02実行予定の操作を担当者が編集する
  3. 03一括処理前に承認待ちを確認する
  4. 04プリセットからウォッチャーを作成する

MCP 対応

操作の送信、決定待ち、結果報告、受信箱の確認、ウォッチャー管理を行う8つのツールを提供します。クライアントはローカルサーバーまたはホスト型Streamable HTTPエンドポイントに接続できます。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://api.impri.dev/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

すべてのエンドポイント
Streamable HTTPhttps://api.impri.dev/mcp認証が必要
パッケージ
npm@impri/mcp0.1.3

ツール

8
パラメーター型必須説明
kindstringはい受信トレイのフィルタリングに使う分類ラベル(例:'reddit.comment'、'email.send'、'blog.publish')。自由形式です。一貫した方式を選んでください。
titlestringはい受信トレイのカードに表示する短い見出しです。120 文字以内にしてください。
previewobjectはいレビュー担当者が決定前に読む内容です。
preview.formatenumはいプレビュー本文の表示形式です。markdown | text
preview.bodystringはいレビュー担当者に承認してもらうテキスト全体です。
payloadanyいいえwebhook コールバックでそのまま返される不透明なデータです。コンテキスト(例:Reddit の投稿 ID、下書き ID、キュー内の位置)の保存に便利です。レビュー担当者には表示されません。
target_urlstringいいえレビュー担当者がコンテキストを確認するために開ける URL(例:Reddit のスレッド、メールの下書き)。任意ですが、強く推奨します。
expires_innumberいいえ操作が自動的に期限切れになるまでの秒数(デフォルトは 86400 = 24 時間)。期限切れ後、ステータスは 'expired' になり、決定できなくなります。
idempotency_keystringいいえ再試行時の重複送信を防ぐ安定したキー。同じキーを 24 時間以内に使用すると、新しい操作を作成せず、元の操作を返します。
editablearrayいいえレビュー担当者が承認前に編集できる、ドット記法のフィールド(例:['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-Signaturesha256=abc123…${timestamp}.${nonce}.${rawBody} に対する HMAC-SHA256
X-Impri-Timestamp1752134400Unix エポック秒(古いリプレイを拒否するために使用)
X-Impri-Noncea1b2c3d4…ランダムな 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

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。