cineplex-mcp
MCP server that lets Claude search Cineplex Canada showtimes and filter by seat quality (e.g. "IMAX 70mm, not the first 3 rows, not on the sides"). Unofficial, personal-use — talks directly to Cineplex's undocumented public endpoints.
Install / Use
claude mcp add yinbri -- npx -y github:yinbri/cineplex-mcpIf the server publishes to npm under a different name, use that package instead — check the repo README.
MCP Server
Model Context Protocol server
Quality Score
Category
OperationsSupported Platforms
Our assessment of cineplex-mcp
cineplex-mcp scores 83/100 on our quality scale, 590th of 757 Operations skills we index.
Its MCP Server is 26 KB long, well organised into 27 sections with 15 code examples: a thorough specification that gives an agent plenty to work with.
It has 3 GitHub stars, so there is little community track record yet; judge it on its content.
Maintenance, license and trust
- The repository was last updated about 2 months ago, so cineplex-mcp is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 92/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
cineplex-mcp compared with similar skills
All 4 of these similar skills score higher than cineplex-mcp; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| cineplex-mcp (this skill)by yinbri | 83 | 3 | 2mo ago | MCP Server |
| Agent-Reachby Panniantong | 100 | 106.6k | 5d ago | CLAUDE.md |
| headroomby headroomlabs-ai | 100 | 78.3k | today | CLAUDE.md |
| CowAgentby zhayujie | 100 | 47.7k | today | CLAUDE.md |
| Scraplingby D4Vinci | 100 | 90.4k | 1d ago | MCP Server |
Frequently asked questions
- How do I install cineplex-mcp?
- Run
claude mcp add yinbri -- npx -y github:yinbri/cineplex-mcp. The install tabs above show the steps for each supported agent. - Which AI agents does cineplex-mcp work with?
- It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
- Is cineplex-mcp safe to use?
- It is MIT-licensed and scores 92/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is cineplex-mcp still maintained?
- The repository was last updated about 2 months ago, so cineplex-mcp is actively maintained.
Skill content
View source on GitHubcineplex-mcp
An MCP (Model Context Protocol) server that lets Claude look up Cineplex Canada showtimes and find ones with good seats available — e.g. "Find showtimes for The Odyssey in IMAX 70mm near me with good seats, not the first 3 rows, not on the sides."
This is a personal-use tool, not a commercial product. Cineplex has no
official partner API for this data; this server calls Cineplex's
undocumented public web endpoints directly. It's built to cache
aggressively, keep request volume low, and fail gracefully rather than
pretend otherwise: calls are throttled rather than fired in bursts, transient
failures (429/5xx, dropped sockets) are retried with backoff that honours
Retry-After, and anything still broken surfaces as a clear message instead
of a crash.
Demo
https://github.com/user-attachments/assets/8b19e98a-921c-4041-920b-d82a6b0f14db
This is a personal-use tool, not a commercial product. ...
Status: all five Cineplex data endpoints are confirmed working
All five calls this server depends on hit real, live apis.cineplex.com
endpoints, tested end-to-end against real responses — the original four as of
2026-07-19, the full theatre directory as of 2026-07-31. See
CAPTURE.md for how they were found and what to do if
Cineplex changes something in the future (e.g. rotates the theatrical API's
subscription key).
Setup
npm install
Node.js 18+ is required (for built-in fetch).
No environment variables or session tokens are required — every endpoint
this server calls was confirmed to work unauthenticated (theatre/movie/
showtime discovery uses a static, public subscription key baked into
cineplexClient.js; seat data needs no key at all).
If Cineplex rotates the subscription key
That key is public — Cineplex ships it to every visitor's browser — but it will eventually be rotated, at which point theatre/movie/showtime lookups start failing with a 401. The server resolves it from three sources, in order:
CINEPLEX_SUBSCRIPTION_KEY(env var) — an explicit override. If set, it always wins and automatic discovery is skipped entirely.- A key discovered automatically. On a 401, the server re-captures the
key the same way a human would (per
CAPTURE.md): it reads cineplex.com's homepage, walks the_next/static/chunks/*.jsit references, and extracts the key sitting next to the theatrical API's URL, then retries the request with it. This runs only after a rejected key, at most once per process, so normal operation costs nothing extra. - The bundled fallback in
cineplexClient.js— verified current as of 2026-07-30.
If automatic re-capture also fails, the error tells you so explicitly and
points at CAPTURE.md; recovery is then setting the env var, with no code
change or redeploy.
The extractor anchors on the theatrical API's URL rather than on the
Ocp-Apim-Subscription-Key header name, because Cineplex's bundle ships
several different subscription keys (a separate one guards their marketing
API, and it appears earlier in the bundle). Matching the header name alone
would return that decoy — a key that 401s forever while looking like a
successful re-capture.
Running
npm start
This starts the MCP server on stdio, for use by an MCP client (Claude Desktop, Claude Code, etc.) — it's not meant to be run standalone for interactive use.
Claude Desktop configuration
Add to your Claude Desktop config (claude_desktop_config.json):
{
"mcpServers": {
"cineplex": {
"command": "node",
"args": ["/absolute/path/to/cineplex-mcp/src/index.js"]
}
}
}
Restart Claude Desktop after editing the config.
If you ever need to override the subscription key (see above), add an env
block — otherwise leave it out:
"cineplex": {
"command": "node",
"args": ["/absolute/path/to/cineplex-mcp/src/index.js"],
"env": { "CINEPLEX_SUBSCRIPTION_KEY": "…" }
}
Claude Code configuration
claude mcp add cineplex -- node /absolute/path/to/cineplex-mcp/src/index.js
With an optional key override:
claude mcp add cineplex -e CINEPLEX_SUBSCRIPTION_KEY=… -- node /absolute/path/to/cineplex-mcp/src/index.js
Running in Docker
The server talks over stdio, so it works fine as a container that an MCP
client docker runs per session — no port mapping needed.
Build the image:
docker build -t cineplex-mcp .
Claude Desktop config, using the image instead of a local node install:
{
"mcpServers": {
"cineplex": {
"command": "docker",
"args": ["run", "-i", "--rm", "cineplex-mcp"]
}
}
}
Claude Code:
claude mcp add cineplex -- docker run -i --rm cineplex-mcp
With the subscription key override, pass it through with -e:
claude mcp add cineplex -- docker run -i --rm -e CINEPLEX_SUBSCRIPTION_KEY=… cineplex-mcp
Rebuild the image (docker build -t cineplex-mcp .) after pulling changes to
src/ — the client just launches whatever image tag is on disk, so a stale
image silently keeps running old code.
Tools exposed
-
find_theatres—{ location?, lat?, lon?, rangeKm? }→ nearby theatres (id, name, address, distance), nearest first, plus aresolvedLocationblock saying how the location was understood.Send
lat/lonwhen you can place the location yourself — that is the primary path. Sendlocationfor the things that need looking up: a postal code ("M5B 2H1", or a bare FSA like"M5B"), a Cineplex theatre name ("Yonge-Dundas"), or a city that has a Cineplex theatre. See Location input for how the two divide the work. -
find_movie—{ title }→ best fuzzy match against Cineplex's full current movie catalog, including the Cineplex movie ID. Cineplex'smoviesendpoint returns the whole catalog in one response (it reports atotalCountmatching the items it returns), so no pagination is involved. -
find_optimal_showtimes—{ movieTitle, theatreId, date, formatMatch?, excludeFrontRows?, excludeSideSeats?, minContiguous? }→ showtimes matching a format (default"IMAX", case-insensitive substring match — also works for"IMAX 70mm","UltraAVX","Dolby", etc.), scored for seat quality. Returns both the full scored list and anoptimalsubset. -
get_optimal_seats—{ theatreId, showtimeId, excludeFrontRows?, excludeSideSeats?, minContiguous? }→ seat score for a single already-known showtime. Cineplex's seat endpoints are keyed by the(theatreId, showtimeId)pair, not showtimeId alone. -
render_seat_map_ascii— the default seat-map visualization.{ theatreId, showtimeId, partySize?, excludeFrontRows?, excludeSideSeats?, monochrome?, theatreName?, showLabel?, buyUrl? }→ a compact ASCII/emoji seat-map diagram as plain text: a centered SCREEN banner, the auditorium as a grid of squares (🟩 open, ⬛ taken, 🟪 accessible), the bestpartySize-block highlighted (🟦, centered within the run), a one-line recommendation, and a🎟 Buy ticketslink. Works in any MCP client with no extra setup — it's just text. Because most clients keep tool results collapsed behind a "tools used" disclosure, the diagram is only visible if the assistant pastes it into its reply, so the result ships as two blocks: a display instruction, then a ready-to-paste payload fenced by===== COPY EVERYTHING BELOW THIS LINE =====markers. The payload arrives pre-formatted — the grid already inside afence, the buy line already lifted **out** of the fence as a clickable Markdown link (links don't linkify inside) — so displaying it is copy-paste, not reassembly. PassbuyUrlthrough fromfind_optimal_showtimesfor the correct D-BOX-aware link, or omit it to build acineplex.com/ticketing/previewlink from the IDs. Setmonochrome: true(·/▓/+/★) where emoji width misaligns the grid. Rendering logic lives insrc/seatMapAscii.js. -
render_seat_map_html— the opt-in interactive alternative; needs the bundled skill (see below).{ movieTitle, theatreId, date, theatreName?, theatreAddress?, distanceKm?, formatMatch?, excludeFrontRows?, excludeSideSeats?, minContiguous? }→ a complete, self-contained HTML page visualizing real seat availability: showtime chips, a pannable/zoomable auditorium seat map, live filter controls, and a stats strip. Meant to be rendered inline in the chat as a widget (via the Visualizer'sshow_widget), not saved to a file, published as a hosted artifact, or read as data — seesrc/seatMapTemplate.html/.js. The tool only injects real data into an already-built, already-tested template; it never generates new HTML/JS per call, so there's no risk of a fresh generation shipping a UI bug.
theatreId/showtimeId accept either a string or a number — Cineplex's IDs
are numeric, and find_theatres/find_optimal_showtimes hand them back as
numbers, so chaining one tool's output straight into the next one's input
just works.
Location input
Cineplex's theatre search is coordinate-based. find_theatres takes either
coordinates or a location string, and the two are meant to split the work
rather than compete:
Send lat/lon for anywhere you can already place — cities,
neighbourhoods, landmarks, street addresses. A language model converts those
accurately and knows when it can't, so a lookup table would only duplicate it.
This is the expected path and the most precise one.
Send location for what world knowledge gets wrong:
| Input | Example | Resolved from |
|---|---|---|
| postal code / FSA | "M5B 2H1", "M5B" | bundled FSA table |
| Cineplex theatre name | "Yonge-Dundas", "Courtney Park" | live theatre directory |
| city with a theatre | "Mississauga", "London, ON" | live theatre directory |
| coordinates as a string | "43.65, -79.38" | parsed, not looked up |
A postal code is also picked up from inside a longer string, so
"123 Front St W, Toronto, ON M5J 2M2" resolves by its postal code. Input is
case-, punctuation-, and accent-insensitive; a trailing country is ignored
("Halifax, NS, Canada"); provinces work as a code or a full name.
Anything else returns found: false inviting you to pass coordinates. That is
the design, not a gap.
Why postal codes specifically
They are the one input neither a model nor an open geocoder handles reliably.
Canada Post's postal file is proprietary, so OSM's coverage is thin: measured
against Nominatim on 2026-07-31, four of six sampled postal codes returned no
match, and V6B 1A1 — downtown Vancouver — resolved to 48.87, -119.73, about
400 km away near the Washington border.
Recall fares better but fails unpredictably. Claude's own from-memory
coordinates for 16 FSAs landed 12 within 10 km — Waterloo 0.1 km, Victoria
0.3 km — but placed T9K in Cold Lake when it is Fort McMurray, 264 km
off, stated exactly as confidently as the correct answers. A wrong coordinate
doesn't fail loudly; it returns a tidy list of theatres in the wrong city.
The bundled GeoNames table
(src/data/postalCodes.json, 41 KB, CC BY 4.0) covers all 1652 FSAs. Rebuild
it with npm run build:locations.
Precision
Every result reports how sharp it is:
exact— coordinates, or a specific theatre.fsa— an urban postal area, a few blocks across.city— the centroid of that city's Cineplex theatres. Fine for a small city, loose for a big one:"Toronto"lands near Don Mills, because the suburban locations outvote the downtown ones, and returns Don Mills as the nearest theatre where coordinates for downtown return Yonge-Dundas. Preferlat/lonfor large cities.region— a rural FSA (a0in the second position, Canada Post's own convention). The
Truncated for display — read the full file on GitHub.
Related Skills
Agent-Reach
106.6kGive your AI agent eyes to see the entire internet. Read & search Twitter, Reddit, YouTube, GitHub, Bilibili, XiaoHongShu — one CLI, zero API fees.
headroom
78.3kCompress tool outputs, logs, files, and RAG chunks before they reach the LLM. 20% fewer tokens for coding agents, 60-95% fewer tokens for JSON, same answers. Library, proxy, MCP server.
CowAgent
47.7kOpen-source personal AI assistant & Agent Harness. Plans tasks, runs tools and skills, self-evolves with memory and knowledge. Multi-agent, multi-model, multi-channel. Lightweight, extensible, one-line install.
Scrapling
90.4k🕷️ The BEST Web Scraping framework that handles everything from a single request to a full-scale crawl! Don't be shy, join here: https://discord.gg/EMgGbDceNQ and follow here for daily tips and tricks: https://x.com/Scrapling_dev
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
