logseq-mcp
README.md
# logseq-mcp
An [MCP](https://modelcontextprotocol.io) server that lets an AI agent operate a
**Logseq (DB) graph** through a small set of safe, high-level tools — read notes and
tasks, capture notes, create and update tasks, and scaffold projects — without the
agent having to know Logseq's internals.
It talks to Logseq's **local HTTP API** (the same one the desktop app exposes), and
encodes the DB-graph conventions that are easy to get wrong (real task statuses,
`[[page]]` vs `#tag` links, journal date resolution, and soft-delete awareness).
> **Supported:** Logseq **DB graphs** (the newer SQLite-backed graphs). File/markdown
> graphs are not supported yet.
## Features
- **Workflow tools, not raw API.** `list_open_tasks`, `create_task`, `capture_note`,
`create_project`, etc. — each does the right multi-step thing under the hood.
- **Safe by default.** Reads are free; writes are validated; destructive tools
(`archive_page`, `remove_block`) only **soft-delete** and require `confirm=true`
after showing a preview.
- **Read-only mode.** Set `LOGSEQ_MCP_READONLY=true` to disable all writes.
- **Clear failures.** Logseq closed, bad token, or bad input each return an actionable
message, never a stack trace.
## Install
```bash
# from source
pip install -e .
# or install as a stable command for daily use (MCP clients point at this)
uv tool install .
# or run without installing (once published)
uvx logseq-mcp
pipx run logseq-mcp
```
Requires Python 3.10+.
> **Upgrading a `uv tool install`:** `uv tool install . --force` can reuse a cached
> wheel when the version is unchanged, so code edits may not take effect. Use
> `uv tool install . --force --no-cache` to force a fresh build, then restart your
> MCP client so it picks up the new tools.
## Configure
1. In Logseq desktop: **Settings → Features → enable "HTTP APIs server"**, start the
server, and copy the **authorization token**.
2. Provide these to the server (via your MCP client's `env` block, or a local `.env`
for development — see `.env.example`):
| Variable | Default | Meaning |
|---|---|---|
| `LOGSEQ_TOKEN` | *(required)* | HTTP API token |
| `LOGSEQ_API_URL` | `http://localhost:12315` | API base URL |
| `LOGSEQ_MCP_READONLY` | `false` | disable all write tools |
| `LOGSEQ_HTTP_TIMEOUT` | `15` | request timeout (seconds) |
The token is never hardcoded or logged.
## MCP client setup
### Claude Code
```bash
claude mcp add logseq -- logseq-mcp
# then set env, e.g. in .mcp.json:
```
```json
{
"mcpServers": {
"logseq": {
"command": "logseq-mcp",
"env": { "LOGSEQ_TOKEN": "your-token-here" }
}
}
}
```
### Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"logseq": {
"command": "logseq-mcp",
"env": { "LOGSEQ_TOKEN": "your-token-here" }
}
}
}
```
(If not installed on PATH, use `"command": "python", "args": ["-m", "logseq_mcp"]`.)
## Tools
| Tool | Kind | Description |
|---|---|---|
| `search_notes(query, limit=20, status?)` | read | Find blocks by keyword; optionally filter by task status |
| `get_page(name)` | read | Read a page as an outline |
| `list_open_tasks(project?, priority?, due_before?, overdue?)` | read | Open tasks (filtered, sorted by deadline) |
| `list_projects()` | read | Project pages + open-task counts |
| `get_journal(date="today")` | read | Read a journal entry |
| `get_backlinks(name, include_tags=false)` | read | Blocks that link to a page (optionally via `#tags`) |
| `find_unlinked_mentions(name)` | read | Blocks that mention a page's name without linking it |
| `get_outgoing_links(block_uuid)` | read | Pages a block links to |
| `get_block_backlinks(block_uuid)` | read | Blocks that reference a block via `((uuid))` |
| `get_graph_config()` | read | Read user/graph configuration |
| `create_task(title, on_project?, on_journal_date?, status?, priority?, scheduled?, deadline?, validate_links?)` | write | Create a real task |
| `create_tasks(titles, on_project?, on_journal_date?, status?, priority?, scheduled?, deadline?)` | write | Create several tasks at once |
| `set_task_status(task_uuid, status)` | write | Move a task's status |
| `set_task_priority(task_uuid, priority?, clear?)` | write | Set or clear a task's priority |
| `set_task_schedule(task_uuid, scheduled?, deadline?, clear_scheduled?, clear_deadline?)` | write | Set or clear native SCHEDULED/DEADLINE dates |
| `capture_note(text, to="today", validate_links?)` | write | Append a note (journal or page) |
| `create_card(question, answer, on_page?, on_journal_date?)` | write | Create a flashcard (review in Logseq) |
| `list_due_cards(limit=50)` | read | Flashcards due for review (new or past-due) |
| `create_query(query, on_page?, on_journal_date?, title?)` | write | Add a live-query dashboard widget |
| `create_project(name, title, description?, tasks?)` | write | Scaffold a project page |
| `rename_project(old_name, new_name)` | write | Rename a project page |
| `add_link(block_uuid, page_name)` | write | Add a `[[page]]` link to a block |
| `remove_link(block_uuid, page_name)` | write | Remove a `[[page]]` link from a block |
| `link_blocks(source_block_uuid, target_block_uuid)` | write | Reference one block from another (`((uuid))`) |
| `archive_page(name, confirm=false)` | destructive | Soft-delete a page (preview first) |
| `remove_block(uuid, confirm=false)` | destructive | Remove a block (preview first) |
Resources: `logseq://graph`, `logseq://projects`, `logseq://today`.
## Safety model
- **Reads** never modify anything.
- **Writes** validate input first and are disabled entirely in read-only mode.
- **Destructive** tools soft-delete only (recoverable in Logseq's trash), require an
explicit `confirm=true`, and return a preview when `confirm` is omitted.
- `create_task` sets the status *property* (never injects "TODO" text); `capture_note`
is append-only; `create_project` refuses to overwrite an existing live page.
## Troubleshooting
- **"Cannot reach Logseq…"** — the desktop app isn't running, or the HTTP APIs server
is off. Enable it in Settings → Features.
- **"Logseq rejected the API token"** — `LOGSEQ_TOKEN` doesn't match the token shown in
Logseq's HTTP APIs server settings.
- **"supports Logseq DB graphs only"** — the open graph is a file/markdown graph; open a
DB graph.
- **A journal date has no page** — open that day in Logseq once (or `capture_note` to it).
## Development
```bash
pip install -e ".[dev]"
pytest # unit tests (offline)
LOGSEQ_TOKEN=… pytest -m integration # live tests (needs Logseq running)
ruff check . && mypy src
```
## License
MIT
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues