trilium-mcp-server
Provides tools for interacting with a Trilium Notes instance through its ETAPI, enabling search, reading, creation, updating, deletion, and organization of notes; management of revisions, branches, attributes, attachments, and calendar notes; and instance administration such as backups and metrics.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
A Model Context Protocol server for Trilium Notes, built on the ETAPI. It lets Claude Code (or any MCP client) search, read, create and organize notes in your Trilium instance.
40 tools covering notes, revisions, branches, attributes, attachments, calendar notes and instance admin
stdio transport, TypeScript, MCP SDK v2
Destructive tools are annotated so your client can prompt before running them
Requirements
Bun 1.x (runs the TypeScript source directly; Node.js 20.3+ also works after
bun run build)A running Trilium Notes server (TriliumNext) with ETAPI enabled
An ETAPI token: in Trilium, open Options -> ETAPI and create one
Related MCP server: Trilium MCP Server
Install
git clone https://github.com/btafoya/triliumnotes-mcp-server.git
cd triliumnotes-mcp-server
bun installUse with Claude Code
Run straight from GitHub with bun (no clone, no build)
The package's bin points at the TypeScript source (src/index.ts, #!/usr/bin/env bun), and bun runs TypeScript natively, so there is nothing to compile:
claude mcp add \
--env TRILIUM_URL=http://localhost:8080 \
--env TRILIUM_ETAPI_TOKEN=<your-token> \
--transport stdio --scope user \
trilium -- bunx github:btafoya/triliumnotes-mcp-serverbun supports github:user/repo specifiers for packages (docs) and bunx runs a package's bin. Requires bun on your PATH.
Or run from a local clone
Add it with the Claude Code CLI (docs):
claude mcp add \
--env TRILIUM_URL=http://localhost:8080 \
--env TRILIUM_ETAPI_TOKEN=<your-token> \
--transport stdio --scope user \
trilium -- bun /absolute/path/to/triliumnotes-mcp-server/src/index.ts--separates Claude's options from the server command; everything after it runs the server.--envis variadic: it keeps consuming arguments until the next option or--. Always put another option (here--transport stdio --scope user) after the last--envand before the server name. Otherwise the CLI reads the name as another env pair and fails withInvalid environment variable format: trilium.Short forms:
-tfor--transport,-sfor--scope,-efor--env. Drop--scope userfor the defaultlocalscope.
Same thing as JSON:
claude mcp add-json --scope user trilium '{"type":"stdio","command":"bun","args":["/absolute/path/to/triliumnotes-mcp-server/src/index.ts"],"env":{"TRILIUM_URL":"http://localhost:8080","TRILIUM_ETAPI_TOKEN":"<your-token>"}}'Then confirm it connected:
claude mcp get triliumIf claude mcp list shows Failed to connect, check that bun is on your PATH, you ran bun install, the path is absolute, and the token is valid.
Scope (where the config is stored):
Flag | Stored in | Use for |
|
| Personal, one project |
|
| Personal, everywhere |
|
| Team setup; never put the token in it |
For a shared .mcp.json, reference environment variables instead of the token:
{
"mcpServers": {
"trilium": {
"command": "bunx",
"args": ["github:btafoya/triliumnotes-mcp-server"],
"env": {
"TRILIUM_URL": "${TRILIUM_URL:-http://localhost:8080}",
"TRILIUM_ETAPI_TOKEN": "${TRILIUM_ETAPI_TOKEN}"
}
}
}
}Verify and manage:
claude mcp list # trilium should show as connected
claude mcp get trilium # show config
claude mcp remove trilium # unregisterInside a Claude Code session, run /mcp to see connection status and the trilium_* tools.
Example prompts
"Search my Trilium notes for
#projectnotes modified this month and summarize them.""Create a note under my inbox titled 'Meeting 2026-11-05' with these bullet points."
"Open today's day note and append a todo list."
"Find notes tagged
#bookand add the labelread=noto each that lacksread.""Snapshot note
<noteId>as a revision, then rewrite its intro.""Export the subtree under
<noteId>as markdown to/tmp/export.zip."
Permissions
Claude Code asks before each tool call by default. To pre-approve read-only tools, add them to permissions.allow in .claude/settings.json (or your user settings). MCP tools are named mcp__<server>__<tool>, so with the server registered as trilium:
{
"permissions": {
"allow": [
"mcp__trilium__trilium_search_notes",
"mcp__trilium__trilium_get_note",
"mcp__trilium__trilium_get_note_content",
"mcp__trilium__trilium_get_app_info"
]
}
}Leave write and delete tools (create_*, set_*, update_*, delete_*, import_zip, create_backup) on prompt.
Other MCP clients: run bun src/index.ts (or node dist/index.js after bun run build) as a stdio server with the same environment variables.
Configuration
Variable | Required | Default | Description |
| no |
| Base URL of the Trilium server. A trailing |
| yes | ETAPI token sent in the |
The token grants full access to your notes. Keep it out of version control; this repo ignores .env.
Tools
All tool names are prefixed trilium_.
Area | Tools |
Notes |
|
Revisions |
|
Branches |
|
Attributes |
|
Attachments |
|
Calendar |
|
Application |
|
Behavior notes
Search uses Trilium search syntax (for example
towers #book,"exact phrase",note.dateCreated >= '2025-01-01'). It returns trimmed metadata; fetch content withget_note_content. ETAPI offerslimitbut nooffset.Content paging: note, revision and attachment content is returned in chunks of up to 25,000 characters. The response includes
more: call again with offset=Nwhen there is more.Binary content is returned base64-encoded. The
set_*_contenttools acceptencoding: "base64"for binary writes.Export / import read and write ZIP files at absolute local paths (
output_path,zip_path).Protected notes appear as
[protected]and cannot be modified; ETAPI cannot open a protected session.Deleting:
delete_noteremoves a note from every location;delete_branchremoves it from one (and deletes the note if it was the last).undelete_notecan restore recent deletions.Not exposed:
/auth/loginand/auth/logout. The server uses token auth, and logout would revoke the token it is using.
Skills
skills/ holds three Claude Code skills that teach the agent how to use the tools well. The most important one is the note-type guide, which says which type and mime to use so content is stored correctly (code snippets as code notes with a language mime, Markdown as code + text/x-markdown, diagrams as mermaid, text notes as HTML).
Skill | Teaches |
| Note type / mime / content format, plus snapshot-before-overwrite and duplicate checks. Includes a mime reference. |
| Trilium's search language and the |
| Journal and inbox, move vs clone vs delete, attributes, attachments, revisions, undelete, export/import, backup |
Install (the bunx install does not include them, so copy or link them once):
git clone https://github.com/btafoya/triliumnotes-mcp-server.git
mkdir -p ~/.claude/skills
ln -s "$PWD"/triliumnotes-mcp-server/skills/* ~/.claude/skills/ # or cp -rFor one project only, put them in that project's .claude/skills/ instead.
Safety
Write tools can overwrite or delete data. Destructive tools set destructiveHint: true, and Claude Code prompts for permission according to your settings. Consider calling create_revision before set_note_content, and create_backup before bulk changes.
Development
bun run build # compile to dist/
bun run smoke # self-check against a built-in mock ETAPI serverTo run the read-only smoke checks against a real instance, set TRILIUM_URL and TRILIUM_ETAPI_TOKEN first.
Evaluations
evals/trilium_eval.xml holds 10 question/answer pairs that a model should answer using the trilium_* tools. They target a fixed sandbox subtree that evals/seed.ts creates under root:
TRILIUM_URL=... TRILIUM_ETAPI_TOKEN=... bun evals/seed.ts # create "Eval Sandbox" (23 notes)
TRILIUM_URL=... TRILIUM_ETAPI_TOKEN=... bun evals/seed.ts --clean # delete itRun the seed against a throwaway or test instance. It writes only the evalRoot subtree and refuses to run if evalRoot already exists.
Layout:
src/index.ts server factory, stdio entry point
src/api.ts ETAPI client, auth, error mapping
src/tools.ts tool definitions
scripts/smoke.tsTool schemas follow the ETAPI OpenAPI spec.
License
MIT (c) 2026 Brian Tafoya
This server cannot be deployed
Maintenance
Related MCP Connectors
Persistent memory layer for AI tools. Save and recall notes across Claude and other MCP clients.
MCP-native notes and memory for ChatGPT, Claude, and other AI tools.
Notes and memory assistant: one Markdown vault that Claude, ChatGPT and any MCP client can share.
Notes, files, GitHub, and Drive through one MCP connection.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA Model Context Protocol (MCP) server for interacting with TriliumNext via its ETAPI. Enables LLMs to create, read, update, and organize notes, including embedding images and files directly into note content.368 npm71MIT
- AlicenseNot gradedqualityCmaintenanceBrings your Trilium Notes knowledge base into Claude Desktop, enabling full-text search, note management, and content interaction through natural language.7MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI clients to manage Trilium Notes with full CRUD operations, search, calendar integration, and system administration through the Model Context Protocol.9 npm2MIT
- AlicenseNot gradedqualityDmaintenanceEnables users to create, link, explore, and synthesize atomic notes using the Zettelkasten method through MCP-compatible clients like Claude.MIT