Skip to main content
Glama
README.md
# globick-mcp

A local **MCP server** that connects the [Globick](https://globick.com) activities API to
Claude Desktop, so you can **search and filter the catalogue in natural language**:

> *"Find Barcelona activities with separate adult and child rates, under €30, that are refundable."*
> *"Which activities have no images? Group them by operator."*
> *"Give me a data-quality report for the Barcelona inventory."*

Runs entirely on this machine over stdio — nothing to deploy. It reuses the
battle-tested `globick` SDK from [`../globick-cli`](../globick-cli) (auth caching,
per-endpoint rate limiting, 202/429 retries) as an editable path dependency.

## Setup

```bash
cd ~/Dev/globick-mcp
uv sync                       # creates .venv and installs deps + ../globick-cli
cp .env.example .env          # already done — Globick sandbox credentials live here
```

Claude Desktop wiring (`~/Library/Application Support/Claude/claude_desktop_config.json`,
already configured):

```json
{
  "mcpServers": {
    "globick": {
      "command": "/Users/gabriel/Dev/globick-mcp/.venv/bin/globick-mcp",
      "args": []
    }
  }
}
```

No `env` block needed: the server loads `.env` by absolute path (Claude Desktop's
cwd is not this project). Restart Claude Desktop after changing the config or the code.

## Tools

| Tool | What it does |
|---|---|
| `globick_list_locations` | Find a city's `CIT_…` code (~1,500 cities; pass `name_contains`) |
| `globick_list_categories` | Activity categories |
| `globick_search_activities` | Fast keyword/city search (lightweight stubs) |
| `globick_get_activity` | Curated detail: rates, refund policy, content checklist, portal link |
| `globick_filter_activities` | **The star** — filter by rate types (adult/child/group/…), images, content completeness, languages, price, duration, refundability, sandbox bookability |
| `globick_inventory_report` | Data-quality report: % with images, content-completeness histogram, language coverage, rate-category mix, price stats, operators with most content gaps |
| `globick_get_availability` | Available dates (+ sessions with times/prices for ranges ≤ 3 days) |

All tools are **read-only**. Rate types are semantic categories derived from each
rate's display name + age limits (the API's `rateType` codes are supplier-internal).

### How filtering works (v1: live fetching)

Search returns lightweight stubs; the filters need per-activity detail. The filter
and report tools fetch details live (4 workers, capped by `max_fetch`, respecting the
client's rate limits) and **memoize them in-process**, so repeat calls in one Claude
Desktop session are instant and extend coverage. Every response carries a
`coverage_note` saying how much of the candidate set was examined. Activities whose
detail endpoint 404s or 500s in the sandbox (whole supplier ranges do) are cached as
known-missing and counted honestly.

## Demo crib sheet

Warm up before going on stage: ask one filter question first so the cache fills, or
narrate the first fetch as "indexing the city live".

1. **Warm open** — *"Which cities does Globick have activities in? Search Barcelona for Sagrada Familia."*
2. **Detail** — *"Show me everything about the top one — prices, refund policy, languages."* (the `portal_url` opens the activity in the Globick portal)
3. **The star** — *"Find Barcelona activities with separate adult and child rates, under €30, that are refundable."*
4. **Data-quality angle** — *"Which activities have no images or no description? Group by operator — who should the content team chase first?"* (spoiler: Musement activities have zero images in the sandbox)
5. **Closer** — *"Give me a data-quality report for the Barcelona inventory."* → pitch: this server, white-labeled, is what OTA clients could plug into their own AI.

Useful sandbox facts: Barcelona is `CIT_160008` (786 activities; ignore the
"Location not identified" duplicate). Only test/certification suppliers book
end-to-end (`bookable_in_sandbox`); a 68xxx Musement range 500s on detail.

## Tests

```bash
uv run pytest                 # 31 unit tests, no network (fixtures from real sandbox payloads)
uv run mcp dev src/globick_mcp/server.py    # MCP Inspector for manual smoke
```

## Future improvements

- **Pre-warmed persistent cache** — a SQLite cache (`search_index` + `details`
  tables) filled by a `python -m globick_mcp.sync <city>` command run before the
  demo would give instant, full-city coverage for filters and reports (no
  `max_fetch` cap, survives restarts). The in-memory memo in
  `src/globick_mcp/fetch.py` is the seam where it plugs in.
- **Booking tool group** — create/confirm/cancel orders reusing
  `globick/booking.py` validations, gated behind `GLOBICK_MCP_ENABLE_BOOKING=1`;
  confirm is irreversible and must never auto-retry.
- **AI gap-translation tool** — port of the CLI's NXT-16 feature (translate
  activity content into locales the supplier doesn't provide).