MCP server for BBC Good Food. List the axes a recipe search can be narrowed by, with counts. No API key.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
claude mcp add mcp-bbc-goodfood -- npx -y mcp-bbc-goodfood{
"mcpServers": {
"mcp-bbc-goodfood": {
"command": "npx",
"args": ["-y", "mcp-bbc-goodfood"]
}
}
}MCP Servers overview
# mcp-bbc-goodfood
[](https://www.npmjs.com/package/mcp-bbc-goodfood)
[](https://github.com/smeet666/mcp-bbc-goodfood/actions/workflows/ci.yml)
[](./LICENSE)
[](https://registry.modelcontextprotocol.io/v0/servers?search=io.github.smeet666/mcp-bbc-goodfood)
[](https://glama.ai/mcp/servers/smeet666/mcp-bbc-goodfood)
[](https://cursor.com/en/install-mcp?name=bbc-goodfood&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIm1jcC1iYmMtZ29vZGZvb2QiXX0%3D)
[](https://insiders.vscode.dev/redirect/mcp/install?name=bbc-goodfood&config=%7B%22name%22%3A%22bbc-goodfood%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22mcp-bbc-goodfood%22%5D%7D)
An MCP server that reads recipes on [BBC Good Food](https://www.bbcgoodfood.com).
Read-only, no API key, no account.
_[Version française](#mcp-bbc-goodfood-français)_
---
## Why it exists
BBC Good Food accepts any value on a search facet, and answers one it does not
know with a total of zero. Ask for `glutenfree` instead of `gluten-free` and the
site says nothing matches, with the same confidence it says 48 recipes match the
correct spelling. A model that guesses a spelling gets a confident absence
instead of a refusal.
This server publishes the vocabulary, so the question can be asked properly.
## The tools
### `list_filters`
Lists the axes a recipe search can be narrowed along, with the values each one
takes and how many recipes carry them.
| Argument | Type | Meaning |
| -------- | ---------------- | --------------------------------------------------------------------------------- |
| `query` | string, optional | Measure the counts inside this search. Leave it out for the site's whole listing. |
The site counts its facets over the rows a search returns, so the two answer
different questions. Within `chicken`, `diet` reports `gluten-free 48`. Across
the whole listing it reports `gluten-free 2810`. Neither is comparable to the
other, and the answer says which scope it measured.
```json
{
"query": "chicken",
"filters": [
{
"name": "diet",
"label": "Diets",
"options": [{ "value": "gluten-free", "label": "Gluten-free", "count": 48 }],
"option_count": 10
}
],
"filter_count": 9,
"total_available": 363,
"total_is_ceiling": false,
"source": "BBC Good Food",
"notes": ["…"]
}
```
### `search_recipes`
Searches recipes and returns a listing. Every row carries the path of its page,
which is what `get_recipe` reads.
| Argument | Type | Meaning |
| ----------------------------------------------------------------- | ----------------- | --------------------------------------------------- |
| `query` | string | A dish, an ingredient, a technique. |
| `limit`, `page` | integer, optional | Rows per page and which page. Defaults to 30 and 1. |
| `sort` | string, optional | How the site orders the listing. |
| `diet`, `cuisine`, `meal_type`, `difficulty` | string, optional | A value `list_filters` publishes. |
| `max_total_minutes`, `max_calories`, `min_servings`, `min_rating` | number, optional | A bound on the recipe. |
| `exclude_premium` | boolean, optional | Leave out what sits behind the site's subscription. |
The site accepts any value on a facet and answers one it does not know with a
total of zero, so a guessed spelling comes back as a confident absence rather
than as a refusal. Call `list_filters` first.
### `get_recipe`
Reads one recipe: its ingredients, its steps, its times, its rating and its
nutrition.
| Argument | Type | Meaning |
| ---------- | ----------------- | ---------------------------------------------------------- |
| `id` | string | The page's own path, as a `search_recipes` row carries it. |
| `servings` | integer, optional | Put the ingredients to this many people. |
A recipe behind the site's subscription comes back with everything except its
ingredients and its steps, and says so. The page carries them, which is exactly
why the rule exists: reading past a wall the site put in front of its own
readers would make this server the way around it.
### `scale_ingredients`
Puts a list of ingredient lines to a different number of people, without reading
anything on the site.
| Argument | Type | Meaning |
| ------------------------------ | ----------------- | ------------------------------------------------ |
| `ingredients` | string[] | The lines to scale, as a recipe writes them. |
| `factor` | number, optional | What to multiply every quantity by. |
| `from_servings`, `to_servings` | integer, optional | The two ends of the change, instead of a factor. |
```json
{
"factor": 0.5,
"ingredients": [
{
"text": "100 g plain flour",
"original": "200g plain flour",
"scaling": "scaled",
"amount": 100,
"amount_max": null,
"unit": "g"
},
{
"text": "2 eggs",
"original": "3 eggs",
"scaling": "rounded",
"amount": 2,
"amount_max": null,
"unit": null
},
{
"text": "salt and pepper",
"original": "salt and pepper",
"scaling": "unscaled",
"amount": null,
"amount_max": null,
"unit": null
}
],
"scaled_count": 1,
"rounded_count": 1,
"unscaled_count": 1,
"source": "BBC Good Food",
"notes": ["…"]
}
```
## What the answers refuse to overstate
**The published values are a shortlist.** The site shows the ten most frequent
values on an axis and accepts others it never lists: `cuisine=mexican` narrows a
search to 306 recipes without appearing among the ten. The answer says the list
is an excerpt rather than calling it the set of accepted values, because a
server that called it that would refuse values that work.
**A total can be a floor.** The site serves at most 10 000 rows for one search
and stops there. A total landing exactly on that figure was cut, so it states a
floor rather than a count, and `total_is_ceiling` says so.
**A count the site published nothing for is `null`, never `0`.** On a scale that
starts at zero the two would be indistinguishable. A rating runs from one star to
five, so a recipe nobody has rated comes back as `null` rather than as a recipe
rated zero.
**A recalculated quantity says that it was recalculated.** The figures a scaled
list carries are this server's arithmetic and not the site's, and every line says
under `scaling` whether the arithmetic landed exactly or whether the figure moved
to stay usable in a kitchen. Three eggs halved come back as two, because half an
egg is not an amount a kitchen measures out; a cook told `2` deserves to know
which of the two happened.
**A quantity is said in the unit that states it exactly.** Two grams divided by
ten come back as 200 mg, and two hundred grams multiplied by twenty come back as
4 kg. A figure only moves up the ladder when the larger unit states it exactly:
1875 g reads 1.875 kg, and 7492.5 g stays in grams because 7.4925 kg would need a
fourth decimal. A cook who cannot weigh the figure back is worse served by the
shorter one.
**A recipe whose page states no servings cannot be put to a number of people.**
The `servings` argument is then left without effect and a note says so, because
the multiplication would have to start from a figure the site never wrote.
## Install
```bash
npx mcp-bbc-goodfood
```
### Claude Code
```bash
claude mcp add bbc-goodfood -- npx -y mcp-bbc-goodfood
```
### Any MCP client
```json
{
"mcpServers": {
"bbc-goodfood": {
"command": "npx",
"args": ["-y", "mcp-bbc-goodfood"]
}
}
}
```
### Container
```bash
docker build -t mcp-bbc-goodfood .
docker run -i --rm mcp-bbc-goodfood
```
The container needs to reach `www.bbcgoodfood.com` and nothing else. It takes no
credentials, because there are none to take.
## Settings
Every setting is an environment variable, and none is required. A value outside
its range is refused with a line on stderr and the default stands: a setting that
cannot take effect says so rather than being quietly clamped.
| Variable | Default | Range |
| ----------------------- | ------- | ---------------------------------------------------------------------------------- |
| `BGF_USER_AGENT` | — | Your own identifier. This project's stays appended, so the site can reach a human. |
| `BGF_MIN_INTERVAL_MS` | 1500 | 1000 to 60000 |
| `BGF_TIMEOUT_MS` | 20000 | 1000 to 120000 |
| `BGF_MAX_RETRIES` | 3 | 0 to 8 What people ask about mcp-bbc-goodfood
What is smeet666/mcp-bbc-goodfood?
+
smeet666/mcp-bbc-goodfood is mcp servers for the Claude AI ecosystem. MCP server for BBC Good Food. List the axes a recipe search can be narrowed by, with counts. No API key. It has 0 GitHub stars and its last recorded update is dated 2026-08-27.
How do I install mcp-bbc-goodfood?
+
You can install mcp-bbc-goodfood by cloning the repository (https://github.com/smeet666/mcp-bbc-goodfood) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is smeet666/mcp-bbc-goodfood safe to use?
+
Our security agent has analyzed smeet666/mcp-bbc-goodfood and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains smeet666/mcp-bbc-goodfood?
+
smeet666/mcp-bbc-goodfood is maintained by smeet666. The last recorded GitHub activity is dated 2026-08-27, with 1 open issues.
Are there alternatives to mcp-bbc-goodfood?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy mcp-bbc-goodfood to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/smeet666-mcp-bbc-goodfood)<a href="https://claudewave.com/repo/smeet666-mcp-bbc-goodfood"><img src="https://claudewave.com/api/badge/smeet666-mcp-bbc-goodfood" alt="Featured on ClaudeWave: smeet666/mcp-bbc-goodfood" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!