Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
jcodesmore avatar

Recommend

  • 1 installs
  • 8 repo stars
  • Updated April 30, 2026
  • jcodesmore/movies-for-ai-agents

Gives personalized movie shortlists by combining a stored taste profile, watch history, and current mood via TMDB and imdbapi.dev MCP tools.

About

Produces a short personalized movie shortlist with per-pick reasoning, pulling taste profile, watch history, and mood signals from TMDB and imdbapi.dev MCP tools. A developer uses it when building an AI movie-recommendation assistant that tracks what the user watched and updates preferences over time.

  • Routes queries by intent: similar-to-seed, rating/thematic, mood, or open-ended tonight pick
  • Auto-captures watch state and updates preferences via active_add/watched_add MCP calls

Recommend by the numbers

  • 1 all-time installs (skills.sh)
  • Ranked #1,982 of 2,719 Automation & Workflows skills by installs in the Skillselion catalog
  • Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jcodesmore/movies-for-ai-agents --skill recommend

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs1
repo stars8
Last updatedApril 30, 2026
Repositoryjcodesmore/movies-for-ai-agents

What it does

Gives personalized movie shortlists by combining a stored taste profile, watch history, and current mood via TMDB and imdbapi.dev MCP tools.

Files

SKILL.mdMarkdownGitHub ↗

recommend

You are giving the user a short, confident, personalized shortlist of movies — with reasoning tied to what you know about them.

Before picks: check active state

Call active_list first. If any entry has ageHours > 24 AND (askedHoursAgo > 24 OR lastAskedAt is null), pick the OLDEST such entry and lead with ONE short prompt — not a wall of questions:

Quick catch-up — you started [Title](https://www.imdb.com/title/{imdbId}/) on {short date}. How'd it go?
- a) Finished, loved it
- b) Finished, it was okay
- c) Finished, didn't love it
- d) Still watching
- e) Dropped it

