logseq-api-mcp

gustavo-meilus/logseq-api-mcp

3.4

If you are the rightful owner of logseq-api-mcp and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Logseq API MCP Server facilitates seamless integration between Model Context Protocol clients and Logseq knowledge bases, enabling AI assistants to interact with Logseq notes.

Tools
6
Resources
0
Prompts
0

Logseq API MCP Server

Model Context Protocol server for Logseq API integration with dynamic tool discovery

Python Version MCP UV Tests Quality

Table of Contents

Overview

The Logseq API MCP Server provides seamless integration between Model Context Protocol clients and Logseq knowledge bases. This server enables AI assistants and other MCP clients to interact with your Logseq notes, extract educational content, analyze knowledge relationships, and work with structured information through a comprehensive set of specialized tools.

πŸš€ Key Innovation: Features a dynamic tool discovery system that automatically detects, imports, and registers any new tools added to the src/tools/ directory - zero configuration required!

Perfect for:

  • πŸ“š Educational Content Management - Extract and organize flashcards and study materials
  • πŸŽ“ Learning Systems - Build AI-powered study assistants and spaced repetition tools
  • πŸ” Knowledge Base Analysis - Discover relationships and patterns in your notes
  • πŸ“Š Content Discovery - Navigate complex knowledge graphs with AI assistance
  • 🧠 Academic Research - Analyze course materials and learning resources

Features

πŸ› οΈ Core Tools (9 Available)

Read Operations
  1. get_all_pages - Complete page listing with metadata
  2. get_page_blocks - Hierarchical block structure analysis
  3. get_page_links - Page relationship and reference discovery
  4. get_block_content - Detailed block content with children
  5. get_all_page_content - Comprehensive page content extraction
  6. get_linked_flashcards - Advanced flashcard collection and analysis
Write Operations
  1. append_block_in_page - Append blocks to pages with positioning options
  2. create_page - Create new pages with properties and format
  3. edit_block - Edit existing blocks with content, properties, and cursor control

πŸ”„ Dynamic Tool Discovery

  • Auto-Discovery - Automatically finds and imports tools from src/tools/
  • Zero Configuration - No manual imports or registrations needed
  • Instant Integration - New tools are immediately available
  • CI Validation - Automated testing ensures all tools work correctly

🎯 Optimized for AI/LLM Consumption

  • Clean Structured Output - Emoji-enhanced, hierarchical formatting
  • Educational Content Focus - Specialized flashcard and learning material extraction
  • Comprehensive Metadata - Block IDs, UUIDs, timestamps, properties, and relationships
  • Smart Content Organization - Automatic categorization and summary generation
  • Language Agnostic - Works with any Logseq knowledge base language

Installation

Prerequisites

  • Python 3.11+ - Modern Python with async/await support
  • uv - Fast Python package manager and project management
  • Running Logseq instance with API enabled
  • Logseq API token for authentication

Quick Setup

  1. Clone the repository

    git clone https://github.com/gustavo-meilus/logseq-api-mcp.git
    cd logseq-api-mcp
    
  2. Install with uv

    uv sync
    
  3. Configure environment

    cp .env.template .env
    # Edit .env with your Logseq API details
    
  4. Start the server

    uv run mcp run src/server.py
    

Configuration

Create a .env file in the project root:

# Logseq API Configuration
LOGSEQ_API_ENDPOINT=http://127.0.0.1:12315/api
LOGSEQ_API_TOKEN=your_api_token_here

Getting Your Logseq API Token

  1. Open Logseq application
  2. Go to Settings β†’ Features β†’ Developer mode
  3. Enable "HTTP APIs server"
  4. Copy the displayed API token
  5. Note the API endpoint (default: http://127.0.0.1:12315/api)
  6. Activate the API

Available Tools

ToolDescriptionOutputBest For
get_all_pagesLists all pages with essential metadata568 pages (135 journal, 433 regular)Navigation, page discovery
get_page_blocksHierarchical block tree structureMulti-level tree with IDs, UUIDsStructure analysis, navigation
get_page_linksPages linking to target pageReference analysis with metadataRelationship discovery
get_block_contentDetailed block info with childrenBlock content + immediate childrenDeep content analysis
get_all_page_contentComplete page content + referencesFull content with linked sourcesComprehensive content review
get_linked_flashcardsFlashcards from page + linked pages20 flashcards across 2 pagesStudy material extraction
append_block_in_pageAppend blocks to pages with positioningSuccess confirmation with detailsContent creation, organization
create_pageCreate new pages with propertiesPage creation confirmationPage management, structure
edit_blockEdit existing blocks with full controlEdit confirmation with changesContent modification, updates

Tool Details & Examples

πŸ—‚οΈ get_all_pages

Purpose: Get a clean listing of all pages in your knowledge base

Output Format:

πŸ“Š LOGSEQ PAGES LISTING
πŸ“ˆ Total pages: 568
πŸ“… Journal pages: 135
πŸ“„ Regular pages: 433

πŸ“„ REGULAR PAGES:
πŸ“„ Domain Driven Design (DDD) I | ID: 3460 | UUID: 682cfd19-7df6-46e0-a6f3-c09eca3b2530
πŸ“„ MBA Engenharia de Software | ID: 170 | UUID: 682fa28c-a3cc-47f2-ae65-7b7db57e1d67

Use Cases:

  • Knowledge base exploration
  • Page inventory and organization
  • Finding specific pages by name or metadata

🌳 get_page_blocks

Purpose: Get hierarchical block structure of any page

Example Input: "Domain Driven Design (DDD) I"

Output Features:

  • Tree structure with indentation levels
  • Block IDs, UUIDs, and parent-child relationships
  • Property extraction and metadata
  • Multi-level hierarchy support (up to 8+ levels)

Sample Output:

🌳 PAGE BLOCKS TREE STRUCTURE
πŸ“„ Page: Domain Driven Design (DDD) I (ID: 3460)
πŸ“Š Total blocks: 1

πŸ“‹ tipo:: #aula curso:: [[MBA Engenharia de Software]]
   πŸ“Š ID:3544 | UUID:682cfd19-2826-46b7-8222-0821b11abc60 | Level:1
   πŸ‘‡ Children: 7

  H1 # Flashcards [heading: 1]
     πŸ“Š ID:3552 | UUID:682cfd19-4c9c-40dd-8cb1-c2625315b8ae | Level:2
     πŸ‘‡ Children: 10

πŸ”— get_page_links

Purpose: Find all pages that link to a target page

Example Result for "Domain Driven Design (DDD) I":

πŸ”— PAGE LINKS ANALYSIS
πŸ“„ Target Page: Domain Driven Design (DDD) I
πŸ“Š Found 1 pages linking to this page

πŸ“„ 1. Domain Driven Design (DDD) II
   πŸ”‘ ID: 3588 | UUID: 682cfd19-3a24-4636-a5d5-c62ea57d352e
   πŸ“Š References: 1 | Journal: No
   βš™οΈ Properties: relacionado: Domain Driven Design (DDD) I

Applications:

  • Discover related content and cross-references
  • Build knowledge maps and relationship graphs
  • Find course sequences and learning paths

πŸ” get_block_content

Purpose: Get detailed information about a specific block and its immediate children

Example Input: UUID 682cfd19-3c3f-427c-a0be-c5a3a197ea20

Output:

πŸ” MAIN BLOCK
πŸ“Œ Block ID: 3465
πŸ”‘ UUID: 682cfd19-3c3f-427c-a0be-c5a3a197ea20

πŸ“ CONTENT:
πŸ’‘ Flashcard
Por que o DDD prioriza a colaboraΓ§Γ£o entre desenvolvedores e especialistas do domΓ­nio? #card
+ [ ] Porque os especialistas do domΓ­nio sΓ£o responsΓ‘veis apenas por aprovar a infraestrutura tecnolΓ³gica.
+ [ ] Para garantir que o software seja construΓ­do com base no conhecimento profundo do domΓ­nio, reduzindo ambiguidades e erros.

πŸ‘Ά IMMEDIATE CHILDREN:
πŸ”Έ CHILD 1:
Resposta Correta: Para garantir que o software seja construΓ­do com base no conhecimento profundo do domΓ­nio, reduzindo ambiguidades e erros.

πŸ“– get_all_page_content

Purpose: Extract comprehensive content from a page including properties, blocks, and linked references

Key Features:

  • Complete hierarchical content structure
  • Property extraction and formatting
  • Flashcard identification and extraction
  • Linked references analysis
  • Educational content optimization

Example Summary:

πŸ“– Domain Driven Design (DDD) I
πŸ“Š 1 blocks | 1 linked sources

πŸ“„ COMPREHENSIVE CONTENT:
πŸ“„ Page Properties [3544]
   πŸ“‹ curso: MBA Engenharia de Software | tipo: aula | professor: Guilherme Bezerra de Lima

🎯 # Flashcards [3552]
   πŸ’‘ Flashcard [3465]
      ❓ Q: Por que o DDD prioriza a colaboraΓ§Γ£o entre desenvolvedores e especialistas do domΓ­nio?

✏️ append_block_in_page

Purpose: Append new blocks to any page with precise positioning control

Key Features:

  • Positioning Options - Insert before specific blocks, as siblings, or at page end
  • Page-level Blocks - Support for page-level block creation
  • Content Flexibility - Support for any text content including markdown
  • Immediate Feedback - Detailed confirmation with positioning information

Example Usage:

# Basic block append
await append_block_in_page("My Page", "New content here")

# Positioned before specific block
await append_block_in_page("My Page", "Important note", before="block-uuid-123")

# As sibling of another block
await append_block_in_page("My Page", "Related content", sibling="block-uuid-456")

# Page-level block
await append_block_in_page("My Page", "Page property", is_page_block=True)

Output Example:

βœ… **BLOCK APPENDED SUCCESSFULLY**
πŸ“„ Page: My Page
πŸ“ Content: New content here
πŸ“ Positioned: At the end of the page
πŸ”— **NEXT STEPS:**
β€’ Check your Logseq graph to see the new block
β€’ Use get_page_blocks to verify the block was added
β€’ Use get_block_content to get details of the new block

πŸ“„ create_page

Purpose: Create new pages with custom properties and formatting

Key Features:

  • Property Support - Add custom properties and metadata
  • Format Options - Support for markdown and org formats
  • Journal Detection - Automatic journal page recognition
  • Comprehensive Metadata - Full page entity information

Example Usage:

# Basic page creation
await create_page("New Page")

# With properties
properties = {"status": "active", "priority": "high"}
await create_page("Project Page", properties=properties)

# With format specification
await create_page("Org Page", format="org")

# Complete page with all options
await create_page("Complete Page", properties=properties, format="markdown")

Output Example:

βœ… **PAGE CREATED SUCCESSFULLY**
πŸ“„ Page: New Page
βš™οΈ Properties set: 2 items
πŸ“ Format: markdown
πŸ”— **NEXT STEPS:**
β€’ Check your Logseq graph to see the new page
β€’ Use get_all_pages to verify the page was created
β€’ Use get_page_blocks to start adding content

✏️ edit_block

Purpose: Edit existing blocks with full control over content, properties, and behavior

Key Features:

  • Content Editing - Modify block content with preview
  • Property Management - Add, update, or remove block properties
  • Cursor Control - Position cursor at specific locations
  • Focus Management - Control block focus after editing

Example Usage:

# Edit content only
await edit_block("block-uuid-123", content="Updated content")

# Update properties
properties = {"status": "completed", "priority": "high"}
await edit_block("block-uuid-123", properties=properties)

# Set cursor position and focus
await edit_block("block-uuid-123", cursor_position=10, focus=True)

# Complete edit with all options
await edit_block("block-uuid-123",
                content="New content",
                properties=properties,
                cursor_position=5,
                focus=True)

Output Example:

βœ… **BLOCK EDITED SUCCESSFULLY**
πŸ”‘ Block UUID: block-uuid-123
πŸ“ **UPDATED CONTENT:**

New content

βš™οΈ **UPDATED PROPERTIES:**
β€’ status: completed
β€’ priority: high
πŸ“ Cursor positioned at index 5
🎯 Focus: Enabled
πŸ”— **NEXT STEPS:**
β€’ Check your Logseq graph to see the updated block
β€’ Use get_block_content to verify the changes
β€’ Continue editing or add more content

🧠 get_linked_flashcards

Purpose: Comprehensive flashcard extraction from target page and all linked pages

Real Example Results for "Domain Driven Design (DDD) I":

🎯 LINKED FLASHCARDS ANALYSIS
πŸ“„ Target Page: Domain Driven Design (DDD) I
πŸ”— Searched 2 pages (target + 1 linked)
πŸ’‘ Found 20 flashcards total

πŸ“š Domain Driven Design (DDD) I (10 flashcards)
πŸ“š Domain Driven Design (DDD) II (10 flashcards)

πŸ“Š SUMMARY:
β€’ Total flashcards: 20
β€’ Total answer blocks: 0
β€’ Pages with flashcards: 2
β€’ Average answers per flashcard: 0.0

Advanced Features:

  • Multi-choice question support
  • Answer block extraction and linking
  • Cross-page flashcard discovery
  • Educational metadata preservation
  • Learning system integration ready

Usage Examples

Add to your Claude Desktop MCP settings (~/.claude/claude_desktop_config.json):

{
  "mcpServers": {
    "logseq-api": {
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/path/to/logseq-api-mcp",
        "python",
        "src/server.py"
      ],
      "env": {
        "LOGSEQ_API_ENDPOINT": "http://127.0.0.1:12315/api",
        "LOGSEQ_API_TOKEN": "your_token_here"
      }
    }
  }
}

Note: Replace /path/to/logseq-api-mcp with the actual path to your cloned repository.

Development

Project Structure

logseq-api-mcp/
β”œβ”€β”€ .github/
β”‚   β”œβ”€β”€ workflows/             # GitHub Actions CI/CD
β”‚   β”‚   β”œβ”€β”€ test.yml           # Main test suite
β”‚   β”‚   β”œβ”€β”€ pr-validation.yml  # PR validation
β”‚   β”‚   β”œβ”€β”€ comprehensive-test.yml # Extended testing
β”‚   β”‚   └── quality.yml        # Code quality & security
β”‚   β”œβ”€β”€ ISSUE_TEMPLATE/        # Issue templates
β”‚   └── pull_request_template.md # PR template
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ server.py              # MCP server implementation
β”‚   β”œβ”€β”€ registry.py            # Dynamic tool discovery & registration
β”‚   └── tools/                 # Tool implementations (auto-discovered)
β”‚       β”œβ”€β”€ __init__.py        # Dynamic tool importer
β”‚       β”œβ”€β”€ get_all_pages.py   # Page listing tool
β”‚       β”œβ”€β”€ get_page_blocks.py # Block structure tool
β”‚       β”œβ”€β”€ get_page_links.py  # Page links tool
β”‚       β”œβ”€β”€ get_block_content.py # Block detail tool
β”‚       β”œβ”€β”€ get_all_page_content.py # Complete content tool
β”‚       β”œβ”€β”€ get_linked_flashcards.py # Flashcard extraction tool
β”‚       β”œβ”€β”€ append_block_in_page.py # Block creation tool
β”‚       β”œβ”€β”€ create_page.py     # Page creation tool
β”‚       └── edit_block.py      # Block editing tool
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ conftest.py            # Shared test fixtures
β”‚   β”œβ”€β”€ test_append_block_in_page.py # Block creation tests
β”‚   β”œβ”€β”€ test_create_page.py    # Page creation tests
β”‚   β”œβ”€β”€ test_edit_block.py     # Block editing tests
β”‚   β”œβ”€β”€ test_get_tools.py      # Read operation tests
β”‚   β”œβ”€β”€ test_mcp_server.py     # Server validation tests
β”‚   β”œβ”€β”€ test_runner.py         # Test runner utility
β”‚   └── TEST_SUMMARY.md        # Test documentation
β”œβ”€β”€ pyproject.toml             # UV project configuration
β”œβ”€β”€ .env.template              # Environment template
└── README.md                  # This file

Development Setup

# Install with development dependencies
uv sync --dev

# Format code (auto-fixes issues)
uv run ruff check --fix && uv run ruff format

# Test server with MCP inspector
uv run mcp dev src/server.py

# Run server directly
uv run mcp run src/server.py

Adding New Tools

Thanks to the dynamic discovery system, adding new tools is incredibly simple:

1. Create Your Tool File

Create src/tools/your_new_tool.py:

def your_new_tool(param: str) -> dict:
    """
    Your tool description here.

    Args:
        param: Description of parameter

    Returns:
        Dict with tool results
    """
    return {
        "result": f"Processed: {param}",
        "status": "success"
    }

2. That's It! πŸŽ‰

The system automatically:

  • βœ… Discovers your tool file
  • βœ… Imports the function
  • βœ… Registers it with the MCP server
  • βœ… Validates it in CI tests

Tool Requirements

  • File location: Must be in src/tools/ directory
  • Function visibility: Don't start function names with _
  • File naming: Don't start filenames with _
  • Documentation: Include docstring with description
  • Type hints: Use for better IDE support

Dynamic Discovery Process

New Tool File β†’ Auto-Scan β†’ Import β†’ Registration β†’ Validation
  1. Auto-Scan: src/tools/__init__.py scans directory for .py files
  2. Import: Dynamically imports all public functions
  3. Registration: src/registry.py auto-registers with MCP server
  4. Validation: Tests automatically verify tool presence

Testing

Automated Testing

The project includes comprehensive automated testing with 68 test cases covering all functionality:

# Run the full test suite
uv run pytest tests/ --cov=src/tools --cov-report=html

# Run specific tool tests
uv run python tests/test_runner.py --tool append_block_in_page
uv run python tests/test_runner.py --tool create_page
uv run python tests/test_runner.py --tool edit_block

# Run server validation
uv run python tests/test_mcp_server.py

Test Coverage:

  • βœ… 68 Test Cases - Comprehensive coverage of all 9 tools
  • βœ… Server Health - Ensures MCP server starts correctly
  • βœ… Tool Discovery - Validates automatic tool detection
  • βœ… Dynamic Registration - Confirms all tools are registered
  • βœ… Write Operations - Tests for append, create, and edit tools
  • βœ… Read Operations - Tests for all get_* tools
  • βœ… Error Handling - HTTP errors, network issues, edge cases
  • βœ… CI Integration - Runs automatically on all commits
  • βœ… Coverage Reporting - 80% minimum coverage requirement

Manual Testing

# Test with MCP Inspector (interactive)
uv run mcp dev src/server.py

# Direct server testing
uv run mcp run src/server.py

Test Output Example

πŸ” Testing MCP Server Health and Tools...
πŸ”§ Discovered tools (auto-discovery): ['append_block_in_page', 'create_page', 'edit_block', 'get_all_page_content', 'get_all_pages', 'get_block_content', 'get_linked_flashcards', 'get_page_blocks', 'get_page_links']

πŸ₯ Testing server health...
βœ… Server started and responded successfully
βœ… Dynamic tool discovery working correctly

πŸŽ‰ MCP Server test completed successfully!
   πŸ“Š Tools auto-discovered: 9
   πŸ₯ Server health: OK
   πŸ”„ Dynamic discovery: OK

CI/CD Pipeline

The project includes a comprehensive CI/CD pipeline with automated testing, code quality checks, and security scanning.

πŸš€ Automated Workflows

Pull Request Validation
  • βœ… Test Coverage - 80% minimum coverage requirement
  • βœ… Code Quality - Ruff linting and MyPy type checking
  • βœ… Security Scanning - Bandit security analysis
  • βœ… Tool Discovery - Automated tool validation
  • βœ… MCP Server Testing - Server startup and functionality tests
Main Test Suite
  • βœ… Multi-Python Testing - Python 3.11, 3.12, and 3.13
  • βœ… Cross-Platform - Ubuntu, Windows, and macOS
  • βœ… Performance Testing - Memory usage and test duration
  • βœ… Integration Testing - Real MCP server with tools
Code Quality & Security
  • βœ… Daily Security Scans - Automated vulnerability detection
  • βœ… Dependency Checking - Safety and license validation
  • βœ… Code Standards - Automated formatting and linting
  • βœ… Secret Detection - Hardcoded credential scanning

πŸ“Š Quality Gates

All workflows must pass for:

  • βœ… Code to be merged to main
  • βœ… Releases to be published
  • βœ… PRs to be approved

πŸ”§ Local Testing

Run the same checks locally:

# Install dependencies
uv sync --dev

# Run tests with coverage
uv run pytest tests/ --cov=src/tools --cov-report=html

# Run linting
uv run ruff check src/ tests/
uv run ruff format --check src/ tests/

# Run type checking
uv run mypy src/ --ignore-missing-imports

# Run security scan
uv run bandit -r src/

# Run dependency check
uv run safety check

πŸ“ˆ Coverage Requirements

  • Minimum Coverage: 80% for PR validation
  • Target Coverage: 85% for comprehensive testing
  • Coverage Tools: pytest-cov with HTML and XML reports

πŸ›‘οΈ Security Features

  • Bandit - Python security linter
  • Safety - Dependency vulnerability scanner
  • Secret Detection - Hardcoded credential detection
  • License Check - Dependency license validation

Contributing

We follow GitHub Flow for all contributions. See for complete details.

Quick Start

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/add-search-tool
    
  3. Create your tool (just add the file - automatic integration!)
    # Create src/tools/search_tool.py with your function
    
  4. Format and test
    uv run ruff check --fix && uv run ruff format
    uv run python tests/test_mcp_server.py
    
  5. Commit and push
    git commit -m "feat: add search tool for content discovery"
    git push origin feature/add-search-tool
    
  6. Open a Pull Request

Development Benefits

  • Zero Configuration - No manual imports or registrations
  • Instant Feedback - Tools work immediately after creation
  • Automated Validation - CI tests verify everything works
  • Clean Architecture - Dynamic system keeps code organized
  • Comprehensive Testing - 68 test cases with 80% coverage
  • Quality Assurance - Automated linting, type checking, and security
  • CI/CD Pipeline - Automated testing on every PR and push

Code Quality Standards

  • Python 3.11+ with modern async/await patterns
  • PEP 8 compliance via Ruff formatting
  • Type hints for better IDE support
  • Error handling with comprehensive exception management
  • Environment variables for configuration
  • Modular design with dynamic tool loading

Documentation & Resources

License

This project is licensed under the MIT License - see the file for details.

Acknowledgments


Made for the Logseq and MCP communities