Skip to content
OwnlyPlans

Plan

Build Your First MCP Server (TypeScript)

Give Claude new tools: a read-only MCP server over your notes folder with list, read and search, tested with the MCP Inspector.

Remix

Use it with Claude or any AI tool. Copy the prompt and paste it in. The link inside gives the AI the whole page as Markdown.

Markdown

Overview

MCP is how you plug your own data and tools into Claude and other AI apps. This plan builds a real, small server from an empty folder: three tools over a folder of Markdown notes, safe by design (read-only, no path escapes), tested in the official Inspector and then connected to Claude Code.

Once you have done it once, the same shape works for anything: your database, an internal API, a CLI you use every day.

Before you start: Node.js 20+, Claude Code (or Claude Desktop) and a folder with a few .md files. About 1 hour.

Build it step by step

Sign in to tick steps off
  1. 1

    Create the project

    Make an empty folder and save CLAUDE.md in it. Then run:

    npm init -y
    npm i @modelcontextprotocol/sdk zod
    npm i -D typescript @types/node

    Create a notes folder next to it with three or four short .md files to test with.

    Prompt
    Read CLAUDE.md. Set up this folder as a TypeScript ES module project: tsconfig.json targeting ES2022 with module and moduleResolution set to Node16, outDir build, rootDir src. Add "type": "module", a "build" script (tsc) and a "bin" entry pointing at build/index.js. Do not write server code yet.

    Done when npm run build runs without errors (on an empty src/index.ts).

    Uses CLAUDE.md MCP TypeScript SDK

  2. 2

    Start a server that does nothing (yet)

    Get the skeleton right first: a server object, a stdio transport, and logging that goes to stderr only. Printing to stdout breaks the protocol, which is the number one beginner bug.

    Prompt
    Using the official TypeScript SDK (check its README for the current API), write src/index.ts that creates an MCP server named "notes" version 0.1.0 and connects it over stdio. Read NOTES_DIR from the environment and exit with a clear message on stderr if it is missing or not a folder. Log "notes server ready" to stderr.

    Done when NOTES_DIR=./notes node build/index.js starts and waits silently, with "notes server ready" on stderr.

    Uses MCP TypeScript SDK

  3. 3

    Add a safe path helper

    Before any tool reads a file, make it impossible to read outside the notes folder. This is the security core of the server, so it gets its own function and its own test.

    Prompt
    Add src/paths.ts with resolveNote(name: string): string. It must resolve the path inside NOTES_DIR (use realpath), only allow .md files, and throw a friendly error for anything outside NOTES_DIR (../, absolute paths, symlinks that point out). Add a tiny test script (node --test) with cases: a valid note, ../secret.md, /etc/passwd, a symlink pointing out.

    Done when All four test cases behave as expected.

  4. 4

    Tool 1 and 2: list_notes and read_note

    Two tools with zod input schemas and short, specific descriptions. The model decides which tool to call by reading those descriptions, so write them like documentation for a colleague.

    Prompt
    Register two tools. list_notes (no input): returns each note file name with its first heading and size in KB. read_note ({ name: string }): returns the full text of one note using resolveNote. Return errors as text content with isError true instead of throwing. Keep each description under 20 words.

    Done when npm run build passes and both tools are registered.

    Uses CLAUDE.md

  5. 5

    Tool 3: search_notes

    Search is what makes the server genuinely useful: the assistant can find the right note without reading all of them.

    Prompt
    Add search_notes ({ query: string, limit?: number default 5, max 20 }). Case-insensitive search over all .md files in NOTES_DIR; return the best matches with file name, line number and a one-line snippet around each hit, ranked by number of hits. Cap total output at about 4,000 characters and say when results were cut.

    Done when Searching a word you know is in two notes returns both with line numbers.

  6. 6

    Test by hand in the MCP Inspector

    The Inspector lets you call your tools yourself before any AI touches them. Run:

    npx @modelcontextprotocol/inspector node build/index.js

    Set NOTES_DIR in its environment panel, connect, open Tools and try each one, including bad input.

    Prompt
    I am testing in the MCP Inspector. Give me a checklist of 8 calls to try (valid and invalid input for each tool, including a path escape attempt) and what the correct response looks like for each.

    Done when Every call on the checklist returns what it should, and the path escape is refused.

    Uses MCP Inspector

  7. 7

    Connect it to Claude Code

    Add the server to Claude Code with an absolute path to the build and your notes folder. Then ask questions about your notes in plain language.

    Prompt
    Give me the exact claude mcp add command for this server (stdio, absolute path to build/index.js, NOTES_DIR set with --env). Then suggest three natural questions I can ask Claude that should make it use each tool.

    Done when In Claude Code, /mcp shows notes as connected and a question about your notes triggers search_notes.

    Uses Model Context Protocol docs

  8. 8

    Polish and share

    A good README is what makes other people (and future you) able to use it. Then publish it to GitHub and share the repo here on OwnlyPlans as an MCP server.

    Prompt
    Write README.md: what the server does, the three tools with example inputs, setup for Claude Code and Claude Desktop (claude_desktop_config.json example), the safety rules, and limits. Keep it under 120 lines.

    Done when A friend can set it up from the README alone.

Files and links

What people built

Show yours

Nobody has shared a build yet. Yours could be the first.

Show what you built

Built this plan? Sign in to share your demo video, live app and screenshots.

Your AI tool
Starter prompt

		

Download the plan