AI-powered interactions with Logseq through two interfaces:
- MCP Server - Enables external AI tools (Windsurf, Claude Desktop) to interact with your Logseq graph
- Lain - Embedded AI assistant plugin within the Logseq UI
"No matter where you go, everyone's connected." - Serial Experiments Lain
- Node.js 18+
- Logseq desktop app with HTTP API server enabled (Settings → Features → HTTP APIs server)
# Install dependencies
pnpm install
# Build all packages
pnpm buildimport { LogseqClient, LogseqOperations } from "@logseq-ai/core";
// Create client and operations
const client = new LogseqClient({
baseUrl: "http://localhost:12315",
token: "your-api-token" // optional
});
const ops = new LogseqOperations(client);
// Search for pages
const results = await ops.search("meeting notes");
// Get page content as text
const content = await ops.getPageContent("My Notes");
// Create a new block
const block = await ops.createBlock({
pageName: "My Notes",
content: "New idea from AI!"
});
// Create multiple blocks with hierarchy (more efficient for structured content)
const result = await ops.createBlocks("My Notes", [
{
content: "## Project Overview",
children: [
{ content: "Goal: Build a new feature" },
{ content: "Timeline: Q1 2025" },
]
},
{
content: "## Tasks",
children: [
{ content: "Design the API" },
{ content: "Implement backend" },
{ content: "Write tests" },
]
}
]);
console.log(`Created ${result.created} blocks`);
// Run a Datalog query to find TODOs
const todos = await ops.query(`
[:find (pull ?b [*])
:where [?b :block/marker "TODO"]]
`);import { LogseqClient, LogseqOperations } from "@logseq-ai/core";
const client = new LogseqClient();
const ops = new LogseqOperations(client);
// Get all active tasks
const tasks = await ops.getTasks();
// Get tasks from a specific page
const projectTasks = await ops.getTasks({ pageName: "Project A" });
// Create a new task with priority and deadline
const task = await ops.createTask({
pageName: "Project A",
content: "Review pull request",
priority: "A",
deadline: "2024-12-15"
});
// Mark task as in progress
await ops.markTask(task.uuid, "DOING");
// Complete the task
await ops.markTask(task.uuid, "DONE");
// Set/change priority
await ops.setTaskPriority(task.uuid, "B");
// Set scheduled date
await ops.setTaskScheduled({ uuid: task.uuid, date: "2024-12-10" });
// Remove deadline
await ops.setTaskDeadline({ uuid: task.uuid, date: null });// Get overdue tasks
const overdue = await ops.getOverdueTasks();
console.log(`You have ${overdue.length} overdue tasks`);
// Get tasks due in the next 7 days
const dueSoon = await ops.getTasksDueSoon({ days: 7 });
// Get task statistics
const stats = await ops.getTaskStats();
console.log(`Total: ${stats.total}, Overdue: ${stats.overdue}`);
console.log(`By status:`, stats.byMarker);
// Search tasks by keyword
const reviewTasks = await ops.searchTasks({ query: "review", markers: ["TODO"] });// Get or create today's journal
const today = await ops.getToday();
console.log(`Today's journal: ${today.page.name}`);
// Quick capture to today's journal
await ops.appendToToday("Meeting notes: discussed Q1 roadmap");
// Get recent journal entries
const journals = await ops.getRecentJournals({ days: 7, includeContent: true });
journals.forEach(j => console.log(`${j.date}: ${j.content.substring(0, 50)}...`));// Find pages related to a topic
const links = await ops.findRelatedPages("Project A");
console.log("Pages linking to Project A:", links.backlinks);
console.log("Pages Project A links to:", links.forwardLinks);
// Find blocks referencing a specific block
const backlinks = await ops.getBlockBacklinks("block-uuid-123");
console.log(`Found ${backlinks.backlinks.length} references`);import {
LogseqOperations,
LogseqApiError,
LogseqNotFoundError,
isLogseqError
} from "@logseq-ai/core";
try {
await ops.getPageContent("Nonexistent Page");
} catch (error) {
if (error instanceof LogseqNotFoundError) {
console.log(`Page not found: ${error.identifier}`);
} else if (isLogseqError(error)) {
console.log(`Logseq error: ${error.toDetailedString()}`);
}
}Shared library for Logseq API interactions. Used by both the MCP server and plugin.
Key exports:
LogseqClient- Low-level HTTP client for Logseq APILogseqOperations- High-level operations with error handling- Error classes:
LogseqError,LogseqApiError,LogseqConnectionError,LogseqNotFoundError,LogseqValidationError - Type definitions:
Page,Block,SearchResult, etc.
MCP server that exposes Logseq operations as tools for AI clients.
Features:
- 34 tools for comprehensive Logseq interaction
- Input validation with clear error messages (powered by Zod)
- Proper error handling for Logseq API errors
# Build
pnpm --filter @logseq-ai/mcp-server build
# Run
LOGSEQ_API_TOKEN=your-token pnpm --filter @logseq-ai/mcp-server start
# Test
pnpm --filter @logseq-ai/mcp-server testAdd to your MCP configuration:
{
"mcpServers": {
"logseq": {
"command": "node",
"args": ["/path/to/logseq-ai/packages/mcp-server/dist/index.js"],
"env": {
"LOGSEQ_API_URL": "http://localhost:12315",
"LOGSEQ_API_TOKEN": "your-token"
}
}
}
}Page & Block Operations
| Tool | Description |
|---|---|
search_logseq |
Search for pages and blocks |
get_page |
Get page content as plain text |
get_pages |
Get multiple pages in a batch (more efficient) |
get_page_with_context |
Get page with backlinks and forward links |
list_pages |
List all pages in the graph |
create_page |
Create a new page (optionally with blocks) |
delete_page |
Delete a page |
create_block |
Create a single block |
create_blocks |
Create multiple blocks with hierarchy |
update_block |
Update a block's content |
delete_block |
Delete a block |
query_logseq |
Run Datalog queries |
update_page_properties |
Update properties on an existing page |
Graph Discovery
| Tool | Description |
|---|---|
get_current_graph |
Get current graph info |
get_graph_stats |
Get graph statistics (pages by type, orphans, etc.) |
find_missing_pages |
Find referenced pages that don't exist |
find_orphan_pages |
Find pages with no incoming links |
find_pages_by_properties |
Find pages by property values |
find_related_pages |
Find backlinks and forward links |
get_block_backlinks |
Find blocks referencing a block |
Journal Operations
| Tool | Description |
|---|---|
get_today |
Get today's journal page |
append_to_today |
Add content to today's journal |
get_recent_journals |
Get recent journal entries |
Task Management
| Tool | Description |
|---|---|
get_tasks |
Get TODO/DOING tasks |
create_task |
Create a new task |
mark_task |
Change task status |
mark_tasks |
Change multiple tasks' status (batch) |
search_tasks |
Search tasks by keyword |
get_overdue_tasks |
Get tasks past deadline |
get_tasks_due_soon |
Get tasks due within N days |
get_task_stats |
Get task statistics |
set_task_priority |
Set task priority (A/B/C) |
set_task_deadline |
Set task deadline |
set_task_scheduled |
Set task scheduled date |
When creating pages with multiple sections, use create_blocks for efficiency:
User: Create a page about Python with sections for Overview, Features, and Links
AI uses:
1. create_page("Python", "type:: #Technology\ntags:: #Programming")
2. create_blocks("Python", [
{
content: "## Overview",
children: [
{ content: "Python is a high-level programming language." }
]
},
{
content: "## Features",
children: [
{ content: "Dynamic typing" },
{ content: "Garbage collection" },
{ content: "Large standard library" }
]
},
{
content: "## Links",
children: [
{ content: "[Official Site](https://python.org)" }
]
}
])
Lain - AI assistant plugin for Logseq.
# Build
pnpm --filter logseq-lain build
# Development (watch mode)
pnpm dev:plugin- Enable Developer Mode in Logseq (Settings → Advanced → Developer mode)
- Go to Plugins → Load unpacked plugin
- Select the
packages/logseq-plugindirectory - Use
/lain ask,/lain summarize,/lain expandslash commands
See doc/architecture.md for detailed architecture documentation.
# Build everything
pnpm build
# Run all tests (188 tests)
pnpm test
# Type check all packages
pnpm typecheck
# Lint
pnpm lintMIT