KS
Killer-Skills

tmdb-integration — how to use tmdb-integration how to use tmdb-integration, tmdb-integration setup guide, react native tv tmdb api, tmdb integration alternative, tmdb-integration vs themoviedb, tmdb-integration install, what is tmdb-integration, tmdb api optimization, typescript types for tmdb

v1.0.0
GitHub

About this Skill

Ideal for Media Integration Agents needing seamless access to movie and TV show data via The Movie Database API tmdb-integration is a skill that facilitates the integration of The Movie Database API with React Native TV applications, enabling features like data fetching and image display.

Features

Fetches movie and TV show data using TMDB API
Displays poster and backdrop images in React Native TV apps
Implements search functionality for trending content
Fetches video trailers and handles TMDB authentication
Optimizes API usage with rate limiting and TypeScript types

# Core Topics

giolaq giolaq
[0]
[0]
Updated: 3/6/2026

Quality Score

Top 5%
54
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add giolaq/Multi-TV-dev-power/tmdb-integration

Agent Capability Analysis

The tmdb-integration MCP Server by giolaq is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for how to use tmdb-integration, tmdb-integration setup guide, react native tv tmdb api.

Ideal Agent Persona

Ideal for Media Integration Agents needing seamless access to movie and TV show data via The Movie Database API

Core Value

Empowers agents to fetch movie and TV show data, display poster and backdrop images, and implement search functionality using React Native TV and TMDB API, while handling authentication, rate limiting, and optimization

Capabilities Granted for tmdb-integration MCP Server

Fetching trending movie and TV show content
Implementing search functionality with TMDB API
Displaying video trailers and poster images in React Native TV applications

! Prerequisites & Limits

  • Requires TMDB API key
  • Rate limiting applies to API requests
  • Specific to React Native TV applications
Project
SKILL.md
11.2 KB
.cursorrules
1.2 KB
package.json
240 B
Ready
UTF-8

# Tags

[No tags]
SKILL.md
Readonly

TMDB Integration Skill

You are an expert in integrating The Movie Database (TMDB) API with React Native TV applications. This skill activates when users ask about:

  • Fetching movie or TV show data
  • Displaying poster and backdrop images
  • Implementing search functionality
  • Getting trending content
  • Fetching video trailers
  • TMDB authentication and API keys
  • Rate limiting and optimization
  • TypeScript types for TMDB responses

Authentication

TMDB offers two equivalent authentication methods:

API Key (Query Parameter)

typescript
1const url = `https://api.themoviedb.org/3/movie/550?api_key=${API_KEY}`;

Bearer Token (Header) - Recommended

typescript
1const headers = { 2 'Authorization': `Bearer ${ACCESS_TOKEN}`, 3 'Accept': 'application/json' 4};

Both tokens are generated in your TMDB account settings. Bearer token is recommended for production as credentials aren't visible in URLs.

Image URL Construction

Base URL: https://image.tmdb.org/t/p/

Official Sizes (use these for CDN caching):

TypeAvailable Sizes
Posterw92, w154, w185, w342, w500, w780, original
Backdropw300, w780, w1280, original
Logow45, w92, w154, w185, w300, w500, original
Profilew45, w185, h632, original

Image URL Helper:

typescript
1const TMDB_IMAGE_BASE = 'https://image.tmdb.org/t/p/'; 2 3type PosterSize = 'w92' | 'w154' | 'w185' | 'w342' | 'w500' | 'w780' | 'original'; 4type BackdropSize = 'w300' | 'w780' | 'w1280' | 'original'; 5 6export function getPosterUrl(path: string | null, size: PosterSize = 'w500'): string | null { 7 if (!path) return null; 8 return `${TMDB_IMAGE_BASE}${size}${path}`; 9} 10 11export function getBackdropUrl(path: string | null, size: BackdropSize = 'w1280'): string | null { 12 if (!path) return null; 13 return `${TMDB_IMAGE_BASE}${size}${path}`; 14}

Important: Only use official sizes - non-standard sizes bypass CDN caching and are 10-50x slower.

Essential Endpoints

Trending Content

GET /trending/{media_type}/{time_window}

media_type: movie, tv, person, all
time_window: day, week

Discovery

GET /discover/movie
GET /discover/tv

Parameters:
- sort_by: popularity.desc, vote_average.desc, release_date.desc
- with_genres: 28,12 (AND) or 28|12 (OR)
- page: pagination (20 items per page)

Search

GET /search/movie?query={term}
GET /search/tv?query={term}
GET /search/multi?query={term}  // Movies, TV, and people

Details with Related Data

GET /movie/{id}?append_to_response=videos,credits,images
GET /tv/{id}?append_to_response=videos,credits,images,season/1,season/2

append_to_response combines multiple requests into one (doesn't count toward rate limits).

Genres

GET /genre/movie/list
GET /genre/tv/list

TypeScript Interfaces

typescript
1// Base types 2export interface Movie { 3 id: number; 4 title: string; 5 overview: string; 6 poster_path: string | null; 7 backdrop_path: string | null; 8 release_date: string; 9 vote_average: number; 10 vote_count: number; 11 popularity: number; 12 genre_ids?: number[]; 13 adult: boolean; 14} 15 16export interface TVShow { 17 id: number; 18 name: string; 19 overview: string; 20 poster_path: string | null; 21 backdrop_path: string | null; 22 first_air_date: string; 23 vote_average: number; 24 vote_count: number; 25 popularity: number; 26 genre_ids?: number[]; 27 origin_country: string[]; 28} 29 30export interface TMDBResponse<T> { 31 page: number; 32 results: T[]; 33 total_pages: number; 34 total_results: number; 35} 36 37// Detail types 38export interface MovieDetails extends Movie { 39 budget: number; 40 revenue: number; 41 runtime: number; 42 status: string; 43 tagline: string; 44 genres: Genre[]; 45 production_companies: ProductionCompany[]; 46 credits?: Credits; 47 videos?: { results: Video[] }; 48 images?: Images; 49} 50 51export interface TVDetails extends TVShow { 52 number_of_episodes: number; 53 number_of_seasons: number; 54 episode_run_time: number[]; 55 seasons: Season[]; 56 networks: Network[]; 57 status: string; 58 credits?: Credits; 59 videos?: { results: Video[] }; 60} 61 62export interface Genre { 63 id: number; 64 name: string; 65} 66 67export interface Video { 68 id: string; 69 key: string; // YouTube/Vimeo video ID 70 name: string; 71 site: 'YouTube' | 'Vimeo'; 72 size: number; 73 type: 'Trailer' | 'Teaser' | 'Clip' | 'Featurette' | 'Behind the Scenes'; 74 official: boolean; 75 published_at: string; 76} 77 78export interface Credits { 79 cast: CastMember[]; 80 crew: CrewMember[]; 81} 82 83export interface CastMember { 84 id: number; 85 name: string; 86 character: string; 87 profile_path: string | null; 88 order: number; 89} 90 91export interface CrewMember { 92 id: number; 93 name: string; 94 job: string; 95 department: string; 96 profile_path: string | null; 97} 98 99export interface Season { 100 id: number; 101 season_number: number; 102 name: string; 103 overview: string; 104 air_date: string; 105 episode_count: number; 106 poster_path: string | null; 107} 108 109export interface Episode { 110 id: number; 111 name: string; 112 overview: string; 113 episode_number: number; 114 season_number: number; 115 still_path: string | null; 116 air_date: string; 117 runtime: number; 118 vote_average: number; 119}

Axios Client Setup

typescript
1import axios from 'axios'; 2 3const TMDB_BASE_URL = 'https://api.themoviedb.org/3'; 4 5const tmdbClient = axios.create({ 6 baseURL: TMDB_BASE_URL, 7 timeout: 10000, 8 headers: { 9 'Accept': 'application/json', 10 'Authorization': `Bearer ${process.env.TMDB_ACCESS_TOKEN}`, 11 }, 12}); 13 14// Add default language 15tmdbClient.interceptors.request.use((config) => { 16 config.params = { 17 ...config.params, 18 language: 'en-US', 19 }; 20 return config; 21}); 22 23// Error handling 24tmdbClient.interceptors.response.use( 25 (response) => response, 26 (error) => { 27 if (error.response?.status === 429) { 28 // Rate limited - implement retry with backoff 29 console.warn('TMDB rate limit hit'); 30 } 31 return Promise.reject(error); 32 } 33); 34 35export default tmdbClient;

React Native Hooks

useTrending Hook

typescript
1import { useState, useEffect } from 'react'; 2import tmdbClient from '../services/tmdbClient'; 3import { Movie, TVShow, TMDBResponse } from '../types/tmdb'; 4 5type MediaType = 'movie' | 'tv' | 'all'; 6type TimeWindow = 'day' | 'week'; 7 8export function useTrending<T extends Movie | TVShow>( 9 mediaType: MediaType = 'movie', 10 timeWindow: TimeWindow = 'week' 11) { 12 const [data, setData] = useState<T[]>([]); 13 const [loading, setLoading] = useState(true); 14 const [error, setError] = useState<Error | null>(null); 15 16 useEffect(() => { 17 let cancelled = false; 18 19 async function fetchTrending() { 20 try { 21 setLoading(true); 22 const response = await tmdbClient.get<TMDBResponse<T>>( 23 `/trending/${mediaType}/${timeWindow}` 24 ); 25 if (!cancelled) { 26 setData(response.data.results); 27 } 28 } catch (err) { 29 if (!cancelled) { 30 setError(err as Error); 31 } 32 } finally { 33 if (!cancelled) { 34 setLoading(false); 35 } 36 } 37 } 38 39 fetchTrending(); 40 return () => { cancelled = true; }; 41 }, [mediaType, timeWindow]); 42 43 return { data, loading, error }; 44}

useMovieDetails Hook

typescript
1export function useMovieDetails(movieId: number) { 2 const [movie, setMovie] = useState<MovieDetails | null>(null); 3 const [loading, setLoading] = useState(true); 4 const [error, setError] = useState<Error | null>(null); 5 6 useEffect(() => { 7 let cancelled = false; 8 9 async function fetchDetails() { 10 try { 11 setLoading(true); 12 const response = await tmdbClient.get<MovieDetails>( 13 `/movie/${movieId}`, 14 { 15 params: { 16 append_to_response: 'videos,credits,images', 17 }, 18 } 19 ); 20 if (!cancelled) { 21 setMovie(response.data); 22 } 23 } catch (err) { 24 if (!cancelled) { 25 setError(err as Error); 26 } 27 } finally { 28 if (!cancelled) { 29 setLoading(false); 30 } 31 } 32 } 33 34 if (movieId) { 35 fetchDetails(); 36 } 37 return () => { cancelled = true; }; 38 }, [movieId]); 39 40 return { movie, loading, error }; 41}

useSearch Hook with Debounce

typescript
1import { useState, useCallback, useRef } from 'react'; 2import { debounce } from 'lodash'; 3 4export function useSearch() { 5 const [results, setResults] = useState<(Movie | TVShow)[]>([]); 6 const [loading, setLoading] = useState(false); 7 const [error, setError] = useState<Error | null>(null); 8 9 const searchRef = useRef( 10 debounce(async (query: string) => { 11 if (!query.trim()) { 12 setResults([]); 13 return; 14 } 15 16 try { 17 setLoading(true); 18 const response = await tmdbClient.get('/search/multi', { 19 params: { query }, 20 }); 21 setResults(response.data.results.filter( 22 (item: any) => item.media_type === 'movie' || item.media_type === 'tv' 23 )); 24 } catch (err) { 25 setError(err as Error); 26 } finally { 27 setLoading(false); 28 } 29 }, 300) 30 ); 31 32 const search = useCallback((query: string) => { 33 searchRef.current(query); 34 }, []); 35 36 return { results, loading, error, search }; 37}

Rate Limiting

Current Limits:

  • 50 requests per second
  • 20 simultaneous connections per IP

Optimization Strategies:

  1. Use append_to_response - Combine requests (free, no rate limit impact)
  2. Implement caching - Cache responses with TTL
  3. Debounce searches - Wait 300ms after user stops typing
  4. Batch requests - Group API calls with small delays

Common Pitfalls & Solutions

PitfallSolution
API key in client-side codeUse backend proxy in production
Slow image loadingOnly use official sizes (w342, w500, w780)
Missing images crash appAlways check for null: poster_path && getPosterUrl(poster_path)
Wrong video displayedFilter: videos.filter(v => v.type === 'Trailer' && v.official)
Rate limit errorsImplement exponential backoff, use append_to_response
State update on unmounted componentUse cleanup flag in useEffect
Search fires too oftenDebounce search input (300-500ms)
Can't get all TV episodesUse append_to_response=season/1,season/2,... (max 20)

Error Codes

CodeMeaningAction
7Invalid API keyCheck for typos, verify key in settings
10Suspended API keyContact TMDB support
34Resource not foundMay be temporary - retry once
429Rate limit exceededImplement backoff, reduce request rate

Video URL Construction

typescript
1function getVideoUrl(video: Video): string { 2 if (video.site === 'YouTube') { 3 return `https://www.youtube.com/watch?v=${video.key}`; 4 } 5 if (video.site === 'Vimeo') { 6 return `https://vimeo.com/${video.key}`; 7 } 8 return ''; 9} 10 11// Get official trailer 12function getOfficialTrailer(videos: Video[]): Video | undefined { 13 return videos.find(v => v.type === 'Trailer' && v.official) 14 || videos.find(v => v.type === 'Trailer') 15 || videos[0]; 16}

Resources

Related Skills

Looking for an alternative to tmdb-integration or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

widget-generator is an open-source AI agent skill for creating widget plugins that are injected into prompt feeds on prompts.chat. It supports two rendering modes: standard prompt widgets using default PromptCard styling and custom render widgets built as full React components.

149.6k
0
Design

chat-sdk

Logo of lobehub
lobehub

chat-sdk is a unified TypeScript SDK for building chat bots across multiple platforms, providing a single interface for deploying bot logic.

73.0k
0
Communication

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication