Skip to main content
Glama
anshulbansod2

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

Maintenance

ActivitySlowing
ResponsivenessNo issues