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
- a third kind of server went live: the one that keeps the books of my own practice
- so the set is sorted by what a server can do now, rather than by what it knows
- the rule that follows: a public address only for a server that can’t change anything
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
Three Kinds of Server
I run three kinds, and what separates them isn’t what they know. It’s what they can do.
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 keeps the books of a working practice. Picture the client list, the project folder, and the contracts drawer of a small studio. This one doesn’t hand out reference notes; it opens projects, logs hours, and sends contracts out for signature.
The third kind is a platform’s back office: the appointment book, the filing cabinet, and the till behind my education practice, Human. It keeps the records straight and lets the platform run its own day-to-day.
The split that matters runs between the first and the other two. A librarian can’t change anything, so it can live at a public address and nothing much is at stake. The other two hold real records about real people, so neither one gets a public address at all. You reach them from inside my own network or not at all.
That’s the whole rule, and it decides more of this system than any technical choice I made: a server gets a public address only if it can’t change anything. Most of this guide is about the librarians, since they’re the easier place to start.
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 product 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 material only |
| 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 Back-Office Server
This is the second kind, and the newest of the set. It went up in August 2026.
Freelance work has a shape: someone gets in touch, a project opens, the scope gets written down, a contract goes out, and eventually a signature comes back. I was running that across two separate tools and relaying between them by hand. This server puts both behind one door, so the whole sequence can happen in one conversation, from the first client record to the signed contract.
It can change things, and it holds other people’s details: names, email addresses, signed agreements. So it has no public address and never will. It lives on my private network, and the network membership is the lock. There’s no login page to misconfigure, because there’s no door facing the street.
One decision I’d repeat anywhere. The tools that delete things aren’t switched off by a permission check; they aren’t loaded at all unless I deliberately turn them on. A tool that was never handed to Claude can’t be reached by Claude misreading me, which is a stronger promise than one that’s checked at the moment it’s used.
The Platform Server
This is the third kind, and the most 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 as well as 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 | Studio back office | Platform back office | |
|---|---|---|---|
| What it holds | fixed reference (brand, writing rules) | clients, projects, contracts | live business records |
| Can it change things? | no, reads only | yes, that’s the point | yes, it runs the operation |
| Who talks to it | Claude | Claude | the platform’s own apps |
| Where it lives | a small public server | my private network | 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. There’s no login in front of them, on purpose: a login answers the question who’s asking, and on a server that publishes a style guide and can’t be changed, the answer changes nothing.
- The studio back office runs on a third machine and the platform back office on my NAS (a home storage box). Neither has a public address. Both are reachable only from inside my own 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, no app-level auth code and no access policy on the read-only servers
- private servers: reached over a private mesh network; membership is the access boundary
One thing that cost me an afternoon, in case it saves you one. My tunnel was duplicated across two machines so a blip on either one wouldn’t take everything down. Sensible, except that traffic then gets shared between both copies, and each copy has to be able to reach every server on it. The reference servers only listen on the Mac itself, so the second copy couldn’t reach them, and about half the requests failed. Nothing appeared in any log, because those requests never arrived. The servers now sit on their own separate tunnel that runs in one place only.
Data Flow
┌───────────┐ HTTPS ┌──────────────────┐ Docker ┌────────────┐
│ Claude.ai │───────>│ Cloudflare Tunnel │────────>│ MCP Server │
│ or Claude │ MCP │ (edge-local) │ local │ on edge Mac│
│ Code │ calls │ no auth layer │ │ (read-only)│
│ │<───────│ │<────────│ │
└───────────┘ JSON └──────────────────┘ └─────┬──────┘
│ read
┌─────┴──────┐
│/data/*.json│
└─────┬──────┘
│ baked in, or
│ pulled at start
┌─────┴──────┐
│ GitHub │
└────────────┘
- Claude fires an MCP tool call over the web
- Cloudflare passes it down the tunnel 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. Decide what it’s allowed to do, first.
Before the framework, before the data: can this server change anything? If it only reads reference material, it can have a public address and the rest is easy. If it writes anything, or holds details about other people, keep it off the public web entirely. And if it writes files but only ever runs on your own machine, it doesn’t need a web address at all.
Guessing wrong here is the expensive kind of wrong. A server that ships public and later grows a write tool has to move house. Changing a setting won’t save you.
2. 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.
3. 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
4. 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"
}
}
5. 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.
6. 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"]
7. 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
- start from what a server can do, and let that decide where it can be reached from. Sorting mine that way replaced a tidier-looking scheme that had stopped describing what I actually had
- leave dangerous tools unregistered rather than permission-checked. A tool you never handed over can’t be called by mistake
- 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
Get in Touch
I’m Nico Jan, a service and product designer in Vancouver. Every
server described here runs in my own practice, so if you’re
standing something similar up and hit one of the walls above, write to
me at [email protected]. I’d
rather you skip the hours I lost to BaseHTTPMiddleware.
The design work these servers support is at nicojan.com, and I’m on LinkedIn.