This document captures my learnings from building a Model Context Protocol (MCP) server from scratch using Anthropic’s Claude Code over a weekend. The project included about 20 files, mostly Python, and approximately 2k lines of code. These are just my observations and experiences that might be useful to others trying similar projects.
Time. I built the project in two sessions. The first one lasted about two hours, which produced the bulk of the project. That includes the time for me to write the initial documentation and context for Claude Code (more on this below). The second session was about an hour, and it was mostly testing and polishing.
Cost. Claude Code consumes tokens for each interaction. Anthropic says that “The average cost is $6 per developer per day, with daily costs remaining below $12 for 90% of users.” My costs were, however, a little bit higher over the two days I used to build this project ($17.22). Perhaps because it was a greenfield project, it required a larger amount of code upfront.
There are many articles providing best practices when using coding agents like Claude Code, which I recommend reading. The following points especially resonated with me while building this project:
Do your homework before producing any code. LLMs work best when they have the right context, not too much, but not too little. Work on your README.md
file first and make sure it explains the purpose of the project, focusing on what is in scope. Use the /init
command to create the CLAUDE.md
file, and review it once it’s created. Keep updating it to drive the behavior of Claude Code (its “memory”). I didn’t use it this time, but I hear good results from creating a SPEC.md
and/or a TODO.md
file as well.
Build the skeleton before jumping into the implementation. Once you have the basic docs in place, create the skeleton of the app. This also includes setting the style for the project by creating an initial implementation. For example, I created the maps_geocode
tool first. The initial implementation that Claude Code brought in put everything in one file. Before I created any other tools, I extracted constants, utils, model files, and created tests. That way, when I added additional features later, it understood how they should be structured, and the resulting code was much easier to understand.
The interface is more powerful than it seems. Claude Code is essentially a terminal application and that will give you the impression of having a limited interface compared to modern IDEs. However, it comes with powerful features that make your life easier (and were not obvious to me at first). For example, if you paste a URL in the prompt, it will download its content and use it for context, which is great for posting API documentation. If you want to focus your changes on a specific file, you can use file autocomplete (tab tab
) to provide its path inside the prompt.
Use Claude Code to brainstorm before implementing changes. You will be tempted to generate code with every instruction, but remember, this is a conversation and you have a thinking model available under the hood. Before jumping to an implementation, provide the model with the context it needs. For example, in addition to the files mentioned earlier, some projects are starting to provide LLM-friendly links. Use them (example). You can also ask the model explicitly to think and give you options before building anything. I found this particularly helpful to avoid over-architecting the project.
Be precise in your instructions. Once you have everything in place, you should not tell the model to “Build a MCP server using Python.” Who knows what comes out of it. For Claude Code to be effective, you need to know what you’re doing. Instead, you will say something like “Now we are gonna build the maps_geocode
tool in this file: xxx. For that, we will be using the Search Box API with docs on this URL: xxx. The tool will take A, B, and C as parameters, and it will return A, B, and C as fields. Don’t write the tests yet, we’ll do that later.”
Build tests, but separately. You can and should use Claude Code to build tests as you go, but I find it more effective if you do that on a separate pass before/after the initial implementation is ready. Writing a class and its tests, executing them, and addressing any resulting issues can confuse the model.
Ask Claude Code to run tests after every change. You could run the project manually and paste any error messages back in the prompt, and that works, but I find that a last resort. I found it more effective to use Claude to build the tests for you and to run them after every change to confirm the changes are correct. If it doesn’t do it the first time, ask it to do it, and it will learn to do it subsequently. It often happens that it hallucinates on a method that doesn’t exist, and running the test will trigger the model to correct itself. You will want to include the right commands to test the project inside the CLAUDE.md
file.
Do not auto accept all changes. After you’ve been watching the magic go for a while, you will be tempted to auto-accept all commands and code changes, and that is a mistake. On one hand, you want to make sure that you keep understanding everything that is being added to the project. On the other hand, at some point, things will go wrong. It will get stuck, it will enter a non-ending loop, it will refactor and over-architect what it shouldn’t, it will rm -rf /
. For that reason, keep reviewing every step manually.
Commit your changes frequently. Start over frequently. Once you’ve made some progress and you are happy with the changes, commit your changes. Claude is great at creating a meaningful commit message, and you can also instruct it to highlight what you think is more important about the change. This can also be a good moment to restart Claude Code and start over with a fresh context, especially if you are going to switch gears to an unrelated task.
MCP. Claude Code itself supports MCP, and you can add MCP servers to augment its functionality. Ironicallly, I didn’t use MCP servers to develop this project, although it would have been helpful to have a tool that could bring in technical documentation as needed, instead of having to manually find API docs and paste URLs into the prompt. Claude Code itself can also act as an MCP server for other applications!
As they say, what we’re seeing today is the worst these coding agents will ever be. If Claude Code is already this useful in its current form, imagine what our development experience will be like in just a year or two. I’m equally excited and mind-blown about where this is all headed.
→ Comments? You can find me on Bluesky