omdb-mcp
# omdb-mcp
An [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) server for the [OMDb API](https://www.omdbapi.com/) — search movies, series, and episodes from any MCP-compatible client.
Built with [FastMCP](https://github.com/jlowin/fastmcp). Supports both **STDIO** and **Streamable HTTP** transports, with optional bearer-token auth for HTTP mode.
## Features
- Five tools: `search_movies`, `get_by_title`, `get_by_imdb_id`, `get_episode`, `get_season`
- Dual transport: STDIO (for MetaMCP / Claude Desktop / Hermes) and Streamable HTTP (for standalone agents)
- Optional bearer-token authentication for HTTP mode
- Configuration via `.env` or environment variables
- Minimal dependencies: `fastmcp`, `httpx`, `python-dotenv`
## Install
```bash
# Recommended: run directly with uvx (no install needed)
uvx omdb-mcp
# Or install into your environment
pip install omdb-mcp
```
Get a free OMDb API key at <https://www.omdbapi.com/apikey.aspx> (1,000 requests/day on the free tier).
## Configuration
All settings come from environment variables (a `.env` file in the working directory is auto-loaded).
| Variable | Default | Description |
| ---------------------- | ----------------------------- | ---------------------------------------------------------- |
| `OMDB_API_KEY` | _(required)_ | Your OMDb API key |
| `OMDB_MCP_TRANSPORT` | `stdio` | `stdio` or `http` |
| `OMDB_MCP_HOST` | `127.0.0.1` | HTTP bind address (`0.0.0.0` for LAN/Docker) |
| `OMDB_MCP_PORT` | `8087` | HTTP port |
| `OMDB_MCP_PATH` | `/mcp` | HTTP mount path |
| `OMDB_MCP_AUTH_TOKEN` | _(unset)_ | If set, HTTP clients must send `Authorization: Bearer ...` |
| `OMDB_MCP_LOG_LEVEL` | `INFO` | `DEBUG`, `INFO`, `WARNING`, `ERROR` |
| `OMDB_REQUEST_TIMEOUT` | `10` | OMDb HTTP timeout (seconds) |
| `OMDB_BASE_URL` | `https://www.omdbapi.com/` | Override only if proxying/mirroring OMDb |
See `.env.example` for a copy-paste template.
## Running
### STDIO mode (for MCP clients that spawn the process)
```bash
omdb-mcp
# or with uv:
uvx omdb-mcp
```
### Streamable HTTP mode (for standalone, long-lived service)
```bash
omdb-mcp-http
# or override port/host:
omdb-mcp-http --port 8087 --host 0.0.0.0
```
CLI flags `--transport`, `--host`, `--port`, `--path` override env vars.
## Client setup
### MetaMCP
**Option A — STDIO (simplest, no service to manage):**
- **Type:** STDIO
- **Command:** `uvx`
- **Args:** `omdb-mcp`
- **Env:** `OMDB_API_KEY=your_key_here`
**Option B — Streamable HTTP (standalone service):**
Run the server on the host:
```bash
OMDB_API_KEY=your_key OMDB_MCP_AUTH_TOKEN=mysecret omdb-mcp-http
```
In MetaMCP:
- **Type:** Streamable HTTP
- **URL:** `http://host.docker.internal:8087/mcp`
- **Header:** `Authorization: Bearer mysecret` (if `OMDB_MCP_AUTH_TOKEN` is set)
### Claude Desktop
Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
```json
{
"mcpServers": {
"omdb": {
"command": "uvx",
"args": ["omdb-mcp"],
"env": {
"OMDB_API_KEY": "your_key_here"
}
}
}
}
```
### Cursor / Windsurf / Cline
Same JSON shape, different config path. Cursor reads `~/.cursor/mcp.json`:
```json
{
"mcpServers": {
"omdb": {
"command": "uvx",
"args": ["omdb-mcp"],
"env": { "OMDB_API_KEY": "your_key_here" }
}
}
}
```
### Generic Streamable HTTP client
```json
{
"mcpServers": {
"omdb": {
"url": "http://127.0.0.1:8087/mcp",
"headers": {
"Authorization": "Bearer your_token_here"
}
}
}
}
```
## Tools
| Tool | OMDb param(s) | Description |
| ---------------- | ------------------------------------ | -------------------------------------------- |
| `search_movies` | `s`, `y`, `type`, `page` | Free-text search (paginated, 10 per page) |
| `get_by_title` | `t`, `y`, `type`, `plot` | Lookup by exact title |
| `get_by_imdb_id` | `i`, `plot` | Lookup by IMDb ID (`tt...`) |
| `get_episode` | `i`/`t`, `Season`, `Episode`, `plot` | Single TV episode |
| `get_season` | `i`/`t`, `Season` | All episodes in a season |
## Running as a service (HTTP mode)
### macOS — launchd
Create `~/Library/LaunchAgents/com.dworf.omdb-mcp.plist`:
```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key><string>com.dworf.omdb-mcp</string>
<key>ProgramArguments</key>
<array>
<string>/Users/YOU/.local/bin/uvx</string>
<string>omdb-mcp-http</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>OMDB_API_KEY</key><string>your_key_here</string>
<key>OMDB_MCP_AUTH_TOKEN</key><string>your_token_here</string>
<key>OMDB_MCP_HOST</key><string>127.0.0.1</string>
<key>OMDB_MCP_PORT</key><string>8087</string>
</dict>
<key>RunAtLoad</key><true/>
<key>KeepAlive</key><true/>
<key>StandardOutPath</key><string>/tmp/omdb-mcp.log</string>
<key>StandardErrorPath</key><string>/tmp/omdb-mcp.err</string>
</dict>
</plist>
```
Load it:
```bash
launchctl load ~/Library/LaunchAgents/com.dworf.omdb-mcp.plist
# stop / unload:
launchctl unload ~/Library/LaunchAgents/com.dworf.omdb-mcp.plist
```
### Linux — systemd
Create `~/.config/systemd/user/omdb-mcp.service`:
```ini
[Unit]
Description=OMDb MCP server (Streamable HTTP)
After=network.target
[Service]
ExecStart=%h/.local/bin/uvx omdb-mcp-http
Environment=OMDB_API_KEY=your_key_here
Environment=OMDB_MCP_AUTH_TOKEN=your_token_here
Environment=OMDB_MCP_HOST=127.0.0.1
Environment=OMDB_MCP_PORT=8087
Restart=on-failure
RestartSec=5
[Install]
WantedBy=default.target
```
```bash
systemctl --user daemon-reload
systemctl --user enable --now omdb-mcp
systemctl --user status omdb-mcp
journalctl --user -u omdb-mcp -f
```
### Docker
```dockerfile
FROM python:3.12-slim
RUN pip install --no-cache-dir omdb-mcp
EXPOSE 8087
ENV OMDB_MCP_HOST=0.0.0.0 OMDB_MCP_PORT=8087
CMD ["omdb-mcp-http"]
```
```bash
docker build -t omdb-mcp .
docker run -d --name omdb-mcp -p 8087:8087 \
-e OMDB_API_KEY=your_key \
-e OMDB_MCP_AUTH_TOKEN=your_token \
--restart unless-stopped omdb-mcp
```
## Development
```bash
git clone https://github.com/Dworf/omdb-mcp
cd omdb-mcp
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest
```
## Security note
If you bind to `0.0.0.0` without setting `OMDB_MCP_AUTH_TOKEN`, anyone on the network can use your OMDb API key. The server logs a warning at startup in that case — **set a token** in any non-localhost deployment.
## Changelog
### v0.1.0 — 2026-05-14
- Initial release.
- Five tools: `search_movies`, `get_by_title`, `get_by_imdb_id`, `get_episode`, `get_season`.
- Dual transport: STDIO (default) and Streamable HTTP.
- Optional bearer-token auth for HTTP mode.
- `.env` loading via `python-dotenv`.
- 20 unit tests; smoke-tested against the live OMDb API.
## Acknowledgements
- [OMDb API](https://www.omdbapi.com/) — Brian Fritz's free movie/series database. If you use this MCP server in production, please consider [donating to OMDb](https://www.omdbapi.com/) or upgrading to a Patreon-tier key.
- [FastMCP](https://github.com/jlowin/fastmcp) — the Python MCP framework this server is built on.
- [Model Context Protocol](https://modelcontextprotocol.io/) — the open protocol that makes this possible.
## License
MIT
TDQS
Scored across 5 tools
Each tool targets a distinct operation: lookup by IMDb ID, by title, episode details, season listing, and free-text search. There is no overlap in functionality, and the descriptions clearly differentiate the use cases.
Most tools follow a 'get_X' pattern, but 'search_movies' uses 'search' instead of 'get', and 'get_by_imdb_id' and 'get_by_title' use 'get_by' rather than 'get'. This minor inconsistency does not hinder readability.
With 5 tools, the server covers the core OMDb operations—title lookup, ID lookup, season and episode retrieval, and text search—without unnecessary bloat. The count is well-scoped for a movie database API.
The tool surface covers the primary OMDb functionality (search, details by ID/title, season/episode). Missing are explicit tools for ratings or poster retrieval, but these are likely included in the results of existing tools, so gaps are minor.