Skip to main content
Glama
markusl
by markusl

Alko MCP Server

A production-grade Model Context Protocol (MCP) server that provides AI assistants with access to the Alko.fi alcohol product catalog.

Features

  • Product Search: Search 11,900+ products by name, type, country, price range, alcohol %, and more

  • Product Details: Get detailed information including enriched data (taste profile, food pairings, certificates, serving suggestions)

  • Vivino Ratings: Get wine ratings from Vivino.com by name or URL

  • Store Hours: Check store opening hours with "open now" filtering

  • Store Availability: Check real-time stock availability at Alko stores (via web scraping)

  • Recommendations: Get product recommendations based on food pairings, occasions, and preferences

  • Store Listing: Browse 360+ Alko stores by city

All tools return compact JSON for efficient LLM token usage.

Related MCP server: MatMCP

Demo

Claude Desktop using Alko MCP to search products, check availability, and get recommendations.

MCP Tools

Tool

Description

search_products

Search products by name, type, country, price range, alcohol %

get_product

Get product details. Set includeEnrichedData=true for taste, food pairings, serving tips

get_store_hours

Get store opening hours. Filter by city, name, or openNow=true. Auto-refreshes if stale

get_availability

Check store stock for a product (scrapes alko.fi)

list_stores

List Alko stores by city

get_recommendations

Get personalized product recommendations

get_vivino_rating

Get Vivino wine rating by name or URL (scrapes vivino.com)

sync_products

Sync database with latest Alko price list

get_sync_status

Check sync status and product count

Quick Start

Prerequisites

  • Node.js 24+

  • Google Cloud Firestore (or emulator for local dev)

  • Playwright (auto-installed for web scraping)

Installation

# Clone the repository
git clone https://github.com/yourusername/alko-mcp.git
cd alko-mcp

# Install dependencies
npm install

# Install Playwright browsers
npx playwright install chromium

# Build
npm run build

Local Development with Firestore Emulator

Step 1: Start Firestore Emulator (keep running in background)

gcloud emulators firestore start --host-port=localhost:8081

Step 2: Start Claude Desktop (or other AI assistant)

The MCP server will automatically load bundled seed data (~12,000 products, ~360 stores) on first query if the emulator is empty. No manual sync required!

Note: The emulator doesn't persist data. After restarting the emulator, seed data will be auto-loaded again on first use.

Optional: Fresh Data Sync

If you need the latest product data from Alko.fi:

export FIRESTORE_EMULATOR_HOST=localhost:8081

# Sync fresh products from Excel (~30 seconds)
npm run sync-data

# Sync fresh stores from website (~2 minutes)
npm run sync-stores

# Export to seed file (for sharing with team)
npm run export-seed

AI Assistant Configuration

Claude Desktop

Config file: ~/Library/Application Support/Claude/claude_desktop_config.json (macOS)

Local development:

{
  "mcpServers": {
    "alko": {
      "command": "node",
      "args": ["/absolute/path/to/alko-mcp/dist/server.js"],
      "env": {
        "FIRESTORE_EMULATOR_HOST": "localhost:8081"
      }
    }
  }
}

Production (Cloud Run):

{
  "mcpServers": {
    "alko": {
      "url": "https://YOUR-CLOUD-RUN-URL.run.app/mcp",
      "transport": "streamable-http"
    }
  }
}

ChatGPT Desktop

Config file: ~/.config/chatgpt/mcp.json (macOS/Linux) or %APPDATA%\chatgpt\mcp.json (Windows)

Local development:

{
  "servers": {
    "alko": {
      "command": "node",
      "args": ["/absolute/path/to/alko-mcp/dist/server.js"],
      "env": {
        "FIRESTORE_EMULATOR_HOST": "localhost:8081"
      }
    }
  }
}

Production (Cloud Run):

{
  "servers": {
    "alko": {
      "url": "https://YOUR-CLOUD-RUN-URL.run.app/mcp",
      "transport": "streamable-http"
    }
  }
}

Google Gemini (AI Studio)

For Gemini, use HTTP transport. Start the server with:

MCP_TRANSPORT=http PORT=3000 node dist/server.js

Then configure in AI Studio with the MCP endpoint URL:

http://localhost:3000/mcp

For production, deploy to Cloud Run with API token authentication (see below).

Claude Code CLI

