A Guide to Nico's MCP Servers
how I give Claude a dependable memory of my brand, my design system, and the platform I run
- the servers moved from my NAS to a small always-on Mac on my desk
- trimmed the live set to three reference servers, and made them read-only on purpose
- added the second kind of server: the live data layer behind my education platform
What Are MCPs?
Model Context Protocol is an open standard from Anthropic. In plain terms: it lets Claude look things up in a place you control, instead of you pasting the same background into every conversation.
- A server holds some knowledge and offers Claude a few tools. A tool is just a labelled request, like “get the brand colours.”
- Claude sees what’s on offer, picks the tool it needs, and gets back a tidy answer.
- Without this, you re-explain your rules every time. With it, Claude fetches only the piece it needs, when it needs it.
Why build my own?
- consistency: the same rules in every conversation, no drift
- one source of truth: change a colour once and it updates everywhere
- less waste: Claude pulls only the slice it needs for the task in front of it
- history: the rules live in version control, so every change is tracked and reversible
Two Kinds of Server
I run two kinds, and they do very different jobs.
The first kind is a reference library. Picture a specialist librarian: Claude asks a question, the librarian hands over exactly the right page, and that’s the whole job. These servers only ever read knowledge out. Mine cover my brand voice, my design system, and the craft of writing well. They never change anything.
The second kind is a platform’s back office. Picture the appointment book, the filing cabinet, and the till of a small business. This server doesn’t hand out reference notes; it runs the operation behind my education practice, Human. It keeps the records straight, and it lets Claude help run the day-to-day directly.
Same idea underneath, a dependable place for Claude to look things up, but two very different jobs. Most of this guide is about the first kind, since it’s the easier place to start. The second kind is a bigger story, and I’ll come to it.
In Practice
Here’s what it looks like when the reference servers are in the room.
Teaching
“Make me a short lesson on narrative structure for Grade 8.”
-
designer-for-human →
get_design_brief: the colours, type, and spacing, so the material looks like the brand - humanizer: keeps the explanations sounding like a person
- then, on my own machine, a small deck tool turns the outline into a ready-to-present slide file, using those same brand rules
Claude hands back a lesson that looks and reads like the brand. The type, colour, and spacing are already in place.
Design
“Draft a proposal email for the website redesign.”
-
writer-for-designer →
get_communication_guide: how to pitch it, matched to whether the client speaks design or not - humanizer: so it reads like I wrote it
Claude writes plain language for a non-designer and precise terms for a design-literate client, from the same underlying rules.
The Reference Servers
Three are live right now. Each owns one domain of knowledge and nothing more. I built them for my day-to-day as a bilingual educator and freelance UI/UX designer.
| Server | What it knows |
|---|---|
| designer-for-human | the Human brand’s visual system: colour, type, spacing, logo use, and what to avoid |
| humanizer | how to make writing sound human instead of machine-made |
| writer-for-designer | how a freelance designer talks to clients: proposals, feedback, the awkward conversations |
What Each Does
-
designer-for-human: hands Claude the
brand’s visual rules, colour, typography, spacing, logo
choices, and a list of design clichés to avoid. Its data and
logo files are baked right into the server, so there’s nothing
to change at runtime; it only reads out. One
get_design_briefcall returns everything needed for a given task. - humanizer: research-based rules for natural writing, plus a checker that flags the giveaways of AI-written text. It works on anything written, an email, a lesson, a paragraph of a case study. (This very page went through it.)
- writer-for-designer: client-communication rules for design work, matched to two kinds of reader, the design-literate and the non-designer. Proposals, feedback, scope changes, and the difficult talks too.
What Else I Built
The set didn’t arrive all at once. Some servers were retired, one stayed on my own machine, and a couple I released to the public. Here’s the honest state of things.
| Server | What it is | Status |
|---|---|---|
| writer-for-human | the Human brand’s bilingual writing voice | retired for now |
| deck + homework builder | turns an outline into a branded slide file | my machine only |
| meta | notes and templates for building these servers | reference, not a server |
| humanizer (public) | an open-source copy of the humanizer, with a browser demo | public release |
| humanize-text-prompt | the humanizer’s rules as a single prompt, for people without a server | public release |
The Platform Server
This is the second kind, and the more ambitious one.
Behind Human, my education practice, one server acts as the whole back office. It keeps the records that matter: who’s enrolled, when sessions happen, what was covered, what’s owed. Unlike the reference librarians, this one changes things. It books a session, records a payment, updates a student’s progress. Claude can help run the practice through it, not just write about it.
A few honest notes:
- It’s built on a proper database rather than simple files, since it’s holding live records that keep changing.
- It carries the “MCP” name out of habit, but under the hood it speaks a plainer web format. The label is looser than the librarians’.
- It isn’t open to the public internet. It sits on my home network, reachable only by the platform’s own apps, and its secrets are encrypted. Student information doesn’t belong on a public doorstep.
| Reference librarian | Platform back office | |
|---|---|---|
| What it holds | fixed reference (brand, writing rules) | live business records |
| Can it change things? | no, reads only | yes, it runs the operation |
| Who talks to it | Claude | the platform’s own apps |
| Where it lives | a small public server | my private network |
Architecture
For the curious. Skip it if the what matters more to you than the how.
Where It Runs
- The three reference servers run on a small, always-on Mac on my desk (I call it edge). Each one is a little Docker container.
- A free Cloudflare Tunnel gives them public web addresses without opening my home network, and Cloudflare’s access layer handles the login check, so the servers need no login code of their own.
- The platform back office runs separately, on my NAS (a home storage box), and stays on the private network.
The stack, for the technical reader:
- reference servers: Python 3.12 + FastMCP, Streamable HTTP, data in plain JSON files
- platform server: a database-backed web service (PostgreSQL)
- containers: Docker throughout
- public edge: Cloudflare Tunnel + Access (no app-level auth code)
Data Flow
┌───────────┐ HTTPS ┌──────────────────┐ Docker ┌────────────┐
│ Claude.ai │───────>│ Cloudflare Tunnel │────────>│ MCP Server │
│ or Claude │ MCP │ + Access (auth) │ local │ on edge Mac│
│ Code │ calls │ │ │ (read-only)│
│ │<───────│ │<────────│ │
└───────────┘ JSON └──────────────────┘ └─────┬──────┘
│ read
┌─────┴──────┐
│/data/*.json│
└─────┬──────┘
│ baked in, or
│ pulled at start
┌─────┴──────┐
│ GitHub │
└────────────┘
- Claude fires an MCP tool call over the web
- Cloudflare checks it’s allowed, then passes it to the edge Mac
- the server reads its JSON data and answers
- no writing back: the data only ever flows out
Keeping Data Fresh
Because the servers are read-only, updating them is simple. I edit the rules in one place, a Git repository, and the server picks up the new version one of two ways: the change is built into a fresh copy of the server, or the server pulls the latest when it restarts. No live editing, and nothing to break.
Why read-only? Earlier versions could write changes back over the web. When I moved everything onto the little Mac and gave the servers public addresses, I decided that a public write door, plus a saved password sitting inside the container, was a risk with almost no upside, since I author the rules in the repository anyway. So I removed every write tool. Less to secure, and less to go wrong.
Build Your Own
You can stand up one of these in an afternoon. Here’s the shape of it. The Download button gives you a longer guide written for Claude: drop it into a Claude project and it’ll walk you through building your own.
Prerequisites
- an always-on machine: a NAS, a spare Mac, a Raspberry Pi, even your laptop if it stays on
- Docker: keeps the setup reproducible
- a tunnel (Cloudflare’s is free) if you want Claude.ai to reach it; skip it if you’ll only use Claude Code on your own network
- version control: somewhere to keep the files, like GitHub
Steps
1. Start with one server.
Pick the single thing you re-explain most, brand rules, writing style, a component library, whichever hurts most to repeat. Build only that. Don’t try for six at once.
2. Pick a framework.
- FastMCP (Python): what I use
-
@modelcontextprotocol/sdk(TypeScript): the official kit, and the natural choice for a tool that runs on your own machine - anything that serves web requests and returns data works
3. Put your knowledge in plain files.
One /data folder, one file per topic. This is your source
of truth.
{
"brand_colours": {
"primary": "#2D5A3D",
"secondary": "#8B6F47"
},
"tone": {
"default": "warm, direct, encouraging",
"formal": "respectful, precise, understated"
}
}
4. Hand back only the slice that’s asked for.
Get this right and the rest barely matters. A tool should return the smallest useful answer, with filters so Claude can ask for just one piece:
@mcp.tool()
async def get_colours(role: str | None = None) -> dict:
"""Get brand colours, optionally filtered by role."""
colours = load_json("colours.json")
if role:
return {k: v for k, v in colours.items()
if v.get("role") == role}
return colours
Keeps things fast, and keeps the token cost low.
5. Put it in a container and start it.
A read-only container is the simplest thing that works: bake the data into the image, publish the port to your machine only, and let the tunnel reach it.
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
COPY data/ ./data/
ENV PYTHONPATH=/app
CMD ["python", "src/server.py"]
6. Connect it to Claude.
- Claude.ai / Desktop: Settings → Connectors → Add custom connector with your server’s address
- Claude Code: add it to your project settings with the streamable HTTP transport
Lessons Learned
Things I figured out the hard way. The last few are for the coders:
- keep each server to one job. A do-everything server is harder to change without breaking something else
- keep your servers read-only unless you truly need writing. A public server that can change its own data is a bigger thing to secure, and most reference knowledge never needs it
- edit your rules in version control, never in the running server: you get history and an undo for free
-
never use
mcp.run(); serve it withuvicorninstead. And skip custom HTTP middleware with FastMCP, it quietly corrupts the connection -
save files as UTF-8
(
ensure_ascii=False) if you use non-English characters, or your accents and Chinese turn into\ugibberish -
name tools distinctly across servers
(
humanizer_get_rulesvsstyle_get_rules) so they don’t collide
Further Reading
- Model Context Protocol spec
- FastMCP docs
- MCP quickstart guide
- Claude Code docs
-
Figma Console MCP: a good ready-made server to try first. It connects Claude to your
Figma files and runs with
npx, so there’s nothing to host. - humanizer: the humanizer server itself, released as open source with a browser demo
- humanize-text-prompt: the humanizer’s rules as a single open-source prompt