zennotes-mcp
# zennotes-mcp
MCP server that connects AI agents to a self-hosted ZenNotes vault. It wraps the
complete HTTP API of the ZenNotes Go server and exposes it as typed MCP tools,
so agents can read, search, create and organize notes directly.
## Features
65 tools covering the whole vault API:
* vault: info, settings, server-side directory browser
* notes: list, read, write, create, rename, move, duplicate, trash, restore,
archive, plus `capture`, `append` and `prepend` helpers
* search: full-text search, search capabilities
* tasks: vault-wide aggregation or per note
* folders: create, rename, delete, duplicate
* assets: list, upload, download, rename, move, duplicate, delete, plus the
deleted-assets trash (list, restore, purge)
* templates and workflows: full CRUD, workflow runs (apply, undo, history)
* comments, Excalidraw drawings, demo tour, session management
## Requirements
* Python 3.10+
* A running ZenNotes server (local `zennotes-server`, Docker image
`adibhanna/zennotes`, or any remote deployment)
## Install
From source:
```bash
pip install -e .
```
Or directly from GitHub:
```bash
pip install git+https://github.com/PacomeKFP/zennotes-mcp.git
```
This provides the `zennotes-mcp` command.
## Configuration
Everything goes through environment variables. Nothing personal is hardcoded.
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `ZENNOTES_URL` | no | `http://127.0.0.1:7878` | Base URL of the ZenNotes server |
| `ZENNOTES_AUTH_TOKEN` | for protected routes | empty | Bearer token of the server |
```bash
cp .env.example .env # then fill in your values
export ZENNOTES_URL="http://127.0.0.1:7878" # or your remote URL
export ZENNOTES_AUTH_TOKEN="your-token-here"
```
Public routes (`health_check`, `get_version`, `get_capabilities`, ...) work
without a token. Everything else returns HTTP 401 until the token is set.
## Run
Stdio mode (for agents):
```bash
zennotes-mcp
```
## Connect an agent
OpenCode v1 (`~/.config/opencode/opencode.jsonc`):
```jsonc
{
"mcp": {
"zennotes": {
"type": "local",
"command": ["zennotes-mcp"],
"environment": {
"ZENNOTES_URL": "http://127.0.0.1:7878",
"ZENNOTES_AUTH_TOKEN": "your-token-here"
},
"enabled": true
}
}
}
```
OpenCode v2 moves the same block under `mcp.servers` (see
`opencode.json.example`). The same stdio command also works in Claude Code,
Claude Desktop and Codex. Restart the agent after editing the config, as MCP
servers connect at startup.
## Examples
Once connected, just ask:
* "with zennotes, list my notes"
* "find my notes about backups and summarize them in a new note"
* "capture this in my quick notes: ..."
## Development
```bash
pip install -e .
python tests/test_smoke.py # public endpoints, no token needed
```
`ZENNOTES_URL` can point at a remote server for the smoke test:
```bash
ZENNOTES_URL="https://my-server.example.com" python tests/test_smoke.py
```
## Security
* The auth token only ever lives in environment variables or your local agent
config. Never commit it: `.env` is git-ignored.
* Prefer read-only prompts for shared agents, and keep `delete`, `empty_trash`
and `session_rotate_token` for supervised use.
## Roadmap
Progressive updates following ZenNotes releases: tags endpoint if re-exposed,
real-time watch events, batch operations.
TDQS
Scored across 65 tools
Most tools map to a clear resource/action pair (list_notes, rename_asset, delete_workflow). A few boundary cases could be confused—create_note, write_note, and capture_note all write note content with subtly different semantics—and browse_directories may be mistaken for list_folders, but descriptions mostly clarify intent.
The dominant verb_noun snake_case pattern is readable and predictable, e.g., list_notes, create_folder, restore_deleted_asset. There are minor exceptions like session_status, vault_info, assets_exists, and demo_generate, but they do not obscure the overall convention.
With 65 tools, this server far exceeds even the 25+ threshold and crosses the 50+ extreme mismatch threshold. No matter how broad ZenNotes is, this many endpoints overwhelms an agent's tool-selection space and context window.
The tool surface covers the full lifecycle for notes, folders, assets, templates, and workflows, including soft-delete/restore and permanent delete paths. Session management, search, tasks, comments, and demo utilities are also present, leaving no major workflow dead ends.