chowdown
io.github.mridang由 GitHub 账号 mridang 发布v0.1.0更新于 Oct 24, 2026
Your recipes as plain files in your own Google Drive, searchable by your AI assistant.
概览
Chowdown 是一个远程 MCP 服务器,让助手浏览、搜索和编辑存放在你自己 Google Drive 中的 Cooklang 食谱。
- 可以做什么
- 按菜系、饮食类型或时长浏览和搜索食谱,并列出可用筛选条件
- 根据手头食材找出能做的菜,以及只差一两样食材的菜
- 新增、编辑、打标签、收藏和添加备注食谱,支持只读或读写权限
- 从链接导入食谱,并列出相似食谱或建议
- 适用场景
- 适合把食谱以 Cooklang 文件保存在 Google Drive 中的人,让助手回答今晚做什么、冰箱里的食材能做什么,或把新找到的食谱归档。
- 运行要求
- 需要远程端点 chowdown.apps.mrida.ng/mcp,通过 Google 的 OAuth 2.1 登录,无需复制密钥。使用食谱工具前还须在应用内单独连接 Google Drive(drive.file 权限)。授权时可选择只读或读写权限。
安装
在 SourceWeft 中
- 打开 控制台中的 chowdown,将其添加到工作区。
- 连接 所需的 凭据。它们会被私密存储,绝不会在公开页面上展示。
- 为需要使用其工具的对话启用该服务。
Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。
交给智能体安装
把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。
阅读 https://sourceweft.com/mcp/io.github.mridang%2Fchowdown/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。其他 MCP 客户端
把它添加到你客户端的 mcpServers 配置中。 客户端会在首次连接时完成 OAuth 登录。
{
"mcpServers": {
"chowdown": {
"type": "http",
"url": "https://chowdown.apps.mrida.ng/mcp"
}
}
}README
🍳 Chowdown
A recipe app for Cooklang .cook files, kept in the
person's own Google Drive. Built as a Next.js app on Cloudflare Workers (OpenNext).
The Cloudflare Worker does the real work: Google sign-in, a separate "Connect Google Drive" step, syncing the Recipes folder into a D1 cache, the REST API, the MCP server (with its OAuth 2.1 endpoints) and the model calls for tagging and "find similar" (Workers AI). Drive stays the source of truth; D1 is a cache so pages render in one round trip.
Stack
- Next.js 16 (App Router), React 19 and Tailwind 4, on Cloudflare Workers via OpenNext (
@opennextjs/cloudflare) - D1 with Drizzle, plus the Workers AI and Images bindings
- devbox pins Node 24
- Jest for unit tests, Cypress for end-to-end tests
@mridang/eslint-defaultsfor linting@cooklang/cooklang-tsfor parsing
Google setup
Signing in and connecting Google Drive are two separate steps, each with its own Google consent screen:
- Sign in asks for identity only (
openid email profile). It creates the account and a signed session cookie, and nothing else. - Connect Google Drive (the button in the header, the account menu, and on
pages that need it;
GET /auth/drive) adds thedrive.filescope and an offline refresh token, then creates the app-managed "Recipes" folder.drive.fileis non-sensitive and only reaches files Chowdown created, so there is no Google verification and nothing is published to the Marketplace.
Until Drive is connected a person can look around and see anything already
cached, but anything that reads or writes their Drive files is refused (the REST
API answers 409 /problems/drive-not-connected, MCP tools return an error
result that says what to do).
Set up in Google Cloud:
- Enable the Google Drive API.
- OAuth consent screen: External, add the
.../auth/drive.filescope, add your Gmail as a test user (or publish to production — still review-free). - OAuth client ID (Web application) → Authorized redirect URIs:
http://localhost:3737/auth/callback(dev)https://chowdown.apps.mrida.ng/auth/callback(prod)
Secrets, in .env locally and wrangler secret put <NAME> in production (see Deploy):
APP_URL is optional (the public origin, if it can't be read from the request).
Connecting an assistant (MCP)
Chowdown is an MCP server at https://<your-domain>/mcp, protected with
OAuth 2.1 as the MCP authorization spec
describes. Add that URL as a connector in ChatGPT, Claude or any MCP client, sign
in with Google when asked, and approve. There is no secret to copy. The person
needs to have connected Google Drive (see above); until then the assistant is
told so instead of being shown an empty collection.
Chowdown is listed in the MCP Registry
as io.github.mridang/chowdown; the listing is server.json in this repository.
- Scopes:
recipes:read(browse and search) andrecipes:write(add, edit, tag, favourite, annotate). An assistant can be granted read only. - Asking what to cook:
browse_recipes("I feel like cooking Indian", "something vegetarian under 30 minutes"),recipes_from_ingredients("I have 3 tomatoes and 400 g of pasta" returns what can be cooked now and what is a couple of ingredients short) andlist_filters. Every recipe is classed as vegan, vegetarian, pescatarian or non-vegetarian from its ingredients, so results can be grouped and filtered by diet; existing recipes get this without being re-tagged. - Discovery:
/.well-known/oauth-protected-resource/mcp(RFC 9728) and/.well-known/oauth-authorization-server(RFC 8414). - Client registration: Client ID Metadata Documents (preferred) and dynamic
registration (
/oauth/register, RFC 7591). Public clients only, PKCES256required. - Tokens: opaque, stored hashed. Access tokens last an hour; refresh tokens rotate on every use, and reusing an old one revokes the whole connection.
- Disconnect: "Connected apps" in the app, or
POST /oauth/revoke.
REST API
The app's data is available as a REST API under /api, designed to the
Zalando RESTful API guidelines
(plural nouns, snake_case JSON, RFC 9457 problem details, cursor pagination,
JSON Merge Patch, ETag / If-Match, X-Flow-ID). The deliberate departures are
the /api prefix and path segments without hyphens (recipes/imports, not
recipe-imports).
Auth is the signed session cookie. Writes must come from the app's own pages
(cross-site writes get 403). Signing in does not connect Google Drive: writes
and /api/recipes/suggestions answer 409 /problems/drive-not-connected until
the person has connected it in the browser. Everything that is not a resource stays out
of the API: MCP (/mcp), OAuth (/oauth/*, /.well-known/*), the Google
sign-in and Drive-connection redirects (/auth/*), the health check (/health), the
image proxy (/img), CSP reports (/csp/reports).
OpenAPI
openapi.json at the root of the repository describes exactly
the routes under src/app/api, nothing else. test/openapi.test.ts fails when
the two drift: every exported METHOD /path must be an operation and the other
way round, a public operation must answer without a session and a secured one
must answer 401, bad input must answer a documented status as
application/problem+json, and good answers must fit their schemas.
Testing the API with Schemathesis
Every operation can be called by one ordinary signed-in account; there is no
administrator role. Sign in with Google in a browser, connect Google Drive once
(until then the operations that read or write recipe files answer 409), and
copy the value of the chowdown_session cookie from the browser's developer
tools into an environment variable. Then run, against a local or deployed
instance:
Leave the last two operations out of a long run: they delete the account and
end every session, so the account is gone after the first call. The requests
Schemathesis generates carry no Sec-Fetch-Site or Origin header, which the
cross-site check lets through; they count against the platform's rate limits
and the daily allowances of importing and suggesting, so expect some 429s
with Retry-After.
Local development
All commands go through devbox, which pins Node 24:
Put the secrets listed under Google setup in .env (gitignored) before signing in. http://localhost:3737 needs no certificate, because Google OAuth allows http for localhost: add http://localhost:3737/auth/callback to the OAuth client's redirect URIs.
Deploy
The custom domain chowdown.apps.mrida.ng requires the apps.mrida.ng zone on the Cloudflare account, and the Worker needs the AI and Images bindings (declared in wrangler.jsonc).
GitHub Actions (deploy.yml) applies the D1 migrations and deploys on pushes to master. It needs a CLOUDFLARE_API_TOKEN secret and a CLOUDFLARE_ACCOUNT_ID variable in the production environment.
Operations
Settings. SESSION_SECRET signs the session cookie and TOKEN_ENCRYPTION_KEY
seals Drive refresh tokens; both are Worker secrets. APP_URL is the public
origin: set it in production, because when it is missing the origin is read from
the request's Host header. MCP_ALLOWED_ORIGINS (comma-separated, exact
origins such as chrome-extension://abcdef) lets a browser-based or webview MCP
client call /mcp; leave it unset for assistants that run on a server.
Rate limits. Three layers, cheapest first:
- Cloudflare Workers Rate Limiting bindings (
ratelimitsinwrangler.jsonc, thirteen of them), checked in the Worker before the app runs. Which request counts against which binding is insrc/lib/core/http/edge-limits.ts, and a test keeps the two in step. They are per Cloudflare location and eventually consistent: a cost guard that refuses floods, not an accounting system. Optionally add one Cloudflare WAF rate-limiting rule on top (dashboard: Security, WAF, Rate limiting rules) to stop a flood before the Worker is invoked at all. - Exact, durable counters in D1: OAuth client registration, token endpoint,
per-user MCP calls, and the daily budgets for imports, suggestions
and the assistant tools that call a model (
src/lib/util/daily-budget.ts). - Hard caps inside a request: ten links or recipes per import, body sizes, page and image byte caps, 5,000 Cooklang lines.
A refused call answers 429 with Retry-After.
Checks. devbox run -- npm test runs the official MCP conformance suite against the
server's request handling for 2026-07-28 and 2025-11-25
(test/e2e/mcp.e2e.test.ts, which also lists the known gaps with their
reasons). MCP 2024-11-05 clients work over
streamable HTTP only (no HTTP+SSE transport is hosted).
Agent skills
Skills are folders an AI agent can load to carry out a task end to end. They
follow the open Agent Skills format (a SKILL.md plus helper scripts), so they
work in Claude Code, Cowork, GitHub Copilot and other agents that read it.
To install one, copy or symlink its folder into your agent's skills folder:
In Cowork, upload the folder (zipped) as a custom skill. The skill also needs Chowdown added to the agent as an MCP connector: use the MCP server address on the home page or the app's "Cook with AI" page, then approve the connection.
来源:README.md,提交 a11b214
工具
0版本历史
1- v0.1.0最新Oct 24, 2026
评分
已满足适用检查项的 85%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通必需25 分
- 已声明认证方式必需10 分
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分