chowdown について
chowdownは、Cooklangファイルをユーザー自身のGoogle Driveに保存し、AIアシスタントから利用できるレシピアプリです。レシピ検索や食材からの料理探しに加え、OAuth 2.1で保護されたMCPサーバーを備えています。
主な機能
- 01Google DriveにCooklang形式でレシピを保存
- 02レシピの閲覧と絞り込み
- 03手持ちの食材からレシピを検索
- 04レシピの追加、編集、タグ付け、注釈
- 05お気に入りとメモの管理
活用シーン
- 01食事の種類や調理の希望に合わせてレシピを検索
- 02手持ちの食材で作れる料理を探す
- 03アシスタントからレシピ集を閲覧・更新
- 04エージェントスキルでブックマークのレシピURLを取り込む
MCP 対応
MCPサーバーは、レシピの閲覧、食材検索、絞り込み、レシピ管理のツールを読み取り・書き込み権限で提供します。クライアントはサーバーURLに接続し、OAuth 2.1で認可します。利用前にGoogle Driveの接続が必要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://chowdown.apps.mrida.ng/mcpclaude mcp add --transport http mridang-chowdown https://chowdown.apps.mrida.ng/mcp{"mcpServers":{"mridang-chowdown":{"type":"http","url":"https://chowdown.apps.mrida.ng/mcp"}}}Cursor で開く{"servers":{"mridang-chowdown":{"type":"http","url":"https://chowdown.apps.mrida.ng/mcp"}}}VS Code で開く{"mcpServers":{"mridang-chowdown":{"type":"http","url":"https://chowdown.apps.mrida.ng/mcp"}}}{"mcpServers":{"mridang-chowdown":{"serverUrl":"https://chowdown.apps.mrida.ng/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
🍳 chowdown
ユーザー自身の Google Drive に保存されている Cooklang の .cook ファイルを対象とするレシピアプリです。Cooklang に対応しています。Cloudflare Workers 上で動作する Next.js アプリ(OpenNext)として構築されています。
Cloudflare Worker が実際の処理を担います。Google サインイン、「Google Drive を接続」の個別のステップ、「Recipes」フォルダーの D1 キャッシュへの同期、REST API、OAuth 2.1 エンドポイントを備えた MCP サーバー、タグ付けと「類似検索」のためのモデル呼び出し(Workers AI)を処理します。Drive を信頼できる唯一の情報源とし、D1 をキャッシュとして使うことで、ページを 1 回のラウンドトリップでレンダリングします。
技術スタック
- Next.js 16(App Router)、React 19、Tailwind 4。OpenNext(
@opennextjs/cloudflare)を介して Cloudflare Workers 上で動作します - Drizzle を使用した D1、および Workers AI と Images のバインディング
- devbox で Node 24 を固定しています
- 単体テストには Jest、エンドツーエンドテストには Cypress を使用します
- リントには
@mridang/eslint-defaultsを使用します - パースには
@cooklang/cooklang-tsを使用します
Google の設定
サインインと Google Drive の接続は別々のステップで、それぞれに独自の Google 同意画面があります。
- サインインでは本人確認のみを要求します(
openid email profile)。アカウントと署名済みセッション Cookie を作成します。それ以外の処理は行いません。 - Google Drive を接続(ヘッダー、アカウントメニュー、接続が必要なページにあるボタン。
GET /auth/drive)すると、drive.fileスコープとオフラインのリフレッシュトークンが追加され、アプリが管理する「Recipes」フォルダーが作成されます。drive.fileは機密性の高いスコープではなく、chowdown が作成したファイルにのみアクセスするため、Google による検証は不要で、Marketplace に公開する必要もありません。
Drive を接続するまでは、ユーザーはアプリを閲覧し、キャッシュ済みの情報を確認できます。ただし、Drive ファイルの読み書きはすべて拒否されます(REST API は 409 /problems/drive-not-connected を返し、MCP ツールは対処方法を示すエラー結果を返します)。
Google Cloud で以下を設定します。
- Google Drive API を有効にします。
- OAuth 同意画面:External を選び、
.../auth/drive.fileスコープを追加し、Gmail アカウントをテストユーザーとして追加します(または本番環境に公開します。審査は引き続き不要です)。 - OAuth クライアント ID(Web アプリケーション)→ 承認済みのリダイレクト URI:
http://localhost:3737/auth/callback(開発環境)https://chowdown.apps.mrida.ng/auth/callback(本番環境)
シークレットは、ローカルでは .env に、本番環境では wrangler secret put <NAME> で設定します(Deploy を参照)。
GOOGLE_OAUTH_CLIENT_ID=....apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET=...
SESSION_SECRET=... # openssl rand -base64 32 — signs the session cookie
TOKEN_ENCRYPTION_KEY=... # openssl rand -base64 32 — seals Drive refresh tokens
APP_URL は任意です(リクエストから読み取れない場合に指定する公開オリジンです)。
アシスタントの接続(MCP)
chowdown は https://<your-domain>/mcp にある MCP サーバーで、MCP の認可仕様の規定に従って OAuth 2.1 で保護されています。この URL を ChatGPT、Claude、または任意の MCP クライアントのコネクターとして追加し、求められたら Google でサインインして、接続を承認してください。コピーするシークレットはありません。利用者は Google Drive に接続済みである必要があります(上記を参照)。接続するまでは、空のコレクションを表示する代わりに、その旨がアシスタントに伝えられます。
chowdown は MCP Registry に io.github.mridang/chowdown として登録されています。登録情報は、このリポジトリ内の server.json です。
- スコープ:
recipes:read(閲覧と検索)とrecipes:write(追加、編集、タグ付け、お気に入りへの追加、注釈)。アシスタントには読み取り専用の権限を付与できます。 - 料理の相談:
browse_recipes(「インド料理を作りたい」「30 分以内でできるベジタリアン料理」など)、recipes_from_ingredients(「トマトが 3 個とパスタが 400 g あります」と入力すると、今すぐ作れるものと、あと材料が 2、3 個あれば作れるものが返されます)、list_filters。すべてのレシピは材料に基づいて、ビーガン、ベジタリアン、ペスカタリアン、または非ベジタリアンに分類されるため、食事の条件でグループ化や絞り込みができます。既存のレシピにも、タグを付け直さずにこの分類が適用されます。 - 検出:
/.well-known/oauth-protected-resource/mcp(RFC 9728)と/.well-known/oauth-authorization-server(RFC 8414)。 - クライアント登録: Client ID Metadata Documents(推奨)と動的登録(
/oauth/register、RFC 7591)。パブリッククライアントのみ対応し、PKCES256が必須です。 - トークン: 不透明なトークンをハッシュ化して保存します。アクセストークンの有効期間は 1 時間です。リフレッシュトークンは使用するたびにローテーションされ、古いトークンを再利用すると接続全体が無効になります。
- 接続解除: アプリ内の「接続済みアプリ」から行うか、
POST /oauth/revokeを実行してください。
REST API
アプリのデータは /api 配下の REST API から利用できます。Zalando RESTful API ガイドラインに沿って設計されており(複数形の名詞、snake_case の JSON、RFC 9457 の問題詳細、カーソルページネーション、JSON Merge Patch、ETag / If-Match、X-Flow-ID)、意図的に異なる点は /api プレフィックスと、ハイフンを含まないパスセグメント(recipe-imports ではなく recipes/imports)です。
| リソース | メソッド |
|---|---|
/api/recipes, /api/recipes/{recipe_id} | 一覧、作成 · 読み取り、置換、パッチ、削除 |
/api/recipes/{recipe_id}/notes[/{note-id}] | 一覧、作成 · 読み取り、置換、削除 |
/api/recipes/{recipe_id}/similar | 一覧 |
/api/recipes/suggestions?q= | 一覧 |
/api/recipes/imports[/{import-id}] | 一覧、作成 · 読み取り、削除 |
/api/users/self | 読み取り、パッチ |
/api/users/self/favourites[/{recipe_id}] | 一覧 · 読み取り、設定、削除 |
/api/users/self/connections[/{grant_id}] | 一覧 · 削除 |
/api/sessions/self | 削除(サインアウト) |
認証には署名付きセッションクッキーを使用します。書き込みはアプリ自身のページから行う必要があります(クロスサイトの書き込みは 403 になります)。サインインしても Google Drive には接続されません。ブラウザーで接続するまでは、書き込みと /api/recipes/suggestions は 409 /problems/drive-not-connected を返します。リソースではないものはすべて API の対象外です。MCP(/mcp)、OAuth(/oauth/*、/.well-known/*)、Google のサインインと Drive 接続のリダイレクト(/auth/*)、ヘルスチェック(/health)、画像プロキシ(/img)、CSP レポート(/csp/reports)が該当します。
ローカル開発
すべてのコマンドは、Node 24 を固定する devbox 経由で実行します。
devbox run -- npx wrangler login # once: the AI binding is remote-only in dev
devbox run -- npm run migrate # apply D1 migrations to the local database
devbox run -- npm run build:views # once, and after changing src/views: the generated widget pages
devbox run -- npm run dev # next dev on http://localhost:3737
devbox run -- npm test # jest, including the MCP conformance suite
devbox run -- npm run lint # eslint
devbox run -- npm run typecheck # tsc --noEmit
devbox run -- npm run format # prettier
サインインする前に、Google の設定に記載されているシークレットを .env(Git で追跡されません)に設定してください。Google OAuth では localhost の http が許可されるため、http://localhost:3737 に証明書は不要です。OAuth クライアントのリダイレクト URI に http://localhost:3737/auth/callback を追加してください。
デプロイ
# one-time per environment
devbox run -- npx wrangler d1 create chowdown-db # paste the id into wrangler.jsonc
devbox run -- npx wrangler d1 migrations apply DB --remote
devbox run -- npx wrangler secret put GOOGLE_OAUTH_CLIENT_ID
devbox run -- npx wrangler secret put GOOGLE_OAUTH_CLIENT_SECRET
devbox run -- npx wrangler secret put SESSION_SECRET
devbox run -- npx wrangler secret put TOKEN_ENCRYPTION_KEY
# every release
devbox run -- npm run deploy # opennextjs-cloudflare build && wrangler deploy
カスタムドメイン chowdown.apps.mrida.ng には、Cloudflare アカウントの apps.mrida.ng ゾーンが必要です。また、Worker には AI と Images のバインディングが必要です(wrangler.jsonc で宣言されています)。
GitHub Actions(deploy.yml)は、D1 のマイグレーションを適用し、master へのプッシュ時にデプロイします。production 環境に CLOUDFLARE_API_TOKEN シークレットと CLOUDFLARE_ACCOUNT_ID 変数が必要です。
運用
設定。 SESSION_SECRET はセッション Cookie に署名し、TOKEN_ENCRYPTION_KEY
は Drive のリフレッシュトークンを暗号化します。どちらも Worker シークレットです。APP_URL は公開オリジンです。リクエストの Host ヘッダーからオリジンが読み取られるため、本番環境では設定してください。MCP_ALLOWED_ORIGINS(カンマ区切りの完全一致オリジン。例:chrome-extension://abcdef)を設定すると、ブラウザベースまたは WebView の MCP クライアントが /mcp を呼び出せます。サーバー上で動作するアシスタントの場合は、設定しないでください。
レート制限。 コストの低い順に、次の 3 層で制限します。
- Cloudflare Workers の Rate Limiting バインディング(
wrangler.jsoncのratelimitsに 13 個)は、アプリの実行前に Worker 内でチェックされます。各バインディングの対象となるリクエストはsrc/lib/http/edge-limits.tsに記載されており、テストで両者の整合性を確認しています。これらは Cloudflare のロケーションごとに適用され、最終的に整合します。大量リクエストを拒否するためのコストガードであり、計数システムではありません。必要に応じて、Cloudflare WAF のレート制限ルールを追加で設定できます(ダッシュボード:Security、WAF、Rate limiting rules)。これにより、Worker が呼び出される前に大量リクエストを止められます。 - D1 で正確かつ永続的にカウンターを記録します。対象は、OAuth クライアントの登録、トークンエンドポイント、ユーザーごとの MCP 呼び出し、インポート、提案、モデルを呼び出すアシスタントツールの日次上限です(
src/lib/util/daily-budget.ts)。 - リクエスト内で上限を設けます。インポートごとにリンクまたはレシピを 10 件まで、本文サイズ、ページと画像のバイト数、Cooklang の行数を 5,000 行までに制限します。
拒否された呼び出しには、Retry-After を付けて 429 を返します。
チェック。 devbox run -- npm test は、2026-07-28 および 2025-11-25 のリクエスト処理を対象に、公式 MCP 適合性テストスイートを実行します(test/e2e/mcp.e2e.test.ts。既知の未対応項目とその理由も記載されています)。MCP 2024-11-05 のクライアントはストリーミング可能な HTTP のみで動作します(HTTP+SSE トランスポートは提供していません)。
エージェントスキル
スキルは、AI エージェントがタスクを最初から最後まで実行するために読み込めるフォルダーです。オープンな Agent Skills 形式(SKILL.md とヘルパースクリプト)に準拠しているため、Claude Code、Cowork、GitHub Copilot など、スキルを読み込めるエージェントで動作します。
| スキル | 機能 |
|---|---|
import-bookmarked-recipes | ブラウザーのブックマークからレシピのリンクを見つけ、MCP コネクターを通じて chowdown にインポートし、欠けているカバー写真を補い、結果を確認します。インポートしたブックマークを削除するのは、あなたが承認した後だけです。スケジュールに従って(「レシピを定期的にインポートして」など)実行することもできます。その場合はインポートのみ行い、削除はしません。 |
インストールするには、フォルダーをエージェントのスキルフォルダーにコピーするか、シンボリックリンクを作成します。
# Claude Code (all projects)
ln -s "$PWD/skills/import-bookmarked-recipes" ~/.claude/skills/import-bookmarked-recipes
# GitHub Copilot (this repository)
mkdir -p .github/skills && cp -R skills/import-bookmarked-recipes .github/skills/
Cowork では、フォルダーを ZIP 形式にしてカスタムスキルとしてアップロードします。このスキルを使うには、chowdown を MCP コネクターとしてエージェントに追加する必要もあります。ホームページまたはアプリの「Cook with AI」ページにある MCP サーバーのアドレスを使用し、接続を承認してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。