notes-mcp-server-l16
by devkievskiy
README.md
# Lesson 16 — Notes MCP Server
A Model Context Protocol (MCP) server that gives Claude a persistent personal
notebook. Notes are stored on disk as JSON, so they survive restarts and are
shared across every tool and resource — no stubbed responses.
- **Stack:** Python 3.10+ · official `mcp` SDK (FastMCP) · **stdio** transport
- **Theme:** Notes (recommended option)
## Tools
| Tool | Arguments | Required? | What it does |
|---|---|---|---|
| `add_note` | `text: str`, `tags: list[str]` | `text` **required**, `tags` *optional* | Create a note (optionally tagged) |
| `search_notes` | `query: str` | **required** | Case-insensitive full-text search over text + tags |
| `list_notes` | `tag: str` | *optional* | List all notes, or only those with a given tag |
| `delete_note` | `note_id: int` | **required** | Delete a note by id |
(Satisfies the rubric: ≥2 tools, one with a required-only arg, one with an optional arg.)
## Resources
| Resource URI | What it returns |
|---|---|
| `notes://all` | All notes as a JSON array |
| `notes://stats` | Computed stats: total count, tag frequencies, most-recent note |
| `note://{note_id}` | A single note by id (templated resource) |
## Storage
Notes live in a JSON file, default `~/.notes_mcp/notes.json`. Override with the
`NOTES_DB_PATH` environment variable (set in the Claude Desktop config below).
## Setup
### 1. Install the dependency
```bash
# from this folder, using the course venv (or any Python 3.10+ env)
pip install "mcp[cli]"
```
### 2. (Optional) try it locally with the MCP Inspector
```bash
mcp dev server.py
```
This opens a local web inspector where you can call the tools and read the
resources without Claude Desktop — handy for verifying everything works.
### 3. Connect to Claude Desktop
1. Install Claude Desktop from https://claude.ai/download
2. Open its config file (Claude Desktop → Settings → Developer → Edit Config, or
directly at `~/Library/Application Support/Claude/claude_desktop_config.json`
on macOS).
3. Merge in the contents of [`claude_desktop_config.json`](./claude_desktop_config.json).
Adjust the three absolute paths to match your machine:
- `command` → your Python interpreter (the one where `mcp` is installed)
- `args[0]` → the absolute path to `server.py`
- `env.NOTES_DB_PATH` → where you want the notes file
4. **Fully quit and reopen Claude Desktop.** The `notes` server should appear
under the tools (🔌 / hammer icon) in the chat input.
## Example dialogs
> **1 — Add notes (required + optional args)**
> 👤 Add a note "Buy oat milk and coffee beans" tagged shopping and groceries.
> 🤖 *(calls `add_note(text="Buy oat milk and coffee beans", tags=["shopping","groceries"])`)*
> Saved note #1. Tags: shopping, groceries.
> 👤 Also note "Read the MCP spec" — no tags.
> 🤖 *(calls `add_note(text="Read the MCP spec")`)* Saved note #2.
> **2 — Search & filter**
> 👤 Which of my notes mention coffee?
> 🤖 *(calls `search_notes(query="coffee")`)*
> 1 match for 'coffee': #1 Buy oat milk and coffee beans [tags: shopping, groceries]
> 👤 Show me everything tagged shopping.
> 🤖 *(calls `list_notes(tag="shopping")`)* … lists note #1.
> **3 — Resource + cleanup**
> 👤 Give me a summary of my notebook.
> 🤖 *(reads the `notes://stats` resource)* You have 2 notes; tags: shopping (1),
> groceries (1); most recent is "Read the MCP spec".
> 👤 Delete the shopping note.
> 🤖 *(calls `delete_note(note_id=1)`)* Deleted note #1.
(See `examples/` for real screenshots of these in Claude Desktop.)
## Known limitations
- **Single-user, local only.** One JSON file, no auth, no multi-user support.
Concurrent writes from multiple server instances could race (last-write-wins);
fine for a single Claude Desktop client.
- **No full-text index.** `search_notes` is a linear substring scan — perfectly
fast for hundreds/thousands of notes, not meant for millions.
- **No edit/update tool.** You can add, search, list, and delete; editing means
delete + re-add. (Easy to extend.)
- **Plain substring search**, not semantic — "groceries" won't match "food"
unless that word is present.
- **stdio transport only.** Designed to be launched by Claude Desktop; not
exposed as a network service.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessUnresponsive