What This Guide Does
This guide replaces the painful "download, delete, re-upload" cycle for your living project documents with a system where Claude.ai can both read and write your documents directly.
When you are done:
- Your living documents live on your Azure VM as plain markdown
- Claude.ai searches them with semantic search (understands meaning, not just keywords)
- Claude.ai writes changes back at wrap-up, no downloading, no uploading, no manual merging
- Works from your phone, your laptop, anywhere you use Claude.ai
- Claude Code connects to the same files when you need it
- Total added cost: โฌ0/month
The Problem
Claude.ai Projects let you upload files. Claude can read them. But Claude cannot write back to them. Every session that changes your project status, backlog, or knowledge base ends the same way:
- Claude produces a complete replacement file (often 100K+)
- Claude hits tool limits, drops content, or gets version numbers wrong
- You download the file, delete the old version, upload the new version
- This takes 20+ minutes and breaks constantly
- You cannot do any of this from your phone
The bigger your files get, the worse it gets.
The Solution
Basic Memory is an open-source MCP server that stores your documents as plain markdown, provides semantic search (hybrid keyword + vector), and exposes read AND write tools over HTTPS. Claude.ai connects to it via a custom connector. When you say "wrap up," Claude searches the relevant docs, makes surgical edits, and saves them.
Basic Memory has 2,300+ GitHub stars, is actively maintained, and uses local embeddings (FastEmbed). No API costs and no data leaves your VM.
How It Works
The architecture has three layers:
Your VM
~/brain/docs/ <- Your living markdown files
Basic Memory <- MCP server with semantic search + write tools
cloudflared (tunnel) <- Makes it reachable over HTTPS
Cloudflare (free)
mcp.yourdomain.com <- HTTPS endpoint for the tunnel
Claude.ai (web/mobile)
Custom Connector <- Connects to mcp.yourdomain.com
search_notes <- Semantic search across all docs
read_note <- Read a specific document
write_note <- Create or overwrite a document
edit_note <- Make surgical edits (append, find/replace, replace section)
What Stays Where
Not everything moves. This is a hybrid setup.
Moves to Basic Memory (your living documents)
Any file that changes frequently belongs here. The rule of thumb: if Claude updates it at least once a week, it should be in Basic Memory.
Common examples:
- A status file tracking where you left off and what is next
- A todo list or next-actions scratchpad
- A backlog of work items with checkboxes
- An architecture doc describing your system setup
- A change log for bugs you found and fixed
- A runbook with maintenance procedures
Start with 3-5 files. Add more as your project grows. You can also add a journal folder for session logs.
Stays in Claude.ai Project (stable files)
Any file that rarely changes, like reference documentation, how-to notes, or config templates. These stay as regular Claude.ai project uploads. Claude searches them automatically via its built-in project file search.
TIP: Keep each file focused on one topic. Each MCP tool response is capped at 25,000 tokens. Smaller, purpose-specific files work better than one giant knowledge base file.
What You Need Before Starting
| Requirement | Notes |
|---|---|
| Azure VM (Ubuntu 24.04) | Or any Linux server you can SSH into |
| Python 3.12+ | Needed for Basic Memory |
| Node.js 22+ | If running OpenClaw (not required for Basic Memory alone) |
| Claude Pro, Max, or Team plan | Custom connectors require a paid plan |
| SSH access to your VM | Termius, PuTTY, or VS Code Remote-SSH |
| A domain name | Any registrar, around โฌ10/year |
| Cloudflare account (free) | For the tunnel that connects your VM to the internet |
Cost Summary
| Component | Cost | Notes |
|---|---|---|
| Basic Memory on VM | โฌ0 | Open source, local embeddings |
| Cloudflare Tunnel | โฌ0 | Free tier |
| Domain (if needed) | ~โฌ10/year | One-time if you don't have one |
| Embedding model | โฌ0 | FastEmbed runs locally, no API key |
| Claude.ai Connectors | โฌ0 | Included in all paid plans |
Total added cost: โฌ0/month
Phase 1: Domain and Cloudflare Tunnel
This phase sets up the secure connection between your VM and the internet.
Step 1: Set up Cloudflare DNS
- Register a domain if you don't have one (any registrar works)
- Add the domain to Cloudflare (free plan)
- Point your domain's nameservers to Cloudflare (your registrar has a setting for this)
Step 2: Disable "Block AI Training Bots"
In Cloudflare, go to Security > Bots and disable "Block AI Training Bots."
WARNING: This is critical. Claude.ai connects from Anthropic's servers, not your browser. If Cloudflare blocks AI bots, the connector silently fails with no useful error message.
Step 3: Install cloudflared on the VM
SSH into your VM:
curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared.deb
Step 4: Create a tunnel
cloudflared tunnel login
cloudflared tunnel create mcp-brain
cloudflared tunnel route dns mcp-brain mcp.yourdomain.com
Step 5: Configure the tunnel
Create /etc/cloudflared/config.yml:
tunnel: <your-tunnel-id>
credentials-file: /home/<your-user>/.cloudflared/<your-tunnel-id>.json
ingress:
- hostname: mcp.yourdomain.com
service: http://localhost:8000
- service: http_status:404
Replace <your-tunnel-id> with the ID from Step 4, and <your-user> with your Linux username.
Step 6: Start as a systemd service
sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
Phase 2: Install Basic Memory
Step 1: Install uv (Python package manager)
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrc
uv is a fast Python tool installer. Basic Memory uses it.
Step 2: Install Basic Memory
uv tool install basic-memory
Verify it installed:
basic-memory --version
Step 3: Create the docs folder
mkdir -p ~/brain/docs
Step 4: Add your living documents
Create your markdown files inside ~/brain/docs/. Start simple. For example:
~/brain/docs/
status.md <- Where you left off, next steps
todo.md <- Quick tasks
backlog.md <- Active work items
architecture.md <- How your system is set up
Name the files whatever makes sense for your project. Add more as your needs grow. Each file should cover one topic. You can copy files from your local machine via SFTP, or create them fresh on the VM.
Step 5: Create a Basic Memory project
basic-memory project add brain ~/brain/docs/
This tells Basic Memory to index and watch the ~/brain/docs/ directory.
Step 6: Run initial sync
basic-memory sync
This reads all your markdown files, chunks them by heading, generates vector embeddings locally via FastEmbed, and stores everything in a SQLite database. For about 10 files totaling 200KB, this takes a few seconds.
NOTE: The first run downloads the embedding model (around 90MB). This is a one-time download.
Step 7: Test locally
Start the MCP server:
basic-memory mcp --transport streamable-http --port 8000 --project brain
In another terminal tab, test it:
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","id":1,
"params":{"protocolVersion":"2025-03-26",
"capabilities":{},
"clientInfo":{"name":"test","version":"1.0"}}}'
If you get a JSON response, it works. Press Ctrl+C to stop for now.
Phase 3: Security
Claude.ai's custom connector UI does not support bearer tokens or custom headers. It only offers OAuth client ID/secret in advanced settings. There is no field for Authorization: Bearer. This is a known limitation.
Your security options
Option A: Accept the risk (recommended for now)
Your MCP server serves only your markdown project docs. No secrets, no credentials, no personal data. The URL is not publicly listed. The risk of someone guessing your exact subdomain AND knowing it is an MCP endpoint is very low.
Start here. Add security later when Anthropic adds bearer token support to connectors.
Option B: Allowlist Anthropic's IP ranges
Anthropic publishes the IP ranges their servers use to connect to MCP servers. You can configure Cloudflare or your VM firewall to only accept connections from those IPs. This does not authenticate users but prevents random internet traffic from reaching your server.
Option C: Cloudflare Access
Cloudflare Zero Trust can add authentication in front of your tunnel. However, since Claude.ai connects from Anthropic's servers (not your browser), email-based Cloudflare Access may block Claude. Test before relying on this.
TIP: For Claude Code (covered in Phase 8), bearer tokens DO work. You can secure the HTTP endpoint with a token for Claude Code while leaving it open for Claude.ai through the tunnel.
Phase 4: Run as a Permanent Service
Step 1: Find where Basic Memory installed
which basic-memory
Note the full path. You need it for the service file.
Step 2: Create systemd service
Create the file /etc/systemd/system/brain-mcp.service:
[Unit]
Description=Basic Memory MCP Server
After=network.target
[Service]
Type=simple
User=<your-username>
WorkingDirectory=/home/<your-username>/brain
ExecStart=/home/<your-username>/.local/bin/basic-memory mcp --transport streamable-http --port 8000 --project brain
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Replace <your-username> with your Linux username. Adjust the ExecStart path to match the output of which basic-memory.
NOTE: The --project brain flag tells Basic Memory which project to serve. If you skip it, it defaults to whatever is set in your config, which may not be what you want.
Step 3: Start the service
sudo systemctl daemon-reload
sudo systemctl enable brain-mcp
sudo systemctl start brain-mcp
sudo systemctl status brain-mcp
You should see "active (running)".
Step 4: Auto-reindex on file changes
Basic Memory v0.12.0+ auto-syncs when the MCP process starts. When Claude writes a file via edit_note, the index updates automatically. When you edit a file manually via VS Code, it picks up the change too.
Check your config at ~/.basic-memory/config.json:
{
"sync_changes": true,
"update_permalinks_on_move": true
}
Step 5: Test from outside
From your Windows or Mac machine:
curl https://mcp.yourdomain.com/mcp
If you get a response, the tunnel + Basic Memory chain works.
Phase 5: Connect Claude.ai
Step 1: Add the connector
- Open claude.ai in your browser
- Click your profile icon (bottom-left), then Settings
- Click Connectors
- Click "Add" next to "Remote MCP Servers"
- Paste your MCP server URL:
https://mcp.yourdomain.com/mcp - Leave advanced settings empty (no OAuth needed for your personal server)
- Click Add
WARNING: If clicking Add crashes the page with "Claude will return soon," this is a known intermittent bug. Wait a few minutes and try again in a new browser tab. If it persists, try a different browser.
NOTE: You can remove a custom connector later via Settings, then Connectors, then the three dots menu, then Remove.
Step 2: Enable in your project
- Open any chat in your Claude project
- Click the "+" button next to the message box
- Select "Connectors"
- Find your MCP connector and enable it
- Set it to "Tools already loaded" (not "Load when needed")
WARNING: "Load when needed" means Claude does not know the tool exists until it decides to look for it. This causes Claude to frequently skip searching your knowledge base. Always use "Tools already loaded" for your brain server.
Step 3: Test reading
Type in the chat:
Use search_notes to find information about my current project status
Claude should call your MCP server and return relevant chunks from your docs.
If Claude says it cannot find the tool or shows "Connected" but no tools appear:
- Disconnect and reconnect the connector in Settings
- Clear browser cache
- Try a different browser
- Check that brain-mcp service is running on the VM
This "tools connected but invisible" issue is a known Claude.ai bug that sometimes resolves by reconnecting.
Step 4: Test writing
Type:
Use write_note to create a test note called "test" with content "Hello from Claude"
Then verify on the VM:
cat ~/brain/docs/test.md
If the file exists with the content, write-back works.
Also test edit_note:
Use edit_note on "test" with operation append and content "This line was appended"
NOTE: Basic Memory uses memory:// permalink format internally. When editing, use the note title or permalink. Test which format works and document it for your project instructions.
Step 5: Test from your phone
Open the Claude app on your phone. Start a chat in your project. Try:
Use search_notes to show me my todo list
If it works from mobile, your setup is complete for all devices.
Phase 6: Update Project Instructions
Remove from project instructions
Delete the old wrap-up protocol that says "produce all updated files in one batch" and "bump the minor version number."
Add to project instructions
Copy something like this into your Claude project's custom instructions:
## Knowledge Base Access
Living documents are served via MCP connector (Basic Memory on the VM).
All other files remain as uploaded project files.
### Session Startup
Before doing anything else, search for your status and todo files to get
current state. Check the backlog if the session involves planned work.
### During Session
When you need project context, use search_notes with relevant keywords.
The search is semantic. For full file contents, use read_note.
### Wrap-Up Protocol
When I say "wrap up", "save", or "end of session":
1. Review what changed this session.
2. For each living document, determine if it needs updating.
3. Use edit_note to update each changed document directly.
- edit_note with operation append for adding new content
- edit_note with operation find_replace for changing specific text
- edit_note with operation replace_section for rewriting a section
4. Do NOT produce files for download. Write changes directly via MCP.
5. End with a handoff summary (2-3 sentences).
List your actual file names in the instructions so Claude knows what to look for. The key idea: Claude writes changes back directly instead of producing download files.
Remove old living docs from Claude project
Delete the versioned copies of your living documents from your Claude project uploads. They now live on the VM only. Keep any stable reference files as regular uploads.
Phase 7: Set Up Git for Version History
Without version suffixes in filenames, you need git to track changes.
cd ~/brain/docs
git init
git add .
git commit -m "Initial: living documents migrated from Claude project"
Optional: auto-commit daily via cron. Add a cron line like this:
30 23 * * * cd /home/<your-username>/brain/docs && git add -A && git commit -m "Auto-save $(date +\%Y-\%m-\%d)" 2>/dev/null || true
Useful git commands:
git log --oneline # See change history
git diff HEAD~1 # See what changed last
git checkout HEAD~1 -- backlog.md # Roll back a file
Phase 8: Connect Claude Code (When Ready)
If you use Claude Code on the VM, it connects via stdio (no tunnel needed, no token cap):
claude mcp add --transport stdio --scope user my-brain basic-memory mcp
Verify:
claude mcp list
WARNING: Claude Code may auto-inject your Claude.ai connectors, creating a duplicate. Check with /mcp after starting. If you see both a local and a remote version of your brain server, the remote one is slower and has the 25K token cap. Disable auto-sync if this happens.
| Use Claude.ai for | Use Claude Code for |
|---|---|
| Planning and strategy | Running scripts on the VM |
| Research and discussions | Debugging and checking logs |
| Wrap-up (writing changes back) | Heavy file editing beyond markdown |
| Reading project context | Security audits, cron management |
| Mobile access | Anything requiring terminal access |
The Daily Workflow
From your laptop or phone
- Open Claude.ai, start a chat in your project
- Claude reads your status and todo files via MCP (knows where you left off)
- You plan, discuss, build. Claude searches Basic Memory when it needs context
- You say "wrap up"
- Claude updates the living docs directly via MCP (edit_note calls)
- Done. Close the tab. 2 minutes instead of 20.
What changed vs before
| Before | After |
|---|---|
| Claude produces full replacement files | Claude makes surgical edits via MCP |
| You download, delete old, upload new | Nothing to download or upload |
| Version numbers in filenames | Git handles history |
| Files get bigger, wrap-up gets worse | File size does not matter (surgical edits) |
| Cannot wrap up from mobile | Works from anywhere |
| 20+ minutes of manual work | 2 minutes, mostly verifying |
Known Limitations
| Constraint | Impact | Mitigation |
|---|---|---|
| 25,000-token MCP response cap | Cannot return a full large file in one call | Keep files focused on one topic, use chunked search |
| Claude.ai does not always auto-invoke MCP tools | Sometimes you need to say "check my knowledge base" | Project instructions + "Tools already loaded" setting |
| No bearer token support in Claude.ai connectors | Cannot add API key auth via Claude.ai | URL obscurity + Cloudflare. Bearer works for Claude Code. |
| Basic Memory is pre-1.0 | Newer than some alternatives | Plain markdown means zero lock-in. Migrate away trivially. |
| Non-markdown files cannot be served via MCP | Word docs, PDFs, and other binary files stay as Claude.ai uploads | Hybrid setup covers both |
| Tools may show "Connected" but be invisible | Known Claude.ai bug, intermittent | Disconnect/reconnect, try different browser |
Troubleshooting
Claude.ai says "Claude was unable to connect"
- Check the service:
sudo systemctl status brain-mcp - Check the tunnel:
sudo systemctl status cloudflared - Check Cloudflare's "Block AI Training Bots" is OFF
- Try the URL in your browser:
https://mcp.yourdomain.com/mcp - Disconnect and reconnect the connector in Claude.ai Settings
Claude does not search the knowledge base automatically
- Verify connector is set to "Tools already loaded"
- Check project instructions include the session startup rule
- Say "search my brain for [topic]" to trigger it explicitly
Write fails or times out
- Check the 25,000-token cap. Use
edit_note(surgical edits) notwrite_note(full replace) for large files - Check systemd logs:
sudo journalctl -u brain-mcp -f - Verify Basic Memory is the latest version:
basic-memory --version
Search returns irrelevant results
- Basic Memory uses hybrid search (semantic + keyword). Try different query terms
- Force re-index:
basic-memory reindex - Check files are valid UTF-8 markdown
Adding connector crashes the Claude.ai page
This is a known intermittent bug. Wait a few minutes and try in a new browser tab. If persistent, try a different browser entirely.
Quick Reference
# Start/check/stop the server
sudo systemctl start brain-mcp
sudo systemctl status brain-mcp
sudo systemctl stop brain-mcp
# View logs
sudo journalctl -u brain-mcp -f
# Force re-index
basic-memory reindex
# Check git history
cd ~/brain/docs && git log --oneline
# Roll back a file
cd ~/brain/docs && git checkout HEAD~1 -- filename.md
# Test MCP server locally
curl -X POST http://localhost:8000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"tools/list","id":2,"params":{}}'
What's Next?
Now that your knowledge base lives on the VM and Claude can read and write it directly, here are some logical next steps:
- How to Set Up OpenClaw on Azure - If you have not set up your VM yet, start here. You need a running Azure VM before you can install Basic Memory.
- Managing Secrets Without Getting Hacked - Your VM now has a Cloudflare tunnel and a public MCP endpoint. Make sure your secrets are stored safely.
- Your First Morning Briefing Agent - Put your Second Brain to work. Build an agent that reads your status and todo files every morning and sends you a summary on Telegram.