I have been reading many articles and watching many videos on the Model Context Protocol (MCP), the latest hot thing in AI.
Some people love it, thinking it’s the perfect thing we need to make AI more useful by creating a standardized bridge between AI and our tools and data.
Some hate it, arguing that it is overcomplicating things when OpenAPI is sufficient to get AI to figure out how to use APIs to do things and get data.
Some are skeptical, believing that while it might sound good technically, businesses won’t adopt it.
Honestly, I still don’t know what to think about it. Like Richard Feynman said, “What I cannot create I do not understand.” And Alfred Intelligence is all about building things to learn about them.
So…
I built an MCP server!
It’s nothing crazy. My little MCP server can get tasks from my Todoist account. In other words, when I connect my MCP server to Claude for Desktop, Claude can get tasks from my Todoist account and know what they are while I chat with it.
For example, I can ask Claude for my P1 tasks for today:
If I add more MCP tools, I could maybe even get Claude to complete the tasks for me! But for now, this newsletter is written by yours truly. :)
Building my Todoist MCP server
It was fairly easy to create this MCP server by following the official MCP guide.
todoist.py
, the only file I added code to, has only 38 lines of code. To be fair, I created only a get_tasks
tool for this practice. If I were to add more tools or want more complicated tools, the file might get much longer.
Trying my Todoist MCP server with Claude for Desktop
To use my MCP server with Claude for Desktop, I had to list my Todoist MCP server in claude_desktop_config.json
. This is so that Claude knows it has this new capability and will use it when required.
{
"mcpServers": {
"todoist": {
# I had to use the full path here, or it wouldn't work
"command": "/Users/alfredlua/.local/bin/uv",
"args": [
"--directory",
"/Users/alfredlua/Documents/Alfred/Projects/mcp-server-test/todoist",
"run",
"todoist.py"
]
}
}
}
Once that was done and I restarted Claude for Desktop, Claude for Desktop then has the get_tasks
tool that I created.
When Claude wants to use the tool or any tools from MCP servers, it will always first ask for permission.
Then, it will use my get_tasks
tool to get the specified set of tasks (i.e. those due today) from my Todoist account.
Claude does a few things behind the scenes to make the workflow feel seamless:
Detect when the LLM is calling for a tool
Get the tool name (
get_task
) and arguments({‘filters’: ‘today’})
from the tool callExecute the function with the arguments
Append the tool call and the tool result to the message history
Get the LLM to generate another response, incorporating the tool result
What do I think of MCP?
I can only comment from this short experience of building a super simple MCP server, so please take it with a pinch of salt.
[Developer experience] While many people have complained about how complicated building an MCP server is, it was rather easy to build my Todoist MCP server (which, again, is really simple). But if I just wanted to give an LLM the get_tasks
tool, I could have just passed the Python function to it, which is even simpler. Perhaps MCP is more suitable for more complex use cases?
response = client.responses.create(
model="gpt-4o",
input=[{"role": "user", "content": "What are my tasks today?"}],
tools=tools # the `get_tasks` function can be passed here
)
[User experience] The caveat to my criticism above, though, is that I can use an AI API and pass it the tools I want. Most people can’t and won’t do that. Apps like Claude for Desktop make it possible for people to use various tools easily, even though some setup is still required.
[Developer experience] So, if I simply want others to use the tools I built, building them in MCP servers allows people to actually use them because they can’t use my Python functions in Claude or OpenAI. But if I want people to use an AI app with my tools, then I probably won’t build them in MCP servers but directly in my app.
[User experience] For now, we have to use MCP tools via desktop apps “because servers are locally run, MCP currently only supports desktop hosts. Remote hosts are in active development.” Essentially, when Claude wants to use a tool, it runs the server locally using the information in claude_desktop_config.json.
I think MCP tools will be much more useful and accessible when I can use them via my browser and also use remote servers, ideally by the respective official organizations (and not rely on running scripts on my computer). In other words, I shouldn’t need to configure anything in Claude or OpenAI. The MCP stuff should be behind the scenes, just like how I can use image generation or web research tools in OpenAI without setting them up.
[User experience] Consequently, I’m not sure I’d use MCP servers created by unofficial organizations or developers. For example, I can trust Stripe’s MCP servers since it already has access to all my data and information but I would have to scrutinize an unofficial Stripe MCP server before using it with any credentials. I guess this is similar to using official APIs instead of unofficial ones.
To be frank, I’m still not sure what to think of MCP in general but I’d follow it closely.
What are your thoughts on MCP?
Jargon explained
Auto-load .env: I didn’t realize that VS Code and most IDEs would automatically load my env file. Foolishly, I removed all
load_dotenv()
from my scripts, thinking that I didn’t need it. While the scripts could run in my IDE, they couldn’t in the regular Terminal, which doesn’t automatically load environment variables.
Multiprocessing vs subprocessing vs threading: I’ll admit I don’t fully understand them yet because I have not used them myself. But I’m sharing my notes and ChatGPT conversation here for future-me.
Threading: Takes turns running multiple tasks (not in parallel) in the same process, best for I/O-bound operations.
Multiprocessing: Runs tasks in parallel by using multiple CPU cores, ideal for CPU-bound work.
Subprocessing: Executes external programs or shell commands from within Python.
Interesting links
Malicious MCP server: An MCP tool can pretend to be doing what it is supposed to do, such as fetching data for you, while secretly accessing your sensitive information. (Though, if you are already running the MCP server locally, it can do whatever it wants on your computer without having to pretend it is working for you.)
Model Context Protocol (MCP), clearly explained (why it matters): Ras Mic gave a great explanation of MCP. I think the key benefit, as he said, will be when companies offer their official MCP servers for us to use.
The yaml document from hell: I only started working with YAML files this year, and they seem pretty handy. But it was only because I was using them for really simple use cases. Because of this article, we have switched to using TOML files.