I built a tiny MCP notes server in Python — here's the whole thing, free
Most MCP (Model Context Protocol) examples are either toy "hello world" servers or sprawling frameworks. I wanted the smallest useful thing: a notes server an AI assistant can actually use — create a note, list notes, search notes — backed by a plain local JSON file. No database, no cloud, no account. It's open source (MIT) and free: Code: https://github.com/bradraylucas-eng/mcp-notes-server…
I created a simple MCP notes server using Python for an AI assistant. This server allows the user to create notes, list notes, and search notes, all backed by a local JSON file. It is open-source (MIT licensed) and available for free at https://github.com/bradraylucas-eng/mcp-notes-server.
The server provides three tools: create_note(title, body, tags) to add a note, list_notes(limit) to list the notes in descending order of their creation time, and search_notes(query) to perform a case-insensitive substring search over the title, body, and tags of the notes. The notes are stored in a local file named notes.json, with atomic saves that prevent data corruption in case of a crash during the write operation.
During the development of this server, I encountered two issues that are relevant to anyone deploying an MCP server. First, when creating notes with same-second timestamps, sorting by timestamp alone results in an unstable order. To avoid this, a monotonically increasing insertion index should be kept, and the notes should be sorted by (created_at, index) instead.
Second, it is crucial to pin the SDK major version when using MCP. Using mcp =1.6.0 will resolve to the 2.x SDK, which introduces breaking changes at import time for 1.x-style code. My requirements file now specifies mcp =1.6.0, 2 to ensure compatibility.
To test the server end-to-end, I used the real SDK via stdio, which successfully created, listed, searched, and retrieved notes. However, there is a gotcha when packaging the server as an .mcpb bundle. Anthropic's mcpb pack tooling and some registries require the inputSchema objects on each tool in the manifest, while Anthropic's packer rejects that key. I maintained two separate bundles—one Anthropic-packed and one hand-packed for Smithery—to avoid compatibility issues with the target registry's manifest rules.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.