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
https://kinelo-mcp-uddmbd7l7q-uc.a.run.app/mcp
- Open your MCP-enabled client (ChatGPT Developer Mode, Claude, or another MCP client) and add a new server.
- Paste the URL above.
- 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.
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.
{
"limit": 200,
"cursor": "string"
}
All fields are optional. limit max is 500.
{
"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.
{
"movieId": "movie_doc_id"
}
movieId is required. Use search_movies first if you only have a title. Requires kinelo:write.
{
"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.
{
"movieId": "movie_doc_id"
}
movieId is required. Use search_movies first if you only have a title. Requires kinelo:write.
{
"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.
{
"query": "parasite",
"limit": 10
}
query is required. limit is optional and max is 50.
{
"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.
{
"movieId": "movie_doc_id"
}
movieId is required and must match the movie document id.
{
"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"
}
}
{
"limit": 200,
"cursor": "string",
"sort": "elo"
}
All fields are optional. sort can be elo (default) or recent for chronological recency. limit max is 500.
{
"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"
}
get_recommended_movies
Personalized recommendations with filtered rank, global rank, and explicit score semantics.
{
"limit": 20
}
limit is optional. Max is 200.
{
"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.
{
"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.
{
"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.
{
"handle": "target_handle",
"limit": 200,
"cursor": "string"
}
handle is optional and defaults to your account handle. limit max is 500.
{
"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.
{
"handle": "target_handle",
"limit": 200,
"cursor": "string"
}
handle is optional and defaults to your account handle. limit max is 500.
{
"users": [
{ "handle": "filmlover", "name": "Film Lover", "avatarUrl": "https://..." }
],
"count": 1,
"totalCount": 18,
"hasMore": false,
"targetHandle": "target_handle"
}
{
"handle": "target_handle",
"limit": 200,
"cursor": "string",
"sort": "elo"
}
handle is required. sort can be elo or recent.
{
"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.1orhttp://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:readfor read tools andkinelo:writefor mutation tools. - After migration: Existing connections may require a one-time reconnect so the new scope grant is issued.