espresso-mcp
Allows Google Gemini to find and recommend espresso cafes using a curated database and scoring algorithm.
Allows Hermes to find and recommend espresso cafes using a curated database and scoring algorithm.
Allows ChatGPT to find and recommend espresso cafes using a curated database and scoring algorithm.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@espresso-mcpFind great espresso near the Brandenburg Gate"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
espresso-mcp
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):
Settings → Connectors → Advanced → toggle Developer mode on.
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@latestThen 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 inspectTravel & 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 disqualifyingonly_dark_roast(−8) — masks bean defectsno_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:
Add the entry in alphabetical order by city, then name.
Use exact coordinates when possible (
"coord_precision": "exact"). Look them up on Google Maps.Set
last_verifiedto today's ISO date.Only include signals you've personally observed or can cite.
If you're naming a new roaster, add it to
data/roasters.jsonwith a reasonable reputation tier (notable,regional-leader, orworld-class).Run
npm testandnpm run validate-databefore 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 — seedata/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
World's 100 Best Coffee Shops — annual industry-voted ranking; the backbone of the world-class tier
European Coffee Trip — 6,229+ curated European specialty cafes; used heavily for the London and Berlin batches
D Magazine — Best Dallas Coffee Shops and Roasters — the canonical DFW specialty guide
Drips of God — New York — Manhattan + Brooklyn curation
Bee An Coffee — Best Specialty Coffee in NYC 2026 — Brooklyn roastery focus
Grounds Club — Hong Kong Specialty Coffee Guide — HK-specific
Asian Coffee Map — Asia regional anchor
Awards and rankings
Sprudgie Awards — Sprudge's annual community awards
Good Food Awards: Coffee — US specialty roaster recognition
Coffee Review (95+ scores) — exceptional roast quality
SCA World Barista Championship — competition involvement is a high-signal indicator
Frameworks and taxonomies
Sprudge — long-form specialty coffee journalism; the original "signal taxonomy" intuition came from years of Sprudge reading
Specialty Coffee Association — Barista Skills curriculum — equipment shortlist and certification framework
SCA Certified Commercial Equipment list — what "quality espresso machine" means
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
@modelcontextprotocol/sdk— the official MCP TypeScript SDKZod, tsup, Vitest, Firecrawl (for scraping city guides during curation)
Available Tools
6 toolsfind_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.
| Name | Required | Description | Default |
|---|---|---|---|
| lat | Yes | Latitude in decimal degrees (-90..90). | |
| lon | Yes | Longitude in decimal degrees (-180..180). | |
| limit | No | Maximum number of cafes to return. Default 10. | |
| min_score | No | Filter out cafes below this espresso quality score (0-100). Default 50. | |
| radius_km | No | Search radius in kilometers. Default 2km. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Cafe id (slug) — e.g. 'tim-wendelboe-oslo'. Use search_cafes to find ids. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of entries to return. Default 20. | |
| category | No | Filter to a specific anti-pattern category. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of roasters to return. Default 50. | |
| country | No | Filter by ISO-3166 alpha-2 country code. | |
| min_reputation | No | Minimum reputation tier. Default: 'notable' (includes all known). |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Optional cafe name (used in reasoning and roaster lookup). | |
| source_rankings | No | Awards / rankings the cafe appears in. | |
| observed_signals | Yes | Signals observed about the cafe. Omit fields you don't know — unknowns are skipped, not penalized. |
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Filter by city name (case-insensitive exact match). | |
| limit | No | Maximum number of cafes to return. Default 20. | |
| query | No | Free-text query matched against cafe name, city, district, and notes (case-insensitive). | |
| country | No | Filter by ISO-3166 alpha-2 country code (e.g. 'JP', 'DK', 'US'). | |
| roaster | No | Filter to cafes that roast in-house under this name, or serve beans from this roaster. | |
| min_score | No | Minimum espresso-quality score (0-100). Default 0 (no filter). |
TDQS
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.
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.
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.
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.
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.
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.
6 tool updates
v0.2.0- First observed
find_espresso_near - First observed
get_cafe_details - First observed
list_anti_patterns - First observed
list_great_roasters - First observed
score_cafe - First observed
search_cafes
TDQS
Scored across 6 tools
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.
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.
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.
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
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
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Trust, freshness, policy, and discovery layer for public MCP servers.
Public MCP server for discovering open jobs. Search, filter, and get application links.
Trust-scored search engine for MCP servers. 1,900+ sources indexed. IETF draft published. Referenced by OWASP MCP Security Cheat Sheet. L0-L4 trust levels based on cryptographic verification.
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server for Gaggiuino-modified espresso machines, enabling monitoring, shot analysis, and profile management.4141MIT
- AlicenseAqualityBmaintenanceA 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.32MIT
- FlicenseAqualityBmaintenanceMCP 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-
- FlicenseNot gradedqualityBmaintenanceMCP server that archives Decent DE1 espresso shots from Visualizer.coffee into SQLite and provides analysis tools for shots, beans, and profiles via MCP.-
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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