{
  "version": "2",
  "generatedAt": "2026-11-03T22:49:39.280Z",
  "listing": {
    "slug": "triliumnext--trilium",
    "name": "Trilium Notes",
    "tagline": "Hierarchical note tree with attributes and scripting, driven by the ETAPI REST API and an in-repo MCP route.",
    "shortTagline": "Hierarchical note tree",
    "description": "Trilium is a self-hostable notes app (desktop and server) built around an arbitrarily deep note tree with labels, relations, note versioning, encryption, and scripting. The server ships ETAPI, a documented REST API for notes, branches, attributes, attachments, and calendar notes, and since 2026 an MCP route (apps/server/src/routes/mcp.ts) that exposes the LLM tool registry.",
    "capabilities": [
      "adaptable",
      "operable"
    ],
    "vertical": "notes-knowledge",
    "alternativeTo": [
      "Evernote",
      "Notion",
      "Obsidian"
    ],
    "shape": "business-app",
    "formFactor": "web-app",
    "executionModel": "hybrid",
    "provenance": "mixed",
    "codeStack": {
      "languages": [
        "TypeScript"
      ],
      "frameworks": [
        "Express",
        "Electron",
        "CKEditor"
      ],
      "packageManager": "pnpm",
      "database": [
        "SQLite"
      ],
      "hostingTarget": [
        "docker",
        "binary"
      ]
    },
    "modelStack": {
      "providers": [
        "configurable LLM providers for the built-in AI chat"
      ],
      "models": [],
      "requiredKeys": [],
      "promptLocations": [
        ".claude/skills/"
      ],
      "tools": []
    },
    "repos": [
      {
        "url": "https://github.com/TriliumNext/Trilium",
        "owner": "TriliumNext",
        "name": "Trilium",
        "license": "AGPL-3.0",
        "stars": 37683,
        "lastCommit": "2026-09-03"
      }
    ],
    "interface": {
      "kind": "api",
      "url": "https://docs.triliumnotes.org/user-guide/advanced-usage/etapi",
      "official": true,
      "hosted": "local"
    },
    "operability": "official",
    "recommendedWrapper": null,
    "reach": [
      {
        "job": "Create, read, update, and delete notes",
        "reachable": true,
        "evidence": "ETAPI /notes and /create-note"
      },
      {
        "job": "Place notes in the tree (branches, clones)",
        "reachable": true,
        "evidence": "ETAPI /branches"
      },
      {
        "job": "Labels and relations",
        "reachable": true,
        "evidence": "ETAPI /attributes"
      },
      {
        "job": "Search with Trilium's query language",
        "reachable": true,
        "evidence": "ETAPI /notes?search="
      },
      {
        "job": "Attachments",
        "reachable": true,
        "evidence": "ETAPI /attachments"
      },
      {
        "job": "Day, week, month, and year calendar notes",
        "reachable": true,
        "evidence": "ETAPI /calendar/days, /weeks, /months, /years"
      },
      {
        "job": "Note revisions and export",
        "reachable": true,
        "evidence": "ETAPI /notes/{id}/revision, /notes/{id}/revisions, /notes/{id}/export and /import"
      },
      {
        "job": "Backup",
        "reachable": true,
        "evidence": "ETAPI /backup/{name}"
      },
      {
        "job": "Scripting and widgets",
        "reachable": false,
        "evidence": "backend scripts run inside the app; ETAPI cannot execute them"
      },
      {
        "job": "Sync and protected (encrypted) notes",
        "reachable": false,
        "evidence": "sync is app-to-server; protected notes need the session password in the UI"
      }
    ],
    "editions": [
      {
        "name": "Free",
        "price": null,
        "open": true,
        "distributions": [
          {
            "kind": "source",
            "url": "https://github.com/TriliumNext/Trilium"
          },
          {
            "kind": "binary",
            "url": "https://github.com/TriliumNext/Trilium/releases"
          },
          {
            "kind": "container",
            "url": "https://hub.docker.com/r/triliumnext/trilium",
            "command": "docker compose up -d"
          }
        ]
      }
    ],
    "skills": {
      "kind": "contributor",
      "paths": [
        ".claude/skills/*/SKILL.md"
      ],
      "install": null,
      "note": "Repo tooling for Trilium contributors: client UI, Electron and Capacitor builds, coverage, releases."
    },
    "customization": {
      "summary": "config.ini (from apps/server/src/assets/config-sample.ini) sets instanceName, noAuthentication, noBackup, port, https with certPath and keyPath, trustedReverseProxy, session cookieMaxAge, OAuth multi-factor (oauthBaseUrl, oauthClientId, oauthClientSecret, oauthIssuerBaseUrl), and the security switches backendScriptingEnabled and sqlConsoleEnabled. TRILIUM_DATA_DIR and its siblings relocate data, logs, backups, and the config file. docker-compose.yml is in the repo.",
      "envVars": [
        "TRILIUM_DATA_DIR",
        "TRILIUM_CONFIG_INI_PATH",
        "TRILIUM_DOCUMENT_PATH",
        "TRILIUM_BACKUP_DIR",
        "TRILIUM_LOG_DIR",
        "TRILIUM_TMP_DIR",
        "TRILIUM_OCR_CACHE_DIR",
        "TRILIUM_ANONYMIZED_DB_DIR"
      ],
      "configFiles": [
        "config.ini",
        "docker-compose.yml"
      ],
      "promptFiles": [
        ".claude/skills/"
      ],
      "effort": "config-only",
      "editCount": 11
    },
    "useWhen": [
      "you want a deeply nested personal or team knowledge tree that an agent can populate through a stable REST API",
      "you outgrew flat markdown folders and want attributes, relations, and saved searches"
    ],
    "accounts": [
      "an OAuth provider (optional, for multi-factor login)"
    ],
    "active": true,
    "lastActivity": "2026-09-03",
    "gotchas": [
      "AGPL-3.0",
      "The desktop app and server versions must match for sync; disable auto-updates on the server when using TriliumDroid",
      "ETAPI needs a token created in the UI (Options > ETAPI) or from POST /etapi/auth/login with the instance password",
      "MCP route tool names were not read; they come from the core LLM tool registry (packages/core llm/tools)"
    ],
    "fit": {
      "adaptable": 2,
      "operable": 3
    },
    "evidence": {
      "formFactor": "README: server install with Docker with web UI; desktop builds also exist",
      "executionModel": "built-in LLM chat and tool registry (mcp_server.ts imports allToolRegistries from the llm tools); notes work without a model",
      "operability": "docs.triliumnotes.org ETAPI page: token from Options > ETAPI or POST /etapi/auth/login with the password; sent as 'Authorization: <token>', 'Authorization: Bearer <token>' (v0.93+), or Basic with username etapi. OpenAPI spec in repo at apps/server/src/assets/etapi.openapi.yaml (securitySchemes EtapiTokenAuth apiKey + basic); 31 paths incl. /notes, /branches, /attributes, /attachments, /calendar/*, /backup, /metrics. apps/server/src/routes/mcp.ts also present.",
      "effort": "config-sample.ini keys and TRILIUM_* names in apps/server/src/services/data_dir.ts",
      "editions": "AGPL, free; third-party hosting only",
      "active": "pushedAt 2026-09-03",
      "provenance": "CLAUDE.md and .claude/skills in repo; project from 2017"
    },
    "confidence": {
      "formFactor": 0.7,
      "executionModel": 0.7,
      "operability": 0.95,
      "effort": 0.9,
      "reach": 0.7,
      "editions": 0.95,
      "provenance": 0.4
    },
    "openQuestions": [
      "Read the MCP tool names from the core LLM tool registry and decide whether the MCP route should replace ETAPI as the stated interface",
      "Decide whether the MCP route (apps/server/src/routes/mcp.ts) should replace ETAPI as the stated interface once its tool list is read"
    ],
    "sources": [
      {
        "url": "https://github.com/TriliumNext/Trilium",
        "foundBy": "sourcing:notes-knowledge:github"
      },
      {
        "url": "https://github.com/TriliumNext/Trilium/blob/main/apps/server/src/assets/config-sample.ini",
        "foundBy": "analysis"
      }
    ],
    "research": {
      "stage": "verified",
      "verdict": "approve",
      "reason": "ETAPI is Builder-documented, token-authenticated through the Authorization header, and the token can be minted non-interactively from /etapi/auth/login. Slip fixed: the OpenAPI file lives at apps/server/src/assets/etapi.openapi.yaml, not apps/server/src/etapi/.",
      "disputed": []
    },
    "url": "apps/triliumnext--trilium.html",
    "coverage": "partial",
    "paid": false,
    "source": "research/verified/triliumnext--trilium.json"
  }
}
