Skip to main content
Glama
mattgierhart

espresso-mcp

by mattgierhart

espresso-mcp

npm version npm downloads MCP Registry code license data license

An MCP server that finds great espresso cafes — and codifies what makes them great.

espresso-mcp is a Model Context Protocol server you can plug into Claude Desktop, Claude.ai, ChatGPT, Google Gemini, Cursor, Hermes, OpenClaw, and any other standard MCP host. It ships with a curated database of 100+ specialty-coffee shops, 75+ specialty roasters, and a transparent scoring algorithm that captures why a shop is good — sourcing, freshness, equipment, training — and why a shop is bad (the heaviest negative signal: menus dominated by flavored syrups).

It is not a Yelp clone. The data is hand-curated, the scoring is explicit, and the philosophy is "if it's covering bad coffee with flavors, we don't want it."


The bias

espresso-mcp has an opinion. Shops that hide bad coffee behind flavored syrups are the failure pattern this tool is designed to filter out. The scoring algorithm gives syrup_emphasis the heaviest non-disqualifying penalty (−22) — heavier than any single positive signal. Mass-market chains (Starbucks, Dunkin', Costa, Tim Hortons, Peet's, Caribou) and "looks third-wave but tastes flavored" shops (the algorithm's flavor-led-specialty category) score in avoid or fair tier regardless of how good the signage looks.

Positive credit goes to the signals great shops actually invest in:

  • In-house roasting, or named-partner sourcing from a known specialty roaster

  • Single-origin espresso (not just blends)

  • Roast date on retail bags (peak-freshness commitment)

  • Espresso + pour-over both offered — the "complete program"

  • Cortado on the menu — a confidence proxy; shops avoid small milk drinks when their espresso can't hold up

  • Competition involvement / SCA-certified staff

  • Equipment from the third-wave shortlist (Slayer, La Marzocco, Synesso, Decent, Victoria Arduino, Modbar)

  • Recognition from authoritative rankings (World's 100 Best, SCA championships, Coffee Review 95+, Good Food Awards)

Every signal is documented at src/scoring/weights.ts and surfaced to clients via the score breakdown on every result — you can see exactly why a cafe is recommended.


Related MCP server: coffee-price-mcp

See it in action

You: I'm near Brandenburg Gate in Berlin. Find me 3 great espresso cafes 
     within walking distance.

Claude: [resolves Brandenburg Gate → 52.5163, 13.3777]
        [calls find_espresso_near with radius_km=2]

  Found 3 specialty cafes within 2km of Brandenburg Gate, sorted by quality:

  • The Barn (Mitte)         — 0.8km — score 95 (world-class) — World's #61
    In-house roastery, single-origin focus, "never blends beans." Founded 
    2010, one of Europe's leading third-wave roasters.

  • Companion Coffee (Mitte) — 1.1km — score 83 (great)
    Curated multi-roaster with rotating guest beans. Tea + coffee crossover 
    in a quiet Mitte design space.

  • Westberlin (Mitte)       — 1.3km — score 82 (great)
    Iconic third-wave anchor since ~2010. Magazine + coffee concept; pours 
    The Barn and rotating European roasters.

What it does

Once installed in your MCP client, you can ask things like:

  • "I'm at the Hotel Adlon Berlin — find me great espresso within walking distance."

  • "I'm staying near the Brandenburg Gate. Recommend 3 cafes and rank by quality."

  • "Search for cafes in Tokyo scoring above 80."

  • "Tell me about Tim Wendelboe."

  • "Score this cafe — they have a Slayer, in-house roasting, single-origin espresso, and no flavored syrups."

  • "What are the world-class roasters in Denmark?"

  • "What should I avoid in Chicago? Show me an anti-pattern example."

The model gets a structured score with reasoning, distance, awards, and per-signal contributions — enough to give you an honest recommendation rather than a popularity list.


Quick install

Client

Section

Claude Desktop

Claude.ai (Browser MCP)

ChatGPT

Google Gemini CLI

Hermes (Nous Research)

OpenClaw

Cursor

VS Code

Any standard stdio

From source

Recommendation: use @latest while the project is iterating

While we're still adding cafes and refining the algorithm, pin to the live npm tip:

"args": ["-y", "espresso-mcp@latest"]

Once the data and scoring stabilize, you can drop @latest and pin a specific version for reproducibility.


Per-client configuration

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows). If the file doesn't exist, create it:

{
  "mcpServers": {
    "espresso": {
      "command": "npx",
      "args": ["-y", "espresso-mcp@latest"]
    }
  }
}

Restart Claude Desktop. The 🔌 menu should show 6 tools under "espresso."

Claude.ai (Browser MCP)

Claude.ai's web app supports MCP servers via OAuth and remote endpoints. For local installation, use Claude Desktop instead (above). To expose espresso-mcp to Claude.ai as a remote server, wrap it with mcp-remote (see the ChatGPT section below — same approach).

ChatGPT

Important: ChatGPT only supports remote MCP servers (HTTPS endpoints), not local stdio processes. You have two options:

Option 1: Use the hosted version (when available). If we publish a hosted endpoint we'll list it here.

Option 2: Bridge espresso-mcp to HTTPS via mcp-remote. Run a small bridge on a machine you control:

npx -y mcp-remote bridge espresso-mcp \
  --port 8080 \
  --token "your-shared-secret"

Then expose port 8080 via a tunnel (Cloudflare Tunnel, Tailscale Funnel, or a small VPS) and use the resulting HTTPS URL.

Enabling MCP in ChatGPT (Plus / Pro / Team / Enterprise plans only):

  1. Settings → ConnectorsAdvanced → toggle Developer mode on.

  2. Add a custom connector pointing at your bridge URL.

OpenAI's MCP docs have the latest connector setup.

Google Gemini CLI

Edit ~/.gemini/settings.json:

{
  "mcpServers": {
    "espresso": {
      "command": "npx",
      "args": ["-y", "espresso-mcp@latest"]
    }
  }
}

Restart Gemini CLI. It will auto-connect at startup and show "Connected" if successful. See Gemini CLI MCP docs for the full reference.

Hermes (Nous Research)

Hermes uses YAML, not JSON. Edit ~/.hermes/config.yaml:

mcp_servers:
  espresso:
    command: "npx"
    args: ["-y", "espresso-mcp@latest"]

Optional: filter to just the tools you want exposed:

mcp_servers:
  espresso:
    command: "npx"
    args: ["-y", "espresso-mcp@latest"]
    tools:
      include: [find_espresso_near, search_cafes, score_cafe]

Restart Hermes — it auto-discovers MCP tools at startup. See Hermes MCP docs.

OpenClaw

OpenClaw uses standard stdio MCP config. Install OpenClaw if you haven't:

curl -fsSL https://openclaw.ai/install.sh | bash
# or: npm install -g openclaw@latest

Then add to your OpenClaw config (typically ~/.openclaw/config.json — check OpenClaw MCP docs for the current location):

{
  "mcpServers": {
    "espresso": {
      "command": "npx",
      "args": ["-y", "espresso-mcp@latest"]
    }
  }
}

Cursor

Edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "espresso": {
      "command": "npx",
      "args": ["-y", "espresso-mcp@latest"]
    }
  }
}

