imdb-personal-mcp
# IMDb Personal MCP
[](https://github.com/TimurKutsenko/imdb-personal-mcp/actions/workflows/tests.yml)
A small **Python MCP server for your own IMDb account**: search titles, manage ratings, and add or remove titles from your Watchlist.
Works with clients that support local stdio MCP servers. No OpenClaw installation, Node.js runtime, IMDb developer API key, or paid search provider is required.
> **Experimental and unofficial.** This uses IMDb's internal web API, which can change without notice. Browser impersonation does not guarantee access. Use it only with an account you control and respect IMDb's terms and rate limits. Not affiliated with IMDb or Amazon.
## How it works
```text
MCP client → Python → curl_cffi → IMDb
│
session challenge
↓
import IMDb cookies from
your existing local browser
↓
retry HTTP once
```
- All account operations run over HTTP using `curl_cffi` and coherent Chrome-style default headers.
- Brave/Chromium supplies **cookies only**, through its local Chrome DevTools Protocol (CDP) endpoint. The server does not launch a browser, navigate tabs, run page JavaScript, or execute the original operation in a browser.
- A challenge triggers at most one cookie import and one HTTP retry. A persistent challenge is returned as an error, not disguised as success.
- Watchlist writes are verified by reading the list again. Cookie values are not logged or returned by MCP tools.
Copying an expired cookie does **not** renew a session. If IMDb needs to refresh its browser/WAF session, open or reload IMDb in your browser, then import cookies again. Safari does not expose the Chromium CDP interface used here.
## Quick start
### 1. Install
Requires **Python 3.10+** and [uv](https://docs.astral.sh/uv/getting-started/installation/).
```sh
git clone https://github.com/TimurKutsenko/imdb-personal-mcp.git
cd imdb-personal-mcp
uv sync --locked
```
Alternatively, install from a local checkout with `python -m pip install .`. This project is published on GitHub, **not currently on PyPI**.
### 2. Sign in using a local browser
Start a Chromium-based browser with a CDP port bound to loopback, sign in to IMDb manually, and leave the browser running. For example, on Linux:
```sh
brave-browser \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/.local/share/imdb-browser"
```
On macOS:
```sh
open -na "Brave Browser" --args \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-port=9222 \
--user-data-dir="$HOME/Library/Application Support/imdb-browser"
```
These examples create a separate browser profile: **sign in there once**. You may instead use an existing profile already exposing CDP. Adding a flag to an already-running browser does not necessarily enable debugging. Do not expose the CDP port to your network: it grants control over that browser profile.
Import the session:
```sh
uv run imdb-auth --cdp-url http://127.0.0.1:9222
```
The helper requests only IMDb cookies from an existing page target; it does not read the browser's on-disk database. It requires authenticated session cookies, not merely an anonymous IMDb session ID.
### 3. Configure your account and MCP client
Open your IMDb profile. Copy the identifier between `/user/` and the next `/`, such as `ur12345678` or the newer `p.…` form. **Use your own ID**, not the example below.
Add this to your MCP client's configuration, replacing the two example paths and account ID:
```json
{
"mcpServers": {
"imdb-personal": {
"command": "/absolute/path/to/uv",
"args": [
"run", "--locked", "--directory",
"/absolute/path/to/imdb-personal-mcp",
"imdb-personal-mcp"
],
"env": {
"IMDB_USER_ID": "ur12345678"
}
}
}
}
```
Find the executable with `command -v uv` on macOS/Linux or `where uv` on Windows. Restart or reload your MCP client after configuration changes.
Ask your assistant to check `auth_status`, then read `list_my_watchlist`. Title search works without signing in or configuring a profile. List operations require your profile ID; Watchlist writes also need it for verification. An authentication check alone does not prove HTML list access works.
## Tools
| Tool | Purpose |
| --- | --- |
| `search_titles(query, limit=10)` | Find exact IMDb title IDs; no login required |
| `auth_status()` | Check the saved session with a live account request |
| `get_my_rating(title_id)` | Read your rating for a title |
| `list_my_ratings(max_pages=10)` | Read your ratings from live account data |
| `set_my_rating(title_id, rating)` | Set a rating from 1 to 10 and verify it |
| `delete_my_rating(title_id)` | Delete a rating; call `get_my_rating` to verify |
| `list_my_watchlist(max_pages=10)` | Read your current Watchlist |
| `add_to_watchlist(title_id)` | Add a title and verify membership |
| `remove_from_watchlist(title_id)` | Remove a title and verify absence |
Writes change the real account. Ask your assistant to resolve the exact title first and confirm that a change is intended. Large lists are limited by `max_pages`; reaching the limit is reported rather than silently returning an incomplete list.
## Configuration
| Variable | Default / meaning |
| --- | --- |
| `IMDB_USER_ID` | No default; your profile identifier |
| `IMDB_RATINGS_URL` | Optional explicit `https://www.imdb.com/…` ratings URL |
| `IMDB_WATCHLIST_URL` | Optional explicit `https://www.imdb.com/…` Watchlist URL |
| `IMDB_DATA_DIR` | OS-specific user data directory, outside the repository |
| `IMDB_COOKIE_FILE` | `cookie.txt` in that data directory |
| `IMDB_CDP_URL` | Saved endpoint, otherwise `http://127.0.0.1:9222`; empty disables automatic import |
| `IMDB_IMPERSONATE` | `chrome150` |
| `IMDB_USER_AGENT` | Unset: use headers matching the impersonation profile; override only for diagnosis |
| `IMDB_TIMEOUT_SECONDS` | `30`, per HTTP attempt |
Typical state paths are `~/Library/Application Support/imdb-personal-mcp` on macOS and `~/.local/share/imdb-personal-mcp` on Linux. Windows uses the per-user application data directory supplied by `platformdirs`. Cookies are written atomically with private file permissions on POSIX. Protect the containing directory with your user account's access controls on Windows.
Use the same `IMDB_DATA_DIR` / `IMDB_COOKIE_FILE` in both `imdb-auth` and the MCP client when overriding defaults. `.env` files are not loaded automatically. No account ID or cookies ship with the package.
## Troubleshooting
- **`CONFIG_REQUIRED`**: configure your own profile ID or explicit list URL. Nothing defaults to the author's account.
- **`AUTH_REQUIRED`**: sign in to IMDb in the selected browser and rerun `imdb-auth`.
- **Cookie import unavailable**: check that the browser is running, CDP is on the chosen loopback port, and IMDb is signed in. The server never switches to another browser automatically.
- **`ANTI_BOT` after import**: update the IMDb session in the browser, then import again. The same expired WAF token cannot be refreshed simply by copying it.
- **`RATE_LIMITED`**: stop and retry later. Do not increase concurrency or retry in a tight loop.
- **`BAD_RESPONSE` / page data missing**: IMDb may have changed its HTML or GraphQL schema. Share a sanitized description in an issue, not raw authenticated responses or HAR files.
- **`PAGE_LIMIT`**: increase `max_pages` for a larger list; the server will not claim a truncated list is complete.
- **A write timed out or verification failed**: read the current account state before retrying. A failed response does not necessarily mean no change occurred.
## Development and contributions
```sh
uv sync --locked
uv run pytest -q
uv run ruff check .
uv build
```
Tests use synthetic cookies and mocked HTTP/CDP responses: they do not sign in, contact IMDb, or change a real account. CI tests supported Python versions on Linux and a macOS runner, and builds the distributable package. Windows is not currently covered by CI.
Contributions are welcome: see [CONTRIBUTING.md](CONTRIBUTING.md). Useful areas include schema resilience, pagination, clearer recovery diagnostics, and cross-platform testing. For private vulnerability reports, see [SECURITY.md](SECURITY.md).
## Acknowledgements
Built on [curl_cffi](https://github.com/lexiforest/curl_cffi), the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), [websockets](https://github.com/python-websockets/websockets), and [platformdirs](https://github.com/tox-dev/platformdirs).
Existing IMDb community projects helped identify web-protocol conventions: [Letterboxd-to-IMDb](https://github.com/TobiasPankner/Letterboxd-to-IMDb), [kinopoisk-to-imdb](https://github.com/demrom/kinopoisk-to-imdb), and [MovieRatingSync](https://github.com/Smokelweiss/MovieRatingSync). This repository contains the Python implementation, not copies of their distributions.
## License
[MIT](LICENSE).
TDQS
Scored across 9 tools
Each tool targets a distinct resource-action pair: search for discovery, ratings (get/list/set/delete), watchlist (list/add/remove), and authentication status. There is no overlap in purpose, and singular vs. plural rating operations are clearly differentiated.
Tool names follow a consistent snake_case verb_noun pattern (search_titles, set_my_rating, remove_from_watchlist). Prepositional forms for add/remove are stylistically consistent with the rest, and the verb clearly indicates the operation.
Nine tools is well-scoped for a personal IMDb account manager: search, rating CRUD, watchlist CRUD (minus update), and auth status. Each tool serves a necessary function without redundancy or bloat.
The domain of personal IMDb management is fully covered: ratings have get/list/set/delete, watchlist has list/add/remove, and search enables finding titles. There are no dead ends or missing operations for core workflows.