Create a Local IMDb MCP Server in Python
I was looking for examples on creating an MCP (Model Context Protocol) server in Python and took me awhile cobbling together a few different sources and actually getting it to work. Plus too much useful content hides behind Medium paywalls, how is this still a thing? So, I figured I’d write it all up and let Cunningham’s Law help me where I get it wrong.
An MCP server is a way to connect an LLM to your own custom functions giving it the ability to interact with external tools or sources.
MyMDb
My example MCP server is using the IMDb dataset and connecting it to an LLM. This allows you to ask questions like “compare the directors Christopher Nolan vs. David Fincher”
Repo: https://github.com/mkaz/mymdb
Setup
Tools: You need Python, Install uv
for Python environment and dependency management and just
as a task runner; both optional but helpful. With Homebrew: brew install just uv
Database: Use the fetch.sh
script in the data directory to download all the data from IMDb and then run import.py
to create a the local sqlite database. Just a heads up, the download is about 1.1gb and db is around 2.6gb.
Lastly you’ll want to install the mcphost tool that coordinates running the MCP and LLM. You can download from their releases page or if you already have go
installed and its binary path, use: go install github.com/mark3labs/mcphost@latest
Code
An MCP tool is relatively straight-forward, it is just a function that you apply the @mcp.tool()
decorator from the FastMCP library.
The mymdb code creates 6 tools which you can see from the mcp_config.json
file
{
"mcpServers": {
"imdb": {
"type": "local",
"command": ["./.venv/bin/python3", "mcp_server.py"],
"args": [],
"cwd": ".",
"env": {},
"allowedTools": [
"execute_sql_query",
"top_rated_movies",
"get_movie_details",
"search_movies",
"query_movies_by_actor",
"query_movies_by_director"
]
}
}
}
Looking at one of the tools query_movies_by_director
the function starts like the following, I’m going to truncate it because it is mostly basic SQL code. One of the most important parts it the docstring, the LLMs will use this description of the function and arguments to help it understand when and how to use it.
@mcp.tool()
def query_movies_by_director(
director_name: str,
order_by: str = "rating_desc",
limit: int = 20
) -> str:
"""Find movies directed by a specific director, optionally ordered by rating
Args:
director_name: Name of the director to search for
order_by: How to order the results (rating_desc, rating_asc, year_desc, year_asc, title_asc)
limit: Maximum number of results to return
"""
conn = get_db_connection()
try:
query = f"""
SELECT DISTINCT tb.primaryTitle, tb.startYear, tr.averageRating, tr.numVotes,
nb.primaryName as director_name
FROM title_basics tb
JOIN title_principals tp ON tb.tconst = tp.tconst
JOIN name_basics nb ON tp.nconst = nb.nconst
LEFT JOIN title_ratings tr ON tb.tconst = tr.tconst
WHERE tb.titleType = 'movie'
AND tp.category = 'director'
AND nb.primaryName LIKE ?
...
Look at the mcp_server.py
file in the repo and see how each of the tools are defined.
Connect Everything
The mcp_config.json
script is the carpet that really ties it all together. It specifies what tools are available and the command to start the server. When you run mcphost
it will automatically run the server, you don’t start it ahead of time.
Lastly, you’ll need an LLM to connect to. You can run them locally using Ollama or use the common providers that will require using an API key. For example OpenAI requires the OPENAI_API_KEY enviornment variable set.
I’ve had moderate success using Ollama with qwen3
, be sure the model you use supports tools. The local Ollama models are a bit slower and don’t process things nearly as well. Experiment with differnt ones.
Run using: mcphost -m MODEL --config mcp_config.json
For Ollama, mcphost -m ollama:qwen3 --config mcp_config.json
For OpenAI, mcphost -m openai-gpt4 --config mcp_config.json
Result
Here is the result for my prompt “compare the directors Christopher Nolan vs. David Fincher”
Here are the top 5 rated movies for each director:
Christopher Nolan:
- The Dark Knight (2008) - Rating: 9.0 - Votes: 3,035,784
- Inception (2010) - Rating: 8.8 - Votes: 2,698,024
- Interstellar (2014) - Rating: 8.7 - Votes: 2,362,382
- The Prestige (2006) - Rating: 8.5 - Votes: 1,522,647
- Memento (2000) - Rating: 8.4 - Votes: 1,385,030
David Fincher:
- Fight Club (1999) - Rating: 8.8 - Votes: 2,480,103
- Se7en (1995) - Rating: 8.6 - Votes: 1,922,298
- Gone Girl (2014) - Rating: 8.1 - Votes: 1,126,513
- The Curious Case of Benjamin Button (2008) - Rating: 7.8 - Votes: 724,332
- The Social Network (2010) - Rating: 7.8 - Votes: 793,925
Both directors have a strong filmography with high ratings. Christopher Nolan’s movies have slightly higher ratings and vote counts overall, but both directors have made highly impactful and popular films.
Shameless Plugs
- I query IMDb often for my Reel DMC movie podcast I do with my buddies.
- Check out my new Working with Python book