Skip to main content
Glama
cyanheads

@cyanheads/tmdb-mcp-server

by cyanheads

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


Tools

Eight tools organized search-before-detail — tmdb_search_titles resolves a name to an integer id, the get_* tools fetch full records, and tmdb_discover_titles / tmdb_get_trending / tmdb_get_watch_providers cover filtered browsing and streaming availability. TMDB keys on integer ids, not titles, so search comes first.

Tool

Description

tmdb_search_titles

Search movies, TV, and people by name. The required first step — resolves a name to the integer id the detail tools consume.

tmdb_get_movie

Full movie detail in one call — synopsis, runtime, genres, US certification, budget/revenue, cast, crew, trailers, recommendations, keywords, external ids.

tmdb_get_show

Full TV show detail — overview, air dates, status, season/episode counts, creators, networks, season summaries, cast, trailers, content rating.

tmdb_get_season

Episode list for one season — names, air dates, runtimes, vote averages, stills, per-episode guest stars, plus the season's regular cast.

tmdb_get_person

Person detail and full filmography — biography, vital dates, the combined_credits cast/crew lists, and cross-platform external ids.

tmdb_discover_titles

Filtered, sorted discovery across movies or TV — the power-query: genre, date/vote ranges, vote-count floor, cast/crew/network, watch providers, runtime, sort.

tmdb_get_trending

Trending movies, TV, or people for the day or week.

tmdb_get_watch_providers

Region-scoped streaming availability (JustWatch) — flatrate/rent/buy/ads/free provider lists plus the TMDB link. A region code is required.

All list and detail responses resolve image *_path fields to full https://image.tmdb.org/t/p/… URLs and resolve genre_ids[] to genre names. Every tool carries the TMDB attribution in its output enrichment.

tmdb_search_titles

Resolve a movie, show, or person name to ranked results with integer ids.

  • multi mode (default) mixes movies, shows, and people, each result tagged with media_type; movie/tv/person restrict to one type and enable type-specific ranking

  • Optional year filter (movie/tv modes), language override, include_adult toggle, and page for paging past the first 20

  • Each result carries id, media_type, title/name, release_year, overview, vote_average, resolved genre_names, and the relevant poster/profile URL

  • An empty result set is a valid answer, returned with recovery guidance — not an error


tmdb_get_movie

Fetch full movie detail by TMDB id in a single request.

  • Folds credits, videos, recommendations, similar, keywords, external ids, and release dates into one call via append_to_response — trim the append array to shrink the payload (e.g. ["credits"] for cast only)

  • US theatrical certification extracted from the release_dates namespace; top-billed cast and key crew (Director/Writer/Screenplay/Producer); YouTube trailers with watch URLs

  • Does not include streaming availability — that is region-specific; use tmdb_get_watch_providers


tmdb_get_show

Fetch full TV show detail by series id — the series mirror of tmdb_get_movie.

  • Same append_to_response set, with content_ratings (US TV rating) in place of release_dates

  • Adds season summaries, creators, networks, and the last/next episode to air

  • Pass a season_number from seasons[] to tmdb_get_season for the episode list


tmdb_get_season

Fetch the episode list for one season of a show — bridges the show-level summary and per-episode detail.

  • Per-episode names, air dates, runtimes, vote averages, still URLs, and guest stars (embedded per episode)

  • Plus the season's regular recurring cast (distinct from per-episode guest stars)

  • series_id is echoed from the input — the TMDB season endpoint does not return it. Season 0 is "Specials"


tmdb_get_person

Fetch person detail and the full combined filmography.

  • Biography, birth/death dates, place of birth, known-for department, aliases, gender label

  • combined_credits split into cast_credits and crew_credits, recency-ordered (most recent first) and capped to a display size — the pre-cap totals are reported and truncation is disclosed in the enrichment

  • IMDb id plus the extended cross-platform id set (Wikidata, social handles) for chaining to other servers


tmdb_discover_titles

The power-query — filtered, sorted discovery across movies or TV.

  • Filter by with_genres/without_genres, exact year or a release_date_gte/lte window, vote_average range, vote_count_gte floor, with_cast/with_crew (movie), with_networks (tv), with_watch_providers + watch_region, with_original_language, and runtime range

  • Sort by popularity, revenue, vote average, vote count, or release date. Pair vote_average.desc with vote_count_gte (~100–1000) so a 10.0-from-3-votes title does not dominate

  • with_cast/with_crew are movie-only and with_networks is tv-only on TMDB; the tool accepts them for both media_type values and no-ops the inapplicable ones with a notice

  • with_watch_providers requires a watch_region — streaming availability is region-specific. Omitting the region returns a typed region_required error


tmdb_get_watch_providers

Find where a movie or TV title streams in one region.

  • Returns flatrate (subscription), rent, buy, ads (ad-supported free), and free provider lists with logo URLs, plus the TMDB JustWatch-backed link — the supported path to actual deep links

  • A watch_region (ISO 3166-1 alpha-2) is required: availability is region-specific and there is no global answer; the response always carries a region caveat

  • An empty result for a region is a valid "not available to stream here" answer, not an error

  • Provider ids in the result feed back into tmdb_discover_titles with_watch_providers

Resources

Type

Name

Description

Resource

tmdb://movie/{movie_id}

Movie detail by id, as injectable context — the same enriched record as tmdb_get_movie.

Resource

tmdb://tv/{series_id}

Show detail by id — the same enriched record as tmdb_get_show.

Resource

tmdb://person/{person_id}

Person detail and filmography by id — the same record as tmdb_get_person.

All resource data is also reachable via tools — the three resources are convenience wrappers over the detail service methods, so tool-only clients lose nothing. Search, discovery, trending, and seasons are query paths or intermediate records, not addressable entities, so they have no resources. There are no prompts: this is a data/lookup server with no recurring multi-step interaction template.

Features

Built on @cyanheads/mcp-ts-core:

  • Declarative tool and resource definitions — single file per primitive, framework handles registration and validation

  • Unified error handling — handlers throw, framework catches, classifies, and formats

  • Typed error contracts — every tool declares its failure reasons with recovery guidance for the agent

  • Pluggable auth: none, jwt, oauth

  • Swappable storage backends: in-memory, filesystem, Supabase, Cloudflare KV/R2/D1

  • Structured logging with optional OpenTelemetry tracing

  • STDIO and Streamable HTTP transports — runs locally or on Cloudflare Workers from the same codebase

TMDB-specific:

  • Single typed client for the TMDB v3 REST API, authenticated with a v4 Read Access Token over Authorization: Bearer

  • Image *_path fields resolved to full https://image.tmdb.org/t/p/{size}{path} URLs — null paths omit the field rather than emitting a broken URL

  • genre_ids[] resolved to genre names from per-media_type maps cached at startup, so list results carry readable genres without an extra call

  • Detail tools collapse credits, videos, recommendations, similar, keywords, and external ids into one HTTP call via append_to_response

  • Region-aware streaming availability backed by JustWatch — region is always an explicit input, never assumed

Agent-friendly output:

  • TMDB attribution on every response — surfaced in enrichment.attribution so it reaches both the structuredContent and content[] client surfaces

  • Provenance and pagination on list responses — total-result counts, page/total-pages, and an effective-filter notice so agents can reason about what was actually queried

  • Empty results and empty provider regions return normally with recovery guidance, not as errors — "no titles matched" and "not streamable here" are real answers an agent must act on

  • Region and truncation caveats are explicit — watch-provider results always state the region; capped filmographies disclose the pre-cap totals

Getting started

A TMDB API Read Access Token is required. Create a free TMDB account, then copy the API Read Access Token (a v4 JWT) from your API settings — this server authenticates v3 endpoints with Authorization: Bearer <token>, not the legacy ?api_key= query parameter.

