How I take notes with Claude, MCP and SilverBullet

I wanted one place for my notes that I own, that is always on, and that I can write to from anywhere. My phone while walking, a browser on my desktop, or a chat with Claude. This is how I got there. It runs self-hosted on my Pi.

Where I started

I tried Obsidian. The paid version allowed sync on multiple devices. I wanted to self-host and didn’t want to pay, so I tried Syncthing, but it’s fimsy on the iphone. I tried a number of self hosted solutions like Blinko and Nextcloud, but they seemed like an overkill.

For a while my notes lived in Notion. I had older notes from Obsidian as plain markdown files, and I imported them into a Notion database so everything would be in one place, with Claude connected through Notion's MCP connector.

It did not work out, for three reasons:

My original markdown files were still sitting in my old Obsidian folder, so I went back to them. Plain files I own, on hardware I own, with Claude connected through my own MCP server instead of someone else's platform.

The idea

My notes are plain markdown files in a folder (a Zettelkasten folder with around 800 notes). The folder lives on the Raspberry Pi in my house, and everything else is just a different door into the same folder:

SilverBulletA web editor, so any desktop browser can edit the notes folder without installing anything
A notes MCP serverLets Claude (claude.ai and the mobile app) search, read and write the notes folder

There is no database and no proprietary format. If every service below disappeared, I would still have a folder of markdown files.

flowchart LR
  Phone["Claude on phone"] --> CF["Cloudflare Tunnel"]
  Web["claude.ai"] --> CF
  CF --> MCP["notes-mcp (Docker)"]
  Browser["Desktop browser (home network)"] --> SB["SilverBullet (Docker)"]
  Sync["Syncthing (laptop sync)"] --> V
  MCP --> V[("Notes folder on the Pi")]
  SB --> V

Part 1: the MCP server

MCP (Model Context Protocol) is a standard way to give an AI assistant tools. Claude supports remote MCP servers as "custom connectors", so if you can host a small server, Claude can use it from the web and from the phone.

I wrote a small Python server using the MCP SDK and run it in Docker on the Pi. You can find it here: karanmhatre1/notes-mcp on GitHub has the code and a getting started guide. It mounts the notes folder read-write and exposes a handful of tools:

search_notes(query, limit)Full-text search over titles and contents. Every word must match; title matches rank first.
read_note(title)Returns the full markdown of a note.
list_notes(limit, order, contains)Lists notes by most recently modified or by title, optionally filtered.
backlinks(title)Lists every note that links to [[title]].
create_note(title, content, tags)Creates a new note in the notes folder. Fails if the title already exists. Optional tags go into YAML frontmatter.
append_to_note(title, content)Adds text to the end of an existing note. The safest way to add to something.
edit_note(title, old_text, new_text, replace_all)Exact-text replacement. old_text must match exactly once unless replace_all is set.
rewrite_note(title, content, keep_frontmatter)Replaces a note's whole body, keeping its frontmatter. The previous version is saved to .trash/versions/.
rename_note(title, new_title)Renames a note and updates [[wikilinks]] to it everywhere.
trash_note(title)Moves a note to .trash/. Nothing is ever permanently deleted.
refresh_mocs(title, dry_run)Regenerates auto-generated link lists inside notes.

The trash choice matters. I am giving an AI write access to my notes, so the worst thing it can do should be recoverable.

Getting it onto the internet safely

Claude's servers need to reach the MCP server, but I do not open any ports on my router. The server is exposed through the same Cloudflare Tunnel that serves my websites, on its own hostname.

Auth

A public endpoint that can write to my notes needs real authentication. The server implements single-owner OAuth with dynamic client registration, which is what Claude's connector flow expects. When I add the connector, Claude opens a login page on my server and I enter a passphrase. Only a scrypt hash of the passphrase is stored, login attempts are rate limited, and tokens are stored hashed. Rotating the passphrase is a new hash in the .env file and a container restart.

What it feels like

From my phone I can say "add this to my note about the Berlin trip", "what did I write about Immich backups?" or "turn this voice rambling into a note and link it to the right topics". Claude searches first, appends to an existing note when one fits, and creates a new one only when it does not. Capturing a thought takes a few seconds, wherever I am.

Part 2: SilverBullet

The MCP server covers capture from my phone, but for long writing I want a real editor on a big screen. SilverBullet is a self-hosted, browser-based markdown editor that works directly on a folder of files, which is exactly what my notes folder is.

It runs as a Docker container on the Pi. Two details I like:

Because SilverBullet edits the same files as the MCP server, a change made in any of the two shows up in the others.

What is next

Why bother

Because the notes are mine. The AI is a convenient interface to them, not their owner. A few things follow from that: