emf-bar-mcp
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., "@emf-bar-mcpfind a gluten free cider"
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.
emf-bar-mcp
A small, public MCP server over the EMF Camp bar API, built for a low‑context voice model: fuzzy drink discovery by one or two keywords, the bar each drink is served at, and live stock — while touching the upstream API as little as possible.
Discovery is free. The whole menu (124 drinks) and which bar carries each one is pulled in one call to
/api/stocktypes.jsonat container start, then refreshed slowly in the background.find_drinksandlist_barsnever hit the network.Live checks are cheap and targeted.
check_stockreads one drink via/api/stocktype/<id>.json;whats_on_tapreads the two on‑tap endpoints. Both sit behind short TTL caches, so a burst of voice traffic collapses to one upstream request.
The paste‑into‑a‑prompt guide for the voice model is PROMPT.md.
Live instance: https://emf-bar-mcp-37viybmxjq-ew.a.run.app/mcp — Cloud Run (llm-voice, europe‑west1), public, scale‑to‑zero. Health: /health.
Quick start
npm install
npm start # HTTP server on http://0.0.0.0:8787/mcp (default)
# or
npm run stdio # stdio transport, for desktop MCP clientsHealth check: curl localhost:8787/health
Docker
docker build -t emf-bar-mcp .
docker run -p 8787:8787 emf-bar-mcpRelated MCP server: bar-assistant-mcp
Connecting a client
Streamable HTTP (remote / public) — point your MCP client at http://<host>:8787/mcp.
stdio (e.g. Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"emf-bar": { "command": "node", "args": ["/abs/path/to/emf-bar-mcp/src/index.js"], "env": { "MCP_TRANSPORT": "stdio" } }
}
}Tools
Tool | Args | Live call? | Returns |
| — | no | The 3 bars (slug, name, drink count, map link) |
|
| no | Ranked drinks: |
|
| 1 |
|
|
| 1 (cached) | Casks/kegs/ciders pouring now, each with |
|
| 1 (cached) |
|
Every tool returns a short spoken‑style content string and machine‑readable
structuredContent. check_stock returns a candidates list when a name is ambiguous.
On sale vs in stock. EMF only serves some draught beers/ciders at a time ("not all draught
beers and ciders are on sale at the same time"). The API models this: a product is on sale when it
has a stockline (a place to buy it), and in stock when base_units_remaining > 0. So a cask in
the cellar can be in stock but not on sale. check_stock.status surfaces the three cases —
on_sale, in_stock_not_on_sale, out_of_stock — and find_drinks hides not‑on‑sale drinks unless
include_unavailable: true.
Bar names are fuzzy: robotarms/"Robot Arms"/"main bar", cybar/"Cybar"/"Null Sector",
spacebar/"SpaceBAR"/"space bar" all resolve.
Configuration (env vars)
Var | Default | Purpose |
|
|
|
|
| HTTP bind |
|
| Upstream API base |
|
| Background catalog refresh interval |
|
| Per‑drink live‑stock cache TTL |
|
| On‑tap cache TTL |
|
| Opening‑times cache TTL |
|
| Upstream request timeout |
How it works
startup + every CATALOG_REFRESH_MS
/api/stocktypes.json ───────────────► catalog cache (drinks, tags, bar placement, Fuse index)
│
find_drinks / list_bars ◄──────────────────┘ (0 upstream calls)
check_stock ──► /api/stocktype/<id>.json (TTL STOCK_TTL_MS)
whats_on_tap ──► /api/on-tap.json + /api/cybar-on-tap.json (TTL ONTAP_TTL_MS)Discovery matching is deterministic (keyword/synonym/style/flavour tags derived from each drink, including "hoppy"/"gluten free"/"alcohol free"), with a Fuse.js fuzzy fallback for typos and mis‑transcriptions. The HTTP transport is stateless (a fresh MCP server per request; the catalog cache is a shared singleton), so it scales and hosts simply.
The upstream /api/stocktypes.json is flagged expensive — do not poll; this server honours that
by pulling it only at start‑up and on the slow refresh timer, never per request.
Notes
Not affiliated with EMF; uses the public read‑only bar API. Data © EMF.
Node ≥ 18 (uses global
fetch). MIT licensed.
This server cannot be installed
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 Servers
- AlicenseAqualityAmaintenanceMCP server for searching and discovering 4,000+ public APIs3MIT
- Alicense-qualityCmaintenanceMCP server for Bar Assistant that enables searching cocktails, managing ingredients, shelves, shopping lists, and collections via natural language.MIT
- AlicenseAqualityAmaintenanceAn MCP server that interfaces with Untappd's mobile API to search beers, breweries, venues, and user data, and to post check-ins, toasts, and comments using your own account.45487MIT
- Alicense-qualityBmaintenanceMCP server for Untappd connectivity, enabling beer search with optional limit, offset, and sorting.MIT
Related MCP Connectors
MCP server for accessing curated awesome list documentation
MCP server exposing the AceDataCloud Fish Audio API (text-to-speech with voice conditioning)
MCP server exposing Kettle Logic insight articles & industry guidance as tools + resources.
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/rjp44/emf-bar-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server