blog.pierrehenry.be

How to Build an MCP Server and Boost Data Without the Hassle

HTC icon in 3D. My 3D work may be seen in the section titled “3D Render.” How to Build an MCP Server and Boost Data Without the Hassle - Photo by Rubaitul Azad on Unsplash

Alright, today I want to walk you through the basics of setting up an MCP server architecture. This is something I’ve been tinkering with, and honestly, it’s way simpler than you might think. I’ll show you my setup, some practical code, and a few tips I picked up along the way. If you’re curious about how MCP servers work, or you want to build your own, you’re in the right place.

What’s an MCP Server Anyway?

Let’s start with the basics. MCP stands for Model Context Protocol. Think of it as a RESTful API, but with a twist: it’s got a very specific set of endpoints and a unique way of returning data. The whole idea is to act as a bridge between an API model and an application—or even between two different applications. Recently, I saw Google Analytics release their own MCP server in Python (it’s open source on GitHub, by the way), which lets LLMs talk directly to Google Analytics. Super cool.

My Minimal MCP Server Setup

I built a tiny MCP server to show you the essentials. Here’s how I structured it:

 1    APP_VERSION=1.0.0
 2    MCP_NAME=MyMCPApp
 3    DESCRIPTION=Minimal MCP server example
 4    TAGS=ai,api,fastify
 5    CONTACT_EMAIL=me@example.com
 6    WEBSITE=https://example.com
 7    BASE_URL=http://localhost
 8    PORT=3000
 9    ```
10
11- **Fastify**: I’m a big fan of Fastify for JavaScript or TypeScript apps. It’s fast, lightweight, and easy to use. Of course, you could use Express or Nest.js if you prefer, but Fastify just feels right for this kind of project.
12
13- **Static Public Folder**: I register `fastify-static` to serve a public folder. This is where I keep the MCP server’s specification file—just a simple JSON that lays out the API’s structure.
14
15- **Entry Point**: My entry point is `server.ts`, but you could call it `index.ts` if you want. The important thing is to set the right entry in your `package.json`:
16
17```json
18    "main": "dist/server.js",
19    "scripts": {
20      "build": "tsc",
21      "start": "node dist/server.js",
22      "dev": "ts-node-dev --respawn server.ts"
23    }
24    ```
25
26- **TypeScript Compilation**: I use `tsc` to compile TypeScript to JavaScript. Nothing fancy here.
27
28## Routing and Context
29
30Here’s where things get interesting. The MCP server has a set of context routes. In Fastify, this is just like setting up any other route, but with a focus on returning specific metadata from the ENV file.
31
32![Next.js server script](https://images.unsplash.com/photo-1643116774075-acc00caa9a7b?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w2NjcyMjF8MHwxfHNlYXJjaHwyfHxNQ1AlMjBzZXJ2ZXIlMjBGYXN0aWZ5JTIwVHlwZVNjcmlwdHxlbnwwfDB8fHwxNzY3MjQ4MzE1fDA&ixlib=rb-4.1.0&q=80&w=1080 "How to Build an MCP Server and Boost Data Without the Hassle")
33*How to Build an MCP Server and Boost Data Without the Hassle - Photo by [James Wiseman](https://unsplash.com/@jameswiseman) on [Unsplash](https://unsplash.com/photos/a-computer-screen-with-a-program-running-on-it-imgCpfIMoRw)*
34
35```typescript
36fastify.get('/.well-known/model-context', async (request, reply) => {
37  return {
38    name: process.env.MCP_NAME,
39    description: process.env.DESCRIPTION,
40    tags: process.env.TAGS.split(','),
41    contact_email: process.env.CONTACT_EMAIL,
42    website: process.env.WEBSITE,
43    version: process.env.APP_VERSION
44  };
45});

Notice how I split the TAGS string into an array using .split(','). If you ever want to turn it back into a string, just use .join(','). Simple and effective.

Versioning and Breaking Changes

I like to version my API endpoints. So, for content, I use /v1/content. If I ever need to make breaking changes, I’ll bump it to /v2/content. This keeps things clean and avoids breaking clients unexpectedly.

The Well-Known Model Context

This is a newer part of the spec, but it’s super useful. Instead of just /context, I use the well-known path: /.well-known/model-context. You can read more about this online, but the gist is that it standardizes where clients can find your API’s metadata.

Serving the Specification

I serve the API spec as a static JSON file from the public folder. This makes it easy for others (or even yourself, six months from now) to see exactly how the API is structured.

Handling Dependencies and Updates

I ran into a version mismatch with Fastify at one point. The fix? Just install the latest versions:

1npm install fastify@latest
2npm install

Always good to keep your dependencies up to date. I also commit my package-lock.json so everyone gets the exact same versions.

Citations and Licensing

I generate a citation file for the GitHub repo using AI. It’s just a simple citation in CSL-JSON format, so people know how to cite your work. For the license, I use Markdown for clarity.

Quick Note on MVP vs MCP

Just to clear up any confusion: MVP is Minimum Viable Product—build something with minimal effort for maximum impact. MCP, on the other hand, is Model Context Protocol (or, as I like to call it, Machine Consumable Protocol). Two very different things!

Example: Splitting Tags

A 3D render of the Mastodon logo How to Build an MCP Server and Boost Data Without the Hassle - Photo by Chethan on Unsplash

Here’s a quick example of how I handle tags in the context route:

1const tags = process.env.TAGS ? process.env.TAGS.split(',') : [];
2// To convert back to a string:
3const tagsString = tags.join(',');

It’s all about keeping things simple and readable.

Wrapping Up

That’s pretty much it for my minimal MCP server. The code is small, the architecture is straightforward, and you can easily adapt it to your own needs. If you want to check out the repo, it’s at github.com/open-data-for-science/mcp-server-api. I’ve added some useful info there to help you build your own MCP server.

If you have questions or suggestions, let me know! I’m always happy to hear feedback and ideas.


Key Takeaways

“Minimum effort for maximum impact—that’s the goal of a good MVP. But with MCP, it’s all about making your API machine-consumable and easy to integrate.”

“If you want to build something useful, start small, keep it clean, and iterate fast.”


Pierre-Henry Soria

GitHub · PierreHenry.Dev · YouTube

<< Previous Post

|

Next Post >>

#Data Processing #Fastify #Mcp Server #Productivity #Server Setup #Tech #Typescript