VS Code

VS Code uses a dedicated mcp.json file (not settings.json). For workspace-scoped config, create .vscode/mcp.json. For user-wide, run the MCP: Open User Configuration command from the Command Palette.

{
  "servers": {
    "espresso": {
      "command": "npx",
      "args": ["-y", "espresso-mcp@latest"]
    }
  }
}

Note: VS Code uses the key servers (not mcpServers) — this is the most common copy-paste mistake when migrating configs from other clients.

Generic stdio client

For any MCP-compatible host that spawns local processes:

{
  "command": "npx",
  "args": ["-y", "espresso-mcp@latest"]
}

The server writes JSON-RPC to stdout and logs to stderr only — capture stderr if you want startup messages.

From source (development)

git clone https://github.com/mattgierhart/espresso-mcp
cd espresso-mcp
npm ci
npm run build

# Point your client at:
#   command: node
#   args:    ["/absolute/path/to/espresso-mcp/dist/index.js"]

Or run the MCP Inspector against the local build:

npm run inspect

Travel & address-based queries

The most common real-world question is "I'm at X, where should I get coffee?" Here's the pattern in practice.

Hotel-based recommendation

You: I'm staying at the Hotel Adlon Berlin. Find me 3 great espresso cafes nearby.

[Claude searches for the Adlon's coordinates: ~52.5163, 13.3795]
[Claude calls find_espresso_near with those lat/lon]
[Returns ranked Berlin cafes within walking distance]

The model resolves the address to coordinates (using its built-in knowledge or a web search), then calls find_espresso_near. No extra config needed.

Address-based query

You: I'm walking around Millennium Park in Chicago. What's the closest specialty espresso?

[Claude resolves the landmark → ~41.882, -87.622]
[Calls find_espresso_near with radius_km: 2]
[Ranks results by quality, then distance]

Multi-city trip planning

You: I have trips coming up to Tokyo, Berlin, and Hong Kong. Build me a coffee plan —
     top 2 cafes per city, plus the one roaster I should buy beans from in each.

[Claude calls search_cafes for each city, sorts by score]
[Calls list_great_roasters filtered by country]
[Composes a per-city itinerary]

Score what you're looking at right now

You: I'm at a cafe with a Slayer machine, they roast on-site, single-origin espresso 
     option, roast date on bags, and they only have plain milk drinks — no syrups. 
     Score it.

[Claude calls score_cafe with those signals]
[Returns 95/100 ("world-class") with per-signal contributions]

Hotel coffee-walkability comparison (manual, until v0.4)

You can do this today with multiple tool calls:

You: Compare these Berlin hotels by walkable specialty coffee:
     - Hotel Adlon (Mitte)
     - Soho House Berlin (Mitte)
     - 25hours Hotel Bikini (Charlottenburg)

[Claude calls find_espresso_near three times, one per hotel]
[Composes a comparison table]

A dedicated score_hotel_coffee_access tool is on the roadmap for v0.5.

Best-effort with cities not yet in the database

If you query a city we haven't curated yet (e.g., Lisbon, Seoul, Mexico City), find_espresso_near returns no curated matches. The model can still combine its own knowledge with score_cafe to evaluate any cafe you describe. We're filling in cities one batch at a time — open an issue if you want yours prioritized.


Tools

find_espresso_near

Find ranked specialty espresso cafes within a radius of coordinates.

{ "lat": 35.6855, "lon": 139.6904, "radius_km": 3, "min_score": 60, "limit": 10 }

Returns cafes from the curated database sorted by espresso-quality score, with per-cafe distance and reasoning.

search_cafes

Search the curated database by query, city, country, roaster, or minimum score.

{ "query": "natural wine", "country": "DE", "min_score": 70, "limit": 20 }

get_cafe_details

Full record for a cafe by id, including the score breakdown signal-by-signal and a few related/nearby cafes.

{ "id": "tim-wendelboe-oslo" }

score_cafe

The codified algorithm exposed directly. Pass in signals you've observed (from a website, a review, a photo) and get a 0-100 score with a per-signal contribution breakdown. No database lookup required.

{
  "name": "Hypothetical Shop",
  "observed_signals": {
    "roasting": "in-house",
    "brew_methods": ["espresso", "pour-over"],
    "single_origin_espresso": true,
    "roast_date_on_bags": true,
    "cortado_on_menu": true,
    "syrup_emphasis": false
  }
}

list_great_roasters

Curated specialty roasters by country and reputation tier.

{ "country": "DK", "min_reputation": "regional-leader", "limit": 25 }

list_anti_patterns

Curated shops that exemplify what to avoid — the contrast set for the algorithm. Two flavors:

  • mass-market-chain — Starbucks, Dunkin', Costa, Tim Hortons, Peet's, Caribou. Generic dark roasts, flavored-drink menus, low sourcing transparency.

  • flavor-led-specialty — shops that display third-wave signage (in-house roasting, single-origin signs, roast dates) but in practice serve a syrup-forward menu. Looks specialty, drinks flavored. Useful contrast when explaining why a recommended shop is the real thing.

{ "category": "flavor-led-specialty", "limit": 10 }

Anti-patterns are stored separately in data/anti-patterns.json so they never bleed into find_espresso_near or search_cafes results.


How scoring works

The full weight table is the source of truth at src/scoring/weights.ts. In short:

Positive signals (the things great shops do):

  • In-house or named-partner roasting from a known specialty roaster

  • Single-origin espresso

  • Roast date on retail bags (peak-freshness commitment)

  • Espresso + pour-over both offered ("complete program")

  • Cortado on the menu (confidence in espresso)

  • Competition involvement / SCA-certified staff

  • Quality espresso machines (Slayer, La Marzocco, Synesso, Decent, Victoria Arduino, Modbar)

  • Awards (World's 100 Best, SCA championships, Coffee Review 95+, Good Food Awards)

Negative signals (the cover-up patterns):

  • syrup_emphasis (−22) — menu dominated by flavored-syrup drinks. The strongest avoid-signal. Great shops don't hide behind syrups.

  • flavored_drink_share > 0.5 (additional −7)

  • no_grinder_visible (−25) — effectively disqualifying

  • only_dark_roast (−8) — masks bean defects

  • no_origin_info (−7) — they don't know or don't care

Roaster reputation bonus: cafes that roast in-house or partner with a known roaster get +25 (world-class), +15 (regional-leader), or +8 (notable) on top of structural signals.

Null/unknown signals are skipped, not penalized. The score includes a confidence value proportional to how many signals were actually observed.

Score tiers:

Score

Tier

≥ 85

World-class

≥ 70

Great

≥ 55

Good

≥ 40

Fair

< 40

Avoid

The "looks specialty but isn't" pattern is tricky — a cafe with genuine third-wave structural signals plus a flavored-drink menu will score in the "good" range despite the syrup penalty. For those cases, the explicit category: flavor-led-specialty flag in data/anti-patterns.json is the authoritative human override.


Curated coverage (v0.2.0)

The database is hand-curated. Coverage skews toward cities where we (or trusted curated guides) have actual recent visits. We add cities batch-by-batch — open an issue if you want yours prioritized.

Region

Cafes

Districts represented

Berlin

15

Mitte, Kreuzberg, Neukölln, Charlottenburg

London

15

Holborn, Shoreditch, City, Marylebone, Bishopsgate, Hammersmith (incl. Workshop × 3)

NYC (Manhattan + Brooklyn)

17

East Village, Nolita, Noho, Flatiron, FiDi, NoMad, Williamsburg, Bushwick, Park Slope

Dallas / DFW

18

Design District, Lower Greenville, Oak Cliff / Bishop Arts, Deep Ellum, Knox-Henderson, Plano

Denver metro

18

Capitol Hill, RiNo, LoHi, Tennyson, Edgewater, Aurora, Lone Tree, Littleton

Hong Kong

10

Causeway Bay, Sheung Wan, Tsim Sha Tsui, Tai Hang

Tokyo / Osaka

6

Omotesando, Nakameguro, Kuramae, Shimokitazawa, Sangubashi

Guangzhou

8

Tianhe, Yuexiu, Liwan

Other

~9

Oslo, Copenhagen, Dublin, Galway, Vienna, Singapore, Santa Ana SV, Rogers AR

Plus 8 deliberately-flagged anti-pattern entries (Starbucks, Dunkin', Costa, Tim Hortons, Peet's, Caribou, plus two "looks specialty but tastes flavored" examples).

Gaps worth filling next: SF, LA, Seattle, Portland, Melbourne, Sydney, Stockholm, Amsterdam, Paris, Taipei, Seoul, Mexico City.


Contributing a cafe

Open a PR against data/cafes.json:

  1. Add the entry in alphabetical order by city, then name.

  2. Use exact coordinates when possible ("coord_precision": "exact"). Look them up on Google Maps.

  3. Set last_verified to today's ISO date.

  4. Only include signals you've personally observed or can cite.

  5. If you're naming a new roaster, add it to data/roasters.json with a reasonable reputation tier (notable, regional-leader, or world-class).

  6. Run npm test and npm run validate-data before opening the PR.

See data/README.md for the full schema reference.

Suggesting an anti-pattern

Anti-patterns belong in data/anti-patterns.json with a category field set. Strong candidates are shops you've personally verified as either mass-market or "looks specialty but drinks flavored." Include a notes field explaining the gap between signage and experience.

Reporting feedback

Open an issue with what you tested, what worked, what surprised you, and what's missing. We track the roadmap (community contribution tool, automated address geocoding, live data fallback, hotel-proximity scoring) as open issues.


License

  • Code is MIT — see LICENSE.

  • Data (data/*.json) is CC-BY 4.0 — see data/LICENSE. Attribution required.

If you redistribute the data, please link back to this repository.


Sources we trained the patterns on

The curated cafe roster, the signal weight table, and the anti-pattern category framing were built by reading and cross-referencing the people who already do this work well. Credit and links:

City and region guides

Awards and rankings

Frameworks and taxonomies

A lot of time spent in cafes. Fieldwork. Probably not tax-deductible. The most honest entry on this list — every weight in src/scoring/weights.ts was calibrated by someone who has been personally disappointed by a Slayer-equipped shop that turned out to lean syrup-forward.

Built on

Available Tools

6 tools
find_espresso_nearFind Espresso Near a LocationA

Find ranked specialty espresso cafes within a radius of given coordinates. Returns cafes from the curated database sorted by espresso-quality score, with distance and score reasoning for each.

ParametersJSON Schema
NameRequiredDescriptionDefault
latYesLatitude in decimal degrees (-90..90).
lonYesLongitude in decimal degrees (-180..180).
limitNoMaximum number of cafes to return. Default 10.
min_scoreNoFilter out cafes below this espresso quality score (0-100). Default 50.
radius_kmNoSearch radius in kilometers. Default 2km.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the burden of disclosure. It reveals that results are sorted by espresso-quality score and include distance and reasoning, giving insight into output behavior. It does not mention rate limits or error handling, but for a read-only search tool, these are secondary.

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?

Two concise sentences deliver all key information: action, resource, filter criteria, ranking, and return details. No filler or redundant 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?

The description explains the core return aspects (sorted results, distance, score reasoning) but lacks a detailed output schema. It doesn't specify sorting direction (ascending/descending) or the exact response shape, but given the schema's thorough parameter coverage, this is adequate for a simple search tool.

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?

Input schema covers 100% of parameters with descriptive comments, so the description does not need to re-explain them. The description adds a slight behavioral context by mentioning coordinates and radius, but it doesn't go beyond the schema in explaining parameter usage.

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 function: finding ranked specialty espresso cafes near given coordinates. It distinguishes itself from siblings like search_cafes by specifying location-based search, sorting by espresso-quality score, and returning distance and score reasoning.

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 implies the primary use case: searching for cafes by proximity to specific coordinates. It does not explicitly mention when not to use this tool or suggest alternatives, but the context is clear enough for an agent to choose it over general search tools.

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

get_cafe_detailsGet Cafe DetailsA

Retrieve a full curated record for a cafe by id, including the espresso-quality score breakdown (per-signal contributions) and a few nearby/related cafes.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesCafe id (slug) — e.g. 'tim-wendelboe-oslo'. Use search_cafes to find ids.

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full burden of behavioral disclosure. 'Retrieve' indicates a read-only operation, and the description goes beyond the schema by specifying the output includes a score breakdown and nearby/related cafes. It does not detail error behavior or caching, but for a simple get-by-id tool this is adequate.

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, front-loaded sentence that states the main action first, then specifies included content. Every part adds value with no redundancy or fluff.

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?

The tool is simple (one parameter, no output schema), and the description adequately summarizes the response content (record, score breakdown, nearby cafés). However, it doesn't mention if the record is filtered or any limitations, though for a get-by-id this is not a major gap.

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 coverage is 100% and the single 'id' parameter already has a rich description with an example ('tim-wendelboe-oslo') and a pointer to search_cafes. The tool description adds no additional parameter semantics, so baseline 3 is appropriate.

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 action ('Retrieve a full curated record for a cafe by id') with a specific resource and scope. It distinguishes itself from siblings like search_cafes (search vs. retrieval by id) and score_cafe (retrieval vs. scoring), while enumerating key content (espresso-quality score breakdown, nearby/related cafes).

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 implies when to use this tool: when you have a cafe id and need detailed information. The schema parameter description adds 'Use search_cafes to find ids,' giving a clear workflow. However, it does not explicitly discuss exclusions or compare against score_cafe or find_espresso_near, leaving some ambiguity.

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

list_anti_patternsList Anti-Pattern Coffee ShopsA

List shops that exemplify what to AVOID when looking for great espresso. Includes mass-market chains (Starbucks, Dunkin', Costa) and 'flavor-led specialty' shops that display third-wave signage but lean heavily on flavored drinks. Each entry shows why it's flagged. Useful as contrast when recommending real specialty cafes, and as regression fixtures for the scoring algorithm.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of entries to return. Default 20.
categoryNoFilter to a specific anti-pattern category.

TDQS

A4.5/5.0
Behavior4/5

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

While no annotations are provided, the description discloses that entries 'show why it's flagged,' revealing output structure. It also details the inclusion criteria (mass-market chains, flavor-led specialty, etc.), giving the agent understanding of what to expect. This is meaningful behavioral context beyond a simple list description.

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 three sentences, with the primary action and purpose in the first sentence. It efficiently packs relevant detail (inclusion criteria, output note, use cases) without redundancy or fluff.

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

Completeness5/5

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

As a simple list tool with two optional parameters and no output schema, the description provides sufficient information: it explains the tool's scope, the nature of list items (with reasons), and practical use cases. Combined with the schema's parameter coverage, this is complete for the task.

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 covers both parameters fully, but the description adds semantic meaning by defining the 'flavor-led specialty' category in prose ('display third-wave signage but lean heavily on flavored drinks') and providing examples like Starbucks, Dunkin', and Costa for mass-market chains. This enriches the enum values beyond their 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 uses a specific verb ('List') and defines the resource as anti-pattern coffee shops, explicitly stating they 'exemplify what to AVOID when looking for great espresso.' It further distinguishes from siblings by mentioning mass-market chains and flavor-led specialty shops, clearly contrasting with list_great_roasters. This provides a clear, unambiguous purpose.

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 states two explicit use cases: 'Useful as contrast when recommending real specialty cafes' and 'as regression fixtures for the scoring algorithm.' It gives clear context for when to leverage this tool, although it does not name alternative tools or explicitly state when not to use it.

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

list_great_roastersList Great Coffee RoastersA

List curated specialty coffee roasters from the database, filtered by country and reputation tier. Useful for finding cafes that serve a given roaster's beans, or planning a roaster-focused trip.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of roasters to return. Default 50.
countryNoFilter by ISO-3166 alpha-2 country code.
min_reputationNoMinimum reputation tier. Default: 'notable' (includes all known).

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It mentions listing/filtering, implying a read-only operation, but does not disclose return format, ordering, or the exact meaning of 'curated.' Given the absence of annotations, more behavioral context would be beneficial.

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, front-loaded with the action ('List...'), and each sentence adds value: the first defines the tool, the second provides use cases. No fluff or redundancy.

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 simple list tool with 3 optional parameters and full schema coverage, the description gives adequate purpose and use-case context. However, since there is no output schema and no annotations, the agent might not know what fields are returned. Still, the description covers the core invocation context well.

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?

The schema covers 100% of parameters with descriptions, so the baseline is 3. The description only restates filtering by country and reputation tier, adding no extra semantic detail beyond the schema. The 'limit' parameter is not mentioned in the description.

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 function with a specific verb and resource: 'List curated specialty coffee roasters from the database, filtered by country and reputation tier.' This distinguishes it from sibling tools like search_cafes or get_cafe_details, which focus on different entities (cafes, details).

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 use cases: 'finding cafes that serve a given roaster's beans, or planning a roaster-focused trip.' This gives contextual guidance on when to use the tool, though it does not explicitly mention alternatives or exclusions relative to sibling tools.

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

score_cafeScore a Cafe by Observed SignalsA

Apply the espresso-quality scoring algorithm to a set of observed signals (no database lookup required). Returns a 0-100 score, tier, per-signal contributions, and reasoning. Use this when you've gathered information about a cafe from a website, photo, or review and want a structured assessment.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoOptional cafe name (used in reasoning and roaster lookup).
source_rankingsNoAwards / rankings the cafe appears in.
observed_signalsYesSignals observed about the cafe. Omit fields you don't know — unknowns are skipped, not penalized.

TDQS

A4.2/5.0
Behavior4/5

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

No annotations are provided, so the description carries the full burden. It discloses the operation (scoring algorithm), the output structure (score, tier, per-signal contributions, reasoning), and that no database lookup is required. It does not detail side effects or error behavior, but as a pure computation tool, these are not likely relevant. The description provides more than minimal transparency.

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 sentence states the primary action and key constraint, the second states outputs and usage context. Every sentence is informative, no redundant or filler content. It is well structured and front-loaded.

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 (nested observed_signals object, multiple signal types, no output schema), the description covers the essential points: what it does, what it returns, and when to use it. The schema handles parameter details. The only minor omission is not explicitly stating that unknown signals are skipped, but this is covered in the schema. Overall, the description is sufficient.

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 already documents all parameters. The description only refers generically to 'observed signals' and adds no parameter-specific meaning beyond what the schema provides. It does not mislead, but it also does not enhance understanding of the parameters. Baseline 3 is appropriate.

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 states a specific verb and resource: 'Apply the espresso-quality scoring algorithm to a set of observed signals.' It also clarifies there is no database lookup and lists concrete outputs. This clearly distinguishes it from sibling tools like get_cafe_details (which would involve lookup) and search_cafes (which finds cafes).

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 gives explicit context: 'Use this when you've gathered information about a cafe from a website, photo, or review and want a structured assessment.' It also adds 'no database lookup required,' implying a contrast with database-backed tools, though it does not explicitly name alternatives or exclusion criteria. This is clear but lacks explicit 'when not to use' guidance.

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

search_cafesSearch Curated CafesA

Search the curated specialty coffee cafe database by name, city, country, roaster, and minimum quality score. Returns scored results sorted by espresso-quality score descending.

ParametersJSON Schema
NameRequiredDescriptionDefault
cityNoFilter by city name (case-insensitive exact match).
limitNoMaximum number of cafes to return. Default 20.
queryNoFree-text query matched against cafe name, city, district, and notes (case-insensitive).
countryNoFilter by ISO-3166 alpha-2 country code (e.g. 'JP', 'DK', 'US').
roasterNoFilter to cafes that roast in-house under this name, or serve beans from this roaster.
min_scoreNoMinimum espresso-quality score (0-100). Default 0 (no filter).

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description carries the transparency burden. It adds useful context: the database is 'curated', results are 'scored', and sorted by espresso-quality score descending. It doesn't mention pagination or result format, but for a search tool this is reasonably transparent.

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, front-loaded with the action and resource, and contains no filler. Every word adds value.

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 moderately complex search tool with 6 parameters but no output schema or annotations, the description plus full schema descriptions provide a complete picture: what is searched, the filter fields, and the result ordering. It lacks explicit mention of pagination/limit, but the schema's default handles that.

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 baseline is 3. The description repeats some parameter names (city, country, roaster, min_score) but adds no additional semantics beyond the schema. It also says 'by name' though there is no explicit 'name' parameter, potentially confusing the query parameter.

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 searches a curated specialty coffee cafe database by multiple filters (city, country, roaster, min score) and returns scored results. This distinguishes it from sibling tools like get_cafe_details (specific details) and find_espresso_near (location-based).

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 by listing searchable fields and result ordering, but it does not explicitly state when to prefer this tool over alternatives or mention any exclusions. For example, it doesn't say 'for a specific cafe's details, use get_cafe_details.'

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. 6 tool updatesv0.2.0
    • First observedfind_espresso_near
    • First observedget_cafe_details
    • First observedlist_anti_patterns
    • First observedlist_great_roasters
    • First observedscore_cafe
    • First observedsearch_cafes

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: get_cafe_details retrieves by ID, find_espresso_near searches by coordinates, search_cafes uses text filters, score_cafe applies the algorithm to arbitrary inputs, list_great_roasters covers roasters, and list_anti_patterns provides contrast examples. No two tools overlap in a confusing way.

Naming Consistency5/5

All tool names follow the same verb_noun pattern in snake_case (get_, find_, search_, score_, list_). The verbs are specific and consistent with the action performed, making the naming predictable and intuitive.

Tool Count5/5

Six tools is well within the ideal range for a domain-specific server. Each tool covers a distinct aspect of cafe discovery and scoring, and none feel redundant or superfluous. The count aligns with the server's focused purpose.

Completeness5/5

The toolset provides complete coverage for the espresso cafe domain: finding cafes (by location or criteria), retrieving detailed information, scoring cafes algorithmically, and accessing supporting data (roasters and anti-patterns). There are no obvious dead ends or missing core operations.

Maintenance

ActivityInactive
ResponsivenessUnresponsive

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
    B
    maintenance
    A read-only MCP server that wraps the coffee.pryzm.gg public API to calculate effective prices of coffee drinks after discounts, enabling users to find the cheapest coffee deals, search for discounts, and verify receipt prices.
    3
    2
    MIT
  • F
    license
    A
    quality
    B
    maintenance
    MCP server that recommends coffee based on preferences (mood, milk, caffeine, temperature) from a static menu; includes tools for listing menu, recommending, and explaining recommendations.
    3
    -

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/mattgierhart/espresso-mcp'

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