logseq-mcp
Reads a local Logseq DB graph directly from disk, exposing journals, tasks, pages and blocks as indented Markdown outlines, with block screenshots attached as viewable images. Provides read-only tools to fetch a day's journal, look up a task or block by name/id, list tasks by status, tag or date, search blocks by text, retrieve a page, and fetch individual images, plus graph_info to report which graph is being read.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@logseq-mcpget task web-12 from yesterday's call, with the screenshot"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
logseq-mcp
Lets your AI agent read your Logseq notes, screenshots included, straight from the graph on disk. No running app, no HTTP API, no token, and no way to modify a single note: it is read-only by construction.
You say "do web-12 from yesterday's call" and the agent opens the note itself:
get_task("web-12", date="2026-09-28")
- web-12 [Doing] ‹3f9c21d7›
- The hero image is blurry on mobile
- [image 1] this one
- Contact form sends twice
[image 1] ← the screenshot itself, as an image the model can seeWhy it exists
I take notes in Logseq all day. In client meetings each request becomes a block
named after the project (web-12), with screenshots pasted underneath and
captions like "this one" or "same here". Those notes are the real spec: the
screenshot says which button, the text says what is wrong with it.
Then I open my coding agent and explain it all over again, and the detail is lost in the retelling. I wanted the agent to read the note itself, and above all to look at the screenshots, because the caption alone means nothing. A sentence that sounds perfectly clear, "not the one on top", is ambiguous on a screen with three similar controls. The screenshot settles it.
Logseq's new DB version no longer stores Markdown files, so there is nothing to grep. The existing Logseq MCP servers go through the app's local HTTP API, which means keeping Logseq open, the API server started and a token configured. I wanted something that works from any terminal, with Logseq closed, and that cannot touch my notes by accident.
Related MCP server: Obsidian MCP Second Brain Server
What it does
Journals, tasks, pages and blocks as indented Markdown outlines, in the order you wrote them.
Screenshots come attached as image content, numbered where they appear in the outline, so "this one" keeps pointing at the right picture.
Tasks by status, by tag (on the task or any parent block) or by day. The same task name on several days is expected, not an error.
Reads while Logseq is running, including the notes from the last minutes.
Read-only. It never opens the real database for writing: it reads a copy.
No network. The graph never leaves the machine.
How it works
db.sqlite + WAL ──► snapshot ──► kvs B-tree from the root ──► transit ──► datoms
(locked by Logseq) (copy) (current state only) decode │
▼
MCP tools ◄── outline + images ◄── graphLogseq DB keeps a datascript database
serialized into a single SQLite table, kvs(addr, content, addresses). There is
no public spec for that layout. A reader for an undocumented format mostly fails
quietly: the output looks fine and is wrong. Most of this code exists to turn
quiet failures into loud ones.
Only the current state
kvs is a persistent B-tree. Every write adds new nodes and leaves the old ones
behind until Logseq garbage-collects them. The obvious approach, decoding every
row, works on the first try and is wrong: it resurrects half-typed blocks that no
longer exist, mixed with the real ones, and nothing looks off.
The row at addr = 0 is the root. It holds the address of each index and, in
:eavt-metadata, how many datoms the index must contain. The reader walks
:eavt from the root down to the leaves, ignores every row that is not
reachable, and counts. If the count does not match what the root declares, it
stops: a Logseq update changed the format, and a tree that looks complete and
isn't is worse than an error.
Transit's string cache
Each row is a transit-json document. Transit replaces strings it has already seen
with back-references like "^1", and map keys enter that cache before their
values. Decode a pair in a single Python expression, out[key()] = value(), and
the right-hand side runs first: the cache fills in the wrong order, every later
reference shifts by one, and attribute names come out where values should be.
The decoder does it in two statements and there is a test for exactly that case.
As a second guard, any datom whose attribute is not a keyword aborts the read.
Reading a database that is still open
Logseq holds the file while it runs.
VACUUM INTO was the first attempt: database is locked.
SQLite's backup API was the second: it blocks, waiting for a lock that never comes.
What shipped: copy the files and read the copy. It has to be db.sqlite
together with its WAL, because the last minutes of notes live in the WAL
until a checkpoint. Without it the reader returns a graph that is slightly in
the past, with no sign of it. A hot copy can catch Logseq mid-write, so the copy
goes through integrity_check and is retried once.
The server keeps the decoded graph in memory and reloads it only when the size or modification time of the database or its WAL has changed.
Screenshots are part of the note
Image blocks point to assets/<uuid>.<ext>. The outline marks them as
[image N] right where they sit, and the files are attached after the text in
the same order, so the model reads the caption and sees the picture together.
Up to 8 per call. The rest are one get_image away, with their ids in the
outline.
Install
Requires Python 3.12+ and uv. Tested on macOS with Logseq 2.0.1.
git clone https://github.com/joseguzmann/logseq-mcp.gitIn Claude Code:
claude mcp add logseq -- uv run --directory /path/to/logseq-mcp logseq-mcpIn Claude Desktop, Cursor or any other MCP client:
"logseq": {
"command": "uv",
"args": ["run", "--directory", "/path/to/logseq-mcp", "logseq-mcp"]
}Flag | Env var | Default |
|
|
|
|
| the only graph, if there is just one |
|
| none: only blocks tagged |
|
|
A trap worth knowing. Not every task is tagged
#Task. If you name tasks the way I do and only sometimes tag them,--task-pattern '[a-z][a-z-]*-\d+'makesweb-12count as a task too. Without it, those tasks simply don't show up inlist_tasks, and nothing says why.
Tools
All of them are annotated read-only.
Tool | Returns |
| A day's journal, with its screenshots. |
| A block by its exact text, with its subtree. If the name repeats, the candidates instead of a guess. |
| A block by the |
| Tasks, filtered by status, tag or day. |
| Blocks containing a text, most recent first. |
| A regular page. |
| One screenshot. |
| Which graph is being read and what is in it. |
What to expect
Measured on my own graph: 16,354 datoms, 1,557 entities, 43 journals.
Call | Time |
First call (snapshot + decode + build) | ~60 ms |
Listing or search, graph already loaded | < 10 ms |
A day with 8 screenshots attached (~4 MB) | ~0.6 s |
Every journal in that graph was cross-checked against an independent reader, block by block. The test suite itself runs on synthetic graphs, so it needs neither Logseq nor anybody's notes.
Layout
File | What it solves |
| Decoding transit-json, including the string cache and its ordering |
| Snapshotting a locked database, walking the index, refusing partial data |
| Blocks, pages, journals, inherited tags, task status, image files, outlines |
| The MCP tools, and reloading only when Logseq has written |
| Synthetic graphs with the real on-disk layout, stale rows and all |
Limitations
DB graphs only. For the classic Markdown version, the files are a better source than any server.
Read-only, on purpose. Writing to Logseq's internal format behind the app's back is how you corrupt a graph.
The format is internal and can change with any Logseq release. When it does, the reader stops with a clear error instead of returning partial data.
Block references inside text are resolved to page titles; queries, embeds and properties other than status and tags are not rendered.
Development
uv sync
uv run pytest
uv run ruff check .License
MIT.
Available Tools
8 toolsget_blockBRead-onlyIdempotent
A block by id (the ‹abcd1234› shown in outlines, or a full uuid) with its subtree.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ||
| include_images | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, openWorldHint=false, and idempotentHint=true, so safety and idempotency are covered. The description usefully adds that the result is the block plus its subtree, but says nothing about depth, pagination, or how include_images affects the payload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that names the resource, the identifier formats, and the returned scope with zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and an undocumented optional parameter, this is only minimally complete: the id is well explained but include_images (default true) and the extent of the subtree returned are left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the parameter burden. It clarifies the required id format (outline-style ‹abcd1234› or a full uuid), which is real added value, but leaves include_images entirely unexplained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (a block) and scope (with its subtree), so the agent knows it returns a tree rather than a flat record. It does not differentiate itself from siblings like get_page or get_task, leaving the agent to infer which retrieval tool applies.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance and no mention of alternatives such as get_page or search for locating a block. The only implicit signal is the id format, which tells the agent what to supply rather than when to choose this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_imageCRead-onlyIdempotent
One screenshot by the id shown next to it.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint=true, idempotentHint=true, openWorldHint=false). The description adds only that a single image is returned, but says nothing about the return format (raw bytes vs URL vs metadata), image type, or any size/rate constraints that an agent would need.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no filler, and the resource is front-loaded. It is efficient, though its brevity contributes to the ambiguity elsewhere.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations about the response, the description should explain what the agent receives (image data, URL, or metadata) and how the id is sourced. It omits both, leaving the definition inadequate for a retrieval tool whose payload is its whole point.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the single 'id' parameter is undocumented in structured data. The description's 'the id shown next to it' adds only marginal meaning and does not specify the id's format or origin, failing to compensate for the coverage gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (one screenshot/image) and implies retrieval by id, so the gist is discernible. However, 'the id shown next to it' is vague about where that id comes from, and there is no differentiation from siblings like get_block, get_task, or get_page that also fetch entities by id.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus the sibling get/list tools, nor any prerequisites about needing an id obtained elsewhere. The phrase 'the id shown next to it' hints at a prior listing context but does not state it as a condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_journalCRead-onlyIdempotent
The journal page of one day as an outline, with its screenshots.
date: "today", "yesterday" or YYYY-MM-DD.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | today | |
| include_images | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and closed-world, so the safety profile is covered. The description adds that the return is an outline with screenshots, but says nothing about behavior for a day with no journal, page size, or how image inclusion affects the payload.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very short and front-loaded: the resource description comes first, then a compact format note. The dangling 'with its screenshots' fragment is slightly awkward but costs little.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Two params, no output schema, and no annotations-driven explanation of return structure. It states the date format but that alone is thin; return shape, error cases and image behavior are all unaddressed for a tool whose entire value is the shape of what it returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage the description must carry the load; it documents the date parameter's accepted formats ('today', 'yesterday', YYYY-MM-DD), which the schema does not. However, include_images is never explained beyond the oblique 'with its screenshots' phrase, leaving the second parameter's semantics implicit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific resource (the journal page of one day) and its return shape (an outline plus screenshots), which distinguishes it from get_page and get_block. It never explicitly names a sibling it is not, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance and no mention of alternatives like get_page or search. The only conditional context is the accepted date values, which is parameter syntax rather than usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_pageBRead-onlyIdempotent
A regular (non-journal) page by title, case-insensitive.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| include_images | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered structurally. The description adds one genuine behavioral trait, case-insensitive title matching, but says nothing about what a page contains, what happens on a miss, or what include_images does. With annotations carrying the safety burden, a 3 is appropriate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single tight sentence with the key lookup qualifier front-loaded. Efficient, though the extreme brevity leaves room that could have been spent on the undocumented parameter.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter lookup with no output schema this is roughly adequate, but the absence of any note on the include_images parameter or miss behavior leaves an agent guessing about one of the two inputs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description carries the full burden. It adds real semantics for 'title' (case-insensitive matching) but is completely silent on 'include_images', whose boolean default of true and effect on the response are undocumented anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names the resource (a regular page) and the lookup key (title), and explicitly excludes journal pages, which routes the agent away from the sibling get_journal. The verb is only implied by the name, but the scope is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The parenthetical '(non-journal)' implies when to use this versus get_journal, but it never states the condition explicitly or names the alternative tool. Usage is inferable rather than instructed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_taskBRead-onlyIdempotent
A block by its exact text (e.g. a task called "web-12") with everything under it.
Names are often reused on different days; pass date (YYYY-MM-DD) to pick one.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | ||
| name | Yes | ||
| include_images | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so safety and repeatability are covered structurally. The description adds useful behavioral context about lookup being exact-text and names being non-unique across days, but says nothing about what happens on no-match, ambiguity, or return size for large subtrees.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very short and front-loaded, which is good, but the first sentence is a fragment with no verb and the indented second paragraph reads as leftover formatting rather than deliberate structure. It is terse without being fully tight.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only lookup with no output schema, the essentials (how the block is identified, how to disambiguate, that the subtree comes along) are present. Missing pieces are the include_images behavior and any routing versus get_block/get_page, leaving an agent with avoidable ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% and there are 3 parameters, so the description carries the full burden. It explains date well (format and disambiguating purpose) and implicitly covers name via 'exact text', but include_images is documented nowhere — neither schema nor description explains its effect on the result.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the resource and the selection rule clearly: a block located by its exact text, returned together with its subtree ('everything under it'). The example ('web-12') grounds the exact-match semantics. It does not differentiate itself from the sibling get_block, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one concrete usage rule — pass date (YYYY-MM-DD) when a name is reused on different days. That is real guidance, but there is no statement of when to prefer this over get_block, list_tasks, or search, which are the obvious alternatives for the same kind of lookup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
graph_infoBRead-onlyIdempotent
Which graph is being read, how big it is and which days have journals.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and openWorldHint=false, so the safety profile is covered without description help. The description adds modest value by disclosing the shape of the payload (graph identity, size, journal days), but says nothing about cost, freshness, or scope limits. Adequate against a low annotation bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single short sentence with no waste, and the returned-field list is front-loaded. It is a sentence fragment rather than a proper statement, which slightly weakens the phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be enumerated here, and annotations carry the safety semantics. With zero parameters, the remaining burden is simply identifying the tool's role, which the description roughly does. The missing piece is routing guidance relative to its many siblings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4; there is no argument surface for the description to clarify or obscure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (graph) and enumerates what is returned: current graph identity, size, and days containing journals. However, it opens with an interrogative fragment ('Which graph is being read') rather than a clear verb+resource statement, and it does nothing to distinguish this from siblings like get_journal or list_tasks. The purpose is inferable but not crisply stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no indication of when to call this versus alternatives, no preconditions, and no mention of siblings such as get_journal or list_tasks. The agent must guess that this is the discovery/orientation call rather than a journal-content call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tasksARead-onlyIdempotent
Tasks in the graph, oldest first. Filter by status (Todo, Doing, Done...), by tag (tags on the task or any parent block) or by journal day.
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | ||
| date | No | ||
| limit | No | ||
| status | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so safety is covered. The description adds real behavioral detail beyond that: results are ordered oldest first, and tag filtering includes tags on the task or any parent block – inheritance semantics that are not in the schema or annotations. It omits the default limit of 50 and any pagination behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with zero filler; the ordering constraint is front-loaded and the filter options follow immediately. Every clause carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, but with 0% schema coverage the description should have covered the limit/cap parameter and the date string format for 'journal day'. It is adequate but leaves gaps an agent may need to guess about.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must carry the params. It clarifies status values (Todo, Doing, Done...), the inheritance semantics of tag, and that date means 'journal day', but leaves limit entirely unexplained despite its default of 50.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the resource clearly ('Tasks in the graph') and the ordering ('oldest first'), which an agent can use immediately. It doesn't name siblings like get_task or search, but the listing scope distinguishes it implicitly from the single-item get_task.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by enumerating the available filters (status, tag, journal day), which tells an agent what contexts this tool serves. However, it offers no explicit when-to-use vs. alternatives guidance, e.g., when to prefer search or get_task over listing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-onlyIdempotent
Blocks whose text contains query (case-insensitive), most recent journals first.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, so the safety profile is covered. The description adds genuinely new behavior: matching is case-insensitive and results are returned most-recent-journals-first, which is exactly the ordering information an agent needs to interpret output. It stops short of describing pagination or result breadth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the matching rule and appends the ordering constraint. No filler, no restatement of the name, every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and one required parameter is documented. The gaps are the undocumented 'limit' parameter and the unspecified scope of the search (which journals/blocks are searched). Enough to call it, but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It clarifies the semantics of 'query' (substring match, case-insensitive) but says nothing about 'limit' — its default of 20, any maximum, or what happens when more matches exist. Partial compensation, so a middle score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific resource (blocks), the matching rule (text contains query, case-insensitive), and the result ordering (most recent journals first). It is clearly distinguishable from the get_*/list_* siblings, which retrieve known entities rather than search by text. It is not a tautology, though it never uses an explicit verb like 'search'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the tool for free-text lookup of blocks, and no sibling offers an alternative search path. However, there is no explicit when-to-use/when-not statement, no mention of scope (all journals vs. a workspace), and no guidance about repeated or alternate queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
get_block - First observed
get_image - First observed
get_journal - First observed
get_page - First observed
get_task - First observed
graph_info - First observed
list_tasks - First observed
search
TDQS
Scored across 8 tools
Each tool maps to a distinct resource or input type: graph metadata, journal, page, block-by-id, task-by-text, search, image. The main overlap is get_block/get_task (both fetch blocks with subtrees) and get_task/search (both locate by text), but the id-vs-exact-text-vs-substring distinction and the descriptions make boundaries workable.
Strong snake_case convention with get_/list_ verb prefixes (get_journal, get_block, get_task, get_page, get_image, list_tasks). Minor deviations: graph_info is noun-only and search has no verb/noun pairing, but they remain readable and predictable.
Eight tools is a well-scoped set for browsing a Logseq graph, with each tool earning its place. No redundant or filler tools.
Read coverage is solid (graph info, journals, pages, blocks, tasks, search, images), but the surface appears read-only with no create/update/delete for blocks, tasks, or pages, and no list_pages/list_journals enumeration. Agents can browse but cannot modify or fully enumerate the graph.
Maintenance
Related MCP Connectors
Personal context for every AI: search, read, and write back to your private Markdown library.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Personal wiki and memory layer for AI assistants. Persistent, structured memory across sessions.
Search and reason over your Obsidian-style Markdown vault, right from ChatGPT.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that provides AI assistants with structured access to your Logseq knowledge graph, enabling retrieval, searching, analysis, and creation of content within your personal knowledge base.70-
- AlicenseNot gradedqualityBmaintenanceEnables read-only access to Obsidian vaults with semantic search, tag filtering, and metadata queries. Provides secure, intelligent note retrieval and summarization for LLMs without modifying your vault.18 npm13ISC
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with your local Logseq knowledge base through advanced search, content creation, template management, and knowledge organization with privacy-first, local-only operations.24 npm7MIT
- AlicenseBqualityCmaintenanceEnables AI assistants like Claude to directly read, write, search, and navigate your local Logseq knowledge graph, including managing journals, pages, backlinks, and page relationships without manual copy-pasting.1114 npm6MIT