italian-cinema-mcp
Click on "Deploy 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., "@italian-cinema-mcpwhat's on tonight after 20:00 in Rome?"
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.
italian-cinema-mcp
A local Model Context Protocol server that lets an
LLM compare showtimes across Italian cinema chains. Spawn it as an MCP host
(claude, Cursor, …) and ask things like "what's on tonight after 20:00 near
me?" — the server fans the question out to UCI Cinemas and The Space Cinema,
shrinks the ~100 KB per-cinema JSON payload into a compact text view, and
returns every option in one answer.
Status
MVP. UCI Cinemas (33 venues) and The Space Cinema (35 venues) are both wired in. Both upstream APIs are unofficial and may change without notice.
Related MCP server: Allociné MCP Server
Disclaimer
This project is not affiliated with, endorsed by, or sponsored by UCI Cinemas or The Space Cinema, and "UCI Cinemas", "The Space Cinema", and any other brand or venue names referenced here are the property of their respective owners. The server relies on the same undocumented JSON endpoints that the official websites call from the browser; it does not authenticate, and those endpoints may change, rate-limit, or stop working at any time without notice. It is intended for personal use; requests are cached (cinema metadata for 24 h, showtimes for 5 min) and dispatched with bounded concurrency so upstream is only contacted when the user actually asks something.
Tools
Tool | Inputs | Output |
|
| every cinema: id, name, chain, city |
|
| titles with duration and the cinemas showing them, no times |
|
| film → cinema → showtimes with format, language, sold-out flag, booking URL |
Cinema ids are namespaced by chain — uci:uci-cinemas-romaest-roma,
thespace:1021. date is YYYY-MM-DD, defaults to today in Europe/Rome.
Times are HH:MM Europe/Rome.
Recommended call flow: list_cinemas once → pick ids → list_films for a
cheap overview → get_showtimes with title_contains or a time window.
Errors from one cinema never fail the whole call; the rest are returned alongside a short note about which cinema failed and why.
Booking links are off by default (include_links=true to surface them).
Example output
Resident Evil (1h30)
The Space Roma Moderno 22:45
The Space Roma Parco de' Medici 21:05, 22:25, 23:25
UCI Porta di Roma 22:10
UCI Roma Est 21:40, 22:30, 23:50Showtime tags: just HH:MM by default. Only non-default format/language
gets a tag — 21:30 IMAX, 20:20 EN, 22:10 OV, 21:30 ISENSE. Italian
is the default and is never printed. Sold-out shows add (sold out).
Booking links are off by default; pass include_links=true to surface them.
Build
npm install
npm run build # tsc → dist/
npm run dev # tsx src/server.ts (no build step)
npm test # vitest, offline only
LIVE=1 npm test # also runs the live smoke tests against UCI and The SpaceRequirements: Node.js >= 20 (uses the global fetch).
Run
The server speaks MCP over stdio, so an MCP host launches it as a subprocess. Register it once and forget it.
Claude Code
claude mcp add --transport stdio --scope user italian-cinema-mcp \
-- node /absolute/path/to/italian-cinema-mcp/dist/server.js(or npm run dev if you prefer running from source).
Claude Desktop
Add the server in claude_desktop_config.json:
{
"mcpServers": {
"italian-cinema-mcp": {
"command": "node",
"args": ["/absolute/path/to/italian-cinema-mcp/dist/server.js"]
}
}
}Tests
npm test runs vitest on:
unit tests for the date helper, the formatter, and per-chain connector mappers (fixture-driven, no network);
the cinema service tests (filtering, per-cinema failures, batch merging);
an opt-in live smoke test (
LIVE=1) that hits both upstream APIs.
Fixtures under test/fixtures/{uci,thespace}/ are trimmed real responses, kept
in-repo so npm test doesn't need network access.
Project layout
src/
server.ts MCP server with three tools
service.ts CinemaService: chains, caching, parallel fetch, filter
connectors/uci.ts UCI Cinemas connector
connectors/thespace.ts The Space Cinema connector
format.ts compact text renderer for showtimes
cache.ts tiny TTL cache
http.ts fetch wrapper, retries, session cookie replay
dates.ts today-in-Rome, date validation, time compare
types.ts internal model shared by all connectors
test/
*.test.ts vitest unit tests
fixtures/{uci,thespace} saved real responses, trimmed
scripts/
mcp-call.mjs tiny JSON-RPC stdio driver used to verify end-to-end
AGENTS.md design briefUpstream APIs (unofficial, no auth)
UCI Cinemas
https://myuci---uci-backend-production-nfluwp7wga-oc.a.run.app/api
GET /theatres— list (id, name, slug, is_luxe, latitude, …). Theslugis the cinema id.GET /theatres/{slug}/programming/{YYYY-MM-DD}— the programming for one day.cart_linkis relative tohttps://ucicinemas.it.
The Space Cinema
https://www.thespacecinema.it/api/microservice/showings
GET /cinemas—{result: [{alpha, cinemas: [cinema]}]}. No city field:fullNameis best-effort, exposed as-is.GET /cinemas/{cinemaId}/films?showingDate=YYYY-MM-DDT00:00:00&minEmbargoLevel=3&includesSession=true&includeSessionAttributes=trueOne query string, not all separate.bookingUrlis relative tohttps://www.thespacecinema.it/.
An in-memory cookie jar in src/http.ts preserves the session cookies the
site sets across calls, the way a browser would, so consecutive requests in
the same session are accepted. We do not perform any challenge solving or
attempt to bypass upstream policies — we only store and replay whatever the
server gave us. Cinema metadata is cached for 24 h, showtimes for 5 min
(src/service.ts).
Out of scope (for now)
Remote HTTP transport, Webtic/18tickets connectors, seat maps.
Available Tools
3 toolsget_showtimesA
Showtimes for the given cinemas on a date, with optional time window and title substring filters. Returns a compact text view grouped by film and cinema: time, and only the format/language tags that deviate from the chain default (2D in Italian -> nothing; e.g. '21:30 IMAX', '20:20 EN', '21:30 ISENSE' otherwise). Italian is the default language and is omitted; EN, OV are normalised. Sold-out shows are tagged '(sold out)'. Booking links stay off by default; pass include_links=true to add them. Pass chain to restrict to one chain or a list (e.g. chain: 'uci' for loyalty promotions); cinema ids that belong to other chains are dropped.
Time axis: each requested date is a 'cinema day' that spans [date 06:00, date+1 06:00) in Europe/Rome. from_time/to_time earlier than 06:00 means the next calendar day (e.g. to_time '01:00' is 'until 01:00+1'). Showtimes after midnight are rendered with a '+1' marker ('22:00+1' is too far east to happen in practice; '00:30+1' is the usual case). If a film has only out-of-window showtimes at a cinema, that cinema line becomes 'cinema - none in window (N earlier, last HH:MM)'; if the film has zero in-window shows anywhere, an 'Outside the time window:' line is appended.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | YYYY-MM-DD in Europe/Rome; defaults to today. | |
| chain | No | Restrict the query to one chain or a list of chains. Cinema ids that do not belong to the allowed chain(s) are skipped. Use this for loyalty promotions (e.g. only uci) or to compare apples to apples. | |
| to_time | No | Latest showtime to include (HH:MM). | |
| from_time | No | Earliest showtime to include (HH:MM). | |
| cinema_ids | Yes | Cinema ids from list_cinemas. | |
| include_links | No | If true, append the booking URL inside [brackets] next to each showtime. | |
| title_contains | No | Case-insensitive substring the film title must contain. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and discloses output format (compact text grouped by film and cinema), default language omission, sold-out tagging, and the time axis convention (06:00 boundary, +1 marker). It also explains out-of-window handling, providing an unusually detailed behavioral contract.
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?
Though lengthy, every sentence adds necessary behavioral detail; the first sentence front-loads the core purpose. The text is structured into general behavior and time-axis specifics without 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?
There is no output schema, so the description must explain return values, and it does so exhaustively: formatting, language tags, sold-out marks, links, and edge cases. For a 7-parameter tool with no annotations, this is complete enough to invoke correctly.
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%, so the baseline is 3, but the description adds value by explaining the date's 'cinema day' span and the meaning of from_time/to_time earlier than 06:00. It also clarifies chain filtering behavior and include_links default, which the schema only names.
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 begins with 'Showtimes for the given cinemas on a date, with optional time window and title substring filters,' naming the resource and filters. It clearly distinguishes from siblings list_cinemas and list_films by focusing on showtimes for specific cinemas.
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 usage context for chain ('Pass chain to restrict to one chain... e.g. chain: 'uci' for loyalty promotions') and include_links ('Booking links stay off by default; pass include_links=true'). It implies the tool is for retrieving showtimes, but it does not explicitly name alternative tools or 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_cinemasA
List every cinema we know about, optionally filtered to a single chain. Call this once at the start of a session to discover cinema ids. Ids are namespaced like uci:slug or thespace:numericId and are needed by the other tools.
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | uci or thespace; omit for both. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It transparently discloses that it lists all known cinemas, optionally filters by chain, and that IDs follow a namespaced format ('uci:slug' or 'thespace:numericId'). It does not mention return structure beyond IDs or pagination, but for a simple list 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?
Three sentences, each carrying distinct information: what the tool does, when to call it, and the format/importance of the IDs. No wasted words or repetitive 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?
In the absence of an output schema and annotations, the description gives essential operational context: when to call, the purpose (discovering IDs), the ID namespace, and their role in the broader API. It could be more precise about the full result shape, but it is sufficient for an agent to use the tool correctly in a discovery workflow.
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%, and the schema already documents the 'chain' parameter with its enum and 'omit for both' behavior. The description only restates the optional filter, adding nothing beyond what the schema provides, so baseline 3 applies.
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 and resource ('List every cinema we know about') and mentions the optional chain filter. It also states that the returned cinema IDs are needed by the other tools, which clearly distinguishes it from the sibling tools list_films and get_showtimes.
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?
It gives explicit when-to-use guidance: 'Call this once at the start of a session to discover cinema ids.' It also explains that the IDs are needed by other tools, establishing it as a prerequisite. However, it does not explicitly contrast it with alternatives or 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_filmsA
Cheap overview of the films playing in the given cinemas on the given date, without showtimes. Use this after list_cinemas to discover which films are worth querying with get_showtimes. Pass chain to restrict to one chain or a list of chains (e.g. chain: 'uci' for loyalty promotions); cinema ids that belong to other chains are dropped.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | YYYY-MM-DD in Europe/Rome; defaults to today. | |
| chain | No | Restrict the query to one chain or a list of chains. Cinema ids that do not belong to the allowed chain(s) are skipped. Use this for loyalty promotions (e.g. only uci) or to compare apples to apples. | |
| cinema_ids | Yes | Cinema ids from list_cinemas. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool is 'cheap' (cost/performance), that it returns 'without showtimes' (content limitation), and that 'cinema ids that belong to other chains are dropped' (filtering behavior). These go beyond the schema and give the agent a realistic expectation of the tool's behavior.
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 with no filler. The first sentence front-loads the core purpose and limitation, the second provides workflow and parameter context. Every sentence earns its place, and the structure is easy to scan.
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?
There is no output schema, so the description must convey what the tool returns. It states it provides an 'overview of the films playing' and that it's used to 'discover which films are worth querying,' implying it returns film identifiers. While it doesn't enumerate exact fields or pagination, it's sufficient for a simple listing tool in the given workflow. Minor gap: no explicit mention of return format, but not critical.
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 adds extra semantic value for the chain parameter by explaining its use case ('loyalty promotions', 'compare apples to apples') and reiterating the filtering behavior. This goes beyond the schema's description and helps the agent choose the right value.
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 a specific verb ('list') and resource ('films'), and adds critical scope: 'playing in the given cinemas on the given date, without showtimes.' It also differentiates from siblings by explicitly positioning it between list_cinemas and get_showtimes, so an agent can immediately tell what this tool does and how it fits.
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 workflow guidance: 'Use this after list_cinemas to discover which films are worth querying with get_showtimes.' It also explains the chain parameter's purpose ('for loyalty promotions') and the filtering behavior, leaving no ambiguity about when and how to invoke the tool.
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.
3 tool updates
v0.1.0- First observed
get_showtimes - First observed
list_cinemas - First observed
list_films
TDQS
Scored across 3 tools
Each tool has a distinct role: list_cinemas discovers venue identifiers, list_films provides a film overview, and get_showtimes gives detailed timings. There is no overlap or ambiguity between them.
All tools follow a consistent verb_noun pattern: list_cinemas, list_films, get_showtimes. The 'list_' prefix for overviews and 'get_' for detailed retrieval is a clear and predictable convention.
Three tools is well-scoped for a cinema showtimes server. Each tool serves a necessary step in the discovery workflow, and none feels redundant or extraneous.
The tool surface covers the full user journey: discover cinemas, identify films, and retrieve showtimes. There are no obvious gaps; the inclusion of filters and options makes the workflow complete for the stated purpose.
Maintenance
Related MCP Connectors
French cultural events search with multi-reseller ticket price comparison (theatre, concerts...)
Independent directory of agentic AI tools — search, compare & recommend via MCP. Read-only.
Booking gateway for AI agents — discover events, movies & hotels, hand off to partner checkout.
Measure what ChatGPT, Claude, Gemini and 4 more AI engines say about any business. No auth.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides a comprehensive movie booking experience for AMC Theatres, enabling users to discover movies, find showtimes, select seats, and process payments through conversational AI. Supports multi-location theater search with real-time seat availability and booking management.61MIT
- FlicenseNot gradedqualityCmaintenanceEnables users to search for movies and retrieve showtimes from Allociné, including cinema locations, screening times, and formats (VF, VOST, 3D, IMAX) for specific cities or postal codes in France.-
- FlicenseNot gradedqualityDmaintenanceProvides movie listings, showtimes, and personalized recommendations for Amsterdam cinemas by scraping filmladder.nl, with support for filtering by date, cinema, rating, and preferred showtimes.1-
- FlicenseNot gradedqualityDmaintenanceEnables searching for movies, checking Google Calendar for conflicts, and booking tickets with seat type and INR pricing, all through natural conversation. Supports demo mode without API keys.-