Add the following to your MCP client configuration file.

{
  "mcpServers": {
    "tmdb-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/tmdb-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "TMDB_API_KEY": "your-tmdb-read-access-token"
      }
    }
  }
}

Or with npx (no Bun required):

{
  "mcpServers": {
    "tmdb-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/tmdb-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "MCP_LOG_LEVEL": "info",
        "TMDB_API_KEY": "your-tmdb-read-access-token"
      }
    }
  }
}

Or with Docker:

{
  "mcpServers": {
    "tmdb-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "-e", "TMDB_API_KEY=your-tmdb-read-access-token",
        "ghcr.io/cyanheads/tmdb-mcp-server:latest"
      ]
    }
  }
}

For Streamable HTTP, set the transport and start the server:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 TMDB_API_KEY=... bun run start:http
# Server listens at http://localhost:3010/mcp

Refer to "your MCP client configuration file" generically — different clients use different config paths, and this server isn't client-specific.

Prerequisites

Installation

  1. Clone the repository:

git clone https://github.com/cyanheads/tmdb-mcp-server.git
  1. Navigate into the directory:

cd tmdb-mcp-server
  1. Install dependencies:

bun install
  1. Configure environment:

cp .env.example .env
# edit .env and set TMDB_API_KEY

Configuration

All configuration is validated at startup via Zod schemas. Key environment variables:

Variable

Description

Default

TMDB_API_KEY

Required. TMDB v4 API Read Access Token (JWT), sent as Authorization: Bearer. Not the v3 ?api_key= value.

TMDB_LANGUAGE

Default response language as ISO 639-1, optionally with region (e.g. en-US). A per-call language input overrides it.

en-US

TMDB_DEFAULT_REGION

Default ISO 3166-1 country hint used in region-aware error messages. tmdb_get_watch_providers still requires an explicit watch_region.

US

MCP_TRANSPORT_TYPE

Transport: stdio or http.

stdio

MCP_HTTP_PORT

Port for the HTTP server.

3010

MCP_AUTH_MODE

Auth mode: none, jwt, or oauth.

none

MCP_LOG_LEVEL

Log level (RFC 5424).

info

STORAGE_PROVIDER_TYPE

Storage backend.

in-memory

OTEL_ENABLED

Enable OpenTelemetry instrumentation (spans, metrics, completion logs).

false

See .env.example for the full list of optional overrides.

Running the server

Local development

  • Build and run:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
  • Run checks and tests:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec

Docker

docker build -t tmdb-mcp-server .
docker run --rm -e TMDB_API_KEY=your-token -p 3010:3010 tmdb-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/tmdb-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

Directory

Purpose

src/index.ts

createApp() entry point — registers tools and resources, and primes the startup cache in setup().

src/config

Server-specific environment variable parsing and validation with Zod.

src/mcp-server/tools

Tool definitions (*.tool.ts) — the eight TMDB tools.

src/mcp-server/resources

Resource definitions (*.resource.ts) — movie, TV, and person detail.

src/services/tmdb

TMDB v3 REST client — Bearer auth, retry/timeout, the image/genre startup cache, and the imageUrl/genreNames helpers.

tests/

Unit and integration tests mirroring src/.

Development guide

See AGENTS.md (or CLAUDE.md, the same content) for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic

  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage

  • Register new tools and resources via the barrels in src/mcp-server/*/definitions/index.ts

  • Wrap the TMDB API: validate raw → normalize to the domain type → return the output schema; never fabricate missing fields (null poster paths omit the URL, unknown genre ids are dropped)

Contributing

Issues and pull requests are welcome. Run checks and tests before submitting:

bun run devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.


This product uses the TMDB API but is not endorsed or certified by TMDB. Streaming availability data is provided by JustWatch via TMDB and is region-specific.

Latest Blog Posts

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/cyanheads/tmdb-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server