Add to your project's .mcp.json:

{
  "mcpServers": {
    "alko": {
      "command": "node",
      "args": ["./dist/server.js"],
      "env": {
        "FIRESTORE_EMULATOR_HOST": "localhost:8081"
      }
    }
  }
}

Example Prompts

Etsi minulle hyviä italialaisia punaviinejä alle 20 euroa

Searches for Italian red wines under €20

🍷 Wine Recommendations

Suosittele viiniä grillatulle lohelle. Budjetti noin 15-25 euroa.

Recommends wine for grilled salmon within budget

🥂 Champagne & Sparkling

Mitä samppanjoita Alkossa on saatavilla? Näytä 5 parasta vaihtoehtoa.

Lists champagne options

Etsi IPA-oluita Suomesta tai muista Pohjoismaista

Searches for Nordic IPA beers

📊 Product Details

Kerro lisää tuotteesta numero 906458

Gets detailed product information with taste profile

🏪 Store Hours

Mitkä Alkon myymälät ovat auki nyt Helsingissä?

Lists Helsinki stores that are open now

📍 Store Availability

Onko Barolo-viiniä saatavilla Helsingin myymälöissä?

Checks product availability in Helsinki stores

🎁 Gift Recommendations

Etsi lahjaideoita viininystävälle. Budjetti 50-100 euroa.

Premium gift ideas for wine lovers

