← MCP Servers
Claude Code MCP server Free

Notes Server in TypeScript Free Claude Code MCP server, copy & paste

The same notes server in TypeScript with the official SDK, zod schemas and the stdio transport.

WHEN TO USE IT

When your team works in Node, or you want to publish the server to npm so others can run it with npx.

Lives in Registered with `claude mcp add`, or shared with the team in .mcp.json at the project root.
Checked

Formats change. If a field stops working, check it against Anthropic's documentation.

Read it before you install it. A MCP server runs with your user account's permissions, on its own, every time it is triggered. That is what makes it useful, and why a stranger's should never be installed unread — this one included.

Install

The package is @modelcontextprotocol/server. The older @modelcontextprotocol/sdk is the v1 line, and these imports will not resolve against it.

mkdir notes-mcp && cd notes-mcp
npm init -y && npm pkg set type=module
npm install @modelcontextprotocol/server zod
server.mjs

registerTool takes a name, a description with a zod inputSchema, and the handler. Log with console.error — console.log writes to stdout and breaks the protocol.

import { readdir, readFile } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";
import { McpServer } from "@modelcontextprotocol/server";
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
import { z } from "zod";

const NOTES = process.env.NOTES_DIR ?? join(homedir(), "notes");

async function markdownFiles() {
  const entries = await readdir(NOTES, { recursive: true });
  return entries.filter((name) => name.endsWith(".md")).sort();
}

const server = new McpServer({ name: "notes", version: "1.0.0" });

server.registerTool(
  "search_notes",
  {
    description: "Find notes containing the query (case-insensitive). Returns file:line: text.",
    inputSchema: z.object({
      query: z.string().describe("Text to look for"),
      limit: z.number().int().positive().default(10),
    }),
  },
  async ({ query, limit }) => {
    const hits = [];
    for (const file of await markdownFiles()) {
      const lines = (await readFile(join(NOTES, file), "utf8")).split("\n");
      lines.forEach((line, i) => {
        if (hits.length < limit && line.toLowerCase().includes(query.toLowerCase())) {
          hits.push(`${file}:${i + 1}: ${line.trim()}`);
        }
      });
    }
    return { content: [{ type: "text", text: hits.join("\n") || "No matches." }] };
  },
);

await server.connect(new StdioServerTransport());
console.error("notes MCP server running on stdio");
Add it to Claude Code

Same shape as any stdio server: name, --, then the command.

claude mcp add --transport stdio --env NOTES_DIR=$HOME/notes notes \
  -- node /absolute/path/to/notes-mcp/server.mjs

claude mcp list

MORE MCP SERVERS

The authority

Anthropic's documentation for MCP Servers

This template is a starting point. Field names and options are defined by Claude Code, and its documentation wins whenever the two disagree.

Read the docs ↗

https://code.claude.com/docs/en/mcp

New drops, every week

Free tools & Claude templates, landing regularly.

We keep shipping new free tools, code recipes and Claude Code templates. Follow @freeyantra on Instagram or join the newsletter so you never miss one.

Follow @freeyantra

or get them by email

Double opt-in. Unsubscribe any time. Privacy