grantd について
grantdは、ユーザーに代わってサードパーティAPIを呼び出すエージェント向けの、セルフホスト可能なOAuthトークンブローカーです。MCPツールで認可やAPI呼び出しを扱い、生のトークンをLLMや呼び出し元に渡しません。
主な機能
- 01サーバー側で暗号化するOAuthトークン保管庫
- 02Google、GitHub、Slack、Notionのプロバイダー登録
- 03OAuthの認可、交換、更新
- 04接続確認とプロバイダーAPIのプロキシ
- 05未認可時の接続リンク応答
活用シーン
- 01接続済みプロバイダーAPIをエージェントから呼び出す
- 02接続がないユーザーに認可を案内する
MCP 対応
list_providers、check_connection、create_connect_link、call_providerをMCPツールとして公開します。認可がない場合、call_providerは接続リンク付きのauthorization_requiredを返します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y grantd-mcpGRANTD_API_KEYシークレットA Grantd secret key (sk_...). Treat it like a password.GRANTD_BASE_URLBase URL of your Grantd broker (default http://localhost:8787).GRANTD_END_USERDefault end-user id so tools don't need it passed each call.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
4掲載時のツール一覧 · 2 週間前に更新
このツールにパラメーターはありません。
詳細
Grantd
エージェント向けOAuth:AI エージェントがサードパーティAPI(Gmail、Slack、GitHub、Notionなど)を介してユーザーに代わり安全に操作できる、シンプルでMCPネイティブなOAuthトークンブローカーです。トークンはサーバー側の保管庫に保存され、LLMに渡ることはありません。
スタック:TypeScript · Hono · Postgres · 宣言的なプロバイダーレジストリで駆動する汎用OAuth2 · エンベロープ暗号化(AES-256-GCM、鍵バージョン管理) · 更新処理の並行制御にPostgresのアドバイザリロックを使用(Redisは不要)。セキュリティモデルと問題の報告方法については、SECURITY.mdをご覧ください。
セキュリティの概要
GrantdはユーザーのOAuthトークンを保管するため、セキュリティは機能の一つではなく、製品そのものです。基本事項は次のとおりです。
- トークンは保存時に暗号化されます — AES-256-GCMによるエンベロープ暗号化を使用し、レコードごとに新しいIVを生成して鍵のバージョンを管理します。また、フェイルクローズ方式のため(鍵がない場合は書き込みを拒否し、平文で保存することはありません)。
- トークンがLLMや呼び出し元に渡ることはありません。 プロキシがネットワーク境界でアクセストークンを挿入し、プロバイダーの応答だけを返します。生のトークンがシリアライズされて返されることはありません。
- APIキーは保存時にハッシュ化されます(ペッパー付きpbkdf2-sha256)。生の
sk_キーが表示されるのは一度だけです。 - SQLインジェクションは発生しません — すべてのクエリで、パラメーター化された
postgres.jsのタグ付きテンプレートを使用します。 - すべてのクエリで環境IDによるテナント分離を行います。すべてのテーブルで行レベルセキュリティが有効なため、Postgres RESTレイヤー(Supabase/PostgRESTなど)が保管庫を読み取ることはできません。
- OAuthの
stateとセッショントークンには256ビットの乱数を使用し、プロバイダーが対応している場合は**PKCE(S256)**を使用します。 - Postgresを基盤とする永続的なレート制限 — 認証ルートではシークレットキーごとに、公開ルートではIPごとに適用します。
これは自分で運用するオープンソースのインフラです。セルフホストの責任(鍵の管理、TLS、ボリューム型DoSに対処するためのエッジ/WAF)と既知の制限事項については、SECURITY.mdに正直に記載しています。他者のトークンを保持するホスト型のマルチテナント環境を運用する場合は、事前にHOSTED-CHECKLIST.mdを確認してください。
プロバイダー
| プロバイダー | 状態 |
|---|---|
| Google(Gmail、Calendarなど) | ✅ トークンの更新を含め、エンドツーエンドで検証済み |
| GitHub | ✅ エンドツーエンドで検証済み |
| Slack | 🧪 実験的 — 設定はありますが、実際のOAuthでの検証はまだです |
| Notion | 🧪 実験的 — 設定はありますが、実際のOAuthでの検証はまだです |
プロバイダーの追加はコードではなくデータで行います(src/providers.tsをご覧ください)。Slack/Notionの検証へのご協力を歓迎します。
クイックスタート(開発)
npm install
npm run keygen # prints an ENCRYPTION_KEYRING + API_KEY_SALT
cp .env.example .env # then paste keygen output + your DATABASE_URL
npm run migrate # apply SQL migrations
npm run dev # start the broker on :8787
MCP サーバー
ブローカーをツールとしてAI エージェント(Claude Code / Cursor / Claude Desktop)に公開します:
list_providers、check_connection、create_connect_link、call_provider。認証ゲートの要となる機能は、エージェントが未接続のユーザーに対してcall_providerを呼び出した場合、失敗させる代わりに、接続リンクを含むauthorization_requiredの結果を返すことです。
MCP サーバーはgrantd-mcpとしてnpmで公開されているため、利用するのにこのリポジトリをクローンする必要はありません。MCPクライアントの接続先に指定するだけです(稼働中のブローカーとシークレットキーが必要です)。ローカル開発の場合はnpm run mcpを実行してください(ブローカーの起動が必要です)。スモークテストはnpm run mcp:testで実行できます。
Claude Codeへの追加方法:
claude mcp add grantd \
--env GRANTD_API_KEY=sk_... \
--env GRANTD_BASE_URL=https://your-broker.example.com \
--env GRANTD_END_USER=user-123 \
-- npx -y grantd-mcp
または、Cursor / Claude DesktopのmcpServers設定に追加します:
{
"mcpServers": {
"grantd": {
"command": "npx",
"args": ["-y", "grantd-mcp"],
"env": {
"GRANTD_API_KEY": "sk_...",
"GRANTD_BASE_URL": "https://your-broker.example.com",
"GRANTD_END_USER": "user-123"
}
}
}
}
ディレクトリ構成
migrations/ SQL schema (Supabase/Postgres compatible)
scripts/ keygen + migrate helpers
src/
config.ts env loading + validation + keyring parse
crypto.ts envelope encryption + API-key hashing
db.ts postgres.js client
providers.ts declarative provider registry (Google, GitHub, Slack, Notion)
oauth.ts generic OAuth2 client (authorize / exchange / refresh) driven by the registry
server.ts Hono app + routes (WIP)
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。