Docs
MCP

Connect KinElo to MCP

KinElo supports remote MCP over OAuth 2.1 (Authorization Code + PKCE). Add the server to your MCP client, sign in with Apple or Google, and approve access to search, ratings, bookmarks, movie details, recommendations, leaderboards, social data your account can access, and write actions like bookmarking and marking watched.

Quick start

MCP Server URL
https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/mcp
Most clients only need this URL.
  1. Open your MCP-enabled client (ChatGPT Developer Mode, Claude, or another MCP client) and add a new server.
  2. Paste the URL above.
  3. Start the OAuth flow and sign in to KinElo.

UI-capable MCP hosts can now render interactive KinElo widgets for search, ratings, bookmarks, movie details, recommendations, leaderboard, and social tools. Non-UI hosts continue to work with normal JSON tool responses.

For developers

Use these details if your client asks for explicit OAuth endpoints.

Authorization URL
https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/authorize
Token URL
https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/token
Client ID
kinelo-mcp-local
Scopes
kinelo:read kinelo:write

Full configuration

{
  "mcp_server_url": "https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/mcp",
  "authorization_url": "https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/authorize",
  "token_url": "https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/token",
  "client_id": "kinelo-mcp-local",
  "scopes": "kinelo:read kinelo:write"
}

Some MCP clients only ask for the base URL. If so, use https://kinelo-mcp-uddmbd7l7q-uc.a.run.app and let the client read /.well-known/oauth-authorization-server. If your client only supports SSE, use https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/sse.

kinelo:write is required for mutation tools such as add_bookmark and set_watched. Keep kinelo:read if you also want read tools.

Tools

get_bookmarked_movies

Your bookmarked movies with title, release date, bookmark date, and poster metadata.

Arguments
{
  "limit": 200,
  "cursor": "string"
}

All fields are optional. limit max is 500.

Returns
{
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "string",
      "releaseDate": "YYYY-MM-DD",
      "bookmarkedDate": "YYYY-MM-DDTHH:mm:ss.sssZ",
      "posterUrl": "https://image.tmdb.org/...",
      "rank": 1
    }
  ],
  "count": 200,
  "hasMore": true,
  "nextCursor": "string"
}

add_bookmark

Adds a movie to your bookmarks using a movie document id. Idempotent if already bookmarked.

Arguments
{
  "movieId": "movie_doc_id"
}

movieId is required. Use search_movies first if you only have a title. Requires kinelo:write.

Returns
{
  "movieId": "movie_doc_id",
  "title": "string",
  "releaseDate": "YYYY-MM-DD",
  "posterUrl": "https://image.tmdb.org/...",
  "bookmarked": true,
  "created": true,
  "alreadyBookmarked": false,
  "bookmarkedDate": "YYYY-MM-DDTHH:mm:ss.sssZ"
}

set_watched

Marks a movie as watched/seen using a movie document id. Idempotent if already marked watched.

Arguments
{
  "movieId": "movie_doc_id"
}

movieId is required. Use search_movies first if you only have a title. Requires kinelo:write.

Returns
{
  "movieId": "movie_doc_id",
  "title": "string",
  "releaseDate": "YYYY-MM-DD",
  "posterUrl": "https://image.tmdb.org/...",
  "viewed": true,
  "created": true,
  "alreadyViewed": false,
  "seenDate": "YYYY-MM-DDTHH:mm:ss.sssZ"
}

search_movies

Typesense-backed movie search for title queries. Use this first when you need a movieId for details.

Arguments
{
  "query": "parasite",
  "limit": 10
}

query is required. limit is optional and max is 50.

Returns
{
  "query": "parasite",
  "source": "typesense",
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "Parasite",
      "releaseDate": "2019-05-30",
      "posterUrl": "https://image.tmdb.org/...",
      "rank": 1
    }
  ],
  "count": 1,
  "found": 42
}

Pass a returned movieId into get_movie_details for full metadata and personal status.

get_movie_details

Detailed metadata for a single movie, including global ratings and your personal status.

Arguments
{
  "movieId": "movie_doc_id"
}

movieId is required and must match the movie document id.

Returns
{
  "movie": {
    "movieId": "movie_doc_id",
    "tmdbMovieId": 12345,
    "title": "string",
    "releaseDate": "YYYY-MM-DD",
    "overview": "string",
    "posterUrl": "https://image.tmdb.org/...",
    "backdropUrl": "https://image.tmdb.org/...",
    "genreIds": [28, 12],
    "ratingCount": 4800,
    "globalElo": 1820,
    "globalGlicko": 1768,
    "yourElo": 1689,
    "viewed": true,
    "rated": true,
    "bookmarked": false,
    "ratedDate": "YYYY-MM-DDTHH:mm:ss.sssZ",
    "bookmarkedDate": null,
    "seenDate": "YYYY-MM-DDTHH:mm:ss.sssZ"
  }
}

