Footlambert MCP

Footlambert exposes a public, read-only Model Context Protocol (MCP) endpoint for Paris theater, movie, showtime, and retrospective data.

Endpoint

https://seance.paris/mcp

Transport: Streamable HTTP. Protocol version: 2025-06-18.

All tools are read-only and intended for query use.

Discovery

  • MCP endpoint: https://seance.paris/mcp
  • Human docs: https://seance.paris/mcp-docs
  • LLM index: https://seance.paris/llms.txt
  • Metadata probe: GET /mcp

HTTP Requirements

  • Initialize with POST /mcp and JSON-RPC initialize.
  • Send Accept: application/json, text/event-stream for MCP POST requests.
  • Send Mcp-Session-Id on all follow-up requests after initialize.
  • Send MCP-Protocol-Version: 2025-06-18 after initialize.
  • Close sessions with DELETE /mcp.

Canonical IDs

  • theater:<slug>
  • movie:wikidata:<QID>
  • movie:slug:<slug>
  • person:<role>:<id>
  • date:<yyyy-mm-dd>

Data Source

The endpoint serves data from the production Footlambert snapshot manifest published to DigitalOcean Spaces. The manifest points to the current shard set and is refreshed multiple times per day.

Notes

  • No mutation tools are exposed.
  • Movie responses use Wikidata-oriented IDs and do not expose IMDb IDs.
  • Showtime timestamps are normalized to ISO-8601 values in the Europe/Paris timezone.
  • Responses may be rate-limited for abuse protection.

Tools

  • search: args query, type?, date?, limit?. Result list across theaters/movies/people/showtimes.
  • fetch: args id. Canonical entity payload by ID (theater/movie/person/date).
  • get_theater: args slug_or_name. Theater details + showtimes grouped by date.
  • get_movie: args movie_id_or_slug. Movie details + showtimes grouped by theater.
  • get_showtimes: args date?, theater_slug?, movie?, movie_id?, limit?. Flat showtime events with Paris-normalized times.
  • get_retrospectives: args role?, person?, limit?. Retrospective buckets for directors/writers/cast.
  • get_person: args id_or_name, role?. Person details + associated movies + showtimes by date.

Initialize Example

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": { "name": "example-client", "version": "1.0.0" }
  }
}

Tool Call Example

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_showtimes",
    "arguments": { "date": "2026-02-18", "limit": 2 }
  }
}

Response Contract

  • Success: { result: { content: [...], structuredContent: {...} } }
  • Tool error: { result: { isError: true, content: [...], structuredContent: { error } } }

Endpoint Return Examples

GET /mcp (metadata probe, no session)

Request:

curl -s https://seance.paris/mcp

Response:

{
  "name": "footlambert-mcp",
  "version": "1.0.0",
  "protocol_version": "2025-06-18",
  "transport": "streamable-http",
  "endpoint": "https://seance.paris/mcp",
  "docs": "https://seance.paris/mcp-docs",
  "llms": "https://seance.paris/llms.txt",
  "tools": ["search", "fetch", "get_theater", "get_movie", "get_showtimes", "get_retrospectives", "get_person"],
  "canonical_ids": {
    "theater": "theater:<slug>",
    "movie": ["movie:wikidata:<QID>", "movie:slug:<slug>"],
    "person": "person:<role>:<id>",
    "date": "date:<YYYY-MM-DD>"
  },
  "time_policy": {
    "timezone": "Europe/Paris",
    "format": "ISO-8601 with Paris UTC offset"
  }
}

POST /mcp initialize (JSON-RPC)

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {},
    "clientInfo": { "name": "example-client", "version": "1.0.0" }
  }
}

Response:

{
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": { "logging": {}, "tools": { "listChanged": true } },
    "serverInfo": { "name": "footlambert-mcp", "version": "1.0.0" }
  },
  "jsonrpc": "2.0",
  "id": 1
}
// HTTP response header includes: Mcp-Session-Id: <uuid>

DELETE /mcp (close session)

Request:

curl -X DELETE https://seance.paris/mcp -H "Mcp-Session-Id: <session-id>"

Response:

HTTP 200 with empty body

POST /mcp tool call without session

Request:

