idf-mcp について
idf-mcpは、Fold runtimeを介してIDFドメインをAIエージェントに公開するMCPアダプターです。ドメイン規則からツールの説明やアクセス範囲を導き、許可されない操作には構造化された拒否情報を返します。
主な機能
- 01実行可能な意図からツールを生成
- 02説明に条件と不変条件を記載
- 03ロール別のリソース表示範囲
- 04構造化された拒否応答
- 05不可逆操作の警告
活用シーン
- 01Claude Desktop、Cursor、Zedにドメインを公開
- 02ドメイン規則による拒否後の対応を支援
- 03ロール別にツールと閲覧データを制限
MCP 対応
stdioのMCPサーバーとして、HTTP経由でFold runtimeに接続します。MCPクライアントに、意図に基づくツールとロール別のリソースを公開します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @intent-driven/mcp-serverIDF_SERVERBase URL of the IDF host runtime (e.g. http://localhost:3001).IDF_DOMAINIDF domain to expose as MCP tools (e.g. invest, booking, planning).IDF_BOOTSTRAPSet to 0 if the host runtime already bootstrapped the domain; 1 (default) to bootstrap from IDF_ONTOLOGY_PATH on first connection.IDF_ONTOLOGY_PATHFilesystem path to the domain ontology module (only used when IDF_BOOTSTRAP=1).IDF_AUTH_TOKENシークレットOptional bearer token forwarded to the host runtime as the agent's role credential.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
@intent-driven/mcp-server
AI エージェントに API キーを渡すのはやめましょう。ドメインを渡しましょう。
@intent-driven/mcp-server は、任意の IDF ドメインを Claude Desktop / Cursor / Zed 向けの Model Context Protocol サーバーとして公開します。ツールの説明にはドメインのセマンティクス(前提条件、不変条件、不可逆性、ロールの適用範囲)が含まれ、エージェントがすべきでないことを試みた場合は構造化された拒否を返します。500 エラーでも、単なる文字列でもありません。LLM が読み取り、対応を調整できる JSON 形式です。
→ ランディングページとデモ:fold.intent-design.tech → 5 分で始めるクイックスタート:github.com/intent-driven-software/fold-runtime-quickstart
70 秒の概要
これが必要な理由
2026 年 4 月 25 日、PocketOS のステージング環境で認証情報の不一致に対応していた Claude Opus 4.6 搭載の Cursor エージェントが、無関係な API トークンを見つけ、問題を解決するために Railway のボリュームを削除することを決め、9 秒で本番データベースとボリュームレベルのバックアップすべてを消去しました。エージェント自身の事後検証によると:
「API 経由でステージングのボリュームを削除すれば、ステージングだけが対象になると思い込んでいました。確認しませんでした。ボリューム ID が環境間で共有されているかどうかも確認しませんでした。」
30 時間の障害が発生しました。PocketOS は 3 か月前のバックアップにロールバックしました。 (The Register · FastCompany · OECD AI Incident #6153)
これはアライメントの問題ではありません。システムは、何が許可されているのか、なぜすべきでないのか、実行すると何が起きるのかを、エージェントにまったく伝えていませんでした。既存の MCP サーバーも同様です。ツールの説明にはエンドポイントの形式が記載されているだけで、それ以上の情報はほとんどありません。エージェントは 500 エラーにぶつかりながら学習します。
このパッケージはその問題を解決します。MCP ツールの説明には、呼び出しが失敗する理由が記載され、拒否には、何が失敗したのかが構造化された形で含まれます。
スタックへの組み込み方
@intent-driven/mcp-server は、HTTP API 経由で Fold ランタイムと通信するstdio MCP アダプターです。ランタイムは独立したサービスです。既存のアプリのミドルウェアでも、実行時のコード生成でもありません。現在のバックエンドはそのまま維持されます。IDF アーティファクトがエージェント向けのインターフェースを記述し、ランタイムは独自のポート(デフォルトは :3001)でそれを提供します。
┌──────────────────┐ stdio ┌──────────────────┐ HTTP ┌────────────────────┐
│ Claude Desktop │ ◀─────────▶│ @intent-driven/ │ ◀───────▶│ Fold runtime │
│ Cursor / Zed │ │ mcp-server │ │ (idf host :3001) │
└──────────────────┘ └──────────────────┘ └────────┬───────────┘
│ reads
▼
┌────────────────────┐
│ IDF artifact │
│ (entities + intents│
│ + invariants + │
│ roles + __irr) │
└────────────────────┘
MCP サーバーは Claude/Cursor が接続するものです。ランタイムは拒否を強制するものです。IDF アーティファクトは作成するものです。
対象となる方。 実際のバックエンド、実際の顧客、そしてまもなく SOC2 審査を控えた環境で、今四半期中に AI エージェントを本番導入する、5〜30 人のチームのエンジニアです。事後に確認するガードレール層ではなく、誤った操作を、呼び出しの前に、エージェントが読み取れる構造化された理由とともに、システム自体が拒否する仕組みを求めています。
エージェントが実際に確認する内容
フリーランスドメインの submit_response:
Executor публикует Response на Task в status=published; Response.status=pending; +1 в Task.responsesCount
Creates: Response(pending)
Preconditions: task.status = "published"
May fail on (domain invariants):
- Response.taskId must reference existing Task.id
- Response: max 1 per taskId where (status="selected")
- Response: row count rule per taskId where (status="pending") [info]
同じドメインの release_payment:
Customer releases escrow to executor. After confirmation, money is gone — forward-correction only.
⚠️ Irreversible action (point-of-no-return: high). Forward-correction only after this effect is confirmed.
May fail on (domain invariants):
- Deal.status transitions allowed: in_progress→completed, on_review→completed, ...
これらはどれも、MCP サーバー用に手作業で記述したものではありません。エンティティ、インテント、不変条件、ロール、不可逆ポイントから成る宣言的な IDF アーティファクトひとつから、すべて生成されています。
構造化された拒否の例
エージェントが事前承認なしで 50,000 ドル分の BTC のロングポジションを申し込みます。ランタイムは、ストレージに何らかの効果が反映される前に、この操作をインターセプトします。
HTTP 403
{
"error": "preapproval_denied",
"intentId": "agent_execute_preapproved_order",
"reason": "no_preapproval",
"details": {
"entity": "AgentPreapproval",
"ownerField": "userId",
"viewerId": "user_5f57c252"
}
}
理性的なエージェントが次に取るべき行動は、処理を止め、人間に事前承認を求めてから再試行することです。500 エラーでも、文字列でもありません。LLM が読み取り、対応できる JSON 形式です。
クイックスタート
最も手早く始めるには、fold-runtime-quickstartをご利用ください。Docker にまとめられており、パスの設定も不要で、コマンド 2 つで実行できます。
git clone https://github.com/intent-driven-software/fold-runtime-quickstart && cd $_
docker compose up # ~3 min first time, ~5 sec after
# in another terminal
npm install
npm run demo:rogue && \ # Act 1: $50K trade → 403 with structured rejection
npm run demo:grant && \ # Act 2: investor issues $1K cap (one declarative effect)
npm run demo:smart # Act 3: agent reads cap, scales to $950, executes 200 OK
ホストを自分で操作したい場合(たとえば、独自のオントロジーを使った開発など)は、次のセクションをご覧ください。
MCP サーバーを直接操作する
localhost:3001 で稼働中の IDF ホストが必要です。クイックスタートの docker-compose で起動するか、idfを手動で実行してください。また、ドメインのブートストラップも必要です。
CLI
# bootstrap from local FS (ontology + intents)
mcp-idf --domain=invest --ontology-path=/abs/path/to/idf/src/domains/invest
# skip bootstrap (domain already loaded by another client / docker)
mcp-idf --domain=invest --no-bootstrap
フラグ/環境変数:
| フラグ | 環境変数 | デフォルト |
|---|---|---|
--domain | IDF_DOMAIN | booking |
--server | IDF_SERVER | http://localhost:3001 |
--ontology-path | IDF_ONTOLOGY_PATH | ./src/domains/<domain> |
--agent-email | IDF_AGENT_EMAIL | mcp-agent@local |
--no-bootstrap | IDF_BOOTSTRAP=0 | ブートストラップ有効(FS オントロジーを読み込み) |
Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"invest": {
"command": "npx",
"args": ["-y", "@intent-driven/mcp-server"],
"env": {
"IDF_SERVER": "http://localhost:3001",
"IDF_DOMAIN": "invest",
"IDF_BOOTSTRAP": "0",
"IDF_AGENT_EMAIL": "claude@local"
}
}
}
}
ホストにドメインがすでに読み込まれている場合(クイックスタートのコンテナでは docker compose up 時に読み込まれます)、IDF_BOOTSTRAP=0 を設定してください。Claude Desktop を完全に再起動してください(⌘Q で終了してから再起動します。ウィンドウを閉じるだけでは不十分です)。エージェントが呼び出せるインテントはすべて、Tools メニューに表示されます。
スキーマのマッピング
IDF intent.canExecute ─→ MCP tool
intent.parameters ─→ JSON Schema inputSchema
intent.conditions ─→ description hint for LLM
ontology.invariants (relevant) ─→ description block "May fail on"
intent.irreversibility:high ─→ annotations.destructiveHint + warning
role.visibleFields ─→ resource per collection
preapproval guard ─→ automatic scope/limits
checkOwnership ─→ automatic access control
ツール
ontology.roles.agent.canExecute に含まれるインテントごとに、ツールが 1 つ作成されます。
name—intentIdtitle—intent.namedescription—intent.description+Creates: …+ 前提条件 +May fail on (domain invariants)ブロック +irreversibility: "high"の場合は不可逆性に関する警告inputSchema—particles.parametersから生成される JSON Schema:entityRef/id/text/textarea/select→stringnumber→numberboolean→booleandatetime→string+format: "date-time"email→string+format: "email"
annotations.destructiveHint—intent.irreversibility === "high"の場合はtrue(IDF §23:効果レベルの取り消し不能点)
リソース
role.visibleFields[entity] のコレクションごとに、リソースが 1 つ作成されます。URI スキーム:
idf://<domain>/<collection>。
resources/read は /api/agent/:domain/world からフィルタリング済みのワールドを返します。閲覧者ごとにスコープが適用済みです(単独オーナー + role.scope による m2m)。
手作業で構築する MCP にはないメリット
MCP コミュニティでは、すべてのサーバーで次の課題を手作業で解決しています。
- スコープ/可視性。 デコレーターやミドルウェアを使います。→ IDF では
role.visibleFieldsで宣言します。 - 権限。 OAuth スコープやカスタム ACL を使います。→ IDF では
roles.agent.canExecuteで宣言します。 - レート制限/支出上限。 サーバーごとに個別実装します。→ IDF では
maxAmount/dailySumを指定したpreapproval.requiredForで宣言します。 - 破壊的操作のヒント。 手動で設定するため、忘れられることもよくあります。→ IDF では
effect.context.__irr.point === "high"の場合にdestructiveHint: trueが自動設定されます。 - LLM へのヒントとしてのビジネスルール。 通常は伝達されません。→ IDF では
intent.conditionsがツールの説明にPreconditions:として反映されます。 - 説明文におけるドメイン不変条件。 ほとんど対応されていません。→ IDF は、インテントごとに関連する不変条件(alpha × エンティティの一致)を計算し、
May fail on (domain invariants)として挿入します。これにより、手作業で構築する MCP サーバーへの最大の不満である「サーバーがドメインの意味を持たず、LLM は何を呼び出せばよいかはわかっても、なぜ失敗するかはわからない」という問題を解消します。
IDF アーティファクトの作成にかかる時間
公開されている IDF ホストランタイムからの参考例を 3 つ紹介します。
| ドメイン | 構成 | 時間 |
|---|---|---|
invest | 14 エンティティ · 61 インテント · 5 不変条件 · 約600行 | 週末に手書き |
gravitino | 253 エンティティ(Apache カタログの OpenAPI) · 120 インテント | 1時間未満でインポート、2日で拡充 |
workflow | 9 エンティティ · 47 インテント · タイマーキュー · カスケードルール | 1日 |
作業時間を短縮できるのは、次の機能(すべて @intent-driven/cli に含まれます)のおかげです。
idf import postgres— ライブスキーマを読み込み、外部キーと列型をfieldRoleとして設定したエンティティのベースラインを生成します。idf import openapi— 既存の API 仕様を読み込み、インテント、パラメーター構成、参照フィールドを生成します。253 エンティティのドメインを立ち上げる際には、この方法を使います。idf import prisma— ORM 主導のバックエンドでも同様に利用できます。idf enrich— 既存のコードコメントをもとに、LLM がlabel、fieldRole、compositions、推奨されるroles.agent.preapprovalの述語を補完します。
一度作成したら、その後は手をかけなくてよい仕組みこそが、重要なポイントです。アーティファクトができたら、スキーマ変更のたびに足場を再生成する必要はありません。ランタイムが同じファイルを再読み込みし、UI、音声、エージェント、ドキュメントという 4 つの利用者に情報を提供します。
ドメインの前提条件
プロトコルの信頼性は高いものの、IDF ドメインが正しく作成されている必要があります。以下が満たされていないと、tools/list が空を返したり、tools/call が domain_not_supported を返したり、リソースが空になったりすることがあります。
ontology.roles.agentを宣言する必要があります。エージェントロールがないと、ツールもリソースもありません。role.agent.canExecute— 安全なインテントのリストです。事前承認なしで__irr:highを使うのは避けてください。role.agent.visibleFields— フィールド、または"own"/"all"/"aggregated"マーカーの配列です。- サーバー側のエフェクトビルダー(
idf内のserver/schema/effectBuildersRegistry.cjs)に、対象ドメインを含める必要があります。含まれていないと、tools/callはdomain_not_supportedを返します。 ownerFieldのない公開カタログ。 エンティティにownerFieldがある場合、SDK のfilterWorldForRoleはrow[ownerField] !== viewer.idとなる行を除外します。公開カタログ(たとえばstatus: "published"のTask)では、via-collection を使うrole.scope、またはエージェントロールで扱える別のプロジェクションを使用してください(ロードマップ)。
制限事項(1.0)
toolsとresourcesのみです。prompts/completionはロードマップにあります。- ブートストラップでは、ローカル FS からオントロジーを読み込みます。SaaS 版(DB/API からオントロジーを取得)は次の予定です。
- 認証はメールアドレス/パスワードでのログインです。PAT/OAuth2 は次の予定です。
- 同期のみです(
POST /exec)。長時間実行は MCP tasks API を通じて対応する予定です。
リンク
- ランディングページとデモ: fold.intent-design.tech
- クイックスタート: intent-driven-software/fold-runtime-quickstart
- ホストランタイム: DubovskiyIM/idf
- ランタイムレイヤーが必要な理由: 論文 — これが答えるエージェントの安全性に関する基本的な問いを扱った、約 1800 語のエッセイです
- MCP 仕様: modelcontextprotocol.io
ライセンス
MIT
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。