🧀 Food Pairing (uses Alko's official pairing data)

Suosittele viiniä äyriäisille / Recommend wine for seafood

Uses Alko's food symbol search to find products officially tagged for seafood pairing

Tarvitsen viinin juustolautaselle. Juustot: brie, manchego ja sinihomejuusto.

Wine for cheese platter - matches "miedot juustot" and "voimakkaat juustot"

Hae espanjalaisia punaviinejä Rioja-alueelta

Spanish wines from Rioja region

💰 Budget Shopping

Parhaat viinit alle 10 eurolla arki-iltoihin

Best budget wines for weeknight dinners

🍾 Special Occasions

Suosittele kuohuviiniä uudenvuoden juhliin 20 hengelle

Sparkling wine for New Year's party

⭐ Vivino Ratings

Etsi punaviinejä 15-25€ ja tarkista niiden Vivino-arvostelut

Searches for red wines and checks their Vivino ratings

🏆 Best Rated Wines

Mikä on Alkon parhaiten arvioitu Barolo Vivinossa?

Finds Barolo wines and compares their Vivino ratings

📈 Wine Comparison

Vertaile näiden viinien Vivino-arvosanoja: Amarone, Brunello di Montalcino

Compares Vivino ratings for premium Italian wines

Data Sources

Product Catalog

  • Source: Alko's public Excel price list

  • URL: https://www.alko.fi/INTERSHOP/static/WFS/Alko-OnlineShop-Site/-/Alko-OnlineShop/fi_FI/Alkon%20Hinnasto%20Tekstitiedostona/alkon-hinnasto-tekstitiedostona.xlsx

  • Products: ~11,900

  • Update: Run npm run sync-data

Store Data

  • Source: Scraped from alko.fi store finder

  • Stores: ~360

  • Includes: Name, address, opening hours (today/tomorrow)

  • Update: Run npm run sync-stores

Enriched Product Data

  • Source: Scraped from individual product pages

  • Includes: Taste profile, usage tips, serving suggestions, food pairings, certificates, ingredients

  • Cached: Persisted to Firestore after first scrape

Product Fields

Field

Description

id

Product ID (e.g., "004246")

name

Product name

producer

Producer/manufacturer

price

Price in EUR

pricePerLiter

Price per liter

bottleSize

Volume (e.g., "0.75 l")

type

Category (punaviinit, valkoviinit, oluet, etc.)

subtype

Flavor profile (e.g., "Mehevä & Hilloinen")

country

Country of origin

region

Wine region

alcoholPercentage

Alcohol %

description

Taste description from Excel

tasteProfile

Detailed taste (enriched, scraped)

usageTips

Usage suggestions (enriched)

servingSuggestion

Serving temperature (enriched)

foodPairings

Food pairing symbols (enriched)

certificates

Certification labels: Luomu, Vegaani, etc. (enriched)

ingredients

Producer declared ingredients (enriched)

assortment

vakiovalikoima, tilausvalikoima, etc.

Development

npm run build        # Compile TypeScript
npm run dev          # Run with tsx watch mode
npm run test         # Run tests in watch mode
npm run test:run     # Run tests once (232 tests)
npm run typecheck    # Type check
npm run sync-data    # Sync products from Excel
npm run sync-stores  # Scrape stores from website
npm run export-seed  # Export data to seed file (with diff)

Logs

tail -f /tmp/alko-mcp.log

Deployment to Google Cloud Run

The server can be deployed to Cloud Run with public access (no authentication) for compatibility with ChatGPT and other MCP clients.

# Enable APIs
gcloud services enable run.googleapis.com firestore.googleapis.com artifactregistry.googleapis.com cloudbuild.googleapis.com

# Create Firestore database
gcloud firestore databases create --location=europe-north1

# Deploy using Cloud Build
gcloud builds submit --config=cloudbuild.yaml

# Or deploy directly from source
gcloud run deploy alko-mcp \
  --source . \
  --region europe-north1 \
  --memory 2Gi \
  --cpu 2 \
  --execution-environment gen2 \
  --set-env-vars="MCP_TRANSPORT=http" \
  --allow-unauthenticated

Test the endpoint:

curl -X POST https://alko-mcp-xxx.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

See DEPLOYMENT.md for API token authentication and other options.

  • The Alko price list is publicly available data

  • Web scraping respects rate limits (2s between requests)

  • This is an unofficial project not affiliated with Alko Oy

  • Alcohol products can only be purchased by persons 18+ in Finland

License

MIT License

Available Tools

9 tools
get_availabilityCheck Product StockA
Read-onlyIdempotent

Check real-time product availability at Alko stores. Returns store names with stock quantities. Filter by city. Scrapes alko.fi for live data.

ParametersJSON Schema
NameRequiredDescriptionDefault
productIdYesThe Alko product ID (e.g., "906458")
cityNoFilter by city name (e.g., "Helsinki", "Tampere")
forceRefreshNoForce a fresh scrape instead of using cached data

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=true, and idempotentHint=true, covering safety and idempotency. The description adds valuable behavioral context beyond annotations: it discloses the data source ('Scrapes alko.fi for live data'), real-time nature, and caching behavior ('Force a fresh scrape instead of using cached data'), which are not captured in annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose in the first sentence, followed by return details, filtering, and data source. Each sentence adds essential information without redundancy, making it efficient and well-structured for quick comprehension.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (3 parameters, no output schema), the description is mostly complete. It covers purpose, data source, and key behaviors. However, it lacks details on output format (e.g., structure of returned store names and quantities) and error handling, which would be helpful since there's no output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with clear descriptions for all parameters (productId, city, forceRefresh). The description adds minimal semantic value beyond the schema, only implying filtering by city and caching behavior, which are already covered in parameter descriptions. Baseline 3 is appropriate given high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Check real-time product availability'), resource ('at Alko stores'), and scope ('Returns store names with stock quantities'). It distinguishes from siblings like 'get_product' (product details), 'list_stores' (store listings), and 'search_products' (product search) by focusing on stock availability with store-level granularity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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 ('Check real-time product availability at Alko stores') and mentions filtering capability ('Filter by city'). However, it does not explicitly state when NOT to use it or name specific alternatives among the sibling tools, such as 'get_product' for product details without stock data.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_productGet Product by IDA
Read-onlyIdempotent

Retrieve detailed product info by Alko product ID. Optional: includeEnrichedData=true adds taste profile, food pairings, serving tips (slower, scrapes alko.fi).

