🐇 Rabbithole ← All lessons Work with us →
Build Your First MCP Day 5 of 30 · ~15 min
Rabbithole · Learn · Day 5 of 30

Build Your First MCP

You learned what an MCP is in Lesson 1 — now build your own, and connect any AI to your real data and tools.

The mental model from Lesson 1 — you're about to build the middle box
Any AI agent
Claude, ChatGPT, Cursor, your own bot…
speaks
MCP
Your MCP Server
a set of tools you wrote, served over HTTP
search_inventory()read_pricelist()get_hours()
reads
Your data
one JSON file you own & edit
1

Write one tool

What's happening: A "tool" is just a normal function with a name, a one-line description, and a list of inputs. The description is the important part — it's how the AI figures out when to call your tool. This is the "self-describing" idea from Lesson 1: you don't write rules telling the AI what to do; you describe each tool well and the AI discovers the rest.

Here's a real read-only tool from the kit — it answers "do you have X, and how many?" by reading one JSON file. It returns plain data; it never writes or sends anything.

// search_inventory — find products by name, SKU, or category.
// The AI reads this description to decide when to call it.
export async function searchInventory({ query = "", inStockOnly = false }) {
  const data = await loadData();        // your shop.json
  let results = data.inventory;
  if (query) results = results.filter(i =>
    (i.name + i.sku + i.category).toLowerCase().includes(query.toLowerCase()));
  if (inStockOnly) results = results.filter(i => i.in_stock > 0);
  return { count: results.length, items: results };  // just reads
}

Two more ship with the kit — read_pricelist and get_hours — written the same way. Three tools, one data file. That's a complete MCP server.

2

Call your tool — and watch the request/response shape

What's happening: Before any AI is involved, you can run the server's dry-run — it calls each tool directly and shows you exactly what goes in and what comes back. Try it below. This panel is live. It runs the same logic the real kit runs, in your browser, against the kit's sample shop — Maple Street Hardware. It is pure read-only JavaScript: it sends nothing, calls no server, charges nothing.

read-only
Nothing is sent — it just reads the sample file.
3

Run the server, then point Claude at it

What's happening: The dry-run proves your tools work. Now you start the real server and let Claude decide when to call them. Claude asks the server "what tools do you have?", reads your descriptions, and fires the right one when a question calls for it — that's the whole MCP loop, running on your machine.

With the kit downloaded:

# 1. set up (writes .env — Claude key is optional)
npm install
npm run setup

# 2. prove it works with NO key and NO network beyond localhost
npm run dryrun

# 3. let Claude drive the tools
npm start                # server on http://127.0.0.1:8765/mcp — leave running
npm run agent -- "Do you sell painter's tape, and is it in stock?"
Where things run: the server listens on 127.0.0.1 only — your data never leaves your computer. The agent demo is the one piece that talks to the internet, and only to send your question and the tool results to Claude so it can phrase an answer. The dry-run talks to nothing but localhost.

Prefer the Claude desktop app over the CLI? Run npm start and add the server at http://127.0.0.1:8765/mcp (Streamable HTTP) as a connector — Claude lists the same three tools and calls them in chat.

Model note: the agent defaults to claude-opus-4-8 (smartest). Set ANTHROPIC_MODEL=claude-haiku-4-5 in .env for a cheaper, faster swap on high-volume questions.

That's a real MCP — and you now understand this better than most devs.

You wrote a tool, ran a real server, saw the request/response shape, and watched an AI fire it against your data. The kit is genuinely yours: free, MIT-licensed, no neutered features. Take it apart.

Get the free first-mcp-kit on GitHub →
4

Make it about your business

What's happening: The tools read from one file, so pointing them at your real business means swapping that file — no code changes. Same three tools, now answering about your shop, your prices, your hours.
  1. Copy data/shop.sample.json to data/my-shop.json.
  2. Replace its contents with your hours, inventory, and prices (same shape).
  3. Run npm run setup again and give it the new path (or set DATA_FILE in .env).
  4. Run npm run dryrun — same tools, now answering about your business.

The file lives on your machine and is yours to own and edit. The kit never invents data it can't read from that file.

5

The safety chapter — read-only first, write tools behind a gate

What's happening: Everything you built is read-only — the worst a read-only tool can do is read a stale price. The moment a tool can change something — place an order, send an email, book a slot — the rules change. The kit shows you the safe pattern, but ships it disabled so there's no foot-gun.
The confirm-before-send rule: a write tool drafts the action and returns it for review — it never performs the action itself. A human approves the plan through a separate, deliberate step that lives outside the AI's reach. So draft_order returns "here's the order I'd place: 3× PVC pipe, $14.37 — approve?" and stops. Nothing is charged until a person clicks approve in your own app.

Before you wire any AI into real tools, run the 5 questions from Lesson 1's safety panel against every tool:

  1. What can it touch? Scope each tool to one narrow action.
  2. Can it spend money? If yes — it drafts only; a human approves.
  3. Can it be undone? Prefer reversible actions; log everything.
  4. Who sees the result? Show the plan before it happens, not after.
  5. What if it's wrong? A draft that's wrong costs nothing. Ship drafts.

The kit's src/server.js carries a commented "ADDING A WRITE TOOL SAFELY" section. You copy it in deliberately, when you understand it — it is not enabled by default.

Going from this toy MCP to a production one is the gap we close.

Making it secure, audited, and wired to your real systems — your inventory, your CRM, your bookings, behind auth and rate limits, with write tools properly gated and logged across your whole stack — is real work. That's our day job.

See what Rabbithole builds →

New here? Start with Lesson 1 — What is an MCP? · or browse all lessons.