elid-wine-mcp
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., "@elid-wine-mcpWhat's in Dom Perignon 2015 and how much does it cost in Swiss shops?"
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.
elid-wine-mcp
An MCP server for ELID, which gives wines readable IDs. It lets Claude and other MCP clients:
turn wine text such as a label or a wine-list line into ranked ELIDs
look up wines by name, ELID prefix or LWIN
get vintage fact sheets: alcohol, sugar, acidity, blend, soil, winemaking, aging, dosage, drinking window and food pairing
search observed retailer prices from Swiss-market shops
An ELID is written {CC}-{RRR}-{PPPP}{NN}[-{VINTAGE}]. For example, FR-CMP-DOMP01-2015 is the 2015 Dom Pérignon. The format is defined in the ELID specification.
Tools
Tool | What it does |
| Matches free text to ranked base-wine ELIDs, with LWINs and scores |
| Searches the catalog by name/ELID substring ( |
| Returns a wine's identity and vintage fact sheets. A full ELID such as |
| Searches Swiss-market shop prices by text, ELID and vintage, shop, or CHF range, with sorting |
| Lists covered shops with observation counts and date ranges |
Every tool is read-only, and no API key or account is needed. Results include a wine_url (for example https://elid.wine/wine/FR-CMP-DOMP01#vintage-2015) that you can cite.
Related MCP server: MCP MySQL
Install
Node.js 20 or newer is required.
Claude Code
claude mcp add elid -- npx -y elid-wine-mcpClaude Desktop, Cursor, Windsurf and other clients
Add this to your MCP config file (for Claude Desktop, claude_desktop_config.json):
{
"mcpServers": {
"elid": {
"command": "npx",
"args": ["-y", "elid-wine-mcp"]
}
}
}Configuration
Variable | Default | Purpose |
|
| Alternative deployment, e.g. |
Example
You: I'm looking at "Dom Perignon 2015" on a wine list. What's in it, and what does it cost in Swiss shops?
Claude calls:
elid_match_wine({ "raw": "Dom Perignon 2015" }), which returnsFR-CMP-DOMP01(Dom Pérignon, Vintage, Champagne; LWIN 1082656).elid_get_wine({ "elid": "FR-CMP-DOMP01-2015" }), which returns the 2015 facts only: 12.5% ABV, 51% Pinot Noir / 49% Chardonnay, dosage 4.5 g/L, 100% malolactic, about 8 years on lees, disgorged 2023-01, drinking window 2023+.elid_search_shop_prices({ "elid": "FR-CMP-DOMP01-2015", "sort": "price" }), which returns observed shop listings with shop, bottle size, currency and observation date.
Then it answers with the ELID, cites https://elid.wine/wine/FR-CMP-DOMP01#vintage-2015, and labels each price as a dated observation, not a current offer.
Data notes
Don't mix vintages.
elid_get_winenever applies one vintage's facts to another. If a vintage has no fact sheet, the tool says so.Prices are observations. Shop rows keep the source currency, bottle size, case quantity and
scraped_atdate. Missing values arenull. Shipping and taxes are not included, and a listed price does not mean the wine is in stock now.Match scores rank candidates. They are not probabilities. An empty list means no accepted match.
The API does not include RRP, restaurant lists or critic reviews. For those, see the pages on elid.wine.
Development
npm install
npm run build
npm test # unit tests (mocked HTTP)
npm run test:live # live tests against elid.wine
npm run inspect # MCP Inspector UIPublishing
Update
versioninpackage.jsonand in both places inserver.json.Run
npm publish. TheprepublishOnlyscript builds and runs the tests first.Optionally, list the server in the MCP Registry:
mcp-publisher login github && mcp-publisher publish.
You can also publish a GitHub release. .github/workflows/publish.yml then publishes to npm (this needs an NPM_TOKEN secret) and to the MCP Registry.
License
MIT. Data © ELID. The catalog comes partly from LWIN (CC BY 4.0); see elid.wine for provenance.
Available Tools
5 toolselid_get_wineGet wine identity and vintage factsARead-only
Get one wine's catalog identity (producer, region, colour, type, classification, LWIN…) and its vintage fact sheets (alcohol, residual sugar, acidity, blend, soil, winemaking, aging, dosage, drinking window, food pairing…). Accepts a base ELID (FR-CMP-DOMP01) or a full ELID with vintage (FR-CMP-DOMP01-2015), which restricts facts to that vintage. Unknown fields are omitted. Does not include prices; use elid_search_shop_prices.
| Name | Required | Description | Default |
|---|---|---|---|
| elid | Yes | Base or full ELID, e.g. FR-CMP-DOMP01 or FR-CMP-DOMP01-2015. | |
| vintage | No | Optional vintage (year, NVXX, or edition) to restrict facts to. Overrides a suffix in elid. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark readOnlyHint and openWorldHint, but the description adds concrete behaviors: 'Unknown fields are omitted' (partial result handling) and 'restricts facts to that vintage' (filtering scope). It also clarifies that prices are not included, which is non-obvious and prevents incorrect expectations. No contradiction with annotations.
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 carry full content: the first lists the returned info and accepted input forms; the second notes unknown-field omission and the price exclusion with a sibling pointer. No filler, and the scope is front-loaded before the alternative. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential categories of returned data and the input variants. It does not enumerate every possible field, but given the openWorldHint and the absence of an output schema, the summarized list is sufficient for an agent to know what it will get. The alternative routing also covers the most likely separate use case. A slightly higher score would require explicit mention of response structure, but that is not necessary for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters are documented. The description adds meaningful semantics beyond the schema: it explains the base vs full ELID usage and notes that the vintage parameter can override a suffix in elid. This interpretive guidance helps the agent construct valid calls without reading deeply into the schema.
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 verb ('Get') and resource ('one wine's catalog identity and vintage fact sheets') and enumerates the types of fields (producer, region, colour, type, classification, LWIN…). It explicitly excludes prices and routes to a sibling tool, distinguishing it from the other ELID tools immediately.
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 explains how the elid parameter can be a base or full ELID and that a vintage suffix restricts facts to that vintage. It also provides an explicit 'use instead' alternative for prices (elid_search_shop_prices), giving a clear when-not-to-use criterion. The vintage parameter's override semantics are also disclosed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
elid_list_shopsList Swiss-market shopsARead-only
List the shops covered by elid_search_shop_prices, with observation counts and the oldest/newest observation dates.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, which cover the safety profile. The description adds value by specifying the data returned (observation counts, oldest/newest dates), which is beyond the annotations. It does not contradict any annotation and provides enough behavioral context for an agent to understand what to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that is front-loaded with the core purpose and immediately specifies the return data. There is no fluff, and every word contributes to understanding. This is an exemplar of concise, well-structured tool documentation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that there are no parameters, no output schema, and the tool is a straightforward list operation, the description is sufficient. It explains what the tool returns and its relationship to a sibling tool. While it does not mention pagination or ordering, these are not critical for a simple listing tool, and the description covers all essential information an agent needs to decide when to call it.
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 has zero parameters, so the description has nothing to add about parameters. The schema is empty (100% coverage trivially), and the description correctly omits any parameter details. With 0 parameters, the baseline is 4, and the description does not need to compensate for anything.
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 verb ('List') and the resource ('shops'), and specifies the scope ('covered by elid_search_shop_prices'), which immediately distinguishes it from siblings like wine search or matching tools. The addition of what is included (observation counts, date ranges) further clarifies the exact output, leaving no ambiguity about the tool's function.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by linking to elid_search_shop_prices, suggesting that this tool is meant to be used when one needs to know the available shops for price queries. While it does not explicitly state 'use this when' or exclude alternatives, the reference to the sibling tool provides strong implicit guidance. For a simple listing tool, this is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
elid_match_wineMatch wine text to ELIDsARead-only
Match free wine text (e.g. 'Kanonkop Paul Sauer 2021', a label or a wine-list line) to ranked ELID base-wine identities. Returns elid, lwin, display_name, producer_name, wine and scores (for ranking only, not probabilities). An empty list means no accepted match. Vintages in the text are not part of the result: pass the vintage to elid_get_wine.
| Name | Required | Description | Default |
|---|---|---|---|
| raw | Yes | Wine text to match, up to 500 characters. | |
| top_n | No | Number of candidates, 1–20 (default 5). | |
| producer_id | No | Optional ELID producer code, e.g. ZA-KNKP. | |
| country_code | No | Optional two-letter country code to restrict matching, e.g. ZA. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description goes further: it states scores are ranking-only, not probabilities, that an empty list means no accepted match, and that vintages are not in the result – all crucial behavioral details an agent needs to interpret output.
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 sentences with the purpose up front, then return contract and a caveat. 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?
For a read-only matching tool with no output schema, the description covers what the result means (empty list, 'no accepted match'), what scores represent, and how vintages are handled. It also signals return fields, making agent interpretation 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 description coverage is 100%, with each parameter (raw, top_n, producer_id, country_code) already documented. The description adds only an example for `raw`, not new parameter semantics, so 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?
States the core function with a specific verb ('Match') and resource ('free wine text... to ranked ELID base-wine identities'). The example inputs and named return fields make the tool's purpose unambiguous and distinguish it from generic search 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?
Provides a direct routing instruction: 'Vintages in the text are not part of the result: pass the vintage to elid_get_wine.' This tells the agent when to hand off to a sibling. It doesn't explicitly contrast with elid_search_wines, but the 'free wine text' scope and example clarify typical use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
elid_search_shop_pricesSearch Swiss-market shop pricesARead-only
Search observed retailer prices from ~26 Swiss-market shops (plus gute-weine.de). Filter by free text (q), exact base ELID (elid) and vintage, shop (site), and CHF price range. Rows keep the source currency, bottle size, case quantity and observation date (scraped_at); missing values are null. These are historical observations, not current offers; shipping and taxes are not included. Always report vintage, size, currency, shop and date.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Free-text search, accent-insensitive, e.g. 'dom perignon 2015'. | |
| max | No | Maximum per-bottle price in CHF. | |
| min | No | Minimum per-bottle price in CHF. | |
| elid | No | Base ELID (vintage suffix is stripped and used as vintage if not given). | |
| site | No | Shop domain, e.g. gute-weine.de. See elid_list_shops. | |
| sort | No | Sort order (default recent). | |
| limit | No | Rows per page, 1–100 (default 20). | |
| offset | No | Pagination offset. | |
| vintage | No | Vintage year, e.g. 2015. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the readOnlyHint annotation by explaining that rows are historical observations, not current offers, that shipping/taxes are excluded, that missing values are null, and that source currency is preserved. This is critical behavioral context for interpreting results and avoiding misuse.
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 dense, well-ordered sentences: scope and filters first, then output semantics and caveats, then a clear reporting instruction. Every sentence earns its place without repetition or 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, the description compensates by naming key row fields (source currency, bottle size, case quantity, scraped_at) and null behavior. It also clarifies interpretation and warns about non-included costs. Combined with the readOnlyHint and openWorldHint annotations, the agent has enough context to call the tool correctly and interpret results.
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?
Input schema coverage is 100%, and each parameter already has a meaningful description. The description restates filters such as 'CHF price range' and 'shop (site)' but adds little semantic value beyond the schema, so the baseline of 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?
The description uses a specific verb and resource: 'Search observed retailer prices from ~26 Swiss-market shops'. It clearly distinguishes this tool from wine-metadata siblings like elid_search_wines and elid_match_wine by focusing on retailer price observations.
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 clear context for when to use the tool: searching historical Swiss shop prices, with explicit caveats that these are 'historical observations, not current offers' and that shipping/taxes are excluded. It does not explicitly name sibling alternatives, but the context strongly implies the intended niche.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
elid_search_winesSearch the ELID catalogARead-only
List ELID wine identities, ordered by ELID. Use q for a case-insensitive substring match on the name or ELID (e.g. 'kanonkop' or 'FR-CMP-DOMP'), or lwin for an exact seven-digit LWIN lookup. For free text such as a full label, prefer elid_match_wine. Paginate by passing next_cursor as after.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | Substring of the wine name or ELID. | |
| lwin | No | Exact seven-digit wine-level LWIN. | |
| after | No | next_cursor from the previous page. Keep other filters unchanged. | |
| limit | No | Results per page, 1–200 (default 50). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark the tool as read-only, and the description adds substantive behavioral detail: case-insensitive substring matching, exact seven-digit LWIN lookup, ordering, and cursor-based pagination. It does not describe the result shape, but that is less critical given the read-only annotation and search-oriented 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?
The description is three sentences with no filler. It front-loads the core purpose and ordering, then covers both query modes, sibling routing, and pagination efficiently.
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 search tool, the description covers query modes, ordering, pagination, and sibling differentiation. A small gap is that it does not explicitly state whether q and lwin are mutually exclusive or what happens if both are supplied, and there is no mention of the returned identity fields since 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?
Schema coverage is 100%, and the description adds real meaning beyond the schema: it explains case-insensitivity, gives examples, clarifies the 'after' cursor semantics ('keep other filters unchanged'), and states the default limit. Every parameter is made actionable.
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 a specific verb and resource ('List ELID wine identities') and adds ordering ('ordered by ELID'). It also explicitly contrasts with elid_match_wine, so an agent can distinguish the tools 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?
It states exactly when to use q versus lwin with concrete examples, and explicitly routes free-text label searches to elid_match_wine. Pagination instructions are also provided, leaving little ambiguity about use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
elid_get_wine - First observed
elid_list_shops - First observed
elid_match_wine - First observed
elid_search_shop_prices - First observed
elid_search_wines
TDQS
Scored across 5 tools
The tools are mostly distinct: match vs search vs get vs list shops vs search prices. One minor overlap: elid_match_wine and elid_search_wines both accept text, but descriptions clearly separate free-text matching from substring/ELID lookup.
All tools follow a consistent elid_<verb>_<noun> pattern (match_wine, search_wines, get_wine, list_shops, search_shop_prices). Minor inconsistency: 'search_wines' vs 'search_shop_prices' both use search, while 'list_shops' uses list, but the pattern is otherwise uniform.
Five tools is well-scoped for a wine identity and price lookup server. Each tool covers a distinct need: matching, searching, retrieving details, listing shops, and searching prices.
The surface covers the core workflow: match free text, get wine details, search prices, and list shops. Minor gaps: no tool for retrieving a specific shop's details or for filtering prices by multiple vintages at once, but agents can work around these.
Maintenance
Related MCP Connectors
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
100+ MCP tools for AI agents: content metadata, trade intelligence, business-expertise analysis.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Real-time Amazon, WIPO & PACER data for AI agents — 19 tools via the MCP protocol.
Related MCP Servers
- FlicenseAqualityDmaintenanceEnables AI agents to explore MySQL database schemas and execute read-only queries through a safe, MCP interface.6-
- FlicenseAqualityBmaintenanceEnables AI assistants to connect to MySQL databases, execute read-only queries, list tables, and describe table schemas via MCP.101-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to access curated SIP/VoIP documentation, troubleshoot traces, and analyze telecom configurations with 20+ read-only tools.MIT
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to analyze BigQuery datasets through MCP, using tools to inspect datasets and execute read-only SQL queries.-