ParametersJSON Schema
NameRequiredDescriptionDefault
productIdYesThe Alko product ID (e.g., "906458")
includeEnrichedDataNoIf true, scrapes additional data from product page: taste profile, usage tips, serving suggestions, and food pairings. This is slower but provides more detailed information.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only, idempotent, non-destructive, and open-world behavior, but the description adds valuable context beyond this: it discloses that includeEnrichedData=true triggers web scraping ('scrapes alko.fi') and impacts performance ('slower'). This provides practical behavioral insights not captured in annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences: the first states the core purpose, and the second explains the optional parameter with its benefits and trade-offs. Every word adds value, with no redundancy or fluff, making it efficiently front-loaded and easy to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (2 parameters, no output schema), the description is nearly complete: it covers purpose, parameter usage, and behavioral nuances. However, without an output schema, it could briefly hint at the return structure (e.g., 'detailed product info' is vague) to achieve full completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents both parameters. The description adds some semantic context for includeEnrichedData (e.g., 'taste profile, food pairings, serving tips'), but this largely overlaps with the schema's description. No new parameter details are introduced beyond what the schema provides, meeting the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('Retrieve') and resource ('detailed product info'), specifies the key identifier ('by Alko product ID'), and distinguishes from siblings like 'search_products' by focusing on single-item lookup rather than search. This is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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 the optional parameter (includeEnrichedData=true for taste profiles, food pairings, etc.), including a performance trade-off ('slower, scrapes alko.fi'). However, it does not explicitly state when to choose this tool over alternatives like 'search_products' or 'get_recommendations', which would be needed for a score of 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recommendationsGet Wine/Drink RecommendationsA
Read-onlyIdempotent

Get personalized product recommendations. Specify occasion, food pairing (uses Alko official pairing data), price range, or preferences (organic, vegan). Supports 33 food categories.

ParametersJSON Schema
NameRequiredDescriptionDefault
preferredTypesNoPreferred product types (e.g., ["punaviinit", "viskit"])
priceRangeNoPrice range for recommendations
occasionNoOccasion for the drink (e.g., "dinner party", "gift", "casual")
foodPairingNoFood to pair with. Uses Alko's official food pairing data. Supported categories (Finnish/English): Äyriäiset (seafood/shrimp/lobster/crab), Rasvainen kala (salmon/tuna/mackerel), Vähärasvainen kala (cod/halibut/white fish), Kana, kalkkuna (chicken/turkey/poultry), Nauta (beef/steak), Porsas (pork/ham/bacon), Lammas (lamb), Riista (game/venison/elk), Riistalinnut (duck/pheasant/goose), Sushi (sushi/sashimi/japanese), Pasta ja pizza (pasta/pizza/italian), Grilliruoka (grilled/bbq), Itämainen ruoka (asian/thai/chinese/indian), Tulinen ruoka (spicy/curry/chili), Salaatit, kasvisruoka (salad/vegetarian/vegan), Miedot juustot (mild cheese/brie/mozzarella), Voimakkaat juustot (strong cheese/blue cheese/parmesan), Simpukat ja osterit (mussels/oysters/clams), Sienet (mushrooms/truffle), Makea jälkiruoka (dessert/chocolate/cake), Aperitiivi (aperitif), Seurustelujuoma (social/party), Nautiskelujuoma (digestif/nightcap), Tapas ja antipasti (tapas/antipasti/mezze), Pikkusuolaiset (snacks/finger food), Keitot (soup/stew), Noutopöytä (buffet), Blinit (blini)
preferOrganicNoPrefer organic products
preferVeganNoPrefer vegan-suitable products
countryNoPreferred country of origin
limitNoNumber of recommendations

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare this as a safe read operation (readOnlyHint: true, destructiveHint: false, idempotentHint: true). The description adds useful context about the food pairing data source ('Alko official pairing data') and the 33 food categories support, but doesn't disclose rate limits, authentication needs, or return format details beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured in two sentences: the first states the core purpose and key parameters, the second adds important context about the food pairing system. Every word earns its place with no redundancy or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only recommendation tool with comprehensive annotations and full schema coverage, the description provides adequate context about what the tool does and its key features. The main gap is the lack of output schema, so the description doesn't explain what the recommendations look like (e.g., format, fields returned), but this is partially mitigated by the tool's straightforward purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the schema already documents all 8 parameters thoroughly. The description adds marginal value by mentioning the same parameters (occasion, food pairing, price range, preferences) but doesn't provide additional syntax, format details, or usage examples beyond what's in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Get personalized product recommendations') and resources ('wine/drink'), distinguishing it from siblings like get_product (single product) or search_products (unfiltered search). It explicitly mentions the recommendation aspect and personalization criteria.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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 ('personalized product recommendations') and lists specific filtering criteria (occasion, food pairing, price range, preferences). However, it doesn't explicitly state when NOT to use it or name alternatives like search_products for broader searches.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_store_hoursGet Store Opening HoursA
Read-onlyIdempotent

Get Alko store opening hours for today and tomorrow. Filter by store name, city, or openNow=true for currently open stores. Auto-refreshes stale data.

