chef-romaine-mcp
A Model Context Protocol server that gives an AI assistant access to your Chef Romaine pantry, shopping list and meal plan — so it can answer "what's in, what's low, what's planned" and make changes, without you opening the app.
It authenticates as you, through your browser. Row Level Security applies, so an assistant can only ever see your household.
Quick start
npx chef-romaine-mcp login
That prints a link. Open it, sign in to Chef Romaine, and approve. The token is stored at ~/.config/chef-romaine/session.json (permissions 0600) and refreshed automatically.
Then add it to your MCP client:
OpenCode
{
"mcp": {
"servers": {
"chef-romaine": {
"type": "local",
"command": ["npx", "-y", "chef-romaine-mcp"]
}
}
}
}
Claude Desktop / any mcpServers client
{
"mcpServers": {
"chef-romaine": {
"command": "npx",
"args": ["-y", "chef-romaine-mcp"]
}
}
}
No API keys or URLs to configure — the public app details are built in.
Authentication
OAuth 2.1 with PKCE, through Chef Romaine's own sign-in. No password is typed into a terminal, and no secret key is involved.
npx chef-romaine-mcp loginstarts a listener on127.0.0.1:43127and prints an authorisation link.- You sign in in a real browser, so captcha and MFA work.
- You approve on a consent screen that names the client and what it can access.
- The browser returns to the local listener, which exchanges the code for tokens.
Tokens are ordinary Supabase JWTs. Revoking access: delete ~/.config/chef-romaine/session.json.
Tools
| Tool | Arguments | Description |
|---|---|---|
household_context |
— | Household id, store, dietary restrictions, pantry counts. Call first. |
pantry_list |
search?, location?, expiring_within_days?, include_archived?, limit? |
Pantry items, capped at 50 rows. |
pantry_add |
name, quantity?, expires_at?, location? |
Adds stock; merges with an existing item of the same name. |
pantry_set |
id, quantity? | stock_state? | expires_at? |
Set a count, a staple level (full/low), or the expiry date (YYYY-MM-DD, or null to clear). quantity: 0 archives the item and records it as eaten. |
shopping_list |
— | Open items. |
shopping_list_add |
names[] |
Add names, skipping duplicates already open. |
shopping_list_check |
name |
Tick an item off. |
meal_plan_week |
week_start? |
Slots for the week containing that date (defaults to this week). |
Resources
| URI | Contents |
|---|---|
chef://pantry |
Up to 200 live items as compact text. |
chef://shopping-list |
Open items as a bullet list. |
Prefer resources for "show me everything"; use tools to filter or to write.
Data semantics
Things an assistant should not get wrong:
- Deleting means eaten. There is no "eaten vs binned" prompt. Archiving records a
consumedevent. - Staples are
full/low, not counts. Milk, rice, coffee and similar are replenished before they run out, so a number would be false precision. Out of stock means the item is archived and on the list. - Counted items are perishables bought per meal; the count is meaningful there.
- Counts are purchase accumulators, not stock levels. Re-scanning a receipt adds to them, so a high count can be stale. Treat it as a signal.
- The household is never passed in. It comes from your authenticated profile and is enforced by RLS.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
No session |
Not logged in, or the file was deleted | npx chef-romaine-mcp login |
invalid redirect_uri |
The app's registered redirect changed | Re-run login; the port must be 43127 (or set CHEF_OAUTH_PORT to match) |
Error generating ID token |
Should not occur — the client no longer requests openid |
Update to the latest version |
| Empty results | Signed in as a user with no household | Check household_context |
401 on every call |
Session revoked | Log in again |
Security
- Tokens are short-lived Supabase JWTs refreshed on start; RLS decides what they can see.
- No service-role key is used or required.
- The session file is
0600in your home directory. Treat it as a password. - Deleting the file forgets the session locally; remove the connection from your Chef Romaine account to revoke it fully.
Limitations
- Dinner-only meal plan. Lunch slots exist in the schema but nothing writes them yet.
- No recipe or nutrition tools yet.
- stdio transport only — the server runs on your machine, not as a remote endpoint.
- One household per user, matching the app.
Licence
MIT — see the LICENSE file in the package. Use it, fork it, ship it. The Chef Romaine name and logo are not covered by the licence.