Introduction#
After the trip to Engestofte, the next class was a short workshop on MCP. The Model Context Protocol is a standard way to connect tools and data to an AI assistant. An MCP server offers a set of tools, and a client like Claude Code, Codex or Mistral Vibe connects to it and shows the tools to the model. The model reads each tool’s name, description and input, and decides by itself when to call one.
The task for the blog was a short reflection on how MCP can be used in our project or in another AI application. Since this is the last post in the series, it is also where I give my verdict on the providers, which the first post set up.
A Small Server#
My server follows the course’s tutorial. It is a Java project built with Maven and the official MCP Java SDK, and it uses the STDIO transport. With STDIO, the client starts the server as a local process and talks to it over standard input and output, so there is no network and no port to open.
The tool I use here is add_numbers, which takes two integers and returns their sum. The tutorial also has a second tool that returns the current time. The Maven shade plugin packs everything into one jar that runs with java -jar. It is simple on purpose, so the parts of MCP are easy to see.
The tutorial connects the server to Claude and Codex. I wanted it in Vibe.
One Line or a Config File#
In Claude Code, adding the server is one line:
claude mcp add demo-server -- java -jar /path/to/mcp-demo-1.0-SNAPSHOT.jarEverything after -- is the command Claude runs to start the server. Codex works the same way with codex mcp add.
Vibe’s docs show no command for a local server, so I wrote the entry myself in config.toml, which Vibe looks for first in ./.vibe/config.toml and then in ~/.vibe/config.toml:
[[mcp_servers]]
name = "demo-server"
transport = "stdio"
command = "java"
args = ["-jar", "/path/to/mcp-demo-1.0-SNAPSHOT.jar"]It is only four lines, but I had to find out which fields to use first. The name becomes a prefix on the tool names, and each tool can get its own permission in the same file. Inside Vibe, /mcp shows the servers it has loaded.
To be fair, remote servers can now be added with vibe mcp add, much like in Claude. The trouble is that Mistral’s docs are not always intuitive or up to date with the latest features. The stdio fields are listed in the README on GitHub, and the docs page and the README show two different formats for how an HTTP server is authenticated. The README calls one of them legacy. It also hints that a different client setting can add stdio servers from the shell, without showing how.
The Compromise#
This is the trade I described when I moved to Mistral, on a small scale. With Mistral, I get GDPR compliance and an EU product. In exchange, it is more technical. Installing the CLI and choosing models is left to me, and a local MCP server means a config file instead of a command.
As a developer, I can live with that. It costs me some time, and I know what I am getting for it. For someone less technical, I think this is where they would stop.
MCP in a Project#
Ragnhild could be an MCP server with one tool that takes a question and returns the matching chunks with their citations. Then any assistant could look up what I have written on this site. Ragnhild only stores public content, so there is little risk in that.
The Engestofte system is more interesting. An MCP server could let an assistant look up free dates or where an inquiry stands, so the staff could ask instead of clicking through screens. But the system also holds the couple’s guests and their allergies, and allergies are health data, which GDPR treats as a special category. A tool that exposes them sends that data to whichever provider runs the assistant. For tools like that, I would use an EU provider, keep them read-only and set them to ask for permission before they run.
There is a token side too. The client sends the tool descriptions to the model, so every server you connect adds to every request. I would rather connect two or three tools with clear descriptions than a server that does everything.
After the trip, I would also ask the event manager before building any of it. He worried about losing the personal contact, so it should be his call.
The Verdict#
At the start of the week, a journalist from the school wanted to hear how my partner and I had worked, and to include our product in an article. We answered by email. One of the things we wrote was that we had used three providers on purpose, so we could compare them. This is where we landed:
| Provider | Used by | Where it did best |
|---|---|---|
| Mistral | Both of us | Embeddings, and anything with sensitive data |
| Claude | Both of us | Building, and usually with fewer tokens than Codex |
| Codex | My partner | Frontend design |
Claude built much better than Codex, and the token difference matters to me for the reasons I gave in the first post. Codex still had an edge on frontend design.
Mistral is viable. Ragnhild runs on mistral-embed and Ministral 3B, and for that kind of job Mistral is still the one I would pick. For building software with an agent, it is a compromise.
So my verdict is the right tool for the job, which is a different answer from the one I had when I moved to Mistral over the summer.
Conclusion#
This is the last post in the series. From here, I will pick the provider by what the data is and what the job needs. Sensitive data stays with an EU provider, and I keep an eye on the tokens. That is still the stance from the first post, now with half a semester of practice behind it. For everything else, I will probably have to use Claude as this is, at this moment, the industry standard.
If Vibe one day makes the setup as easy as the others do, I would like to move more of my work back to Mistral. I hope that day comes sooner rather than later.
- Daniel