ParametersJSON Schema
NameRequiredDescriptionDefault
storeIdNoSpecific store ID to get hours for
storeNameNoSearch by store name (partial match, e.g., "Kamppi" or "Helsinki Arkadia")
cityNoFilter by city name (e.g., "Helsinki", "Tampere")
openNowNoFilter to only show stores currently open
limitNoMaximum number of stores to return

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable behavioral context beyond what annotations provide: 'Auto-refreshes stale data' reveals a caching/refresh behavior not indicated by annotations. The annotations already cover read-only, open-world, idempotent, and non-destructive aspects, so the description appropriately supplements rather than contradicts them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is efficiently structured in two sentences that each earn their place: first establishes core purpose, second adds filtering details and behavioral nuance. No wasted words, front-loaded with essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity, comprehensive annotations, and full parameter documentation, the description provides good contextual coverage. The main gap is the lack of output schema, so the description doesn't explain return format, but this is reasonable given the annotations and clear purpose.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the input schema already documents all 5 parameters thoroughly. The description mentions filtering by store name, city, or openNow, which aligns with but doesn't add significant meaning beyond the schema. This meets the baseline expectation when schema coverage is complete.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Get Alko store opening hours'), resource ('Alko store'), scope ('for today and tomorrow'), and distinguishes from siblings by focusing on hours rather than availability, products, or store listings. It goes beyond just restating the name/title.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about when to use this tool (to get opening hours for today/tomorrow with filtering capabilities). However, it doesn't explicitly mention when NOT to use it or name specific alternatives among the sibling tools (e.g., when to use list_stores instead).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_sync_statusGet Database StatusA
Read-onlyIdempotent

Check database health: product count, last sync timestamp, sync status. Use to verify data freshness before searches.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide strong behavioral hints (readOnly, non-destructive, idempotent, closed-world). The description adds value by explaining the tool's purpose in checking health metrics, but it doesn't disclose additional behavioral traits like potential rate limits, authentication needs, or what 'sync status' entails beyond what annotations cover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is highly concise and well-structured: two sentences that efficiently convey the tool's purpose and usage guideline. Every sentence adds value without redundancy, making it easy to parse and understand quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (0 parameters, no output schema) and rich annotations, the description is reasonably complete. It explains what the tool does and when to use it, though it could be more comprehensive by detailing the return format or error conditions, which aren't covered by annotations or an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 0 parameters with 100% coverage, so no parameter documentation is needed. The description appropriately doesn't discuss parameters, focusing instead on the tool's purpose and usage. This meets the baseline for tools with no parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Check database health' with specific metrics (product count, last sync timestamp, sync status). It uses a specific verb ('Check') and resource ('database health'), though it doesn't explicitly differentiate from sibling tools like 'get_availability' or 'sync_products' which might have related purposes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

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: 'to verify data freshness before searches.' This gives a practical guideline, but it doesn't explicitly state when NOT to use it or mention alternatives among siblings (e.g., 'sync_products' for syncing data).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_vivino_ratingGet Vivino Wine RatingA
Read-onlyIdempotent

Look up wine ratings from Vivino.com. Search by wine name/winery or provide direct URL. Returns: average rating (1-5 stars), rating count, wine details. Results are cached.

ParametersJSON Schema
NameRequiredDescriptionDefault
wineNameNoThe wine name to search for on Vivino (e.g., "Chateau Margaux")
wineryNoThe winery/producer name to help narrow down the search
vivinoUrlNoDirect Vivino URL if known (e.g., "https://www.vivino.com/wines/1129971")

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable behavioral context beyond annotations by disclosing that 'results are cached', which is not covered by the annotations (readOnlyHint, openWorldHint, idempotentHint, destructiveHint). This informs the agent about performance and data freshness considerations. No contradictions with annotations exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose, followed by usage details and return values, all in three concise sentences. Each sentence earns its place by providing essential information without redundancy, making it efficient and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity, lack of output schema, and rich annotations, the description is mostly complete. It covers purpose, usage, return values, and caching behavior. However, it could improve by detailing output structure (e.g., format of 'wine details') or error handling, though annotations help mitigate some gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the input schema already fully documents the three parameters (wineName, winery, vivinoUrl). The description adds minimal semantic value by mentioning search methods but does not elaborate on parameter interactions or usage beyond what the schema provides, aligning with the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('look up', 'search') and resources ('wine ratings from Vivino.com'). It distinguishes itself from siblings by focusing on wine ratings rather than availability, products, recommendations, or store operations, making its unique function immediately apparent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use this tool by specifying search methods ('by wine name/winery or provide direct URL'). However, it does not explicitly state when not to use it or name alternatives among siblings, such as using 'search_products' for broader product searches instead of Vivino-specific ratings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_storesList Alko StoresA
Read-onlyIdempotent