get_rated_movies

Your rated movies with title, release date, rated date, poster URL, and Elo.

Arguments
{
  "limit": 200,
  "cursor": "string",
  "sort": "elo"
}

All fields are optional. sort can be elo (default) or recent for chronological recency. limit max is 500.

Returns
{
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "string",
      "releaseDate": "YYYY-MM-DD",
      "ratedDate": "YYYY-MM-DD",
      "posterUrl": "https://image.tmdb.org/...",
      "userElo": 1234,
      "rank": 1
    }
  ],
  "count": 200,
  "hasMore": true,
  "nextCursor": "string"
}

Personalized recommendations with filtered rank, global rank, and explicit score semantics.

Arguments
{
  "limit": 20
}

limit is optional. Max is 200.

Returns
{
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "string",
      "releaseDate": "YYYY-MM-DD",
      "posterUrl": "https://image.tmdb.org/...",
      "predictedRating": 0.2621,
      "predictedScoreRaw": 0.2621,
      "rank": 1,
      "globalRank": 168,
      "scoreType": "nmf_raw"
    }
  ],
  "count": 20,
  "recommendationType": "collaborative",
  "modelVersion": "model_20260201_020022",
  "rankDefault": "filtered_rank",
  "scoreType": "nmf_raw",
  "scoreCalibrated": false
}

rank is filtered rank after removing already-rated movies; globalRank is the model rank before filtering. predictedRating is a compatibility alias of predictedScoreRaw. For collaborative recommendations, score type is nmf_raw (not calibrated to 1-5).

get_global_leaderboard

Global top movies ranked by Elo or Glicko, with release date and poster metadata.

Arguments
{
  "system": "elo",
  "limit": 100,
  "cursor": "string"
}

system is optional: elo or glicko. Default is elo. limit max is 500. Use cursor from the previous response for pagination.

Returns
{
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "string",
      "releaseDate": "YYYY-MM-DD",
      "posterUrl": "https://image.tmdb.org/...",
      "globalRating": 1750,
      "rank": 1
    }
  ],
  "count": 100,
  "ratingSystem": "elo",
  "hasMore": true,
  "nextCursor": "string"
}

get_followers

Followers list for a handle (or your own account), returning handle, name, and profile image.

Arguments
{
  "handle": "target_handle",
  "limit": 200,
  "cursor": "string"
}

handle is optional and defaults to your account handle. limit max is 500.

Returns
{
  "users": [
    { "handle": "cinefan", "name": "Cine Fan", "avatarUrl": "https://..." }
  ],
  "count": 1,
  "totalCount": 42,
  "hasMore": true,
  "nextCursor": "string",
  "targetHandle": "target_handle"
}

get_following

Following list for a handle (or your own account), returning handle, name, and profile image.

Arguments
{
  "handle": "target_handle",
  "limit": 200,
  "cursor": "string"
}

handle is optional and defaults to your account handle. limit max is 500.

Returns
{
  "users": [
    { "handle": "filmlover", "name": "Film Lover", "avatarUrl": "https://..." }
  ],
  "count": 1,
  "totalCount": 18,
  "hasMore": false,
  "targetHandle": "target_handle"
}

get_users_rated_movies

Rated movies for a specific handle when privacy settings allow access.

Arguments
{
  "handle": "target_handle",
  "limit": 200,
  "cursor": "string",
  "sort": "elo"
}

handle is required. sort can be elo or recent.

Returns
{
  "targetHandle": "target_handle",
  "targetName": "Target Name",
  "movies": [
    {
      "movieId": "movie_doc_id",
      "title": "string",
      "releaseDate": "YYYY-MM-DD",
      "ratedDate": "YYYY-MM-DDTHH:mm:ss.sssZ",
      "posterUrl": "https://image.tmdb.org/...",
      "userElo": 1234,
      "rank": 1
    }
  ],
  "count": 200,
  "hasMore": true,
  "nextCursor": "string"
}

Troubleshooting

  • Redirect URI mismatch: Make sure your MCP client uses the redirect URI it registered. Local clients often use http://127.0.0.1 or http://localhost.
  • Pop-up blocked: Allow pop-ups or try again so the browser can complete sign-in.
  • Scope errors: Ensure the requested scopes include kinelo:read for read tools and kinelo:write for mutation tools.
  • After migration: Existing connections may require a one-time reconnect so the new scope grant is issued.