Polvenn MCP Server
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., "@Polvenn MCP Serversearch new imperial stouts from the last 30 days"
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.
Polvenn MCP Server
A local-first MCP server for tracking beer releases on Vinmonopolet and an external release-feed API backed by your own collector/database.
npm package: @henrikogard/polvenn-mcp-server
CLI command: polvenn-mcp-server
It is designed to run as a local stdio MCP server:
no web app
no telemetry
no cloud sync
data stays on your machine in SQLite
What It Does
Polvenn exposes 8 MCP tools:
Tool | Description | Writes data? |
| Search Vinmonopolet's current | No |
| Search Vinmonopolet's "Kommende nyheter" listing for upcoming beer releases | No |
| Search current | No |
| Check stock for a beer at a Vinmonopolet store, using the official API when possible and Vinmonopolet's web stock locator as fallback | No |
| Find the closest Vinmonopolet stores to a coordinate | No |
| Add, remove, list, and check watch rules | Yes |
| Store API keys, home store, and home coordinates locally | Yes |
| Validate current config and probe upstream capabilities | No |
Typical use cases:
“Show me new imperial stouts from the last 30 days”
“Is article
20162402in stock near Stavanger?”“Find the nearest Vinmonopolet stores to my home”
“Alert me when Amundsen, Lervig, or pastry stouts show up”
If the official Vinmonopolet stock endpoint is not available, Polvenn falls back to Vinmonopolet's own web stock locator for store-level counts when possible. If neither source can verify the store, Polvenn reports store-level stock as unknown instead of incorrectly reporting zero stock or inferring "bestillingsutvalget" as a store-stock answer.
For polvenn_search_new_beers, the since filter is best-effort: Polvenn prefers external release dates when available, and otherwise falls back to Vinmonopolet's lastChanged timestamp.
If you pass storeId, only Vinmonopolet-backed results that are available in that store are included.
Related MCP server: trundler
Architecture
Any MCP client
(Codex, Claude Desktop, Inspector, others)
│
│ stdio
▼
polvenn-mcp-server
├── tools
├── zod schemas
├── Vinmonopolet service
├── External release feed client
└── SQLite storage via sql.js
│
▼
~/.polvenn/polvenn.dbProject structure:
src/
├── index.ts # MCP server entry point
├── constants.ts # URLs, defaults, retry settings
├── types.ts # Domain types
├── sql.js.d.ts # Local sql.js typings
├── tools/
│ └── index.ts # MCP tool registration and handlers
├── schemas/
│ └── tools.ts # Zod input schemas
├── services/
│ ├── release-feed.ts # External release feed client
│ ├── vinmonopolet.ts # Vinmonopolet API client
│ └── watchlist.ts # Watchlist matching logic
├── utils/
│ ├── geo.ts
│ ├── geo.test.ts
│ └── http.ts
└── db/
└── database.ts # SQLite persistence and configSetup
Prerequisites
Node.js 18 or newer
A Vinmonopolet API key from api.vinmonopolet.no
Install
npm install
npx tsc --noEmit
npm run buildPublished npm package:
npm install -g @henrikogard/polvenn-mcp-serverRun
npm startThis starts the MCP server on stdio, which is what local desktop/CLI MCP clients expect.
Using It From MCP Clients
Generic stdio client setup
If your MCP client supports local stdio servers, point it at:
command: node
args: ["/absolute/path/to/polvenn-mcp-server/dist/index.js"]If you installed the package globally from npm, you can also point the client directly at the CLI:
command: polvenn-mcp-server
args: []Claude Desktop
Add this to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"polvenn": {
"command": "node",
"args": ["/absolute/path/to/polvenn-mcp-server/dist/index.js"]
}
}
}After restarting Claude Desktop, configure your own collector from chat:
Configure polvenn with release feed URL https://releases.example.com.Codex
Codex supports MCP server definitions in ~/.codex/config.toml. Add:
[mcp_servers.polvenn]
command = "node"
args = ["/absolute/path/to/polvenn-mcp-server/dist/index.js"]Restart Codex after saving the config.
Then configure your own collector from a Codex chat:
Configure polvenn with release feed URL https://releases.example.com.ChatGPT
As of April 7, 2026, ChatGPT apps/custom MCP integrations use remote MCP servers over SSE or streaming HTTP, not local stdio servers.
That means this repo does not plug directly into ChatGPT in its current form.
To use Polvenn with ChatGPT, you would need to:
Wrap or rebuild it as a remote MCP server.
Expose it over HTTPS using SSE or streaming HTTP.
Add it in ChatGPT developer mode as an app/custom MCP integration.
In other words:
Codex and Claude Desktop can use this project directly as-is.
ChatGPT needs a remote deployment, not this local stdio process.
First-Time Configuration
Once connected from an MCP client, configure the local server with your keys and defaults.
External collector setup
Polvenn expects an external release collector that exposes:
GET /releases/latestYou can run your own collector from GitHub here:
Quick setup:
Clone the collector repo.
Run
npm install.Run
npm run build.Copy
polvenn-release-collector.config.example.jsontopolvenn-release-collector.config.json.Start it with
npm start.Verify
http://127.0.0.1:4100/health.Verify
http://127.0.0.1:4100/releases/latest?limit=3.
If you want to expose it publicly on a VPS, follow the deployment guide in the collector repo:
Once your collector is running, choose your own feed URL, for example:
releaseFeedUrl = http://127.0.0.1:4100or:
releaseFeedUrl = https://releases.example.comThat means the local MCP server will read from:
https://releases.example.com/releases/latest?limit=...Recommended order:
Set up your own
polvenn-release-collector.Verify its
/healthendpoint.Verify its
/releases/latest?limit=3endpoint.Start
polvenn-mcp-serverlocally in Codex or Claude Desktop.Configure Polvenn with the hosted
releaseFeedUrl.Validate the configuration from the MCP client.
Example prompts:
Configure polvenn with release feed URL https://releases.example.com.Configure polvenn with Vinmonopolet API key <key>.
Set home location to Stavanger (58.97, 5.73).
Set home store to 170.Validate my Polvenn configuration and tell me which integrations are working.Example Prompts
These work well in Codex, Claude Desktop, or another MCP client:
Search for new stouts from the last 30 days.Search for new beers available in store 116.Search for new beers from the 1. april 2026 release.Search for new beers and include upcoming Vinmonopolet web releases.Show upcoming beers from Vinmonopolet.Show upcoming sour beers from Vinmonopolet.Show new sour beers near my store.Check whether article 20162402 is in stock at store 170.Find the 5 closest Vinmonopolet stores to 58.97, 5.73.Add a watchlist rule for brewery Lervig.Check my watchlist against the latest release in my external feed.Watchlist Rules
The watchlist supports four rule types:
Type | Matches against | Example |
| Producer name |
|
| Beer style |
|
| Beer name |
|
| Beer name and producer |
|
Storage
All local state lives in:
~/.polvenn/polvenn.dbOverride the data directory with:
POLVENN_DATA_DIR=/some/pathStored data includes:
config values
watchlist rules
cached Vinmonopolet product lookups
API keys are stored locally and only sent to their respective upstream APIs.
Packaging
The package metadata is set up for npm publishing:
npm package name:
@henrikogard/polvenn-mcp-serverinstallable CLI entry:
polvenn-mcp-serverpackaged files limited to
dist/,README.md, andLICENSEprepackbuilds the TypeScript output before publishing
Data Sources
Vinmonopolet API
Base:
https://apis.vinmonopolet.noAuth:
Ocp-Apim-Subscription-KeyUsed for: products, stores, stock
Product lookups fall back to the public product page on
vinmonopolet.nowhen the API returns sparse article dataDocs: api.vinmonopolet.no
External Release Feed
Base: your configured
releaseFeedUrlEndpoint used by MCP:
GET /releases/latest?limit=NExpected response shape:
{
"releases": [
{
"id": "2026-04-01-main",
"title": "April 2026 main release",
"source": "vinmonopolet-monthly",
"publishedAt": "2026-04-01T08:00:00Z",
"url": "https://example.com/release/2026-04-01-main",
"items": [
{
"country": "Norge",
"articleNumber": "20162402",
"producer": "Amundsen Bryggeri",
"name": "Example Beer",
"style": "Imperial Stout",
"abv": 12,
"releaseDate": "1. april 2026"
}
]
}
]
}Development
npm run dev
npx tsc --noEmit
npm run build
npm testTest With MCP Inspector
npx @modelcontextprotocol/inspector node dist/index.jsDependencies
Package | Purpose |
| MCP server framework |
| SQLite in pure JavaScript |
| HTML parsing |
| Input validation |
| Build tooling |
Notes
The server is intentionally local-first and stdio-first.
Stock access may depend on the Vinmonopolet subscription tier you have.
ChatGPT support requires a remote MCP variant of this server.
License
MIT
Available Tools
8 toolspolvenn_check_store_stockCheck store stockARead-onlyIdempotent
Check if a specific beer is in stock at a Vinmonopolet store.
Args:
articleNumber (string): Vinmonopolet article number
storeId (string, optional): Store ID. Defaults to your configured home store.
Returns: Stock status and product details.
| Name | Required | Description | Default |
|---|---|---|---|
| storeId | No | Specific store ID. If omitted, uses your configured home store. | |
| articleNumber | Yes | Vinmonopolet article number (e.g. '20537202') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Description adds useful behavior beyond annotations: mentions return contents (stock status and product details) and the default store behavior. Annotations already declare read-only/idempotent/destructive hints, so this supplemental context is appropriate and not contradictory.
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?
Description is compact and front-loaded: purpose, args, returns in four lines. No filler or redundant explanation beyond a useful summary.
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 two-parameter tool, the description covers purpose, required/optional inputs, and return type. It does not specify exact stock status values or error cases, but these are not essential given the tool's simplicity and annotations.
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 already documents both parameters with 100% coverage, including the optional storeId default and an example article number. The description's Args section largely restates schema info without adding new semantic details.
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?
Clearly states the tool's function with a specific verb 'Check' and resource 'stock at a Vinmonopolet store'. It distinguishes from sibling search/config tools by focusing on checking availability for a specific article at a specific store.
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?
Description provides context that the tool is for checking stock and clarifies that storeId defaults to the home store. It does not explicitly mention when not to use it or alternative tools, but the intended use is clear and no exclusions are needed given the sibling tools' distinct purposes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_configureConfigure PolvennAIdempotent
Set the release feed URL, API key, home store, and location for the Polvenn MCP server.
Args (all optional — only provided values are updated):
releaseFeedUrl: Base URL for your external release feed API
vinmonopoletApiKey: Subscription key from api.vinmonopolet.no
homeStoreId: Your preferred Vinmonopolet store ID
homeLatitude: Home latitude for nearby lookups
homeLongitude: Home longitude for nearby lookups
Returns: Current configuration (keys are masked).
| Name | Required | Description | Default |
|---|---|---|---|
| homeStoreId | No | Your preferred Vinmonopolet store ID | |
| homeLatitude | No | Home latitude for nearby store lookups | |
| homeLongitude | No | Home longitude for nearby store lookups | |
| releaseFeedUrl | No | Base URL for your external release feed API | |
| vinmonopoletApiKey | No | Vinmonopolet API subscription key |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already express idempotency and non-destructiveness. The description adds that only supplied fields are modified and that the returned config masks keys, providing useful behavioral context (partial updates, security-sensitive output) beyond the structured metadata.
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 compact two-part structure: a one-sentence action summary followed by a scannable bullet list of arguments and a return note. Every element earns its place with no redundant wording.
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?
Covers purpose, parameters, return value, and the partial-update nuance; the masked-keys note is an important extra for an agent's trust evaluation. Given no output schema or nested objects, this is sufficiently complete for an AI to invoke 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 covers 100% of parameters with descriptions, giving a baseline of 3. The description enriches semantics by explaining 'only provided values are updated' and adds source hints (e.g., vinmonopoletApiKey from api.vinmonopolet.no), going beyond the schema's simple field names and descriptions.
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 'Set the release feed URL, API key, home store, and location for the Polvenn MCP server' with a clear verb and target resource. This clearly distinguishes polvenn_configure from sibling tools like polvenn_validate_config or polvenn_find_nearby_stores.
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 explicitly notes 'Args (all optional — only provided values are updated)', giving clear context for when to use it (config updates) and the partial-update behavior. It does not explicitly contrast against alternatives, but the configuration purpose is evident, so it meets the 'clear context, no exclusions' bar.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_find_nearby_storesFind nearby Vinmonopolet storesARead-onlyIdempotent
Find the closest Vinmonopolet stores to a given location.
Args:
latitude (number, optional): Defaults to configured home location
longitude (number, optional): Defaults to configured home location
maxResults (number): How many stores to return (default: 5)
Returns: List of nearby stores with address, distance, category, and opening hours.
| Name | Required | Description | Default |
|---|---|---|---|
| latitude | No | Latitude. Defaults to your configured home location. | |
| longitude | No | Longitude. Defaults to your configured home location. | |
| maxResults | No | Number of stores to return |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, idempotent, and non-destructive. The description adds useful context: latitude/longitude default to configured home location, and the return includes address, distance, category, and opening hours. This goes beyond the 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?
The description is well-structured with an Args/Returns layout and front-loaded purpose. However, the Args list largely duplicates schema descriptions, which is slightly redundant but not wasteful enough to drop below 4.
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 no output schema, the description adequately explains return values (list of stores with address, distance, category, opening hours) and optional parameter defaults. No critical behavioral details are missing for an agent to use it 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%, so the schema already documents all parameters. The description repeats the defaults (home location, maxResults=5) without adding new semantics about formatting, constraints, or edge cases, so 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?
The description states 'Find the closest Vinmonopolet stores to a given location' with a specific verb and resource, clearly distinguishing from siblings focused on beer stock/new releases. The return list of stores with address, distance, etc. reinforces the purpose.
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 provides clear context for when to use (nearby store lookup) and what it returns, but does not explicitly mention alternatives or when not to use it. The sibling polvenn_search_new_beers_near_store could be confused, but the description's focus on store details differentiates it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_search_new_beersSearch new beersARead-onlyIdempotent
Search for recently released beers on Vinmonopolet via the official API and/or your external release feed.
Args:
source ('vinmonopolet' | 'external' | 'both'): Where to search (default: 'both')
since (string, optional): Best-effort date filter yyyy-MM-dd using external release dates, otherwise Vinmonopolet lastChanged
includeUpcoming (boolean): Also include beers from Vinmonopolet's "Kommende nyheter" web filter
style (string, optional): Filter by beer style, e.g. 'IPA', 'Stout'
releaseDate (string, optional): Exact release date filter
storeId (string, optional): Limit Vinmonopolet-backed results to beers available in one store
limit (number): Max results (default: 25)
Returns: List of new beers with name, producer, style, ABV, article number, and release date.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results to return | |
| since | No | Best-effort date filter (yyyy-MM-dd). Uses external release dates when available, otherwise Vinmonopolet lastChanged. Defaults to 30 days ago. | |
| style | No | Filter by beer style, e.g. 'IPA', 'Stout', 'Sour' | |
| source | No | Where to look for new beers: Vinmonopolet API, your external release feed, or both | both |
| storeId | No | Filter Vinmonopolet-backed results to beers available in a specific store. Defaults to your configured home store when omitted in store-aware flows. | |
| releaseDate | No | Exact release date filter. Accepts yyyy-MM-dd or a Norwegian date like '1. april 2026'. | |
| includeUpcoming | No | Also include upcoming Vinmonopolet web releases from the 'Kommende nyheter' filter when available. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds behavioral context beyond these by explaining the 'best-effort date filter', the ability to include upcoming releases via 'Kommende nyheter', and the return format ('List of new beers with name, producer, style, ABV, article number, and release date'). This goes further than the annotations alone.
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 front-loaded with a one-sentence purpose, followed by a structured Args list and Returns line. It is not overly verbose but does repeat parameter information already present in the schema. Still, the structure is clear and scannable, and every sentence contributes to understanding the tool.
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 all 7 parameters are optional and the schema fully explains them, and there is no output schema, the description compensates by including a Returns section that lists the output fields. It covers the core functionality well, though it omits potential edge cases, error conditions, or pagination details. For a read-only search tool, this is adequate.
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 the schema already documents every parameter thoroughly. The Args list in the description adds no new meaning beyond the schema; in fact, it omits some schema details (e.g., the Norwegian date format for releaseDate). Since the baseline is 3 for full schema coverage, this score 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 opens with a clear, specific statement: 'Search for recently released beers on Vinmonopolet via the official API and/or your external release feed.' This names the verb (search), the resource (recently released beers on Vinmonopolet), and the data sources, distinguishing it from siblings like search_upcoming_beers or search_new_beers_near_store.
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 by stating what it searches, but it does not explicitly specify when to prefer this tool over alternatives, nor does it mention any exclusions or alternative tool names. For example, it doesn't say 'For upcoming beers, use search_upcoming_beers' or 'For store-specific queries, use check_store_stock'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_search_new_beers_near_storeSearch new beers near your storeARead-onlyIdempotent
Search Vinmonopolet's current "Nyheter" listing for beers available in one store.
Args:
storeId (string, optional): Store ID. Falls back to your configured home store, then your nearest store from your home coordinates
style (string, optional): Filter by beer style, e.g. 'IPA', 'Stout'
releaseDate (string, optional): Exact release date filter
limit (number): Max results (default: 25)
Returns: New beers currently available in the selected store, enriched with external release dates when recent feed items match.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results to return | |
| style | No | Filter by beer style, e.g. 'IPA', 'Stout', 'Sour' | |
| storeId | No | Store ID to search. Falls back to your configured home store, then your nearest store from your configured home coordinates. | |
| releaseDate | No | Exact release date filter. Accepts yyyy-MM-dd or a Norwegian date like '1. april 2026'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false. The description adds valuable behavioral detail beyond these: the storeId fallback chain ('Falls back to your configured home store, then your nearest store from your home coordinates') and the enrichment behavior ('enriched with external release dates when recent feed items match'). This extra context helps the agent understand what happens under the hood.
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 concise and well-structured: a one-sentence purpose, an Args list, and a Returns line. However, the Args list partially duplicates the schema descriptions, which is slightly redundant. Still, it's efficient and front-loaded with the key purpose.
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?
Without an output schema, the description explains the return value ('New beers currently available in the selected store, enriched with external release dates when recent feed items match'). It also covers parameter fallback behavior and the filtering options. It could be more verbose about the exact fields returned, but for a read-only search tool with strong annotations, this is adequate.
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%, with each parameter already well-described in the JSON schema (e.g., releaseDate accepts 'yyyy-MM-dd or a Norwegian date like "1. april 2026"'). The description's Args section largely duplicates this information without adding new semantics. Since the schema carries the heavy lifting, a baseline score 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 clearly states the tool's function: 'Search Vinmonopolet's current "Nyheter" listing for beers available in one store.' It specifies the resource (Vinmonopolet's Nyheter), the action (search), and the unique scope (store-specific), which distinguishes it from sibling tools like polvenn_search_new_beers (which lacks store filtering) and polvenn_check_store_stock (which checks stock for specific products).
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 provides clear context for when to use this tool: when you want new beers from a specific store, with fallback logic for store selection. However, it does not explicitly mention alternatives or when not to use it, relying instead on the name and sibling context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_search_upcoming_beersSearch upcoming beersARead-onlyIdempotent
Search Vinmonopolet's "Kommende nyheter" web listing for upcoming beer releases.
Args:
style (string, optional): Filter by beer style, e.g. 'IPA', 'Stout'
limit (number): Max results (default: 25)
Returns: List of upcoming beers with name, producer, style, ABV, article number, and current website status.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum results to return | |
| style | No | Filter by beer style, e.g. 'IPA', 'Stout', 'Sour' |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already communicate that this is a safe, read-only, idempotent operation, so no safety disclaimers are needed. The description adds context about the data being from a live website listing and includes 'current website status' in the returns, providing some behavioral insight beyond the annotations. No contradictions exist.
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 compact paragraph followed by a clear parameter list and a return note. It is front-loaded with the primary purpose and avoids redundancy, making it easy to parse.
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 helpfully lists the expected return fields (name, producer, style, ABV, article number, website status). It also covers parameters and purpose. However, it omits any mention of configuration prerequisites or dependencies on other tools, which is a notable gap considering the sibling tools include polvenn_configure and polvenn_validate_config.
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?
Both parameters (style and limit) are fully documented in the input schema with types, defaults, and examples. The tool description essentially restates these, adding only a slightly less detailed example for style. Given the high schema coverage, the description adds minimal additional semantic value, hence a baseline score of 3.
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 explicitly identifies the resource (Vinmonopolet's 'Kommende nyheter' web listing) and the action ('Search upcoming beer releases'), which distinguishes it from sibling tools like polvenn_search_new_beers that target different listings. The verb 'Search' is concrete and the scope is clear.
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 clearly indicates the tool is for finding upcoming beer releases, giving an agent a clear context for when to invoke it. However, it falls short of explicitly naming alternative tools for other scenarios (e.g., search_new_beers for current releases), so it earns a 4 rather than a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_validate_configValidate Polvenn configurationARead-onlyIdempotent
Validate current Polvenn configuration and run lightweight capability checks against upstream services.
Checks:
local config presence
external release feed access
Vinmonopolet product and store access
Vinmonopolet stock endpoint accessibility
Returns: A capability report with pass/warn/fail statuses.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate read-only, idempotent, non-destructive behavior. The description adds value by listing specific checks and the return format (pass/warn/fail), providing context beyond the 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?
The description is concise and well-structured: a single opening sentence, a bulleted list of checks, and a closing line about the return type. Every element adds value with no waste.
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 no-parameter tool with no output schema, the description fully covers what the tool does, what it checks, and what it returns. No critical information 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?
With zero parameters, the baseline is 4. The description doesn't need to explain parameters, and it doesn't, which 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 states a specific verb ('Validate') and resource ('Polvenn configuration'), followed by concrete checks. It clearly distinguishes from sibling tools that focus on searching or stock checking.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context is clear: this tool is for validating configuration and checking service accessibility. It doesn't explicitly exclude alternatives or name when-not-to-use, but its purpose is distinct enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
polvenn_watchlistBeer watchlistA
Manage your beer watchlist. Track breweries, styles, series, or keywords to get notified about matching releases.
Args:
action ('add' | 'remove' | 'list' | 'check'): What to do
type ('brewery' | 'style' | 'series' | 'keyword'): Rule type (required for 'add')
value (string): What to watch for (required for 'add')
id (number): Entry ID to remove (required for 'remove')
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | Watchlist entry ID (required for 'remove') | |
| type | No | Type of watch rule (required for 'add') | |
| value | No | Value to watch for (required for 'add') | |
| action | Yes | Watchlist action: add a rule, remove by ID, list all rules, or check for matches |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already indicating readOnlyHint=false and openWorldHint=true, the description adds useful context by stating that the tool tracks rules and gets users notified about matching releases. It discloses the action variants but does not detail side effects of 'check' or removal consequences beyond the schema. The annotations cover safety; the description adds moderate behavioral context.
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 concise and well-structured: a clear one-sentence summary followed by a structured Args list. No wasted words, and the format makes the action-parameter relationships easy to scan.
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?
This multi-action tool has no output schema, so the description should ideally explain return values or side effects. It defines actions and their inputs but does not clarify what 'list' or 'check' return, nor whether 'check' triggers notifications immediately. Despite this gap, the description covers the core purpose and parameter dependencies well for the tool's moderate complexity.
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% with every parameter described, so the baseline is 3. The description's Args block restates the parameter conditions (e.g., 'required for add') but adds no new meaning beyond what the schema already provides. It is helpful grouping but not compensatory.
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 opens with 'Manage your beer watchlist', a specific verb and resource, and further specifies trackable entities (breweries, styles, series, keywords). This clearly differentiates it from sibling tools focused on store stock and beer search.
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 the available actions (add/remove/list/check) but provides no explicit guidance on when to prefer this tool over siblings like search_new_beers or check_store_stock. Usage context is implied through the watchlist domain, but no alternatives or exclusions are mentioned.
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.
8 tool updates
v0.1.2- First observed
polvenn_check_store_stock - First observed
polvenn_configure - First observed
polvenn_find_nearby_stores - First observed
polvenn_search_new_beers - First observed
polvenn_search_new_beers_near_store - First observed
polvenn_search_upcoming_beers - First observed
polvenn_validate_config - First observed
polvenn_watchlist
TDQS
Scored across 8 tools
Most tools are distinct, but the three search tools (search_upcoming_beers, search_new_beers, search_new_beers_near_store) have overlapping functionality, especially since search_new_beers can include upcoming results. Descriptions clarify differences, but there's a risk of selecting the wrong one.
Tool names follow a consistent pattern with the 'polvenn_' prefix and verb_noun format (e.g., check_store_stock, search_new_beers). The exception is 'polvenn_watchlist' which uses a noun instead of a verb action, but it's still clearly named.
With 8 tools, the server is well-scoped for its purpose: searching new/upcoming beers, checking stock, finding stores, managing a watchlist, and configuration. Each tool serves a distinct need without being excessive.
The domain of beer release tracking and store stock is well covered, including search, stock, store location, watchlist, and config. However, there's no general search for all beers, only new/upcoming, which may be a gap for users wanting to look up existing products.
Maintenance
Related MCP Connectors
MCP server for the Émile wine cellar — list, add, recommend, scan and search 100k+ wines.
Unlock the power of food transparency with our Open Food Facts MCP server. Easily look up any food
Trust, freshness, policy, and discovery layer for public MCP servers.
Related MCP Servers
- AlicenseBqualityAmaintenanceA local-first nutrition MCP server for food search, barcode lookup, meal estimation, intake logging, hydration, and nutrition coaching workflows.4690 npm9MIT
- AlicenseAqualityAmaintenanceA local MCP server for grocery shopping, enabling product search, specials, and browsing across NZ supermarkets, with cart and order history for Countdown/Woolworths via browser-assisted login.141MIT
- AlicenseAqualityAmaintenanceAn MCP server that interfaces with Untappd's mobile API to search beers, breweries, venues, and user data, and to post check-ins, toasts, and comments using your own account.45698 npmMIT
- AlicenseNot gradedqualityAmaintenanceMCP server for Untappd connectivity, enabling beer search with optional limit, offset, and sorting.MIT