Generated banner for mcp-logseq
Generated logo for mcp-logseq

mcp-logseq

Memory server

First committed by ergut

Published in ergut/mcp-logseq. Publisher page

351 GitHub stars

What it is

MCP server to interact with LogSeq via its Local HTTP API - enabling AI assistants like Claude to seamlessly read, write, and manage your LogSeq graph.
— the description by ergut

AutoGineer overview, from the brain’s own files

mcp-logseq is a Model Context Protocol server that bridges AI agents with your local Logseq knowledge base. By leveraging Logseq's local HTTP API, it allows agents to interact with your notes, journals, and project pages without manual exports. It supports standard CRUD operations on pages and blocks, advanced querying, and optional semantic vector search using LanceDB. The server includes robust privacy controls, allowing users to restrict AI access via tags or namespace allow-lists, ensuring sensitive information remains private.

How it works

Memory model: Vector store

AutoGineer overview, from the brain’s own files

The server acts as a bridge between an MCP-compatible AI client and your local Logseq application. It connects to the Logseq HTTP API to read and modify your graph files. It provides a suite of tools for managing pages and blocks, including support for hierarchical structures and markdown parsing. Optionally, it can maintain a local vector database to enable semantic search across your notes, allowing the AI to find information based on meaning rather than just keywords.

Folders
FolderRoleFiles
assetsattachments4
docsdocs12
srcsource-code27
teststests30

The agent reads

The agent writes

Requirements

Runtimes: Python >=3.11

Databases: LanceDB

API keys (by name): LOGSEQ_API_TOKEN, MCP_HTTP_AUTH_TOKEN, YOUR_LOGSEQ_TOKEN

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)

Set it up

  1. Not scanned by AutoGineerIts setup steps could not be read from the brain’s own files. https://github.com/ergut/mcp-logseq/tree/0769877448a2be921c280689f7cf57694ed6b0a0
  2. Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (7 declared). https://pypi.org/project/mcp-logseq/
  3. First committed by ergut. Published in ergut/mcp-logseq. Licence: MIT License.

Usage

AutoGineer overview, from the brain’s own files

  • Connect Claude to your Logseq graph for intelligent knowledge management.
  • Automate the creation of meeting notes and task pages.
  • Perform semantic searches across your notes to find related concepts.
  • Enforce privacy by restricting AI access to specific namespaces or tagged pages.
“Analyze all my project notes from the past month and create a status summary.”
The agent reads relevant pages from the Logseq graph and generates a consolidated summary.
“Find everything I wrote about burnout, even if I didn't use that word.”
The agent performs a semantic vector search to retrieve notes conceptually related to burnout.
“Create a new page called 'Today's Standup' with my meeting notes.”
The agent creates a new page in the Logseq graph with the specified content.
“Search for 'Q4 planning' and organize all related content into a new overview page.”
The agent identifies relevant blocks and aggregates them into a new structured page.

Documentation by ergut

<div align="center"> <img src="assets/images/logo.png" alt="MCP LogSeq" width="200" height="200"> <h1>MCP server for LogSeq</h1> <p>Connect Claude to your LogSeq knowledge base. Read, create, and manage pages — with optional semantic vector search and DB-mode graph support.</p> </div>

✨ What You Can Do

Transform your LogSeq knowledge base into an AI-powered workspace! This MCP server enables Claude to seamlessly interact with your LogSeq graphs.

🎯 Real-World Examples

📊 Intelligent Knowledge Management

"Analyze all my project notes from the past month and create a status summary"
"Find pages mentioning 'machine learning' and create a study roadmap"
"Search for incomplete tasks across all my pages"

📝 Automated Content Creation

"Create a new page called 'Today's Standup' with my meeting notes"
"Add today's progress update to my existing project timeline page"  
"Create a weekly review page from my recent notes"

🔍 Smart Research & Analysis

"Compare my notes on React vs Vue and highlight key differences"
"Find all references to 'customer feedback' and summarize themes"
"Create a knowledge map connecting related topics across pages"

🧠 Semantic Search (optional, requires vector setup)

"Find everything I wrote about burnout, even if I didn't use that word"
"What notes relate to my thoughts on deep work?"
"Search across my Dutch and English notes for ideas about productivity"

🤝 Meeting & Documentation Workflow

"Read my meeting notes and create individual task pages for each action item"
"Get my journal entries from this week and create a summary page"
"Search for 'Q4 planning' and organize all related content into a new overview page"
💡 Key Benefits
  • Zero Context Switching: Claude works directly with your LogSeq data

  • Preserve Your Workflow: No need to export or copy content manually

  • Intelligent Organization: AI-powered page creation, linking, and search

  • Enhanced Productivity: Automate repetitive knowledge work

  • Semantic Vector Search (optional): Find notes by meaning using local Ollama or hosted OpenAI-compatible embeddings

  • DB-mode Support (opt-in): Read and write class properties on Logseq DB-mode graphs


🚀 Quick Start

Step 1: Enable LogSeq API
  1. Settings → Features → Check "Enable HTTP APIs server"

  2. Click the API button (🔌) in LogSeq → "Start server"

  3. Generate API token: API panel → "Authorization tokens" → Create new

Step 2: Add to your MCP client (No Installation Required!)
Claude Code
claude mcp add mcp-logseq \
  --env LOGSEQ_API_TOKEN=your_token_here \
  --env LOGSEQ_API_URL=http://localhost:12315 \
  -- uv run --with mcp-logseq mcp-logseq
Claude Desktop

Add to your config file (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "mcp-logseq": {
      "command": "uv",
      "args": ["run", "--with", "mcp-logseq", "mcp-logseq"],
      "env": {
        "LOGSEQ_API_TOKEN": "your_token_here",
        "LOGSEQ_API_URL": "http://localhost:12315"
      }
    }
  }
}
Codex CLI

With uv installed and Logseq's HTTP API running (Step 1), add this to ~/.codex/config.toml:

[mcp_servers.logseq]
command = "uv"
args = ["run", "--with", "mcp-logseq", "mcp-logseq"]

[mcp_servers.logseq.env]
LOGSEQ_API_TOKEN = "YOUR_LOGSEQ_TOKEN"
LOGSEQ_API_URL = "http://127.0.0.1:12315"

Replace YOUR_LOGSEQ_TOKEN with your Logseq token. If Codex cannot find uv, run which uv in Terminal and use the full path for command. Keep your token private.

Use the API base address above, without /mcp. Codex runs this adapter through STDIO; the adapter connects to Logseq's regular HTTP API.

Restart Codex, open a new local task, and ask:

Use Logseq to list my journal pages, then read today's journal. Do not change anything.

Keep Logseq and its API server running. Codex starts the adapter automatically—no tunnel or separate Terminal window is needed.

Tested with a Logseq DB graph for page listing and journal retrieval. This setup is for local Codex tasks, not cloud-hosted ChatGPT Chat.

OpenCode

Add to ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "mcp-logseq": {
      "type": "local",
      "command": ["uv", "run", "--with", "mcp-logseq", "mcp-logseq"],
      "enabled": true,
      "environment": {
        "LOGSEQ_API_URL": "http://localhost:12315",
        "LOGSEQ_API_TOKEN": "your_token_here"
      }
    }
  }
}
Step 3: Start Using!
"Please help me organize my LogSeq notes. Show me what pages I have."

🔬 Vector Search (Optional)

Semantic search over your Logseq graph using configurable embeddings — find notes by meaning, not just keywords. Searches across all your pages using vector similarity and full-text search combined, with cross-language support.

Use Ollama for fully local embeddings, OpenAI, or another OpenAI-compatible embeddings endpoint. LanceDB remains local in every configuration. Hosted providers receive the note text being embedded.

→ Full setup guide: VECTOR_SEARCH.md


🛠️ Available Tools

The server provides 17 tools with intelligent markdown parsing, plus 3 optional vector search tools:

ToolPurposeExample Use
list_pagesBrowse your graph; sort: "updated" / updated_since find recently modified pages"Which pages did I change this week?"
get_page_contentRead page content"Get my project notes"
create_pageAdd new pages with structured blocks"Create a meeting notes page with agenda items"
update_pageModify pages (append/replace modes)"Update my task list"
delete_pageRemove pages"Delete the old draft page"
delete_blockRemove a block by UUID"Delete this specific block"
update_blockEdit block content by UUID"Update this specific block text"
get_blockRead a block by UUID with its properties and children"Show me this specific block"
searchFind content across graph"Search for 'productivity tips'"
queryExecute Logseq DSL queries (raw datalog not supported)"Find all TODO tasks tagged #project"
find_pages_by_propertySearch pages by property"Find all pages with status = active"
get_pages_from_namespaceList pages in a namespace"Show all pages under Customer/"
get_pages_tree_from_namespaceHierarchical namespace view"Show Projects/ as a tree"
rename_pageRename with reference updates"Rename 'Old Name' to 'New Name'"
get_page_backlinksFind pages linking to a page"What links to this page?"
insert_nested_blockInsert child/sibling blocks"Add a child block under this task"
set_block_propertiesSet DB-mode class properties on a block"Set the status of this block to active" (DB-mode only)
vector_search ⚗️Semantic search by meaning"Find notes about shadow work or Jung"
sync_vector_db ⚗️Sync vector DB with graph files"Update the search index"
vector_db_status ⚗️Show vector DB health and staleness"Is my search index up to date?"

⚗️ Requires vector search setup — see VECTOR_SEARCH.md

🎨 Smart Markdown Parsing (v1.1.0+)

The create_page and update_page tools now automatically convert markdown into Logseq's native block structure:

Markdown Input:

---
tags: [project, active]
priority: high
---

# Project Overview
Introduction paragraph here.

## Tasks
- Task 1
  - Subtask A
  - Subtask B
- Task 2

## Code Example
```python
def hello():
    print("Hello Logseq!")
```

Result: Creates properly nested blocks with:

  • ✅ Page properties from YAML frontmatter (tags, priority)

  • ✅ Hierarchical sections from headings (#, ##, ###)

  • ✅ Nested bullet lists with proper indentation

  • ✅ Code blocks preserved as single blocks

  • ✅ Checkbox support (- [ ] → TODO, - [x] → DONE)

Update Modes:

  • append (default): Add new content after existing blocks

  • replace: Clear page and replace with new content

🔁 Safe Retries & Large Writes

create_page fails with a clear error if a page with the same title already exists, instead of letting Logseq silently create numbered duplicates (Page(1), Page 2, ...). This makes retries after a timeout safe: if a previous create_page call timed out but actually committed, the retry tells you the page exists rather than fragmenting your content across ghost pages.

For large writes, prefer this pattern over one giant create_page call:

  1. Create the page with little or no content (create_page with just the title and properties)

  2. Append content in smaller chunks with update_page (mode: append)

  3. Read back with get_page_content to verify the result

If you hit the "already exists" error mid-ingest, use get_page_content to see what landed, then continue with update_page instead of re-creating.


⚙️ Prerequisites

LogSeq Setup
  • LogSeq installed and running

  • HTTP APIs server enabled (Settings → Features)

  • API server started (🔌 button → "Start server")

  • API token generated (API panel → Authorization tokens)

System Requirements
  • uv Python package manager

  • MCP-compatible client (Claude Code, Claude Desktop, etc.)


🔧 Configuration

Environment Variables
  • LOGSEQ_API_TOKEN (required): Your LogSeq API token

  • LOGSEQ_API_URL (optional): Server URL (default: http://localhost:12315)

  • LOGSEQ_VERIFY_SSL (optional): Whether to verify the TLS certificate of an https:// LOGSEQ_API_URL. Defaults to verifying when the URL is https://; set to 0, false, or no to skip verification for self-signed certificates. Any other value enables verification.

  • LOGSEQ_API_CONNECT_TIMEOUT (optional): HTTP connect timeout in seconds (default: 3)

  • LOGSEQ_API_READ_TIMEOUT (optional): HTTP read timeout in seconds (default: 6)

  • LOGSEQ_LOG_LEVEL (optional): Log verbosity — DEBUG, INFO, WARNING, ERROR, or CRITICAL (default: INFO). Logs go to stderr. At DEBUG, the MCP SDK's own logger stays capped at INFO so full request payloads are not logged.

  • LOGSEQ_LOG_FILE (optional): Path to a log file. When unset (the default), nothing is written to disk. Tool calls are logged with argument names and result sizes only, so page/block content does not appear in routine logs.

  • LOGSEQ_DB_MODE (optional): Set to true to enable DB-mode property support. Only for Logseq DB-mode graphs (beta). Markdown/file-based graph users should leave this unset.

  • LOGSEQ_EXCLUDE_TAGS (optional): Comma-separated tags — pages with these tags are hidden from all tools. See Privacy & Access Control below.

  • LOGSEQ_INCLUDE_NAMESPACES (optional): Comma-separated namespace allow-list (e.g. work,projects). When set, only pages in these namespaces and their sub-pages are accessible — everything else, including top-level pages without a namespace, is hidden from listings/search and denied on direct access. See Privacy & Access Control below.

  • LOGSEQ_EXCLUDE_NAMESPACES (optional): Comma-separated namespace deny-list (e.g. finance,work/secret). These namespaces are always blocked, taking priority over the include list. See Privacy & Access Control below.

  • LOGSEQ_WRITE_NAMESPACES (optional): Comma-separated write allow-list (e.g. Beren). When set, write tools may only target pages in these namespaces; everything else that is readable stays read-only. Applied on top of the include/exclude rules, never instead of them. See Privacy & Access Control below.

  • LOGSEQ_CONFIG_FILE (optional): Path to a shared JSON config file holding the graph path, ACL defaults, and the vector block. Env vars (LOGSEQ_EXCLUDE_TAGS, LOGSEQ_INCLUDE_NAMESPACES, LOGSEQ_EXCLUDE_NAMESPACES, LOGSEQ_WRITE_NAMESPACES) override the matching keys in this file.

  • MCP_HTTP_AUTH_TOKEN (required for --transport http): Bearer token clients must send as Authorization: Bearer <token>. The server refuses to start in HTTP mode without it. See Serving over HTTP.

Privacy & Access Control

Pages tagged with excluded tags are completely hidden from AI — they won't appear in listings, searches, or queries, and attempting to read them directly returns an access-denied error.

Quick setup via env var:

LOGSEQ_EXCLUDE_TAGS=private,secret

Via config file (also used for vector search):

{
  "logseq_graph_path": "/path/to/your/logseq/pages",
  "exclude_tags": ["private", "secret"]
}

Point to it with LOGSEQ_CONFIG_FILE=/path/to/config.json.

In your Logseq pages, tag any page you want to protect:

tags:: private

The exclusion applies to all tools: list_pages, get_page_content, search, query, and the optional vector search. If you also use vector search, exclude_tags at the root is automatically merged into the vector index exclusion list — private pages are never embedded.

Namespace access control

You can restrict access to specific namespaces using LOGSEQ_INCLUDE_NAMESPACES and LOGSEQ_EXCLUDE_NAMESPACES.

Include list (strict allow-list): Only the listed namespaces and their sub-pages are visible; everything else is hidden.

LOGSEQ_INCLUDE_NAMESPACES=work,projects

Exclude list (deny-list): The listed namespaces are always blocked, even if they appear in the include list.

LOGSEQ_EXCLUDE_NAMESPACES=work/secret,finance

Via config file:

{
  "include_namespaces": ["work", "projects"],
  "exclude_namespaces": ["work/secret", "finance"],
  "write_namespaces": ["work/drafts"]
}

Write list (write allow-list): Everything the read rules allow stays readable, but write tools (create_page, update_page, delete_page, rename_page, update_block, delete_block, insert_nested_block, set_block_properties) may only target pages in these namespaces. Useful when an assistant should read a wider area than it may edit:

LOGSEQ_INCLUDE_NAMESPACES=Family,Beren
LOGSEQ_WRITE_NAMESPACES=Beren   # reads Family/* and Beren/*, writes only Beren/*

rename_page needs both the old and the new name inside the write list; block tools are checked against the block's owning page (denied if it cannot be resolved). A write outside the list returns "page 'X' is read-only for this assistant". The write list never widens read access: a write namespace not covered by the include list is still denied (a warning is logged at startup). Unset means no extra restriction. Every allowed write is logged at INFO as Write: tool=<name> page=<page name> (names only, never content).

Matching is segment-based and case-insensitive: work matches work and work/projects but not workshop. The behavior mirrors LOGSEQ_EXCLUDE_TAGS: list/search results silently omit blocked pages; direct read, write, delete, and block operations return an access-denied error.

Access control is enforced at the page level and applied across every tool: list/search/query results omit blocked pages, direct page/block access and backlinks are denied, and vector search is filtered. Block-level results from search and query are resolved back to their owning page, so a block belonging to a restricted page is filtered out of those results too.

Index-time namespace scoping (vector DB only). The keys above are query-time: every page is embedded, and blocked ones are filtered out of each response. For the vector DB you can also scope at index time — decide which namespaces are embedded into the DB at all — with include_namespaces / exclude_namespaces inside the vector block of the config file:

{
  "vector": {
    "enabled": true,
    "include_namespaces": ["work"],
    "exclude_namespaces": ["work/secret"]
  }
}

This is global (it shapes the shared DB for every consumer), and it keeps unwanted content off disk entirely rather than filtering it on read — useful for secrets you never want embedded, or to keep the index small when everyone only cares about a subset. Matching is the same segment-based, case-insensitive rule. Because it changes what the index contains, it only takes effect after a full re-index: logseq-sync --rebuild.

🌐 Serving over HTTP, multi-profile & TLS

By default the server speaks stdio — your client spawns it as a subprocess, and most users need nothing more. To serve sandboxed or remote clients over the network, mcp-logseq can run as a long-lived HTTP service with bearer auth, per-profile isolation, and TLS:

mcp-logseq --transport http --host 127.0.0.1 --port 12320   # requires MCP_HTTP_AUTH_TOKEN

The full deployment guide — the server-side security model, the per-profile multi-instance pattern, the separate logseq-sync writer, and native TLS / reverse-proxy setup — lives in docs/SERVING.md. Non-loopback binds over plain HTTP are refused unless you supply TLS or pass --insecure.

Alternative Setup Methods
Using .env file
# .env
LOGSEQ_API_TOKEN=your_token_here
LOGSEQ_API_URL=http://localhost:12315
System environment variables
export LOGSEQ_API_TOKEN=your_token_here
export LOGSEQ_API_URL=http://localhost:12315

🔍 Verification & Testing

Test LogSeq Connection
uv run --with mcp-logseq python -c "
from mcp_logseq.logseq import LogSeq
api = LogSeq(api_key='your_token')
print(f'Connected! Found {len(api.list_pages())} pages')
"
Verify MCP Registration
claude mcp list  # Should show mcp-logseq
Debug with MCP Inspector
npx @modelcontextprotocol/inspector uv run --with mcp-logseq mcp-logseq

🐛 Troubleshooting

Common Issues
"LOGSEQ_API_TOKEN environment variable required"
  • ✅ Enable HTTP APIs in Settings → Features

  • ✅ Click 🔌 button → "Start server" in LogSeq

  • ✅ Generate token in API panel → Authorization tokens

  • ✅ Verify token in your configuration

"spawn uv ENOENT" (Claude Desktop)

Claude Desktop can't find uv. Use the full path:

which uv  # Find your uv location

Update config with full path:

{
  "mcpServers": {
    "mcp-logseq": {
      "command": "/Users/username/.local/bin/uv",
      "args": ["run", "--with", "mcp-logseq", "mcp-logseq"],
      "env": { "LOGSEQ_API_TOKEN": "your_token_here" }
    }
  }
}

Common uv locations:

  • Curl install: ~/.local/bin/uv

  • Homebrew: /opt/homebrew/bin/uv

  • Pip install: Check with which uv

Connection Issues
  • ✅ Confirm LogSeq is running

  • ✅ Verify API server is started (not just enabled)

  • ✅ Check port 12315 is accessible

  • ✅ Test with verification command above


👩‍💻 Development

For local development, testing, and contributing, see DEVELOPMENT.md.


<div align="center"> <p><strong>Ready to supercharge your LogSeq workflow with AI?</strong></p> <p>⭐ <strong>Star this repo</strong> if you find it helpful!</p> </div>

CHANGELOG.md

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.10.0] - 2026-09-27

Added
  • list_pages shows each page's last-updated time (UTC) and accepts sort ("name" default, or "updated" for most recent first) and updated_since (epoch ms or ISO-8601) to find recently modified pages; limit applies after filtering and sorting (#104)

  • LOGSEQ_WRITE_NAMESPACES (config key write_namespaces): a write allow-list applied on top of the read rules, so an assistant can read a wider area than it may edit. Write tools outside the list are denied with a distinct "read-only" message; block writes check the owning page (fail-closed). Unset keeps today's behavior (#105)

  • Allowed writes are logged at INFO as one Write: tool=<name> page=<name> audit line (page names only, never content) (#105)

Fixed
  • query no longer reports Logseq's ["error"] response (e.g. for raw datalog) as a single result; it returns a clear failure explaining that only simple Logseq DSL is supported (#104)

[1.9.2] - 2026-09-13

Added
  • list_pages accepts an optional limit (alphabetical first N, with a "Showing N of M pages" footer) so a large graph no longer dumps every page name into the client's context (#102)

  • The MCP initialize response now reports the installed package version in serverInfo.version instead of an empty string (#102)

Fixed
  • search no longer reveals excluded matches through counts: Total results found and the file list are derived from the filtered result set in text and JSON output. A namespace- or tag-restricted client used to see the raw match count with nothing listed, which works as an oracle for whether a term appears in hidden pages, and file paths carried hidden page names. While exclude_tags or namespace rules are active, has_more is always false and the "more results available" hint is never shown, because the API's flag describes the unfiltered set; results past limit may be cut off without a hint (#102)

  • Vector sync skips the graph's logseq/ directory and hidden directories. logseq/bak/ backups and logseq/.recycle/ deleted pages were being indexed, so a deleted page stayed searchable under a mangled pages/... title. Stale entries are dropped on the next sync (#102)

  • vector_search score semantics follow the search mode. Hybrid (default) and keyword modes return RRF / BM25 scores where higher is better; they no longer get distance-based relevance labels or the "lower is more relevant" note, which only applies to vector mode. If a hybrid or keyword search fails and falls back to vector-only, the distance note is shown (#102)

  • search, query and list_pages accept a limit sent as a JSON number like 20.0 (JSON Schema treats it as an integer) instead of failing with a TypeError (#102)

  • The "Vector DB not initialized" message from vector_search and vector_db_status now points at logseq-sync --once instead of the sync_vector_db tool, which does not sync (#102)

Documentation
  • README: tool count, missing get_block row, LOGSEQ_VERIFY_SSL. VECTOR_SEARCH.md: how to read scores, what the sync indexes, vector_search is read-only and sync_vector_db only points at the CLI. DEVELOPMENT.md and TESTING.md: current package layout, how to add a tool with an access policy, stderr logging, regenerated test tree (#102)

[1.9.1] - 2026-09-13

Fixed
  • logseq-sync no longer aborts the whole run when a page is deleted or renamed while the sync is in progress. A file that vanishes before hashing is skipped and picked up next run; one that vanishes during embedding is treated as deleted. Previously a single missing file threw away all embedding work of that run and left the index stale (#99, closes #91)

  • search exclusion filtering in DB mode now fails closed: a page result with neither fullTitle nor title is hidden when exclude_tags or namespace rules are active, instead of leaking through via content. Text and JSON output share the same check (#99, closes #57)

Changed
  • _acquire_sync_lock raises RuntimeError on a lock conflict instead of calling sys.exit; the CLI entrypoint decides to exit (#99, closes #37)

  • The sdist now ships only src/ (plus README, LICENSE and pyproject), down from 1.5 MB to about 72 KB. Tests, docs, uv.lock and stray working-tree files are no longer packaged (#99)

[1.9.0] - 2026-09-13

Added
  • Embedding provider API keys can be read from an environment variable via vector.embedder.api_key_env, so the key never has to be written to config.json. Plaintext api_key keeps working (#82, closes #81, by ericfitz)

  • vector.max_chunk_length (default 10000): blocks longer than this are skipped at chunk time instead of being sent to the embedder, which rejected them with a 400 (#97, closes #76)

Changed
  • Breaking (dependency): the server now requires mcp>=2.0,<3 and is ported to the 2.x low-level API, which replaced the @server.list_tools() / @server.call_tool() decorators with constructor-based handler registration. Environments pinned to mcp<2 must upgrade (#92)

  • Potentially breaking: LogSeq(...) now defaults verify_ssl=True (was False), so the safe path is the default. The bundled server is unaffected (it always sets verify_ssl explicitly from the protocol), but external code constructing the client directly against a self-signed HTTPS Logseq endpoint must now pass verify_ssl=False explicitly (#89)

  • Potentially breaking: logging is no longer configured at import time and the server no longer writes ~/.cache/mcp-logseq/mcp_logseq.log by default. The CLI entrypoint now configures stderr logging at INFO (was DEBUG), tunable via LOGSEQ_LOG_LEVEL; file logging is opt-in via LOGSEQ_LOG_FILE. Tool arguments and results are redacted from logs — only tool names, argument keys, and result sizes are recorded, so page/block content (including ACL-gated pages) no longer lands in plaintext logs

Fixed
  • The server no longer crashes on import with 'Server' object has no attribute 'list_tools' (surfacing client-side as MCP error -32000: Connection closed) when mcp 2.x is installed (#92)

  • Tool-call failures still reach the model as in-band error results, and tool arguments are still validated against each tool's inputSchema — the 2.x low-level server does neither on a handler's behalf, so the server does both itself (#92)

  • Block uuids survive a page rewrite. update_page in replace mode used to mint fresh uuids for every block, leaving ((uuid)) references elsewhere in the graph dangling; insertBatchBlock is now called with keepUUID (only when every id parses as an RFC 4122 uuid, since Logseq silently discards the whole batch on a malformed one) and the first block no longer bypasses the batch (#93, by sleeyax)

  • A failed embedding batch is retried one chunk at a time, so a single rejected block no longer drops the other chunks in its batch (#97)

Documentation
  • README: Codex CLI (#94, by sqzhang-jeremy) and OpenCode (#95, from #73 by extrospective) client setup sections

  • VECTOR_SEARCH.md: how to index multiple graphs (#96, closes #75)

Internal
  • Tech-debt cleanup: migrate off the deprecated LanceDB table_names(), commit uv.lock for reproducible installs, remove dead code (_get_page_properties, the remove_block alias), and unify the duplicated list-parser logic (#89)

[1.8.0] - 2026-06-19

Added
  • HTTP/SSE transport — run the server as a networked service with --transport http, secured by bearer-token auth (MCP_HTTP_AUTH_TOKEN). A sandboxed or remote client can now reach Logseq over the network with no filesystem mount or direct Logseq-API access, turning the namespace/tag access control into a real server-side security boundary (#69)

  • Per-profile multi-instance serving — run one process per profile (a shared data config file + a per-process env block of namespace/tag/token + its own port). Adds --read-only to disable all write tools, and tag-on-write guards so writes can't land on a tag-excluded page (#69)

  • Native TLS — --tls-cert/--tls-key serve HTTPS directly (uvicorn ssl_certfile/ssl_keyfile), plus a bind guardrail that refuses non-loopback plain-HTTP binds unless you pass --insecure (#71)

  • New deployment guide at docs/SERVING.md — security model, the per-profile pattern, the separate logseq-sync writer, and TLS / reverse-proxy setup

Changed
  • sync_vector_db is now inert — the vector DB is owned by a single external logseq-sync writer process; the tool points operators at it instead of spawning a sync (#69)

Fixed
  • Block-level results from search (DB mode) and query (tag-only profiles) are now resolved to their owning page and filtered by the namespace/tag ACL, closing cases where restricted block content could surface in block-level results (#69)

  • The page-exclusion set now fails closed when ACL rules are active — if it can't be built, search returns an error instead of unfiltered results (#69)

[1.7.0] - 2026-06-14

Added
  • Namespace-based access control — restrict MCP tool access to specific Logseq namespaces via LOGSEQ_INCLUDE_NAMESPACES and LOGSEQ_EXCLUDE_NAMESPACES environment variables (#65)

  • JSON output format for query and search tools — pass format=json to get raw result objects including block UUIDs and page identifiers for deep linking (#56)

  • Configurable API timeout — set LOGSEQ_API_TIMEOUT environment variable to override the default 30-second timeout for Logseq API calls (#47) — thanks @thisdotrob

Fixed
  • create_page now fails on existing pages instead of silently creating numbered duplicates (e.g. Page (1)); retries are safe (#59)

  • update_page property handling is now graph-type aware, correctly serializing properties for both file-mode and DB-mode graphs (#62)

  • Inline key:: value properties are now correctly attached to their parent list item instead of being treated as top-level blocks (#61) — thanks @sehgalmayank001

[1.6.3] - 2025-04-12

See GitHub releases for earlier history.

85 files · 75 not served here

Advantages

  • Enables direct interaction with Logseq data, eliminating the need for manual file exports or context switching. evidence: README.md
  • Provides granular privacy and access control through tag-based exclusions and namespace allow-lists. evidence: README.md
  • Supports semantic vector search, allowing for discovery of notes by meaning. evidence: README.md

Limitations

  • Requires the Logseq HTTP API server to be manually started and configured within the Logseq application. evidence: README.md
  • Vector search features require additional setup and local embedding resources. evidence: README.md

Security

Risk level: No risk found

This brain runs

MCP servers (2)

  • README.md (mcp-logseq): uv run --with mcp-logseq mcp-logseq
  • README.md (mcp-logseq): /Users/username/.local/bin/uv run --with mcp-logseq mcp-logseq

Attribution and licence

First committed by
GitHub avatar of ergutergut
Declared authors
  • Salih Ergüt (declared in pyproject.toml)
Publisher
Salih Ergut (Community)
Source
ergut/mcp-logseq · commit 0769877
Licence
MIT License (files served here)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Contributors
ergut, RobertoGongora, arndjan, ericfitz, lfnovo

AutoGineer is not affiliated with or endorsed by ergut.

Install from source

75 of its files are not served here, so there is no ZIP. ergut/mcp-logseq at 0769877