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.
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.
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]"
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")
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.
https://code.claude.com/docs/en/mcp