PrijsProfeet MCP
Provides tools for querying live supermarket offers, products, and categories for Albert Heijn through the PrijsProfeet API.
Provides tools for querying live supermarket offers, products, and categories for Lidl through the PrijsProfeet API.
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., "@PrijsProfeet MCPcompare milk prices at Albert Heijn and Jumbo"
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.
prijsprofeet-mcp
A Dockerized MCP server for the PrijsProfeet API: live offers from 10 Dutch supermarket chains (Albert Heijn, Aldi, DekaMarkt, Dirk, Ekoplaza, Hoogvliet, Jumbo, Lidl, PLUS, Vomar) as one normalised JSON API.
The 26 tools are generated from the OpenAPI document at https://www.prijsprofeet.nl/openapi.json (a copy is
bundled in the image, because the live one sits behind Cloudflare and is not reachable from a server). Argument
schemas come from the spec; the tool names and descriptions are curated, because a good description is what stops
a model from quoting a price nobody is charging.
Quick start
docker build -t prijsprofeet-mcp .
docker run -i --rm -e PRIJSPROFEET_API_KEY prijsprofeet-mcpThat speaks MCP over stdio, so it wants to be run by an MCP client rather than by hand.
Related MCP server: PriceAtlas MCP Server
Wiring it into a client
The key is read from the PRIJSPROFEET_API_KEY environment variable and sent as the X-API-Key header.
stdio — the client launches the container
This is the default, and the right choice for a local Docker tool: no port, no auth surface, no network listener.
docker run -i --rm -e PRIJSPROFEET_API_KEY prijsprofeet-mcp:latestopencode
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"prijsprofeet": {
"type": "local",
"command": ["docker", "run", "-i", "--rm", "-e", "PRIJSPROFEET_API_KEY", "prijsprofeet-mcp:latest"],
"environment": { "PRIJSPROFEET_API_KEY": "{env:PRIJSPROFEET_API_KEY}" },
"enabled": true
}
}
}opencode prefixes tool names with the server name, so the tools arrive as prijsprofeet_pp_search,
prijsprofeet_pp_get_categories, and so on. Prompt with use the prijsprofeet tools to pull them in.
Claude Desktop / any stdio client
claude_desktop_config.json only accepts command-shaped servers, so the container is the entry point — Desktop
launches it and talks to it over pipes:
OS | Path |
macOS |
|
Windows |
|
Linux |
|
Settings → Developer → Edit Config opens it. Build the image once first, then point the entry at it:
docker build -t prijsprofeet-mcp:latest .{
"mcpServers": {
"prijsprofeet": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--env-file", "/absolute/path/to/.env",
"prijsprofeet-mcp:latest"
]
}
}
}Desktop apps launched from a dock do not inherit your shell environment, so --env-file is the reliable way to
get PRIJSPROFEET_API_KEY in; -e PRIJSPROFEET_API_KEY only works if the variable is already exported in the
process that started the app. Use an absolute path — the app's working directory is not your shell's.
Then fully quit and relaunch. Closing the window leaves the previous container running; the config is read once at process start, so edits made while the app is open do nothing.
With stdio there is no port and therefore no MCP_AUTH_TOKEN — the client owns the container's lifetime and talks
to it over pipes. The token only exists in the HTTP transport.
Never paste a
urlintoclaude_desktop_config.json. Desktop's config schema is stdio-only: an entry withurl,type, orheadersfails validation, and recent builds respond by rewriting the file with the wholemcpServersblock removed — taking your working entries with it, silently (#37286). Theurl+headers+"type": "http"shape belongs to Claude Code's~/.claude.json, which is a different client with a different parser. For a remote endpoint, use the mcp-remote bridge below.
HTTP — the client connects to a URL
Set PRIJSPROFEET_TRANSPORT=http and the same container serves Streamable HTTP instead:
docker run -d --rm -p 127.0.0.1:3000:3000 \
-e PRIJSPROFEET_TRANSPORT=http \
-e MCP_AUTH_TOKEN="$(openssl rand -base64 32)" \
-e PRIJSPROFEET_API_KEY \
prijsprofeet-mcp:latestEndpoint | Auth |
|
|
| none, so a platform health check can poll it |
In opencode that is a remote server rather than a local one:
{
"mcp": {
"prijsprofeet": {
"type": "remote",
"url": "http://localhost:3000/mcp",
"headers": { "Authorization": "Bearer YOUR_TOKEN" },
"enabled": true
}
}
}Or with compose, which keeps it bound to loopback:
cp .env.example .env # then fill in the key
docker compose --profile http up -d prijsprofeet-mcp-httpClaude Desktop
Desktop has no schema for a remote endpoint, so a command entry is the only way in — mcp-remote is a stdio
bridge that speaks Streamable HTTP on the other side, and it carries the Authorization header that Desktop's own
remote path cannot:
{
"mcpServers": {
"prijsprofeet": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://prijsprofeet-mcp.onrender.com/mcp",
"--transport", "http-only",
"--header", "Authorization: Bearer YOUR_MCP_AUTH_TOKEN"
]
}
}
}--transport http-only is not optional decoration: mcp-remote otherwise negotiates the SSE half of Streamable
HTTP first, GETs this endpoint, gets a 405 back, and stalls through a backoff before retrying as POST. With it
pinned, only the POST path is used.
Settings → Connectors → Add custom connector is not an alternative here. That flow is OAuth-only, and this server authenticates with a bearer token it has no OAuth endpoints for.
Desktop reads the config once at process start, so fully quit and relaunch after editing — closing the window is
not enough. Check Settings → Developer for a connected entry with the tool count this server publishes.
That block works unchanged against the local http://localhost:3000/mcp from the compose service above, with
Bearer $MCP_AUTH_TOKEN in the header.
A
401from this server is a dead end, not a login prompt. Clients treat an unauthenticated401from an HTTP MCP server as a request to start an OAuth flow (Claude Desktop 1.24012.0+, andmcp-remotealike). This server has no OAuth endpoints, so the flow cannot complete:mcp-remotelogsDynamic Client Registration rejected (HTTP 404)and exits, and Desktop opens a browser to a sign-in page that can never succeed. Both mean the same thing — a typo in the token, a stale token after rotation, or a wrongurl. The usual culprit is the literal stringYOUR_MCP_AUTH_TOKENstill sitting in the file. A correctly configured client never sees a401.
The token sits in plaintext in this file, so chmod 600 it and keep the file out of any repo. It is the
MCP_AUTH_TOKEN value, not PRIJSPROFEET_API_KEY — never put the partner key in a client config.
The HTTP transport is stateless — no session id, nothing held between requests — so the endpoint survives restarts
and needs no sticky sessions behind a load balancer. Requests must send Accept: application/json, text/event-stream
and Content-Type: application/json; it answers 406 and 415 respectively when you get that wrong, which is
what the MCP spec asks for.
The API key is server-side in this mode, so
MCP_AUTH_TOKENis the only thing standing between the public internet and your rate limit. It is optional in code — unset, the server still starts and logs a warning — but treat an unset token as a deployment mistake, not a local-dev convenience. See Security.
docker compose run --rm prijsprofeet-mcp is still the right command for the stdio service: a stdio server has no
port, so the client has to own the container's lifetime.
Deploying to Render
render.yaml is a Render blueprint, so the deploy is New → Blueprint → point at the repo. It builds the Dockerfile
as a web service in frankfurt with the health check on /healthz.
Two things in it are deliberate. One is a trade-off, the other is easy to "fix" in a way that breaks the deploy:
plan: freeby default, which means the service sleeps. 512 MB at $0, but a Free web service spins down after 15 minutes without traffic and takes about a minute to wake. MCP clients fetchtools/liston connect with a timeout usually measured in seconds, so against a service that has been idle the client reports a timeout and gives up while the server is still booting — the server cannot distinguish that from being dead, and there is nothing to fix from the server side. Staying onfreemeans picking one of:Option
What it costs you
Raise the client timeout to ~90s
The first connect after every idle period eats the wait, or fails if the client caps out earlier
GET /healthza minute before you startA manual step per session, and it only helps if you remember it
Do nothing
Works while you are actively using it, times out on the first connect after a break
None of that is a server problem, it is the plan. If the endpoint has to be up the moment a client opens a session, switch to
plan: 0.5c-512mb(formerlystarter, $7/month): it never sleeps, the cold start disappears, and the only cost is the bill. It is one line inrender.yaml— the free one is left commented out beside it.No
PRIJSPROFEET_HTTP_PORT. Render injectsPORT; the server reads that and falls back to 3000. Pinning the port in the blueprint or the Dockerfile shadowsPORT, the container listens where nobody is looking, and Render reports the deploy as live while every request 502s.
Render prompts for PRIJSPROFEET_API_KEY on first deploy, so the partner key never enters the repo. It generates
MCP_AUTH_TOKEN for you — read it from Dashboard → Environment, then put it in your client's headers.
The service is stateless and single-instance, so deploys are not zero-downtime: a redeploy drops in-flight requests
and clients reconnect. maxShutdownDelaySeconds is left at the 30s default, which is more than the server's own 5s
drain needs.
Security
The threat model is narrow and worth stating plainly: this server has no user accounts, no database, and no writes to your filesystem. What an attacker wants is your PrijsProfeet key's rate limit, or just the data you can query with it. Ordered by what actually helps:
1. Set MCP_AUTH_TOKEN. A 256-bit random string, compared in constant time via crypto.timingSafeEqual, and
returned as a 401 with a WWW-Authenticate: Bearer challenge when missing or wrong. Every failed attempt is
logged with the client IP, so scanning shows up in the Render log stream.
Rotation is comma-separated and overlap-friendly: set MCP_AUTH_TOKEN=new,old, deploy, move your client to new,
then drop old. No window where both are down.
2. Remember what this is not. A static bearer token is a deliberate deviation from the MCP spec, which asks HTTP servers to implement OAuth 2.1. That is the right trade for a single-tenant tool with one operator, and the wrong one for a shared or multi-user deployment — if you need per-caller identity, per-caller revocation, or scoped access, put a real OAuth proxy in front of it rather than extending this.
3. Lock the plan down, not just the endpoint. PRIJSPROFEET_PLAN=free withholds the 6 Pro tools, so a leaked
token cannot reach the matching and price-history endpoints even if the key is Pro.
4. Prefer a tunnel over a public hostname if you can. Cloudflare Tunnel or Tailscale put the endpoint on a URL
nobody can scan, which removes the guessing game entirely. Render's own ipAllowList is not an option here — it
requires a Scale or Enterprise workspace.
5. Do not set a suspicious User-Agent. bot, crawler, spider and slurp in PRIJSPROFEET_USER_AGENT get
403 from PrijsProfeet on keyless requests, which looks like an outage but is not one. The server warns at startup.
If the key or token ever leaks: rotate the PrijsProfeet key in their dashboard, then rotate
MCP_AUTH_TOKEN as above. Rotating the token alone does not help if the key is what leaked, because the key is
what the attacker was spending.
The tools
20 tools are exposed by default, which is everything the API serves on a free key. The remaining 6 need the Pro plan and are withheld — see Plans below.
Tool | What it does |
| Search offers across all chains, filtered by retailer, category, status, price, savings, diet |
| The 18 category slugs with counts — call this before filtering by category |
| Facet counts for a query, to see what a filter would still return |
| Bulk list with retailer, folder, promo-group and validity-window filters |
| Full detail for one product |
| Every product in one promotional folder |
| Everything from one chain |
| Everything currently on offer |
| The older path-based product search; |
| Offer browsing and aggregates |
| Backtested price forecast; returns |
| Liveness of the API and its backing services |
| Availability per calendar month |
| Rate-limit usage and account info for the configured key |
| Emails a free API key to an address (has a real-world side effect) |
Plans
PRIJSPROFEET_PLAN decides whether the Pro-gated tools are exposed. It defaults to free.
| Tools |
| 20 — the set above |
| 26 — adds the 6 below |
The withheld six, all of which answer 403 This endpoint requires the Pro plan on a free key:
Tool | Endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
That list was verified call by call against a live free key, not read off the published docs, which only mention
/match/* and price history. Withholding is deliberate: a tool that always fails costs a round trip and invites
the model to invent a workaround, so on the free plan it is not merely unused but invisible — calling it returns
Unknown tool, and the server's instructions stop advertising the features. If you upgrade, set
PRIJSPROFEET_PLAN=pro and restart; no rebuild needed.
Configuration
Variable | Default | Purpose |
| (unset) | Partner key, sent as |
|
| API origin |
|
|
|
|
|
|
| (unset) | Comma-separated bearer tokens for the http transport. Unset means no auth — the server starts and warns, so this is only safe on loopback. |
| (unset) | Honoured when |
|
| Interface for http mode |
|
| Port for http mode |
|
| Path for http mode |
|
| Per-request timeout |
|
| Retries on 429/5xx and network errors, with backoff honouring |
|
| Responses above this are truncated with a note instead of returned whole |
|
| Sent on every request |
|
| Fetch the OpenAPI document at startup instead of using the bundled copy |
|
| Where to refresh from |
|
| Prefix on every tool name |
|
| Diagnostics on stderr |
Things worth knowing before you trust a price
A price is not a price until you read promotion_status. Every row carries one of four values, and they mean
different things: active (on offer now), upcoming (starts next week), shelf (the regular price — no
promotion at all) and historical (the last price seen, up to 60 days old). Taking the lowest price across all
four hands you a number that no retailer is charging. The tool descriptions and the server instructions push back
on this, but it is the single easiest mistake to make with this API.
This is offers, not an assortment. Products that are not on promotion are absent, so a recipe app built on
pp_search alone will find a fraction of its ingredients, and a different fraction each week. On the free plan
there is no way around it: the only endpoint that exposes regular non-promotion prices, pp_search_shelf_prices,
is Pro-gated along with the matching tools. On Pro you get both that and cross-retailer comparison.
Not every chain publishes an EAN. Aldi, Lidl, Hoogvliet and Vomar do not, so for those chains the cross-retailer match (Pro) falls back to name, brand and category. Those rows are indicative, not product identity.
Pro-gated tools are withheld, not broken. On the default free plan the six tools in
Plans are absent from tools/list entirely, so the model never spends a call discovering they 403. If
you call one by name you get Unknown tool. Set PRIJSPROFEET_PLAN=pro to get all 26.
Do not put bot, crawler, spider or slurp in the User-Agent. The API answers 403 to keyless requests
that look like a scraper, which reads like an outage but is not one. The default User-Agent is clean; the server
warns on stderr at startup if PRIJSPROFEET_USER_AGENT is set to something suspicious. Naming yourself is the
courteous thing to do and is the only way the API operator can reach you before a breaking change.
Rate limits are per IP: 120/min on search and product detail and 30/min on the bulk endpoints with no key, 150/min with a free key, 300/min on Pro, 1000/min on Business. A key is therefore always a rate-limit upgrade, never a downgrade.
Development
npm install
npm run build # tsc + copy the spec into dist/
npm start # run over stdio
npm run typecheck
npm run inspect # print the generated tool surface, no transportnpm run inspect -- --json dumps the full tool definitions, which is the quickest way to see what a model
actually receives.
Layout
File | Role |
| OpenAPI types, endpoint collection, spec loading with fallback |
| Resolves |
| The curated tool catalogue and the spec-to-tool generator |
| HTTP: auth header, retries, timeout, bounded reads, error hints |
| MCP server factory and the instructions handed to the model |
| Transport selection: stdio, or Streamable HTTP plus |
| Environment parsing |
| Bundled copy of the spec, pinned at image build time |
To add a curated description for a new endpoint, add an entry to CATALOG in src/tools.ts keyed by
"METHOD /path". Unlisted endpoints still appear, under a name derived from the path — the catalogue only
overrides.
Available Tools
20 toolspp_get_brand_dealsARead-onlyIdempotent
Every current deal for one brand, e.g. Coca-Cola or Ahold. Brand matching follows the capitalisation in the source data, so keep the brand as the user wrote it and do not normalise it.
| Name | Required | Description | Default |
|---|---|---|---|
| brand | Yes | ||
| limit | No | Max products to return | |
| promotion_type | No | Filter by promotion type |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and non-destructive behavior, so the safety profile is covered. The description adds a genuinely non-obvious behavioral trait: brand matching is case-sensitive against source data and must not be normalised. It doesn't mention pagination or result-size behavior, but the casing warning is real added value.
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 front-loaded sentences with the core purpose stated first and the casing caveat second. Nearly every clause earns its place, though 'keep the brand as the user wrote it and do not normalise it' restates the same idea twice.
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 3-parameter read tool with no output schema but rich annotations, the description covers the purpose and the trickiest parameter caveat. It omits the unknown valid values for promotion_type (no enums in the schema) and any indication of result ordering or pagination, leaving moderate 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?
Schema coverage is 67%: 'limit' and 'promotion_type' are described in the schema, but 'brand' is not. The description compensates for the undocumented 'brand' parameter with critical case-sensitivity semantics, which is more than the schema offers. However it says nothing about limit defaults or valid promotion_type values, so it only partially fills the gap.
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 states a specific verb and resource: 'Every current deal for one brand', with concrete examples (Coca-Cola, Ahold). It implicitly separates itself from pp_get_deals_by_type by scoping to a single brand, but never names or contrasts with its many siblings.
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?
Usage is implied by the purpose — call it to retrieve deals for one brand — but there is no explicit when-to-use or when-not guidance relative to siblings like pp_get_new_deals, pp_get_popular_deals or pp_get_top_deals. The casing instruction is a usage hint for the parameter rather than tool-selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_categoriesARead-onlyIdempotent
The unified categories with Dutch display names, product counts and group.
Call this before pp_search to turn a user's word ("zuivel", "brood") into a valid category slug. Cheap, and worth it before a search that would otherwise return nothing.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered structurally. The description adds non-obvious behavioral context beyond that: the call is cheap and its typical outcome is a mapping from natural-language terms to slug values, which tells the agent it is a cheap prerequisite lookup rather than a result-producing query.
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 what the tool returns and then the usage instruction, with no repetition of the title or schema. The closing clause ('Cheap, and worth it before a search that would otherwise return nothing') is slightly persuasive rather than informational but still carries real decision 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?
No output schema exists, so the description usefully enumerates the fields returned (Dutch display names, product counts, group) and the slug-oriented purpose, which is enough to call it correctly. It stops short of describing the response container or how to map a returned row to a `category` slug value.
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 takes zero parameters and the schema is a closed empty object, so there is nothing parameter-wise to document; the baseline for no-params tools applies. The description correctly implies no input is needed, though it never literally says callers pass nothing.
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?
States the exact resource returned (unified categories with Dutch display names, product counts and group) and pairs it with a named sibling relationship ('Call this before `pp_search`'), so the agent can distinguish it from the many pp_get_* deal/list tools without opening a schema.
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?
Explicit when-to-use: call this before pp_search to translate a user's informal word ('zuivel', 'brood') into a valid `category` slug. It also gives the failure condition it prevents (a search that would otherwise return nothing), which is exactly the routing guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_deals_by_typeARead-onlyIdempotent
Deals for one promotion mechanic, passed as a keyword such as 1+1, 2+2 or korting. The type values used by promotion_type elsewhere are the internal names (percentage, multi_buy, one_plus_one, volume, limited, starting).
| Name | Required | Description | Default |
|---|---|---|---|
| type | Yes | Promotion keyword, e.g. '1+1' | |
| limit | No | Default when omitted: 10. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is fully covered. The description adds no further behavioral context beyond the parameter mapping — nothing about result volume, ordering, or whether unknown keywords yield empty results versus an error.
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 purpose and then immediately the parameter mapping. Every clause earns its place; density is high but nothing is padded.
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?
With a 100% schema coverage, a limit default documented in the schema, and annotations covering safety, the main gap the description had to fill was the keyword-to-internal-name translation, and it does so. The absence of an output schema means return shape is unexplained, but for a simple list tool this is a minor omission.
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 description adds real meaning beyond the schema: it explains that the 'type' input is a promotion keyword like '1+1' or 'korting', and supplies the mapping to the internal names (percentage, multi_buy, one_plus_one, volume, limited, starting) used by promotion_type elsewhere. That translation layer is genuinely useful input guidance, though 'korting' is not tied to a specific internal name.
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 states a clear resource and filter: 'Deals for one promotion mechanic,' which tells an agent this returns deals scoped to a promotion type. It stops short of differentiating itself from siblings like pp_get_new_deals, pp_get_popular_deals, or pp_get_top_deals, which also return deals under different filters.
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?
Usage is only implied: the agent can infer this is the tool to call when it has a promotion keyword such as '1+1' or 'korting' rather than wanting new, popular, or top deals. There is no explicit when-to-use statement, no named alternative, and no exclusion criteria despite a crowded sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_deals_summaryARead-onlyIdempotent
Aggregate stats: total products, retailer count, biggest discount, last update. One cheap call to check that the data is fresh before reporting anything about "this week".
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds genuinely new context: it is cheap, and it is intended as a freshness gate before reporting. It does not describe latency, rate limits, or the exact freshness semantics, keeping it from a 5.
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 tight sentences with no filler. The return contents come first, then the operational use case, which is the right front-loading for an agent deciding whether to call it.
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?
With no output schema, the description carries the burden of describing the return value, and it enumerates the four key aggregate fields. For a zero-parameter summary tool, nothing an agent needs to call it correctly is missing.
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 takes zero parameters, so there is nothing for the description to disambiguate about inputs. Baseline for a no-parameter tool is 4, and the description introduces no misleading parameter behavior.
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 gives a specific resource ('Aggregate stats') and enumerates exactly what is returned: total products, retailer count, biggest discount, last update. This sets it apart from listing tools like pp_get_top_deals or pp_get_deals_by_type. It stops short of explicitly naming a sibling it replaces, so not quite a 5.
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?
It states a concrete situation for calling it: a 'cheap call to check that the data is fresh before reporting anything about this week.' That is real when-to-use guidance tied to a workflow. No exclusions or named alternatives (e.g. pp_health_check) are given, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_filter_statsARead-onlyIdempotent
Facet counts per retailer, promotion status and category. Pass q (and optionally category) to get the counts for one specific search — useful to show what a filter would still return, or to check whether a category exists before searching it.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search query to filter counts | |
| dietary | No | Comma-separated dietary tags: bio, glutenvrij, lactosevrij, vegan | |
| category | No | Filter by category | |
| retailer | No | Filter by retailer | |
| private_label | No | Filter on house brand: true for huismerken, false for A-merken | |
| promotion_status | No | Filter by status |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint=true, idempotentHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds the meaningful behavioral detail that counts are scoped to a query when `q` is supplied, but says nothing about the unscoped (no-q) behavior, result volume, or rate limits.
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, purpose first and usage second, with no filler. The em-dash clause is slightly dense but it carries real routing information (previewing filters, existence checks), so it earns its space.
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?
All six parameters are optional and there is no output schema, so the description's job is to convey the calling pattern and it does: the primary facet-count result plus the query-scoped variant. It could state what an unfiltered call returns, but nothing critical to correct invocation is missing.
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 100%, so each of the six parameters is already documented in the schema. The description only elaborates on `q` and `category`, leaving retailer, dietary, private_label and promotion_status to the schema — the baseline 3 for a fully-covered schema is appropriate.
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?
Opens with a concrete noun phrase ('Facet counts per retailer, promotion status and category') that names the resource and the dimensions returned, so the agent knows this is a statistics/facet endpoint rather than a product list. It does not explicitly distinguish itself from nearby siblings such as pp_get_categories or pp_get_deals_summary, which keeps it from a 5.
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 second sentence gives concrete when-to-use guidance: pass `q` (and optionally `category`) for a specific search, to preview what a filter would still return, or to validate that a category exists before searching it. It stops short of naming an alternative tool or stating when NOT to use this one.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_new_dealsCRead-onlyIdempotent
The most recently started offers, capped at 30 rows.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default when omitted: 10. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds the 30-row cap, a useful behavioral constraint, but it duplicates the schema's maximum:30 and says nothing about ordering, freshness window, or pagination.
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?
A single short sentence, front-loaded with the key qualifier. It earns its place but is arguably too terse for a tool with 19 siblings, leaving ordering and semantics underspecified.
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 read-only list tool with full annotation coverage and no output schema, the description is minimally adequate. It does not explain the return record shape or the ordering key ('recently started' by what metric), which would help an agent use the results correctly.
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 100% for the single limit parameter, so the schema fully documents it, including the default of 10 and the max of 30. The description adds nothing beyond what structured fields already provide, making the baseline 3 appropriate.
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 names the resource (offers/deals) with a temporal qualifier, 'most recently started,' which gives some sense of the ordering. However it uses 'offers' while the tool and siblings use 'deals,' and it never distinguishes itself from close siblings like pp_get_top_deals or pp_get_popular_deals. An agent would have to guess which 'get deals' variant to pick.
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?
There is no statement of when to use this tool versus the many sibling deal tools (by_type, popular, summary, top, brand). No prerequisites, no exclusions, no alternative routing. The agent is left to infer selection from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_partner_usageARead-onlyIdempotent
Current rate-limit usage and account info for the configured API key. Requires a valid partner key, so it fails with 401 when the server is running without one.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnly, idempotent, non-destructive, openWorld), and the description adds useful behavioral detail: it requires a valid partner key and returns 401 when the server lacks one. This auth requirement and failure mode go beyond the structured annotations, though broader return behavior is not described.
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 tightly written sentences with the primary purpose stated first and the prerequisite second. There is no filler or redundant restatement of structured data.
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, read-only tool with rich annotations and no output schema, the description provides what an agent needs: what it returns, the key prerequisite, and the failure condition. No critical context is missing.
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 takes zero parameters, so there are no parameter semantics to document. The baseline for zero-param tools is 4, and the description does not need to compensate for any schema coverage gap.
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 states a specific return payload (rate-limit usage and account info) scoped to the configured API key, which is clear enough for an agent to know what the tool retrieves. It does not explicitly differentiate from any sibling tool, but the resource is distinct enough in context.
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 a prerequisite (requires a valid partner key) and a failure mode (401 without one), which implies the tool should only be called when a partner key is available. However, it does not state when to choose this tool over alternatives or provide broader usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_popular_dealsBRead-onlyIdempotent
The deals users click most often, capped at 30 rows.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Default when omitted: 10. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, non-destructive behavior, so the safety burden is covered. The description adds real context beyond that: the ranking signal (user clicks) and the hard 30-row cap. It does not describe ordering ties or fields returned, but that is a minor omission.
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?
A single sentence with zero filler, leading with the ranking criterion and ending with the size constraint. Nothing needs to be cut or reordered.
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?
There is no output schema, so the description is the only source of return-value information; it communicates row count but not the shape of a deal record. Combined with the unaddressed overlap with pp_get_top_deals, it is barely sufficient for a single-parameter read 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?
Schema coverage is 100% and the schema states the 1-30 bounds and the default of 10, so the description has little room to add value. Its phrase 'capped at 30 rows' merely echoes the schema maximum, and it does not explain how limit interacts with the ranking.
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 defines the resource by its ranking criterion ('deals users click most often'), which is more meaningful than a bare restatement of the name. However, it gives no differentiation from pp_get_top_deals, a sibling that sounds functionally identical, so an agent cannot confidently choose between them.
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?
There is no when-to-use guidance, no statement of prerequisites, and no named alternative. With a near-duplicate sibling (pp_get_top_deals) in the toolset, the absence of routing guidance is a real gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_price_forecastARead-onlyIdempotent
Server-side backtested price forecast for one product ("Profeet voorspelt").
A product with no forecast is not an error: the call returns HTTP 200 with a null forecast, and the reason arrives in the X-Forecast-Reason header. Report it as "no forecast available" rather than retrying.
| Name | Required | Description | Default |
|---|---|---|---|
| product_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds genuinely non-obvious behavior: a missing forecast still returns HTTP 200 with a null body and the reason in the X-Forecast-Reason header. That is real value beyond the structured fields.
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?
Three short sentences, each carrying distinct information: what the tool does, the null-not-error contract, and the anti-retry instruction. Front-loaded and free of filler.
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?
No output schema exists, and the description covers the one surprising return case (null forecast plus reason header) that an agent would otherwise mishandle. It does not describe the shape of a successful forecast, which is a minor remaining gap for a read 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?
Schema coverage is 0% and the single parameter has no description in the schema. The description says the forecast is for 'one product', which maps loosely to product_id, but adds no format, ID namespace, or validity detail to compensate for the coverage gap.
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?
States a specific verb and resource: 'Server-side backtested price forecast for one product'. The domain (price forecasting) is clearly distinct from the deals/products/categories siblings, though the description never names an adjacent tool to differentiate against.
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?
There is no explicit when-to-use-vs-alternative guidance, but the description does give one actionable usage rule: a null forecast is not an error and should not be retried. That covers the edge case but leaves the general call context implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_productARead-onlyIdempotent
Full detail for one product, including EAN, folder, promo group and dietary labels. product_id is the product_id field from any search or list result.
| Name | Required | Description | Default |
|---|---|---|---|
| product_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint, so the safety profile is covered. The description adds value beyond them by disclosing the shape of the returned detail (EAN, folder, promo group, dietary labels) for a tool with no output schema, though it says nothing about missing-product or rate-limit behavior.
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, no filler, with the purpose front-loaded and the parameter-provenance note second. Every clause 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 one-parameter read tool whose annotations already carry the safety profile and whose only parameter is explained, the description is sufficient to call it correctly. Omitting full return-field enumeration is acceptable given the tool's simplicity.
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% and the single parameter is documented only as a bare string type, so the description must compensate. It does so by explaining the provenance of product_id ('the product_id field from any search or list result'), which tells the agent where to obtain a valid value, though not its format.
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 gives a specific verb and resource (full detail for one product) and enumerates the kind of content returned (EAN, folder, promo group, dietary labels). The singular 'one product' implicitly separates it from the plural list/search siblings such as pp_list_products and pp_search_products_by_name.
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 second sentence establishes the precondition for calling it: product_id comes from any search or list result, which routes the agent from the search/list siblings into this detail tool. It stops short of explicitly naming alternatives or a when-not-to-use case, so it does not reach a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_products_by_folderARead-onlyIdempotent
Every product in one promotional folder (a single actie). folder_id is the folder_id field on a product.
page_size may go up to 1000 here, but a big page is expensive in context and in rate limit — ask for what the question needs.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number | |
| folder_id | Yes | ||
| page_size | No | Items per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description contributes non-obvious behavioral context: the 1000-item page ceiling is expensive in context and rate limit, which is operational knowledge not present in the annotations or 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?
Two tightly written sentences, front-loaded with the purpose before the parameter advice; every clause earns its place. Slightly informal phrasing ('a big page is expensive in context and in rate limit') keeps it from being maximally crisp.
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 3-parameter read tool with annotations covering safety, this is largely sufficient. However, with no output schema there is no statement of what a product record contains, how pagination continuation is detected, or whether results are ordered, which a list tool should disclose.
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 coverage is 67% (page and page_size have descriptions). The description adds real meaning beyond the schema: it explains that `folder_id` corresponds to the `folder_id` field on a product (i.e., where to obtain it) and warns that a large `page_size` costs context and rate-limit budget. Only `page` remains undocumented.
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?
States a specific verb+resource (all products) scoped to a single promotional folder, and clarifies the domain term 'actie' as 'folder'. It does not explicitly contrast itself with close siblings such as pp_get_products_by_retailer or pp_list_products, so the differentiation is left to inference.
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 practical sizing advice ('ask for what the question needs') but never states when to choose this tool over pp_get_products_by_retailer, pp_list_products, or pp_get_promotional_products. Usage is implied by the folder scope rather than spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_products_by_retailerARead-onlyIdempotent
Every product from one retailer, paginated. Takes a retailer slug (albert_heijn, jumbo, aldi, lidl, ekoplaza, plus, dekamarkt, hoogvliet, vomar, dirk), not a display name.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number | |
| retailer | Yes | ||
| page_size | No | Items per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), so the description is freed to add the details annotations cannot: that results are paginated and that the key must be a slug. No rate limits or ordering behavior are disclosed, but the added correctness detail is real.
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, zero filler, front-loaded with what the tool returns before the parameter caveat. Every clause 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 simple read-only paginated listing with no output schema, the description covers result scope, identifier format, and pagination. It lacks any indication of ordering or how this fits among the many other product/deal siblings, which keeps it from being fully complete.
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 coverage is only 67%, and the required 'retailer' param has no schema description and no enum. The description compensates by enumerating the ten valid slugs and warning it is a slug, not a display name — meaning an agent could construct a valid call without guessing. This is exactly the value the schema omits.
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?
States a specific verb+resource with scope: 'Every product from one retailer, paginated.' This is distinguishable from generic siblings like pp_list_products or pp_search_products_by_name because the retailer scoping is explicit. It stops short of naming which sibling to use instead when no retailer filter is wanted.
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?
Usage is implied by 'from one retailer' — call it when you want everything for a single retailer — but there is no explicit when-to-use/when-not guidance and no alternative sibling is named (e.g., pp_list_products for a cross-retailer listing). Implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_promotional_productsARead-onlyIdempotent
Everything currently on offer, newest first. Use pp_list_products with is_promotional=true instead when you also need a filter.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number | |
| retailer | No | Filter by retailer | |
| page_size | No | Items per page | |
| max_valid_from | No | Alleen acties die op of vóór deze dag beginnen (YYYY-MM-DD) | |
| min_valid_from | No | Alleen acties die op of ná deze dag beginnen (YYYY-MM-DD) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true and destructiveHint=false, so the safety profile is covered. The description adds one genuine behavioral trait beyond that: results are returned 'newest first' and unfiltered by default. It says nothing about pagination behavior or result size, so the added value is modest given the annotation coverage.
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 short sentences with zero filler; the scope and sort order are front-loaded, and the routing guidance follows immediately. Every clause 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 read-only listing tool backed by four annotations and a fully documented five-parameter schema, the description supplies what an agent needs to select and call it. The only omission is any hint of the result shape, which is not covered by an output schema, but that is a minor gap for a list endpoint.
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 100%, so all five parameters (page, page_size, retailer, min_valid_from, max_valid_from) are already documented in the schema, including date formats. The description adds no parameter-level semantics, so the baseline 3 applies.
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 resource and scope: 'Everything currently on offer, newest first,' which tells an agent this is an unfiltered listing of promotional products ordered by recency. It also explicitly distinguishes itself from the sibling pp_list_products for the filtered case. The main verb is implicit rather than stated, keeping it just short of a 5.
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?
It names a concrete alternative and the condition that selects it: use pp_list_products with is_promotional=true when you also need a filter. That is clear when-to-use-routing. However, it ignores the many other deal-oriented siblings (pp_get_new_deals, pp_get_top_deals, pp_get_brand_deals, pp_get_deals_by_type), so an agent must still guess how this differs from those.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_sla_summaryARead-onlyIdempotent
Availability per calendar month, newest first. Answers "was the API down last Tuesday?" with a number instead of a guess.
| Name | Required | Description | Default |
|---|---|---|---|
| months | No | Default when omitted: 12. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral detail beyond that: ordering ('newest first') and the fact that the return is a quantitative availability figure rather than a qualitative status.
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, purpose front-loaded, no wasted preamble. 'Instead of a guess' is slightly colorful but succinctly conveys the tool returns hard numbers, so it largely 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 simple read-only tool with one fully-documented optional parameter and rich annotations, the description covers what it returns (monthly availability, newest first) adequately. Without an output schema there is minor ambiguity about exact return format, but nothing critical to correct invocation is missing.
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 100% and the single 'months' parameter is fully documented there, including its default. The description's 'per calendar month' hints at granularity but adds no new parameter meaning, so the baseline of 3 applies.
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?
States a specific resource and granularity: availability/SLA per calendar month, ordered newest first. It's clearly distinguishable from the deal/product siblings, which are all unrelated domains. The verb is implicit ('get SLA summary') but the intent is 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 scenario 'was the API down last Tuesday?' implies the appropriate usage context. However, there is no explicit when-not guidance and no named alternative sibling, leaving usage to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_get_top_dealsARead-onlyIdempotent
Top deals grouped per brand, optionally narrowed to one or more retailers.
min_savings defaults to 10%; raise it to cut the noise. Pass retailer as an array to scope the lists to specific chains.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of deals per list | |
| retailer | No | Limit the lists to one or more retailers. Repeat the parameter to pass several: `?retailer=albert_heijn&retailer=jumbo`. Hyphenated slugs (`albert-heijn`) are accepted too. | |
| min_savings | No | Minimum savings percentage |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds one genuinely new behavioral fact — the min_savings default of 10%, which is absent from the schema — but says nothing about return format, ordering, or list size behavior.
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 core purpose and free of filler. The retailer-array sentence partially duplicates the schema text, slightly reducing density but not enough to hurt readability.
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-required-parameter read tool with no output schema and full annotation coverage, the description is adequate: it defines scope, grouping, and the key default. It could say more about what a 'list' contains or how many lists are returned, but nothing essential to invoking it is missing.
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 100%, so limit, retailer, and min_savings are already documented in the schema. The description adds the non-schema default value for min_savings and reinforces the array semantics, but the passing syntax it describes is already spelled out in the schema's retailer 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?
States a specific verb+resource ('Top deals grouped per brand') and a clear scope modifier (optionally narrowed to retailers). It is distinguishable from pp_get_new_deals and pp_get_popular_deals by the brand grouping, though it does not explicitly contrast itself with the similarly-named pp_get_brand_deals sibling.
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?
Gives actionable tuning guidance ('raise min_savings to cut the noise') and how to scope by retailer, which is usable context. However, it never states when to prefer this over the many sibling deal-listing tools (new_deals, popular_deals, deals_by_type), so alternative selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_health_checkARead-onlyIdempotent
Check that the PrijsProfeet API is reachable. Call this when another tool returns 5xx to tell an outage apart from a bad request.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, non-destructive and open-world, so the safety profile is covered. The description adds genuine behavioral context beyond that: it is a diagnostic probe whose meaning depends on other calls failing with 5xx. It does not state what a successful or failed check returns, a minor gap given there is no output 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?
Two short sentences, action first and trigger second, with no filler. Every clause 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 parameterless read-only probe the description is nearly sufficient: purpose and trigger are both covered. The one omission is what the result looks like (reachable vs. unreachable signal), which matters slightly because no output schema exists.
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?
Zero parameters, so the baseline is 4; there is nothing for the description to explain. Schema coverage is 100% and the empty object schema is self-evident.
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?
States a specific verb and resource: 'Check that the PrijsProfeet API is reachable.' This cleanly separates it from all sibling tools, which are data-fetching operations, so an agent can identify it as the diagnostic probe without opening the schema.
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?
Explicitly names the trigger condition ('when another tool returns 5xx') and the decision it informs ('tell an outage apart from a bad request'). This is a rare case of precise when-to-use routing rather than generic guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_list_productsARead-onlyIdempotent
List products with filters, newest extraction first. Use pp_search when the user named a product; use this when you need to enumerate by retailer, folder, promo group or validity window.
promo_group_id returns every product in one shared action — read that field off a product to get the rest of its group.
min_valid_from / max_valid_from (YYYY-MM-DD) bound the date the promotion starts.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number | |
| sort_by | No | Sorteerveld. Toegestaan: extracted_at, price, name, product_id, valid_from | |
| retailer | No | Filter by retailer | |
| folder_id | No | Filter by folder ID | |
| max_price | No | Maximum price filter | |
| min_price | No | Minimum price filter | |
| page_size | No | Items per page | |
| sort_order | No | Sort order (asc, desc) | |
| is_promotional | No | Filter promotional products | |
| max_valid_from | No | Alleen acties die op of vóór deze dag beginnen (YYYY-MM-DD) | |
| min_valid_from | No | Alleen acties die op of ná deze dag beginnen (YYYY-MM-DD) | |
| promo_group_id | No | Alleen producten uit deze actiegroep (zie `promo_group_id` op een product): alle deelnemers aan één gezamenlijke actie |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld and non-destructive, so the safety profile is covered. The description adds real behavioral context beyond them: the default sort order, and that promo_group_id returns every participant of one shared action and can be read off a product to expand its group. It does not mention pagination behavior, the one trait annotations leave untouched.
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?
Three short paragraphs, front-loaded with the core action and default ordering, followed by routing and then the two non-obvious parameters. No filler sentences.
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?
With 12 optional filter parameters and no output schema, the description covers the non-obvious filters (promo group, validity window) and the default sort. Price, name and page filters are self-documented at 100% coverage, and return values need no explanation without an output schema, so this is nearly complete for a filtering list 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?
Schema coverage is 100%, so the baseline is 3, but the description adds semantics the schema alone does not convey in English: min_valid_from/max_valid_from bound the promotion start date, and promo_group_id is described as a cross-call linking key. That is meaningful added value rather than restatement.
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?
States a specific verb and resource ("List products") plus the default ordering ("newest extraction first"), and explicitly names the sibling it is not (pp_search). An agent can distinguish it from the search tool without opening either schema.
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?
Gives an explicit routing rule: use pp_search when the user named a product, use this tool to enumerate by retailer, folder, promo group or validity window. However, it never acknowledges the overlapping siblings pp_get_products_by_folder, pp_get_products_by_retailer, pp_get_promotional_products, leaving an agent unsure whether those are preferred for the same enumerations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_request_free_keyA
Request a free API key for an email address. A one-click link is mailed out; the key itself is never in the response. The response is deliberately identical whether or not that address already has a key, so a success here never confirms someone is a customer. Capped at 5 requests per hour per IP. This has a real-world side effect — it emails a stranger. Only call it when the user has explicitly asked for it in this conversation.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Where we send the key link | ||
| site_url | No | Where the data will appear (optional) | |
| project_name | Yes | What you are building |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations (readOnlyHint=false, openWorldHint=true, idempotentHint=false) by disclosing that the key is never returned, that the response is deliberately identical regardless of prior key existence (anti-enumeration), the 5/hr/IP cap, and the real-world email side effect. Rich, non-obvious disclosure.
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?
Four tight sentences, each carrying distinct information, with the core purpose front-loaded and the safety caveat last. No filler.
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?
With no output schema and full param coverage, the description supplies everything else needed: return behavior (key absent, uniform response), rate limits, and the human-impact caveat. Nothing an agent needs to call this correctly is missing.
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 100%, so all three parameters are already documented in the schema. The description adds no syntax or format detail beyond that, so the baseline 3 is appropriate.
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?
States a specific verb+resource ('request a free API key') and immediately clarifies the mechanism (a link is emailed, not the key). It is trivially distinguishable from all siblings, which are read-only deal/product lookup tools.
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?
Gives an explicit precondition: 'Only call it when the user has explicitly asked for it in this conversation,' plus context about the rate cap and the real-world side effect. This is exactly the when-to-use guidance an agent needs for a side-effecting tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_searchARead-onlyIdempotent
Search supermarket offers across the 10 Dutch chains (Albert Heijn, Aldi, DekaMarkt, Dirk, Ekoplaza, Hoogvliet, Jumbo, Lidl, PLUS, Vomar).
Omit q or pass * to browse the whole catalogue.
How to read a row: promotion_status decides what the price means. active = on offer right now, upcoming = starts next week, shelf = the regular price, historical = the last price seen, up to 60 days old.
Taking the lowest price across rows can therefore return a price nobody is charging today — filter on promotion_status (or leave current_only-style filtering to the caller) before quoting a best price.
Retailer slugs: albert_heijn, jumbo, aldi, lidl, ekoplaza, plus, dekamarkt, hoogvliet, vomar, dirk.
Category slugs are not free text: call pp_get_categories first to map the user's word to a slug.
Keep page_size modest; page through rather than asking for 100 rows when a question needs 3.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Search query (use * to browse all) | |
| page | No | Page number | |
| dietary | No | Comma-separated dietary tags: bio, glutenvrij, lactosevrij, vegan | |
| sort_by | No | Sorteerveld, optioneel met richting: `veld` of `veld:asc` / `veld:desc`. Toegestaan: price, savings_percentage, product_id, savings_amount, original_price, discount_percentage, extracted_at, valid_until. | |
| category | No | Filter by unified category slug (e.g., groente-fruit, zuivel-eieren) | |
| retailer | No | Filter by retailer (aldi, albert_heijn, jumbo, lidl) | |
| max_price | No | Maximum price | |
| min_price | No | Minimum price | |
| page_size | No | Results per page | |
| min_savings | No | Minimum savings percentage (0-100) | |
| private_label | No | Filter on the retailer's own house brand: true for huismerken only, false for A-merken only. Omit for no filter. A chain with no reliable brand signal (Lidl, Vomar) carries no rows on either side of this filter, rather than a guessed one. | |
| promotion_type | No | Filter by promotion type: percentage, multi_buy, one_plus_one, volume, limited, starting | |
| promotion_status | No | Filter by status: active, upcoming, or expired | |
| include_all_retailers | No | Ignore the caller's stored retailer preference and search every retailer. Only meaningful for browser callers carrying a `pp_uid` cookie — an API-key caller has no stored preference, so this is a no-op for integrations. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld), and the description layers substantial non-obvious behavior on top: the meaning of each `promotion_status` value, the fact that historical prices can be up to 60 days old and that the lowest row price may be one nobody is charging today, plus the caveat that Lidl and Vomar carry no rows under `private_label` rather than a guessed brand signal. This is real behavioral disclosure, not restatement.
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 definition is front-loaded — purpose and browse semantics come first, then row interpretation, then slug/paging logistics. Each sentence carries actionable content (slug lists, status meanings, paging advice) and there is no filler or restatement of the name.
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 14-parameter, annotation-covered search with no output schema, the description does the heavy lifting on how to interpret a returned row and how to page. It stops short of describing the response shape or its fields beyond price and promotion_status, which is the one gap an agent composing a query could notice.
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 coverage is 100%, so the schema already documents every parameter and the baseline would be 3. The description still adds meaning the schema lacks: the full ten-retailer slug list (the schema only shows four), the paging strategy, and the interpretation of `promotion_status` during price comparisons. It loses a point because the status values it describes (`active`, `upcoming`, `shelf`, `historical`) do not match the schema's enum (`active`, `upcoming`, `expired`), which could confuse a caller about valid filter inputs.
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 first sentence gives a specific verb and resource ('Search supermarket offers') and scopes it to the 10 named Dutch chains, so the agent immediately knows what the tool does. It does not, however, differentiate itself from overlapping siblings such as pp_get_promotional_products, pp_get_top_deals or pp_search_products_by_name, which an agent must infer from naming alone.
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?
Explicit when-to-use guidance is given for the main knobs: omit `q` or pass `*` to browse the whole catalogue, call `pp_get_categories` first because category slugs are not free text, and keep `page_size` modest and page through instead of asking for 100 rows. It also provides an explicit warning about filtering on `promotion_status` before quoting a best price, which is exactly the kind of conditional guidance that prevents wrong tool output.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pp_search_products_by_nameARead-onlyIdempotent
Search products with the term inside the URL path. This is the older sibling of pp_search: same data, fewer filters, no sorting.
Prefer pp_search for new work.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number | |
| query | Yes | ||
| retailer | No | Filter by retailer | |
| page_size | No | Items per page |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds genuine capability context beyond them: fewer filters and no sorting relative to pp_search. It does not describe pagination behavior, but with annotations carrying the safety burden this is a solid addition.
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 short sentences, zero waste, with the core behavior front-loaded and the deprecation-style guidance following immediately.
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 four-parameter read-only search with no output schema, the description covers purpose and routing adequately. It leaves pagination/return shape unstated, which is a minor gap given the schema fields are self-explanatory.
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 coverage is 75%, so page, page_size and retailer are already documented in the schema. The description's 'term inside the URL path' adds a hint about how query is used but nothing beyond what the schema provides for the other three parameters. Baseline 3 applies when the schema does most of the work.
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?
States a specific verb (search) and resource (products), plus a precise mechanism ('term inside the URL path'). It also names the sibling pp_search and how this differs, so the agent can distinguish it without opening schemas.
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?
Explicitly routes the agent: 'Prefer `pp_search` for new work,' and characterizes this tool as the older sibling with fewer filters and no sorting. Both the when-to-use and the when-not-to-use conditions are stated.
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.
20 tool updates
v1.0.0- First observed
pp_get_brand_deals - First observed
pp_get_categories - First observed
pp_get_deals_by_type - First observed
pp_get_deals_summary - First observed
pp_get_filter_stats - First observed
pp_get_new_deals - First observed
pp_get_partner_usage - First observed
pp_get_popular_deals - First observed
pp_get_price_forecast - First observed
pp_get_product - First observed
pp_get_products_by_folder - First observed
pp_get_products_by_retailer - First observed
pp_get_promotional_products - First observed
pp_get_sla_summary - First observed
pp_get_top_deals - First observed
pp_health_check - First observed
pp_list_products - First observed
pp_request_free_key - First observed
pp_search - First observed
pp_search_products_by_name
TDQS
Scored across 20 tools
Each tool targets a fairly distinct slice (newest, popular, top-by-brand, by-type, by-retailer), and descriptions explicitly differentiate them. However, there are documented redundancies that create real overlap: pp_get_promotional_products vs pp_list_products with is_promotional, and pp_search vs the 'older sibling' pp_search_products_by_name.
Consistent pp_ prefix and snake_case verb_noun pattern (pp_get_*, pp_list_*, pp_search*). Minor deviation with pp_search / pp_search_products_by_name and the unprefixed-looking pp_health_check, but overall predictable.
At 20 tools this sits in the heavy range for a read-mostly price API, with several near-duplicate listing/search tools that could be consolidated. Each tool has some justification, but the surface is larger than strictly needed.
Covers the domain well: search, list, product detail, categories, folders, retailers, price forecast, deal aggregations, health, SLA and account tools. Gaps are minor (no explicit comparison or basket tools), but core supermarket-data workflows are complete.
Maintenance
Related MCP Connectors
Live Dutch supermarket prices and promotions (Albert Heijn, Jumbo, Lidl, Aldi and more) for AI.
Turn any shopping list into a ready-to-checkout grocery cart across 26 European supermarkets.
Live prices, deals & optimal multi-stop shopping routes for German grocery & drug stores.
Danish grocery catalog as MCP tools: live offers across all major chains, stores, EAN lookup, stock.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables users to compare prices, track budgets, and find promotional deals across major Dutch supermarkets and drugstores. It supports automated shopping list optimization, meal planning, and price history alerts for stores like Albert Heijn, Jumbo, and Kruidvat.16MIT
- FlicenseAqualityDmaintenanceEnables AI assistants to track global food prices, search products by barcode or name, and compare costs across 27 countries. It provides tools for real-time price scraping and data aggregation from major international supermarket chains.84-
- AlicenseAqualityCmaintenanceA Model Context Protocol server for real-time Swiss grocery shopping that searches and compares products across 8 major Swiss retailers (Migros, Coop, Aldi, Denner, Lidl, Farmy, Volgshop, Otto’s), normalizes per-unit prices, surfaces promotions, computes optimal multi-store shopping plans, and works with any MCP-compatible client without API keys or accounts.7129 npm33AGPL 3.0
- AlicenseAqualityAmaintenanceEnables searching products, comparing prices, and building optimal shopping lists across major Chilean supermarkets, using your local machine to access real-time prices and loyalty deals.1441 npm66MIT