List all ~360 Alko stores in Finland. Filter by city name. Returns: store id, name, address, city, postal code.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityNoFilter by city name (e.g., "Helsinki", "Tampere")
limitNoMaximum number of stores to return

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true, destructiveHint=false, idempotentHint=true, and openWorldHint=false. The description adds valuable context beyond annotations by specifying the approximate dataset size (~360 stores), the geographic scope (Finland), and the return format (store id, name, address, city, postal code). It doesn't contradict annotations and provides useful operational context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise (two sentences) and front-loaded with the core purpose. Every word earns its place: the first sentence establishes scope and filtering, the second specifies return format. No wasted words or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with comprehensive annotations and 100% schema coverage, the description provides good context about dataset size, geographic scope, and return format. The main gap is the lack of output schema, but the description compensates by explicitly listing return fields. It could be more complete by mentioning pagination behavior or result ordering.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with both parameters (city and limit) fully documented in the schema. The description mentions filtering by city name but doesn't add any semantic details beyond what the schema already provides (e.g., city parameter examples or limit behavior). Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb ('List') and resource ('all ~360 Alko stores in Finland'), specifies the scope ('Filter by city name'), and distinguishes from siblings by focusing on store listings rather than availability, products, or other operations. It provides concrete details about the dataset size (~360 stores) and geographic context (Finland).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool ('Filter by city name'), providing clear context for its filtering capability. However, it doesn't mention when NOT to use it or name specific alternatives among the sibling tools (e.g., get_store_hours for hours information), leaving some room for improvement in distinguishing from closely related siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_productsSearch Alko ProductsA
Read-onlyIdempotent

Search Finnish Alko alcohol catalog (~12,000 products). Filter by name, type, country, price, alcohol%. Returns: id, name, price, type, country, alcohol%, producer.

ParametersJSON Schema
NameRequiredDescriptionDefault
queryNoText search query for product name, producer, or description
typeNoProduct type (e.g., "punaviinit", "oluet", "viskit")
countryNoCountry of origin (e.g., "Ranska", "Italia", "Suomi")
regionNoRegion within country (e.g., "Bordeaux", "Toscana")
minPriceNoMinimum price in EUR
maxPriceNoMaximum price in EUR
minAlcoholNoMinimum alcohol percentage
maxAlcoholNoMaximum alcohol percentage
assortmentNoAssortment type: vakiovalikoima (in stores), tilausvalikoima (order only)
specialGroupNoSpecial group (e.g., "Luomu", "Vegaaneille soveltuva tuote")
beerTypeNoBeer type for beer products (e.g., "ipa", "lager", "stout & porter")
isNewNoFilter for new products only
isOrganicNoFilter for organic products only
isVeganNoFilter for vegan-suitable products only
minSmokinessNoMinimum smokiness level (0-4, for whiskeys: 0=ei savuinen, 4=voimakkaan savuinen)
maxSmokinessNoMaximum smokiness level (0-4, for whiskeys: 0=ei savuinen, 4=voimakkaan savuinen)
sortByNoField to sort byname
sortOrderNoSort orderasc
limitNoMaximum number of results to return
offsetNoNumber of results to skip for pagination

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering safety and idempotency. The description adds valuable context by specifying the catalog size (~12,000 products) and listing return fields, which helps set expectations for result volume and format. No contradictions with annotations exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, dense sentence that efficiently conveys purpose, scope, filtering parameters, and return values without any wasted words. It's front-loaded with the core functionality and appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a search tool with rich annotations (read-only, idempotent) and 100% schema coverage, the description provides adequate context by detailing the catalog scope and return structure. However, without an output schema, it could benefit from mentioning pagination behavior or result limits, though the schema covers 'limit' and 'offset' parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with detailed parameter documentation in the schema itself. The description mentions filtering capabilities ('Filter by name, type, country, price, alcohol%') and return fields, but adds minimal semantic value beyond what the schema already provides. Baseline 3 is appropriate given the comprehensive schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Search'), resource ('Finnish Alko alcohol catalog'), and scope ('~12,000 products'). It distinguishes from siblings like 'get_product' (single product retrieval) and 'get_recommendations' (personalized suggestions) by emphasizing broad filtering capabilities.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through the mention of filtering parameters and return fields, suggesting it's for general catalog exploration. However, it doesn't explicitly state when to use this versus alternatives like 'get_product' for specific items or 'sync_products' for data updates, leaving some ambiguity about optimal use cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

sync_productsSync Product Database (Admin)A
Idempotent

Admin: Download latest Alko price list and update product database. Takes 2-5 minutes. Updates ~12,000 products. Use get_sync_status to check progress.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds valuable behavioral context beyond annotations: it discloses the execution time (2-5 minutes), the scale of updates (~12,000 products), and the need to monitor progress with another tool. While annotations cover safety (destructiveHint: false) and idempotency, the description provides practical operational details that help the agent 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly concise and front-loaded: it starts with the core purpose, adds key operational details (time, scale), and ends with a usage tip. Every sentence earns its place by providing essential information without fluff or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter mutation tool with good annotations but no output schema, the description is highly complete: it explains the action, time, scale, and monitoring method. The only minor gap is not explicitly stating the return value or success indicators, but given the annotations and sibling tool for status checking, this is acceptable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters and 100% schema description coverage, the baseline is 4. The description appropriately confirms there are no parameters by not mentioning any, and it adds context about what the tool does without needing to explain inputs. This is efficient and avoids redundancy.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Download latest Alko price list and update product database'), identifies the resource ('product database'), and distinguishes it from sibling tools by specifying it's an admin operation that updates ~12,000 products. It goes beyond the title by explaining the scope and scale of the operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool ('Admin: Download latest Alko price list and update product database') and when to use an alternative ('Use get_sync_status to check progress'). It also indicates the time commitment ('Takes 2-5 minutes'), helping the agent decide when to invoke it versus other read-only sibling tools.

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. Dates show when Glama detected each change.

  1. 9 tool updates
    • First observedget_availability
    • First observedget_product
    • First observedget_recommendations
    • First observedget_store_hours
    • First observedget_sync_status
    • First observedget_vivino_rating
    • First observedlist_stores
    • First observedsearch_products
    • First observedsync_products

TDQS

A4.3/5.0
Disambiguation5/5

Every tool has a clearly distinct purpose with no overlap. For example, get_availability checks stock, get_product retrieves product details, and get_recommendations provides personalized suggestions, each targeting different user needs. The descriptions reinforce this separation, making misselection unlikely.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern using snake_case, such as get_availability, list_stores, and search_products. This predictability aids in agent navigation and understanding of tool functions without confusion from mixed conventions.

Tool Count5/5

With 9 tools, the server is well-scoped for its domain of Alko product and store management. Each tool serves a specific role, from data retrieval to administrative tasks, avoiding bloat or thin coverage. This count supports comprehensive workflows without overwhelming complexity.

Completeness4/5

The toolset covers core operations like product search, availability checks, store information, and recommendations, with minor gaps such as missing update or delete operations for products or stores. However, these are likely intentional given the server's focus on read-only data access and synchronization from external sources.

Maintenance

ActivityInactive
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to access the Open Food Facts database to query detailed food product information, nutritional data, and environmental scores. Supports product lookup by barcode, smart search with filtering, nutritional analysis, product comparison, and dietary recommendations to help users make informed food choices.
    5
    1
    MIT
  • F
    license
    B
    quality
    C
    maintenance
    Enables AI assistants to interact with Mathem.se, a Swedish online grocery store, allowing users to search for ingredients, add items to their shopping basket, and manage recipes through natural language.
    4
    2
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to interact with Rohlik Group's online grocery delivery services across multiple European countries, supporting product search, shopping cart management, order history analysis, and personalized meal suggestions based on purchase patterns.
    56
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables LLMs to search, profile, and compare Japanese sake using a flavor-space engine, including similarity recommendations and side-by-side comparisons.
    5
    1
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/markusl/alko-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server