umami-recipes-mcp
The Umami Recipes MCP server provides tools to manage recipes and recipe books on the Umami Recipes platform, including: listing recipe books, listing tags with usage counts, finding recipes by name/ingredient/direction/note/URL/time/tag with optional tag filters and result limits, retrieving full recipe details, creating recipes (with name, ingredients, directions, notes, tags, timings, servings, nutrition, visibility, source URL), editing recipes (partial updates, tags fully replaced if provided), and uploading JPEG/PNG/WebP photos (up to 10 MB) from HTTPS URLs or base64 data.
Provides tools for interacting with Umami Recipes, enabling management of recipe books and recipes (listing, searching, reading, creating, editing) and uploading recipe photos.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@umami-recipes-mcpFind vegetarian recipes with mushrooms that take less than 30 minutes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Umami Recipes MCP
An MCP server for Umami Recipes that can:
list the recipe books available to your account;
find recipes by name, ingredient, direction, note, URL, time, or tag;
read a complete recipe;
create recipes, including ingredients, directions, notes, tags, times, source URL, visibility, and nutrition fields;
edit selected recipe fields while preserving everything omitted.
upload JPEG, PNG, or WebP photos to existing recipes from an HTTPS URL or base64 image data.
It supports two deployment modes:
a remote, stateless Streamable HTTP server on Cloudflare Workers at
/mcp;a local stdio server for desktop MCP clients.
The implementation uses the same Firebase project, Firestore collections, document shapes, validation limits, and atomic recipe/tag bookkeeping as Umami's current web client. It never exposes a delete tool.
Install and verify
npm install
npm test
npm run build
npm run deploy:dry-runRelated MCP server: mealie-mcp
Deploy to Cloudflare
The Worker uses OAuth 2.1 authorization code flow with PKCE. Its
MCP_ACCOUNT_MAP secret contains named account entries, and each entry maps a
unique browser login code to one Umami Firebase refresh token:
{
"personal": {
"loginCode": "a-long-random-code-for-personal",
"umamiRefreshToken": "the-personal-firebase-refresh-token"
},
"family": {
"loginCode": "a-different-long-random-code-for-family",
"umamiRefreshToken": "the-family-firebase-refresh-token"
}
}The names are only labels for maintaining the configuration. During OAuth
authorization, entering the personal login code creates a grant that can only
operate as the mapped personal Umami account. Neither the login code nor the
Umami refresh token is included in the OAuth grant.
Copy the ignored account-map template, replace every placeholder, validate it, store the complete map as a Cloudflare secret, and deploy:
cp .mcp-accounts.example.json .mcp-accounts.json
npx wrangler login
npm run accounts:validate
npm run accounts:deploy
npm run deployaccounts:deploy reads .mcp-accounts.json, validates it, and sends it to
wrangler secret put MCP_ACCOUNT_MAP over standard input without printing the
credentials. Pass a different file after -- if needed, for example
npm run accounts:deploy -- .mcp-accounts.production.json. Account-map files
are ignored by Git. Cloudflare limits an individual secret to 5 KiB, so this
mechanism is intended for a small account registry.
The OAUTH_KV binding in wrangler.jsonc stores OAuth clients, grants, and
tokens. Wrangler provisions this KV namespace during deployment. If the Worker
was previously deployed with the fixed bearer-token version, the old
mcpToken field is accepted as a login code during migration; running
accounts:deploy rewrites it to loginCode.
Wrangler prints the deployed workers.dev hostname. The MCP endpoint is:
https://umami-recipes-mcp.<your-subdomain>.workers.dev/mcpThe Worker configuration in wrangler.jsonc uses the current compatibility date, nodejs_compat, generated binding types, required-secret validation, and Workers observability.
Obtain an Umami refresh token
If you have an Umami email/password login, the included helper exchanges those credentials directly with Firebase and prints a refresh token. To keep the password out of shell history in zsh:
read "UMAMI_EMAIL?Umami email: "
read -s "UMAMI_PASSWORD?Umami password: "
export UMAMI_EMAIL UMAMI_PASSWORD
npm run auth:refresh-token
unset UMAMI_EMAIL UMAMI_PASSWORDRepeat this for each Umami login and copy each printed value into the matching
umamiRefreshToken field in .mcp-accounts.json. Treat refresh tokens like
passwords and clear them from terminal scrollback when practical. Generate a
different long random loginCode for every account using a password manager.
Connect a remote MCP client
Configure a Streamable HTTP MCP client with the deployed URL. The client opens
the OAuth authorization page in your browser; enter the loginCode for the
Umami account that client should use.
Claude Code:
claude mcp remove umami-recipes 2>/dev/null || true
claude mcp add --transport http --scope user umami-recipes \
https://umami-recipes-mcp.<your-subdomain>.workers.dev/mcpRun /mcp inside Claude Code and choose umami-recipes to authenticate.
Codex CLI:
codex mcp remove umami-recipes 2>/dev/null || true
codex mcp add umami-recipes \
--url https://umami-recipes-mcp.<your-subdomain>.workers.dev/mcp
codex mcp login umami-recipesFor another OAuth-capable MCP client, the configuration contains only the URL:
{
"mcpServers": {
"umami-recipes": {
"url": "https://umami-recipes-mcp.<your-subdomain>.workers.dev/mcp"
}
}
}Clients that only support local stdio MCP servers can use the local stdio mode
below. OAuth-capable clients manage their own access and refresh tokens; do not
put the account login code in an Authorization header.
Local Worker development
Copy the example secrets file and replace the JSON placeholders. Add more named entries to test multiple accounts locally:
cp .dev.vars.example .dev.vars
npm run devThe local endpoint is normally http://localhost:8787/mcp. .dev.vars is ignored by Git.
Local stdio mode
For local use, choose one of these authentication configurations:
export UMAMI_REFRESH_TOKEN='your Firebase refresh token'
# Or sign in when the MCP first makes a request:
export UMAMI_EMAIL='you@example.com'
export UMAMI_PASSWORD='your Umami password'
# Or use a short-lived Firebase ID token:
export UMAMI_ID_TOKEN='your token'
export UMAMI_USER_ID='your Firebase user id' # only if absent from the tokenBuild and configure the stdio entrypoint in your MCP host:
{
"mcpServers": {
"umami-recipes": {
"command": "node",
"args": ["/absolute/path/to/umami-mcp/dist/index.js"],
"env": {
"UMAMI_REFRESH_TOKEN": "your-refresh-token"
}
}
}
}Run npm run dev:stdio for an unbuilt local development server.
Tools
list_recipe_books— returns book ids and names.list_recipe_tags— returns exact tag names and recipe counts across every accessible book, or one selected book.find_recipes— searches a bounded set of recently updated candidates across all accessible books, or one selected book.get_recipe— returns ingredients, directions, and notes as editable Markdown strings.create_recipe— creates a recipe and atomically updates the selected book's recipe/tag metadata.edit_recipe— patches only supplied fields; whentagsis supplied, it replaces the full tag list and atomically updates tag counts.add_recipe_photo— uploads one JPEG, PNG, or WebP image (up to 10 MB) from a public HTTPS URL or base64 data, then asks Umami to attach and process it.
Ingredients, directions, and notes are Markdown strings. Supported formatting is
paragraphs, headings, bold, italic, <u>underline</u>, HTTP(S) links, and flat
ordered or unordered lists. For example:
{
"name": "Tomato soup",
"ingredients": "- **500g** tomatoes\n- 1 onion",
"directions": "## Method\n\n1. Chop the vegetables.\n2. [Simmer gently](https://example.com/simmering).",
"notes": "Serve <u>hot</u>."
}Raw HTML other than <u>, images, tables, code blocks, task lists, and nested or
multi-paragraph lists are rejected because Umami has no equivalent rich-text
node. Omitting a field during an edit preserves it; supplying an empty string
clears it. Each Markdown field is limited to 50,000 characters.
Security model
The remote deployment supports a small registry of independent Umami accounts:
Clients use OAuth dynamic client registration and authorization code flow with S256 PKCE; a fixed login code is never accepted as an MCP bearer token.
Every login code maps to exactly one Umami refresh token, and duplicate login codes are rejected as invalid configuration. Code comparisons are designed to avoid timing leaks.
The browser authorization form is CSRF-protected and sends restrictive CSP, framing, caching, referrer, and permissions headers.
OAuth grant properties contain only the account label. Umami credentials stay in the Cloudflare secret and are looked up for each authenticated request.
OAuth clients, grants, access tokens, and refresh tokens are stored in
OAUTH_KV. Access tokens expire after one hour, while refresh tokens expire after 90 days; after the latter, the client authorizes again in the browser.Removing an account from
MCP_ACCOUNT_MAPimmediately prevents its existing grants from reaching Umami, even if an OAuth token remains in KV.Each MCP request creates fresh server and Umami authentication state; no request-specific state is stored globally.
Possession of an account's login code allows a person to authorize new clients with all exposed MCP capabilities for that mapped Umami account. Store each code in a password manager and rotate it if disclosed.
Development commands
npm test # Node protocol, OAuth, and Worker HTTP tests
npm run build # stdio build plus Worker type-check
npm run accounts:validate # validate the ignored account map
npm run accounts:deploy # publish it as the MCP_ACCOUNT_MAP secret
npm run types # regenerate Cloudflare binding types
npm run types:check # verify generated types are current
npm run deploy:dry-run # validate and bundle without deployingThe test suite covers OAuth login-code mapping and consent hardening, Umami authentication and rich-text conversion, Firestore values, recipe search/create/edit behavior, atomic tag bookkeeping, MCP v2 protocol discovery/invocation, and the Worker OAuth boundary.
Available Tools
5 toolscreate_recipeCreate an Umami recipeB
Create a new recipe in an accessible Umami recipe book. If exactly one book is accessible, recipeBookId may be omitted.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| tags | No | ||
| notes | No | ||
| public | No | ||
| servings | No | ||
| importUrl | No | ||
| totalTime | No | ||
| activeTime | No | ||
| directions | No | ||
| ingredients | No | ||
| recipeBookId | No | ||
| nutritionInformation | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosing behavior. It only mentions accessibility of the recipe book and the recipeBookId omission condition; it does not disclose return values, error behavior, side effects, or required permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the primary action, no redundant wording. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 12 parameters, no annotations, and no output schema, this description is severely under-specified. It lacks coverage of required fields, return value, error cases, and the meaning of most parameters, making it inadequate for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has 0% parameter description coverage, and the description only adds meaning to recipeBookId by specifying the condition for omission. The other 11 parameters are left undefined, leaving their semantics to be inferred solely from their names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Create') and resource ('new recipe in an accessible Umami recipe book'), clearly distinguishing it from sibling tools like edit_recipe, get_recipe, and find_recipes. The scope is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for creating new recipes but does not mention alternatives or exclusions. The conditional about recipeBookId provides some usage context, indicating when it may be omitted, but lacks a clear when-not-to-use statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
edit_recipeEdit an Umami recipeA
Edit selected fields of an existing Umami recipe. Omitted fields are preserved. Supplying tags replaces the recipe's full tag list.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | ||
| tags | No | ||
| notes | No | ||
| public | No | ||
| recipeId | Yes | ||
| servings | No | ||
| importUrl | No | ||
| totalTime | No | ||
| activeTime | No | ||
| directions | No | ||
| ingredients | No | ||
| nutritionInformation | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose key behavioral traits: fields are edited selectively, omitted fields are preserved, and providing tags replaces the entire tag list. It does not mention return values, permissions, or error behavior, but the disclosed traits go well beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose followed by concise behavioral notes. There is no redundant or filler content; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 12 parameters, nested objects, and no output schema or annotations, the description is somewhat incomplete. It covers the core update semantics but does not address what is returned, how missing recipeIds are handled, or the structure of nested fields like nutritionInformation. The information provided is adequate for basic use but not fully complete for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 0%, so the description must compensate. It adds important semantics about how tags behave (replacement) and clarifies the update model (preserve omitted fields), but it does not explain the purpose or format of individual parameters like nutritionInformation, importUrl, or public, leaving many params to be inferred from names and types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Edit selected fields of an existing Umami recipe,' which clearly states the verb (edit), resource (existing Umami recipe), and scope (selected fields). This distinguishes it from sibling tools like create_recipe (new recipe) and get_recipe (read-only).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'existing Umami recipe' implies this tool is for updates, contrasting with create_recipe, and 'Omitted fields are preserved' explains the partial-update behavior. However, it does not explicitly state exclusions or name alternative tools, so the guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_recipesFind Umami recipesA
Find recently updated recipes across accessible Umami recipe books. Searches a bounded set of candidates by name, ingredients, directions, notes, source URL, times, and tags.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Require every listed tag | |
| limit | No | ||
| query | No | Case-insensitive text to search for | |
| recipeBookId | No | Restrict results to one recipe book |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the search is limited to 'recently updated' recipes and a 'bounded set of candidates', offering some behavioral context. However, it does not state whether the operation is read-only, describe sorting or pagination, or mention side effects, leaving notable gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two concise sentences, front-loaded with the primary purpose and containing no redundant words. It efficiently conveys the search scope and supported fields without unnecessary details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has no annotations or output schema, making the description the main source of information. It provides a reasonable overview but leaves ambiguity around 'recently updated' (time window?) and 'bounded set' (how bounded?), and does not clarify return structure or default behavior like limit. For a search tool this may be adequate, but there are clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides descriptions for three of four parameters, and the description adds context about the fields searched (name, ingredients, directions, notes, source URL, times, tags). This complements the schema but does not add parameter-specific semantics beyond that, and the 'limit' parameter still lacks a schema description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: finding recipes by searching across multiple recipe books. It uses the specific verb 'Find' with a resource ('recipes') and mentions searchable fields. This distinguishes it from siblings such as get_recipe (single recipe retrieval) and list_recipe_books (book listing).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for searching recipes across books, but it does not explicitly say when to use it over alternatives like get_recipe or list_recipe_books, nor does it mention any exclusions. The context is clear from the tool name, but there is no direct guidance on selecting among the sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recipeGet an Umami recipeA
Get the full editable text fields for a recipe by id.
| Name | Required | Description | Default |
|---|---|---|---|
| recipeId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It adds the useful detail that the response contains 'full editable text fields', indicating what data is returned. However, it does not explicitly state read-only behavior, error handling (e.g., what happens if the ID doesn't exist), or any other behavioral traits. This is minimal but not empty.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the core functionality without any unnecessary words. Every element ('Get', 'full editable text fields', 'by id') earns its place. It is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id tool with one parameter, the description is reasonably complete. It specifies the action, the parameter's role, and the type of data returned. It lacks details like error responses or authorization requirements, but given the simplicity and lack of an output schema, the description provides sufficient context for an agent to use the tool correctly in most cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explicitly maps 'by id' to the 'recipeId' parameter, confirming its purpose. This gives the parameter clear meaning beyond the bare schema definition. The mention of 'editable text fields' also hints at the response shape, adding context for what the parameter leads to.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Get') and resource ('recipe') and identifies the retrieval method ('by id'). It clearly distinguishes this from sibling tools that list, search, create, or edit recipes. The phrase 'full editable text fields' further clarifies the scope of the response.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: this is for fetching a single recipe by its ID. It doesn't explicitly state when not to use it or name alternatives like find_recipes for searching, but the 'by id' qualifier implies that it's for direct ID lookup, which differentiates it from search tools. No explicit exclusions are given, so it earns a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_recipe_booksList Umami recipe booksA
List recipe books owned by or shared with the authenticated Umami account. Use this to obtain a recipeBookId before creating a recipe.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the transparency burden. It clarifies the access scope ('owned by or shared with') and the authentication requirement, and 'List' clearly implies a non-mutating read operation. It does not disclose output formatting or pagination, but that is a minor omission for a simple list tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler. The first states the action and resource, the second provides the usage context. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter listing tool with no output schema, the description is complete enough: it defines the resource scope, notes the authentication requirement, and explains the main use case (obtaining a recipeBookId for create_recipe). It does not list return fields in detail, but it names the key result value the agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool accepts zero parameters, so the baseline is 4. The description adds no parameter-level details, but none are needed. It instead tells the agent what the result is used for (obtaining a recipeBookId), which is more valuable here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'List' and identifies the exact resource: 'recipe books owned by or shared with the authenticated Umami account.' It also distinguishes from sibling recipe-focused tools by explaining that it provides the recipeBookId needed before creating a recipe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit use case: 'Use this to obtain a recipeBookId before creating a recipe,' which clearly signals when to call the tool. It does not explicitly state when not to use it or name alternatives, but sibling tool names like find_recipes and create_recipe make the boundary apparent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
create_recipe - First observed
edit_recipe - First observed
find_recipes - First observed
get_recipe - First observed
list_recipe_books
TDQS
Scored across 5 tools
Each tool targets a distinct action: listing books, searching recipes, retrieving a recipe, creating, and editing. There is no overlap; get_recipe retrieves a full recipe while find_recipes returns search candidates, and create/edit are clearly separated.
All tool names follow a consistent verb_noun pattern with lowercase and underscores: list_recipe_books, find_recipes, get_recipe, create_recipe, edit_recipe. The pattern is uniform and predictable.
With 5 tools, the server is well-scoped for a recipe management domain. Each tool covers a necessary operation without redundancy, fitting comfortably within the ideal 3-15 range.
The set covers listing books, searching, retrieving, creating, and editing recipes, but lacks a delete_recipe operation, which is a core CRUD gap. Additionally, find_recipes is search-focused rather than a straightforward list-all tool, which may limit listing by book.
Maintenance
Related MCP Connectors
Remote MCP server for supportsheep: run AI interviews and manage support content for your blog.
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Agent-native MCP server over the public saagarpatel.dev corpus. Read-only, stateless.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables creation and deployment of MCP servers on Cloudflare Workers, with local testing and one-command deployment.75MIT
- AlicenseNot gradedqualityAmaintenanceA read-only MCP server for Mealie that enables searching recipes, managing shopping lists, meal plans, and retrieving household/instance info via tools. Supports secure per-user authentication and multiple Mealie instances.MIT
- FlicenseAqualityBmaintenanceMCP server for Tandoor Recipes, enabling recipe management (create, edit, search, delete) and entity operations (foods, units, keywords) via natural language from Claude.11-
- AlicenseNot gradedqualityBmaintenanceDeployable stateless remote MCP server on Cloudflare Workers without auth, with support for registering custom tools and connecting to MCP clients.12MIT