{
  "jsonrpc": "2.0",
  "id": 12,
  "method": "tools/call",
  "params": { "name": "search", "arguments": { "query": "mk2" } }
}

Response:

{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "No active MCP session. Start with an initialize request or include a valid mcp-session-id header."
  },
  "id": null
}

GET /mcp with Accept: text/event-stream but no session

Request:

curl -H "Accept: text/event-stream" https://seance.paris/mcp

Response:

HTTP 405
{
  "error": "Sessionless GET event streams are not supported. Initialize with POST /mcp first and send Mcp-Session-Id on follow-up requests."
}

Tool Output Examples

search

Tool call params:

{
  "name": "search",
  "arguments": { "query": "godard", "type": "all", "limit": 2 }
}

result.structuredContent sample:

{
  "query": "godard",
  "type": "all",
  "date": null,
  "total_results": 2,
  "results": [
    { "id": "movie:wikidata:Q86427", "type": "movie", "title": "Breathless" },
    { "id": "person:directors:Q53001", "type": "person", "title": "Jean-Luc Godard" }
  ]
}

fetch

Tool call params:

{
  "name": "fetch",
  "arguments": { "id": "theater:mk2-beaubourg" }
}

result.structuredContent sample:

{
  "id": "theater:mk2-beaubourg",
  "type": "theater",
  "theater": {
    "name": "MK2 Beaubourg",
    "address": "50 Rue Rambuteau",
    "website": "https://www.mk2.com/salle/mk2-beaubourg",
    "location": { "latitude": 48.861555, "longitude": 2.352217 }
  },
  "showtimes_by_date": { "2026-02-18": [ ... ] }
}

get_theater

Tool call params:

{
  "name": "get_theater",
  "arguments": { "slug_or_name": "mk2-beaubourg" }
}

result.structuredContent sample:

{
  "id": "theater:mk2-beaubourg",
  "theater": {
    "name": "MK2 Beaubourg",
    "address": "50 Rue Rambuteau",
    "phone": "0 892 69 84 84",
    "cards": { "ugc": true, "pathe": false, "mk2": null }
  },
  "showtimes_by_date": { "2026-02-18": [ ... ] }
}

get_movie

Tool call params:

{
  "name": "get_movie",
  "arguments": { "movie_id_or_slug": "movie:wikidata:Q86427" }
}

result.structuredContent sample:

{
  "id": "movie:wikidata:Q86427",
  "movie": {
    "wikidata_qid": "Q86427",
    "title": "Breathless",
    "director": "Jean-Luc Godard",
    "year": "1960"
  },
  "showtimes_by_theater": { "filmotheque-du-quartier-latin": { "dates": { ... } } }
}

get_showtimes

Tool call params:

{
  "name": "get_showtimes",
  "arguments": { "date": "2026-02-18", "limit": 2 }
}

result.structuredContent sample:

{
  "filters": { "date": "2026-02-18", "theater_slug": null, "movie": null },
  "total_results": 2,
  "showtimes": [
    {
      "date": "2026-02-18",
      "timezone": "Europe/Paris",
      "times": [{ "iso": "2026-02-18T10:30:00+01:00", "label": "10:30" }]
    }
  ]
}

get_retrospectives

Tool call params:

{
  "name": "get_retrospectives",
  "arguments": { "role": "directors", "limit": 2 }
}

result.structuredContent sample:

{
  "role": "directors",
  "person_filter": null,
  "total_results": 2,
  "entries": [
    { "canonical_id": "person:directors:Q51547", "label": "Billy Wilder", "movie_count": 11 },
    { "canonical_id": "person:directors:Q189526", "label": "Brian De Palma", "movie_count": 8 }
  ]
}

get_person

Tool call params:

{
  "name": "get_person",
  "arguments": { "id_or_name": "Jean-Luc Godard", "role": "directors" }
}

result.structuredContent sample:

{
  "person": {
    "canonical_id": "person:directors:Q53001",
    "label": "Jean-Luc Godard",
    "movie_count": 4
  },
  "movies": [{ "id": "movie:wikidata:Q86427", "title": "Breathless" }],
  "showtimes_by_date": { "2026-02-18": [ ... ] }
}