← MCP Servers
Claude Code MCP server Free

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

A Python MCP server that lets Claude list and search a folder of Markdown notes — about 40 lines.

WHEN TO USE IT

When you want Claude Code to reach something on your machine it cannot see by default, and Python is your language.

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 mcp; the [cli] extra adds the inspector for testing a server before any client sees it.

pip install "mcp[cli]"
# or: uv add "mcp[cli]"
server.py

MCPServer from mcp.server — FastMCP from mcp.server.fastmcp is the older name most tutorials still use. Type hints become the input schema; the docstring is what Claude reads to decide when to call the tool.

import os
from pathlib import Path

from mcp.server import MCPServer

NOTES = Path(os.environ.get("NOTES_DIR", "~/notes")).expanduser()

mcp = MCPServer("notes")


@mcp.tool()
def list_notes() -> list[str]:
    """List every Markdown note, as paths relative to the notes folder."""
    return sorted(str(p.relative_to(NOTES)) for p in NOTES.rglob("*.md"))


@mcp.tool()
def search_notes(query: str, limit: int = 10) -> list[str]:
    """Find notes containing the query (case-insensitive).

    Returns matching lines as "file:line: text".
    """
    hits = []
    needle = query.lower()
    for path in sorted(NOTES.rglob("*.md")):
        lines = path.read_text(encoding="utf-8", errors="ignore").splitlines()
        for number, line in enumerate(lines, start=1):
            if needle in line.lower():
                hits.append(f"{path.relative_to(NOTES)}:{number}: {line.strip()}")
                if len(hits) >= limit:
                    return hits
    return hits


if __name__ == "__main__":
    mcp.run(transport="stdio")
Add it to Claude Code

Options go BEFORE the server name, then --, then the command that starts the server. Use an absolute path: Claude Code may start it from another folder.

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

# check it is connected
claude mcp list

# then ask:  search my notes for "quarterly review"

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