Route the answer:

  • awatched_add({ movieId, rating: 5 }) + active_remove({ movieId })
  • bwatched_add({ movieId, rating: 3 }) + active_remove({ movieId })
  • cwatched_add({ movieId, rating: 2 }) + active_remove({ movieId })
  • dactive_touch_asked({ movieId }) (no watched entry, prevents re-asking within 24h)
  • eactive_remove({ movieId }) (no watched entry — they didn't really see it)

Only ever ask about ONE active entry per turn — the oldest. Then continue with the new picks below.

Gather context (always)

Call these three MCP tools in parallel before anything else: 1. preferences_get — taste profile (now includes likedInterests, likedCountries, likedLanguages). 2. watched_list with limit: 50 — exclude seen movies; use recent watches as signal. 3. movies_genres — for name↔id mapping when filtering.

Choose a strategy based on the user's prompt

A. "Something like [seed movie]"

1. movies_search({ query }) → resolve seed to a TMDB ID. Confirm match if ambiguous. 2. movies_recommendations({ movieId }) — TMDB's ML similar-movies. imdbapi.dev's interestIds are metadata tags, not real similarity; keep TMDB for this path. 3. Filter out movies already in watched_list. Filter out dislikedGenres. Pick the top 3–5. 4. For each final pick, call `movies_details({ movieId })` — this hydrates imdbId, IMDb rating, vote count, Metascore, and interest tags in one call. The link and rating fields in the output template depend on this. (TMDB's recommendations endpoint does NOT include imdb_id in list results — movies_details is the only path.) 5. Write a one-sentence "why it fits" per pick, anchored to either the seed or their taste profile.

B. Rating-aware or thematic query ("good sci-fi rated 8+", "heist movies", "Japanese drama")

1. Route to movies_imdb_discover:

  • IMDb threshold → minAggregateRating.
  • Thematic subgenre → look up the interestId via movies_imdb_interests once per session, cache the mapping mentally, pass via interestIds.
  • Director/actor → movies_imdb_find_namenameIds.
  • Language/country → languageCodes / countryCodes.

2. Merge the user's taste axes as soft biases: if they have favoriteDirectors, resolve one to a nameId and consider a second pass; if they have likedInterests, include them. 3. Filter out watched. Pick 3–5 with brief "why it fits" reasoning.

C. Mood / constraint query ("atmospheric thriller under 2 hours", "feel-good comedy", "nothing too heavy")

1. Translate mood → genre filters. Use movies_genres if unsure of IDs. 2. Call movies_discover with:

  • genres from the mood
  • excludeGenres from dislikedGenres
  • minRating: 6.5 and minVotes: 300 by default (quality floor). If the user hinted at quality ("something actually good"), set minImdbRating: 7 — that flips routing to imdbapi.dev automatically.
  • Runtime filters when they mention a time budget
  • sortBy: "popularity.desc" unless they want something obscure

3. Filter out watched. Pick 3–5. 4. For each final pick, call `movies_details({ movieId })` — hydrates imdbId + IMDb rating needed for the output template. Skip this and the format below cannot render correctly. 5. Write brief "why it fits" reasoning per pick.

D. "What should I watch tonight" (no constraint given)

1. Combine signals: mix top 2–3 from movies_trending (week) with 1–2 from movies_discover using likedGenres and favoriteDirectors, and 1 from movies_imdb_discover using likedInterests when present. 2. Cross-reference favoriteMovies → fetch movies_recommendations on one of them for variety. 3. De-duplicate, filter watched, pick 3–5. 4. For each final pick, call `movies_details({ movieId })` — hydrates imdbId, IMDb rating, vote count, Metascore, and interest tags. The picks coming from movies_imdb_discover already have an imdbId, but TMDB-sourced picks do NOT — call movies_details on those before rendering. (Note: movies_imdb_batch_rating only fetches ratings for known imdbIds; it can't backfill imdbIds from TMDB IDs, so it's not the right tool here.)

Present the recommendations

Format each pick as:

**[Title](https://www.imdb.com/title/{imdbId}/)** (Year[, Country]) — IMDb 8.2 — 128 min
[Genre, Genre] · [Heist, Neo-Noir] (if interest tags present)
One-to-two sentence hook from the overview.
→ Why for you: [specific reason anchored to their profile or the current ask]

Output contract (non-negotiable).

  • Title format: **[Title](https://www.imdb.com/title/{imdbId}/)** — bold + IMDb link. The imdbId comes from movies_details({ movieId }), which every strategy above requires per pick. If movies_details returned imdbId: null after that call, fall back to plain bold **Title** with no link.
  • ❌ Never use a TMDB URL (themoviedb.org/movie/..., themoviedb.org/title/...) anywhere in the output. The TMDB ID is internal plumbing — users don't read it. Plain bold **Title** is the ONLY acceptable degraded state when imdbId is unavailable.
  • Rating: IMDb rating only (IMDb 8.2). If movies_details returned no IMDb rating after hydration, fall back to TMDB 7.9. Never dual-list (IMDb X · TMDB Y) unless the user explicitly asks to see both scores.

Close with: "Pick one to start? I'll mark it active so we can check in next time."

Auto-capture: pickup → active

When the user replies with clear intent"I'll watch X tonight", "starting X now", "going with X", "let's do X" — call active_add({ movieId, source: "recommend" }) BEFORE acknowledging. Then confirm in one sentence: "Got it — marked [X](imdb) active. I'll ask how it went next time."

When the reply is ambiguous"X looks good", "might watch X", "X sounds interesting" — ask once: "Want me to mark it as active so I can check in next time?"

Other auto-updates:

  • If they reject all suggestions with a reason ("too slow", "nothing with horror"), immediately call preferences_set to update dislikedGenres or avoidKeywords so future runs improve.
  • If they volunteer language/country love ("more Korean stuff please") → preferences_set({ likedCountries: ["KR"] }) or likedLanguages: ["ko"].
  • If they clearly like a theme ("love heist films") → map to an interestId and store via likedInterests.
  • "Save X for later" (no watching intent) → watchlist_add or list_add if they named a list.

Quality bar

  • Every recommendation must come from TMDB or imdbapi.dev data (never invent titles).
  • Keep the shortlist tight: 3 confident picks beats 10 hedged ones.
  • "Why for you" must be specific to the user, not generic. Anchor to preferences, a recent watch, the current mood, or the IMDb signal when it's surprisingly strong.
  • For fresh query patterns, consult docs/api-reference/imdbapi-dev.md and docs/api-reference/tmdb.md.

Related skills

Automation & Workflowsagentsautomation

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.