toolmesh について
ToolMeshは、AIエージェントをREST APIや既存のMCPサーバーに接続するセルフホスト型ゲートウェイです。宣言型のDADLファイルでRESTツールを定義し、認可、認証情報の処理、ポリシー、監査記録によって利用を管理します。
主な機能
- 01YAML DADLでREST APIをツールとして記述
- 02既存のMCPサーバーをプロキシ
- 03実行時に認証情報を注入
- 04ユーザー、ロール、プラン、会社ごとの認可
- 05JavaScriptポリシーによる入出力の制御
- 06構造化ログまたはSQLiteへのツール呼び出し記録
活用シーン
- 01ラッパーサーバーを作らずにREST API操作を公開
- 02ロールやプランに基づくエージェントツールへのアクセス制限
- 03プロンプトやクライアント設定から認証情報を分離
- 04接続システム全体のツール利用を監査
MCP 対応
ToolMeshはMCPゲートウェイとして、DADLで定義したREST APIツールを公開し、既存のMCPサーバーをプロキシします。MCPクライアントはそのエンドポイントに接続し、リモートアクセスではPKCE対応のOAuth 2.1を利用できます。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://{host}:8123/mcpclaude mcp add --transport http dunkelcloud-toolmesh https://{host}:8123/mcp{"mcpServers":{"dunkelcloud-toolmesh":{"type":"http","url":"https://{host}:8123/mcp"}}}Cursor で開く{"servers":{"dunkelcloud-toolmesh":{"type":"http","url":"https://{host}:8123/mcp"}}}VS Code で開く{"mcpServers":{"dunkelcloud-toolmesh":{"type":"http","url":"https://{host}:8123/mcp"}}}{"mcpServers":{"dunkelcloud-toolmesh":{"serverUrl":"https://{host}:8123/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
ToolMesh — AI エージェントが実システムを安全に操作できるようにします。
AI エージェントとエンタープライズシステムをつなぐ、欠けていた制御レイヤーです。ToolMesh は、制御されていない AI のツール呼び出しを、ガバナンスが適用された監査可能なプロセスに変えます。また、あらゆる REST API や MCP サーバーを、数か月ではなく数分で接続できます。
YAML 30 行。構築するサーバーはありません。
実際には、MCP サーバーがラップしている REST API の一部しか公開していないことが多く、すぐに不足に気づくでしょう。ToolMesh では、ラッパーレイヤーを .dadl ファイルに置き換えられます。これは、あらゆる REST API を MCP ツールとして記述する宣言型の YAML 形式です。構築、デプロイ、保守するラッパーサーバーは必要ありません。
Current: Claude → ToolMesh → MCP Server → REST API
With DADL: Claude → ToolMesh → REST API (via .dadl file)
YAML を手作業で書く必要はありません。LLM に頼めばよいのです。Claude、GPT、Gemini など、DADL 仕様を理解するモデルなら、数秒で動作する .dadl ファイルを生成できます。必要な内容を説明して、ファイルを config/dadl/ に入れれば完了です。
「GitHub API 用の DADL を作成してください。リポジトリの一覧表示、Issue の作成、プルリクエストの作成をお願いします。」
10 秒で完了します。この形式を理解するあらゆる LLM で使えます。
ツール呼び出しをそのまま中継するだけの MCP ゲートウェイとは異なり、ToolMesh には本番環境へのデプロイに実際に必要な機能が追加されています。
- 認証情報のセキュリティ — シークレットは実行時に注入され、プロンプトや LLM クライアント設定には決して含まれません
- 認可 — デフォルトで有効です。ユーザー、ロール、プラン、会社に基づき、誰がどのツールを呼び出せるかを制御します(OpenFGA を内蔵)
- 入力と出力のゲート制御 — JS ポリシーで機密データをブロックし、応答をフィルタリングします
- 監査証跡 — すべてのツール呼び出しを構造化ログまたはクエリ可能な SQLite に記録します
6 つの柱
| 柱 | 機能 | 基盤技術 |
|---|---|---|
| あらゆるバックエンド | DADL 30 行で MCP サーバー全体を置き換えられます。既存の MCP サーバーのプロキシにも対応します。 | Go MCP SDK + DADL(.dadl ファイル) |
| コードモード | MCP サーバーを 15 個同時に使う場合、ToolMesh がなければ不可能です。コードモードなら、50,000 以上のトークンを約 1,000 まで削減します。 | AST で解析したツール呼び出し |
| 認証情報ストア | シークレットは実行時に注入されます。プロンプトにも LLM クライアント設定にも含まれません | Executor パイプラインによるリクエストごとの注入 |
| OpenFGA | 細かな認可を、インストール不要の状態でデフォルト有効にします(ユーザー → プラン → ツール)。例:無料ユーザーには読み取り専用、プロユーザーにはすべての操作を許可します。 | OpenFGA、組み込みまたは外部 |
| ゲート | 実行前に機密データをブロックし、応答内の PII を秘匿化します | goja |
| 監査 | すべてのツール呼び出しを記録し、クエリで検索できます。SQL を使って「そのエージェントは何をしたのか?」に答えられます | slog / SQLite |
デモを試す
インストール前に ToolMesh を試してみませんか?公開デモインスタンスに接続できます。Docker、設定、API キーは不要です。
demo.toolmesh.io — ToolMesh 経由の Hacker News API。Claude Desktop、Claude Code、ChatGPT で利用できます。ログイン情報:dadl / toolmesh
クイックスタート
# Clone
git clone https://github.com/DunkelCloud/ToolMesh.git
cd ToolMesh
# Configure
cp .env.example .env
# IMPORTANT: Set a password — without it, all requests are rejected:
# TOOLMESH_AUTH_PASSWORD=my-secret-password
# Or set an API key for programmatic access:
# TOOLMESH_API_KEY=my-api-key
# Optional: local overrides (build locally, external OpenFGA, HTTPS proxy, ...)
# cp docker-compose.override.yml.example docker-compose.override.yml
# # then edit docker-compose.override.yml — picked up automatically by Docker Compose
# Start (authorization is on: the password/API key above gets every tool;
# without a password or API key every request is rejected)
docker compose up -d
# Verify it's running (default port: 8123)
curl http://localhost:8123/health
# MCP endpoint: http://localhost:8123/mcp
# Note: Most MCP clients require HTTPS — see TLS section below
TLS(重要)
ToolMesh 自体はプレーンな HTTP を提供します。Claude Desktop を含むほとんどの MCP クライアントは HTTPS を必須としており、http:// URL を拒否します。ToolMesh の前段に、TLS を終端するリバースプロキシが必要です。
| 選択肢 | 用途 |
|---|---|
| Caddy | パブリックドメインを使ってセルフホストする場合 — Let's Encrypt 証明書を自動取得 |
| Cloudflare Tunnel | ポートの開放が不要で、TLS の設定も不要 |
| nginx / Traefik | すでにスタックで使っている場合 |
ローカル開発のみの場合は、claude_desktop_config.json を手動で編集すれば TLS を回避できます(GUI では https:// が必須です)。
Claude Desktop に接続
Claude Desktop の MCP 設定に追加します。
{
"mcpServers": {
"toolmesh": {
"url": "https://toolmesh.example.com/mcp"
}
}
}
TLS プロキシを使わずにローカル開発する場合:
{
"mcpServers": {
"toolmesh": {
"url": "http://localhost:8123/mcp"
}
}
}
Claude.ai に接続する(カスタムコネクター)
ToolMesh は、リモートアクセス向けに PKCE S256 を使用した OAuth 2.1 をサポートしています。config/users.yaml でユーザーを設定し、MCP エンドポイントとして公開 HTTPS URL を使用してください。
認証
ToolMesh は、単独でも併用しても使える 2 つの認証方式をサポートしています。OAuth の状態(トークン、認証コード、クライアント)はすべて Redis に永続化され、サーバーを再起動しても保持されます。
OAuth 2.1(インタラクティブログイン)
config/users.yaml で、bcrypt でハッシュ化したパスワードを使用してユーザーを定義します。
users:
- username: admin
password_hash: "$2a$10$..."
company: dunkelcloud
plan: pro
roles: [admin]
bcrypt に対応した任意のユーティリティを使って、パスワードハッシュを生成します。
htpasswd -nbBC 10 "" "my-password" | cut -d: -f2
単一ユーザー構成では、TOOLMESH_AUTH_PASSWORD を引き続きフォールバックとして使用できます。TOOLMESH_AUTH_USER、TOOLMESH_AUTH_PLAN、TOOLMESH_AUTH_ROLES を使って ID を設定してください(デフォルト:owner、pro、admin)。
API キー(プログラムによるアクセス)
config/apikeys.yaml で API キーを定義します。各エントリーでは、キーの SHA-256 をキー名として指定します。
keys:
- key_sha256: "<SHA-256 of the key, 64 hex characters>"
user_id: claude-code-user
company_id: dunkelcloud
plan: pro
roles: [tool-executor]
キーとその key_sha256 を生成します。
KEY="tm_$(openssl rand -hex 32)"
printf '%s' "$KEY" | sha256sum | cut -d' ' -f1
各キーは、それぞれ独自のプランとロールを持つ別個のユーザー ID に対応し、これらは認可に引き継がれます。
以前のバージョン向けに作成されたファイルにあるような、bcrypt の key_hash を含むエントリーも、変更なしで引き続き動作します。起動後にキーが一度も使用されるまでは、このようなエントリーに対して、ほかの方法では認識されないすべてのベアラー認証情報について bcrypt の比較が行われます。key_sha256 は直接検索され、ランダムに生成されたキー向けです。詳細と 2 つの形式の違いについては、docs/configuration.md を参照してください。
単一キー構成では、TOOLMESH_API_KEY を引き続きフォールバックとして使用できます。同じ TOOLMESH_AUTH_USER、TOOLMESH_AUTH_PLAN、TOOLMESH_AUTH_ROLES の各変数で ID を制御します。
認証されていないリクエスト
有効な認証情報を指定せずに /mcp にリクエストすると、MCP の認可仕様の要件に従い、resource_metadata を含む WWW-Authenticate: Bearer チャレンジとともに 401 が返されます。MCP クライアントはこのステータスを受け取ると、OAuth フローを開始するか、期限切れのトークンを更新します。このようなリクエストは INFO でログに記録され、toolmesh_logins_total{method="anonymous"} にカウントされます。詳細については、docs/configuration.md を参照してください。
DCR のレート制限
不正利用を防ぐため、動的クライアント登録は IP ごとに 1 時間あたり 5 件までに制限されています。
ログインのスロットリング
パスワード認証の失敗回数は、アカウントごと、およびクライアントアドレスごとに制限されます。デフォルトでは、15 分以内に、1 つのアカウントに対して 1 つのアドレスから 5 回、すべてのアドレスを合わせて 20 回、また 1 つのアドレスからすべてのアカウントを合わせて 50 回までです。これを超えると、ウィンドウが経過するまでログインに 429 が返されます。ログイン失敗はすべて WARN でログに記録され、toolmesh_logins_total{result="failure"} にカウントされます。すでに発行されたトークンと API キーは、ロックアウトの影響を受けません。変数と、アドレスごとの制限に必要なリバースプロキシの要件については、docs/configuration.md を参照してください。
同時に実行される bcrypt の比較回数は、プロセス全体で制限されます(TOOLMESH_BCRYPT_MAX_CONCURRENT。デフォルトは利用可能な CPU の半数です)。これにより、パスワード認証によってほかの処理に必要な CPU が奪われるのを防ぎます。詳細については、docs/configuration.md を参照してください。
認可
すべてのツール呼び出しは検査され、ツール一覧には各呼び出し元が呼び出せるツールのみが表示されます。セットアップは不要です。ToolMesh は自身のプロセス内で OpenFGA を実行し、データを data/authz.db に保持します。
TOOLMESH_AUTHZ_MODE でエンジンを選択します。
| モード | 動作 |
|---|---|
embedded(デフォルト) | 検査は ToolMesh 内で実行されます。許可はプリセットまたは config/authz.yaml から取得されます。 |
external | 検査は、運用する OpenFGA サーバー(OPENFGA_API_URL、OPENFGA_STORE_ID)に送信されます。ToolMesh が書き込みを行うことはありません。 |
disabled | 検査は行われません。起動のたびに報告され、監査証跡に記録されます。 |
許可設定は、users.yaml、apikeys.yaml、または単一のパスワード/API キーに登録されたユーザー、ロール、プラン、会社を参照します。許可設定ファイルがない場合は、プリセットが適用されます。
| プリセット | 呼び出し可能な対象 |
|---|---|
single-user | オーナー(TOOLMESH_AUTH_USER)とロール admin:すべてのツール。users.yaml/apikeys.yaml がない場合のデフォルトです。 |
team | single-user に加え、プラン pro:すべてのツール、プラン free:すべての read ツール。users.yaml または apikeys.yaml がある場合のデフォルトです。 |
open | 認証済みのすべての呼び出し元:すべてのツール |
より細かく制御するには、config/authz.yaml.example を config/authz.yaml にコピーします。許可設定では、すべてのツール、バックエンド、個別のツール、または DADL アクセスクラス(read、write、…)を指定できます。拒否設定はこれらのいずれもブロックし、すべての許可設定より優先されます。変更は数秒以内に反映されます。
grants:
- plan: pro
backends: [github, deepl]
- plan: free
access: [read]
- role: support
tools: [zammad_list_tickets]
denies:
- plan: pro
tools: [stripe_create_refund]
認可機能のないバージョンからアップグレードしたインストールでは、すべての認証済み呼び出し元にすべてのツールを開放した状態(プリセット open)が維持され、そのことが起動のたびに通知されます。プリセットを選択するか、許可設定を記述するまで、この状態は変わりません。OPENFGA_MODE は非推奨です。restrict は external に、bypass は embedded に対応します。docs/configuration.md を参照してください。
起動時のセキュリティ態勢
ToolMesh はデフォルトで安全です。個々の設定によって、制御が暗黙のうちに緩和されることはありません。起動時には、緩和された状態にある制御(認証情報の欠落、認可の無効化または全員への開放、CORS の開放、デバッグツール、ログイン制限の無効化)を、その強化方法とともに一覧表示するセキュリティ態勢の概要が一度だけログに記録されます。デフォルトの本番環境の設定では、これらは WARN でログに記録されます。ローカル開発マシンで TOOLMESH_DEV=true を設定すると、同じ情報を INFO で一度だけ通知するため、警告がバックグラウンドノイズになりません。TOOLMESH_DEV が変更するのはこの概要のログレベルのみであり、それ自体で設定を緩和することはありません。
設定
すべての環境変数については、docs/configuration.md を参照してください。
タイムアウトの調整
| 変数 | デフォルト | 説明 |
|---|---|---|
TOOLMESH_MCP_TIMEOUT | 120 | 下流の MCP サーバーへの呼び出しに対する HTTP クライアントのタイムアウト(秒) |
TOOLMESH_EXEC_TIMEOUT | 120 | ツール実行のタイムアウト(秒)。バックエンド呼び出しのコンテキスト期限です。 |
ブラウザーベースのウェブフェッチャーなど、より時間がかかるバックエンドでは、これらの値を大きくしてください。
TOOLMESH_MCP_TIMEOUT=180
TOOLMESH_EXEC_TIMEOUT=180
ログ記録
ToolMesh は slog による構造化ログを使用します。デフォルトのレベルは info です。問題の診断時に MCP リクエスト/レスポンスの全フローを追跡するには、LOG_LEVEL=debug を設定します。ただし、デバッグログにはリクエスト URL とペイロード全体が含まれるため、クエリ文字列に API キーを含めている場合は、その認証情報もログに記録される点に注意してください。本番環境では debug を無効にしてください。バックエンドごとのデバッグファイル、ログ形式、すべてのログ関連変数については、docs/configuration.md に記載されています。
メトリクス(Prometheus)
ToolMesh は、別のリスナー(デフォルトのホストポートは 9090)で Prometheus メトリクスを公開します。メソッドと結果別のログイン回数、バックエンドと結果別のツール呼び出し率、REST 向けに調整されたバケットを使用するレイテンシーヒストグラムが含まれます。このエンドポイントは認証されないため、Compose ファイルではデフォルトでホストポートを 127.0.0.1 にバインドします(ローカルおよび同じ Docker ネットワーク上の Prometheus からはアクセスできますが、パブリックインターフェースからはアクセスできません)。別のホストからスクレイプし、ポートを自分でファイアウォール設定している場合に限り、TOOLMESH_METRICS_HOST=0.0.0.0 を設定してください。
.env で TOOLMESH_METRICS_PORT、TOOLMESH_METRICS_ENABLED、TOOLMESH_METRICS_LABEL_TOOL を設定します。スキーマ全体、PromQL クエリの例、スクレイプ設定のサンプルについては、docs/metrics.md を参照してください。
デバッグツール(オプトイン)
.env で TOOLMESH_DEBUG_TOOLS=true を設定すると、2 つの診断用 MCP ツール(debug_echo(バックエンドを使わず、渡されたペイロードのサイズと SHA-256 を返します)と debug_generate(N バイトの印字可能な文字列を生成します))を公開します。これらを使用して、呼び出し元の LLM と ToolMesh 間のトランスポートレベルのサイズ制限を調べたり、往復後のバイトデータの整合性を確認したりできます。デフォルトでは無効です。本番環境ではなく、開発やインシデントのトリアージを目的としています。
アーキテクチャ
アーキテクチャの詳細については、docs/architecture.md を参照してください。
┌─────────────────────────────────┐
│ ToolMesh │
│ │
│ Redis · OpenFGA · Audit │
│ Credential Store · JS Gate │
│ │
AI Agent ──MCP──────────▶ │ AuthZ ▸ Creds ▸ Gate ▸ Exec │
│ │
└──┬──────┬───────┬───────┬───────┘
│ │ │ │
MCP Client .dadl .dadl .dadl
│ │ │ │
▼ ▼ ▼ ▼
MCP Stripe GitHub Vikunja
Server API API API
外部 MCP サーバーの追加
config/backends.yaml を作成または編集します。
backends:
- name: memorizer
transport: http
url: "https://memorizer.example.com/mcp"
api_key_env: "MEMORIZER_API_KEY"
認証情報を環境変数として設定します。
CREDENTIAL_MEMORIZER_API_KEY=sk-mem-xxxxx
各バックエンドのツールは、プレフィックス付き(例:memorizer_retrieve_knowledge)で公開されます。認証情報は実行時に CredentialStore を介して Executor が注入するため、LLM に API キーが渡ることはありません。
REST プロキシモード(DADL)
MCP サーバーが必要なエンドポイントを公開していない場合は、.dadl ファイルに記述すると、ToolMesh が REST API を直接呼び出します。ラッパーサーバーは不要です。両方のモードを並行して実行できます。
config/backends.yaml に REST バックエンドを追加します。
backends:
- name: vikunja
transport: rest
dadl: /app/dadl/vikunja.dadl
url: "https://vikunja.example.com/api/v1"
プライベート IP や自己署名証明書を使用する内部サービスの場合:
backends:
- name: internal-api
transport: rest
dadl: internal.dadl
url: "https://192.168.1.50:8443/api"
allow_private_url: true # allow private/loopback addresses (default: true)
tls_skip_verify: true # accept self-signed certificates (default: false)
Claude に GitHub のイシューを一覧表示させたい場合に必要な設定は、これだけです。
tools:
list_issues:
method: GET
path: /repos/{owner}/{repo}/issues
description: "List issues for a repository"
params:
owner: { type: string, in: path, required: true }
repo: { type: string, in: path, required: true }
state: { type: string, in: query }
ToolMesh は、認証、ページネーション、リトライ、エラーマッピングを処理します。DADL は、ベアラートークン、OAuth2、セッション認証、API キー、自動ページネーション、バックオフ付きリトライ、レスポンス変換、複合ツールなどをサポートしています。
仕様全体、使用例、コミュニティレジストリについては、dadl.ai を参照してください。.dadl ファイルを作成する最も手早い方法は、フォーマットを理解している任意の LLM に依頼することです。
コードモード
15 個の MCP サーバーを 1 つの AI エージェントに接続したい場合、ToolMesh がなければ実現できません。コンテキストウィンドウが埋まり、クライアントが処理しきれなくなるためです。コードモードを使えば実現できます。
ToolMesh は、個別のツール定義を何百個も(50,000 トークン以上)公開する代わりに、discover_tools と execute_code という 2 つのメタツールを公開します。LLM はコンパクトな TypeScript インターフェース(約 1,000 トークン)を受け取り、それを使って JavaScript を記述します。
const repos = await toolmesh.github_list_repos({ sort: "updated" });
const issues = await toolmesh.github_list_issues({
owner: repos[0].owner.login,
repo: repos[0].name,
state: "open"
});
1 回の往復で複数の API 呼び出しが可能です。ToolMesh はコードを解析してツール呼び出しを抽出し、完全な実行パイプラインを通じてルーティングします。
拡張モデル
ToolMesh は、Go の database/sql ドライバーパターンに着想を得た、レジストリベースの拡張モデルを採用しています。3 種類のコンポーネントは、init() による登録を通じて拡張できます。
| コンポーネント | 組み込み | 設定 |
|---|---|---|
| 認証情報ストア | embedded | CREDENTIAL_STORE=<name> |
| ツールバックエンド | mcp、rest(DADL)、echo | config/backends.yaml |
| ゲート評価器 | goja | GATE_EVALUATORS=<list> |
エンタープライズ向け拡張機能(InfisicalStore、VaultStore、Compliance-LLM など)は計画中で、Go のビルドタグを使用して組み込まれる予定です:go build -tags enterprise ./cmd/toolmesh。
詳細については、docs/architecture.md を参照してください。
開発元について
ToolMesh は、Dunkel Cloud GmbH の Axel Dunkel が構築、保守しています。ドイツに拠点を置く同社は、AI エージェントと実際のシステムをつなぐインフラを構築しています。ToolMesh と DADL は、長年にわたり企業向けに運用してきた本番環境のクラウドおよびエッジインフラから生まれました。そのため、匿名のアカウントが手がけるサイドプロジェクトではありません。自社のスタックで稼働しており、[email protected] への問い合わせに対応するメンバーと、コードを書くメンバーは同じです。
関連する DADL レジストリ では現在、コミュニティによる 27 件の API 記述を公開しており、約 3,300 個の生成済みツールを利用できます。4 個のツールを備えた Hacker News リーダーから、608 個のツールを備えた NetBox DCIM/IPAM まで、各 API のカバレッジ率が表示されるため、完全性を正確に確認できます。
- 🌐 ウェブサイト:toolmesh.io
- 📖 DADL の仕様とレジストリ:dadl.ai
- 🐛 セキュリティに関するお問い合わせ:[email protected](SECURITY.md を参照)
コントリビューション
CONTRIBUTING.md を参照してください。
ライセンス
Apache 2.0 — Copyright 2025–2026 Dunkel Cloud GmbH
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。