Files
gh-dnvriend-obsidian-search…/skills/obsidian-search-tool/SKILL.md
2025-11-29 18:23:29 +08:00

16 KiB

name, description
name description
skill-obsidian-search-tool Search Obsidian vault via DQL and JsonLogic

When to use

  • Search Obsidian vault from command line
  • Query notes with Dataview TABLE queries
  • Filter notes with JsonLogic expressions
  • Integrate Obsidian search in workflows

Obsidian Search Tool Skill

Purpose

A professional CLI tool for searching an Obsidian vault through the Obsidian Local REST API using Dataview Query Language (DQL) TABLE queries and JsonLogic queries. Enables programmatic access to Obsidian notes for automation, scripting, and integration workflows.

When to Use This Skill

Use this skill when:

  • You need to search an Obsidian vault from the command line
  • You want to query notes using Dataview DQL TABLE syntax
  • You need to filter notes with JsonLogic expressions
  • You're building automation workflows that interact with Obsidian
  • You want to integrate Obsidian search into CI/CD pipelines

Do NOT use this skill for:

  • Modifying or creating Obsidian notes (read-only tool)
  • Searching without Obsidian Local REST API plugin
  • Complex queries requiring GROUP BY or FLATTEN (API limitation)

CLI Tool: obsidian-search-tool

Python CLI tool (version 0.1.0) that interfaces with Obsidian's Local REST API plugin to perform searches using Dataview Query Language and JsonLogic.

Installation

# Clone repository
git clone https://github.com/dnvriend/obsidian-search-tool.git
cd obsidian-search-tool

# Install with uv
uv tool install .

# Or install from source
uv sync
uv tool install . --reinstall

Prerequisites

  1. Obsidian must be running
  2. Local REST API plugin by Adam Coddington installed and enabled
  3. Dataview plugin by Michael Brenan installed and enabled
  4. OBSIDIAN_API_KEY environment variable set with API key from plugin settings
# Set API key (get from Obsidian → Settings → Community Plugins → Local REST API)
export OBSIDIAN_API_KEY="your-api-key-here"

Quick Start

# Check API connectivity
obsidian-search-tool status

# Validate authentication
obsidian-search-tool auth

# Search with Dataview DQL
obsidian-search-tool search 'TABLE file.name FROM "daily" LIMIT 5'

# Search with JsonLogic
obsidian-search-tool search --type jsonlogic '{"in": ["keyword", {"var": "content"}]}'

Progressive Disclosure

📖 Core Commands (Click to expand)

status - Check API Connectivity

Verifies that the Obsidian Local REST API is reachable and responding. Use this to debug connection issues before performing searches.

Usage:

obsidian-search-tool status [OPTIONS]

Options:

  • --json: JSON output (default, machine-readable)
  • --text / -t: Markdown-formatted text output
  • -v: INFO level logging (operation status)
  • -vv: DEBUG level logging (detailed operations)
  • -vvv: TRACE level logging (full HTTP details + library internals)

Examples:

# Basic status check with JSON output
obsidian-search-tool status

# Human-readable text output
obsidian-search-tool status --text

# With verbose logging for debugging
obsidian-search-tool status -vv

# Trace mode with urllib3 logging
obsidian-search-tool status -vvv

Output (JSON):

{
  "success": true,
  "data": {
    "status": "connected",
    "api_url": "http://127.0.0.1:27123",
    "timestamp": "2025-11-21T10:00:00+00:00",
    "message": "API is reachable"
  }
}

Common Errors:

  • Connection failed: Obsidian not running or plugin disabled
  • OBSIDIAN_API_KEY environment variable is required: API key not set
  • Request timeout: Increase OBSIDIAN_TIMEOUT or check network

auth - Validate Authentication

Verifies that the API key is valid and authentication is working correctly. Use this to test your OBSIDIAN_API_KEY before performing searches.

Usage:

obsidian-search-tool auth [OPTIONS]

Options:

  • --json: JSON output (default)
  • --text / -t: Markdown-formatted text output
  • -v/-vv/-vvv: Verbosity levels (INFO/DEBUG/TRACE)

Examples:

# Basic auth check
obsidian-search-tool auth

# With text output
obsidian-search-tool auth --text

# With debug logging
obsidian-search-tool auth -vv

Output (JSON):

{
  "success": true,
  "data": {
    "status": "authenticated",
    "api_url": "http://127.0.0.1:27123",
    "timestamp": "2025-11-21T10:00:00+00:00",
    "message": "Authentication is valid"
  }
}

Getting Your API Key:

  1. Open Obsidian
  2. Go to Settings → Community Plugins
  3. Find "Local REST API" plugin
  4. Click plugin settings
  5. Copy the API key
  6. Set environment variable: export OBSIDIAN_API_KEY="your-key"

search - Search Vault

Search Obsidian vault using Dataview DQL TABLE queries or JsonLogic queries.

Usage:

obsidian-search-tool search QUERY [OPTIONS]
obsidian-search-tool search --stdin [OPTIONS]

Arguments:

  • QUERY: Search query string (required unless --stdin)
  • --type: Query type - dataview (default) or jsonlogic
  • --stdin / -s: Read query from stdin (mutually exclusive with positional query)
  • --json: JSON output (default, machine-readable)
  • --text / -t: Markdown-formatted text output
  • --table: Pretty-printed table output (best for TABLE results)
  • -v/-vv/-vvv: Verbosity levels (INFO/DEBUG/TRACE)

Dataview DQL Examples:

# Basic TABLE query with FROM
obsidian-search-tool search 'TABLE file.name FROM "daily" LIMIT 5'

# Recent notes with date functions
obsidian-search-tool search 'TABLE file.name, file.mtime WHERE file.mtime >= date(today) - dur(7 days) SORT file.mtime DESC'

# Folder filtering with contains()
obsidian-search-tool search 'TABLE file.name, file.folder WHERE contains(file.folder, "reference")'

# Large files sorted by size
obsidian-search-tool search 'TABLE file.name, file.size WHERE file.size > 10000 SORT file.size DESC LIMIT 10'

# Complex multi-condition query
obsidian-search-tool search 'TABLE file.name FROM "docs" WHERE file.size > 5000 AND file.mtime >= date(today) - dur(30 days)'

JsonLogic Examples:

# Content search
obsidian-search-tool search --type jsonlogic '{"in": ["Claude", {"var": "content"}]}'

# Filename contains
obsidian-search-tool search --type jsonlogic '{"in": ["daily", {"var": "filename"}]}'

# Tag search
obsidian-search-tool search --type jsonlogic '{"in": [{"var": "frontmatter.tags"}, "aws"]}'

Output Formats:

# JSON output (default, for scripting)
obsidian-search-tool search 'TABLE file.name'

# Markdown text output (human-readable)
obsidian-search-tool search 'TABLE file.name' --text

# Pretty table output (best for TABLE results)
obsidian-search-tool search 'TABLE file.name, file.size' --table

Stdin Input:

# Read query from stdin (useful for piping)
echo 'TABLE file.name FROM #meeting' | obsidian-search-tool search --stdin

# From file
cat query.txt | obsidian-search-tool search --stdin

Output (JSON):

{
  "success": true,
  "data": {
    "query": "TABLE file.name FROM \"daily\" LIMIT 5",
    "search_type": "dataview",
    "timestamp": "2025-11-21T10:00:00+00:00",
    "results": [
      {"filename": "daily/2025-11/2025-11-21.md", "result": true},
      {"filename": "daily/2025-11/2025-11-20.md", "result": true}
    ]
  }
}

completion - Shell Completion

Generate shell completion scripts for bash, zsh, or fish to enable tab completion.

Usage:

obsidian-search-tool completion SHELL

Arguments:

  • SHELL: Shell type (bash, zsh, or fish)

Installation Examples:

# Bash (temporary - current session)
eval "$(obsidian-search-tool completion bash)"

# Bash (permanent)
echo 'eval "$(obsidian-search-tool completion bash)"' >> ~/.bashrc
source ~/.bashrc

# Zsh (permanent)
echo 'eval "$(obsidian-search-tool completion zsh)"' >> ~/.zshrc
source ~/.zshrc

# Fish (persistent)
mkdir -p ~/.config/fish/completions
obsidian-search-tool completion fish > ~/.config/fish/completions/obsidian-search-tool.fish

What Gets Completed:

  • Command names: status, auth, search, completion
  • Options: --json, --text, --table, --verbose, -v, -vv, -vvv
  • Choice values: --type dataview|jsonlogic, bash|zsh|fish
  • File paths where applicable
⚙️ Advanced Features (Click to expand)

Dataview DQL Capabilities

Supported Data Commands

Commands refine query results and execute in order:

  1. FROM - Select source pages (tags, folders, files, links)

    FROM #tag               # By tag (includes subtags)
    FROM "folder"           # By folder (includes subfolders)
    FROM [[note]]           # Pages linking TO note
    FROM outgoing([[note]]) # Pages linked FROM note
    
  2. WHERE - Filter pages based on conditions

    WHERE file.size > 1000                          # Comparison
    WHERE contains(file.folder, "ai-ml")            # Contains check
    WHERE file.mtime >= date(today) - dur(7 days)   # Date-based
    
  3. SORT - Sort results by one or more fields

    SORT file.mtime DESC                            # Single field
    SORT file.folder ASC, file.mtime DESC          # Multiple fields
    
  4. LIMIT - Restrict result count

    LIMIT 10                                        # Top 10 results
    

API Limitations

Not Supported:

  • GROUP BY: Returns "TABLE WITHOUT ID queries are not supported"
  • FLATTEN: Returns "TABLE WITHOUT ID queries are not supported"
  • LIST/TASK/CALENDAR: Only TABLE queries supported

Implicit Fields (file.*)

All pages have automatic metadata:

  • Basic: file.name, file.path, file.folder, file.size, file.ext
  • Dates: file.ctime, file.mtime, file.cday, file.mday
  • Links/Tags: file.tags, file.etags, file.inlinks, file.outlinks
  • Content: file.tasks, file.lists, file.frontmatter

Common Functions

  • Constructors: date(), dur(), list(), link()
  • Numeric: round(), min(), max(), sum(), length()
  • String: contains(), lower(), upper(), split(), replace()
  • Logic: all(), any(), none(), choice(), default()
  • Date/Time: dateformat(), striptime()

JsonLogic Capabilities

Available Variables

  • filename: File path relative to vault root
  • frontmatter.*: YAML frontmatter fields (e.g., frontmatter.tags)
  • content: Full file content (for text search)

Supported Operators

  • in: Substring/membership check (works reliably)
  • Standard logic: and, or, not
  • Comparisons: ==, !=, <, >, <=, >=

Limitations

  • startsWith/endsWith: Not supported by API (returns "Unrecognized operation")
  • Use in operator for substring matching instead

Multi-Level Verbosity

Progressive logging detail control:

  • No flag (default): WARNING level - only errors
  • -v: INFO level - operation status, high-level events
  • -vv: DEBUG level - detailed operations, API calls, validation
  • -vvv: TRACE level - full HTTP requests, urllib3 internals, tracebacks

Examples:

# Quiet mode (warnings only)
obsidian-search-tool status

# Verbose mode (operations)
obsidian-search-tool search 'TABLE file.name' -v

# Debug mode (API details)
obsidian-search-tool search 'TABLE file.name' -vv

# Trace mode (HTTP internals)
obsidian-search-tool search 'TABLE file.name' -vvv

Environment Variables

  • OBSIDIAN_API_KEY (required): API token from plugin settings
  • OBSIDIAN_BASE_URL (optional): API URL (default: http://127.0.0.1:27123)
  • OBSIDIAN_TIMEOUT (optional): Request timeout in seconds (default: 30)

Output Piping

JSON output goes to stdout, logs to stderr for clean piping:

# Pipe to jq for processing
obsidian-search-tool search 'TABLE file.name' --json | jq '.data.results[].filename'

# Count results
obsidian-search-tool search 'TABLE file.name' --json | jq '.data.results | length'

# Extract specific fields
obsidian-search-tool search 'TABLE file.name, file.size' --json | jq '.data.results[] | select(.file.size > 10000)'
🔧 Troubleshooting (Click to expand)

Common Issues

Issue: "OBSIDIAN_API_KEY environment variable is required"

# Symptom
Error: OBSIDIAN_API_KEY environment variable is required

Solution:

  1. Open Obsidian → Settings → Community Plugins
  2. Find "Local REST API" plugin settings
  3. Copy the API key
  4. Set environment variable: export OBSIDIAN_API_KEY="your-key-here"
  5. Add to shell profile (~/.bashrc, ~/.zshrc) for persistence

Issue: "Connection failed to http://127.0.0.1:27123"

# Symptom
ConnectionRefusedError: [Errno 61] Connection refused

Solution:

  1. Ensure Obsidian is running
  2. Verify Local REST API plugin is installed and enabled
  3. Check plugin settings show correct port (default: 27123)
  4. Try accessing http://127.0.0.1:27123 in browser

Issue: "Only TABLE dataview queries are supported"

# Symptom
Error: Only TABLE dataview queries are supported

Solution:

  • Use TABLE queries only, not LIST/TASK/CALENDAR
  • Example: TABLE file.name FROM #tag instead of LIST FROM #tag

Issue: "TABLE WITHOUT ID queries are not supported"

# Symptom
Error: TABLE WITHOUT ID queries are not supported

Solution:

  • Don't use GROUP BY or FLATTEN
  • Use WHERE with contains() instead for filtering
  • Example: WHERE contains(file.folder, "reference") instead of GROUP BY

Issue: "Unrecognized operation startsWith"

# Symptom with JsonLogic
Error: Unrecognized operation startsWith

Solution:

  • Use in operator for substring matching
  • Example: {"in": ["prefix", {"var": "filename"}]} instead of startsWith

Issue: No results found but files exist

Solution:

  • Check query syntax carefully
  • Verify folder paths use quotes: FROM "folder" not FROM folder
  • Use contains() for partial matches
  • Test with simpler query first

Getting Help

# Main help
obsidian-search-tool --help

# Command-specific help
obsidian-search-tool status --help
obsidian-search-tool auth --help
obsidian-search-tool search --help
obsidian-search-tool completion --help

# Version info
obsidian-search-tool --version

Debug Workflow

  1. Check connectivity: obsidian-search-tool status -vv
  2. Verify auth: obsidian-search-tool auth -vv
  3. Test simple query: obsidian-search-tool search 'TABLE file.name LIMIT 1' -vv
  4. Add complexity gradually

Exit Codes

  • 0: Success
  • 1: Client error (authentication, connection, API error)
  • 2-255: Other errors

Output Formats

JSON (default):

  • Machine-readable
  • Parseable with jq
  • All logging to stderr
  • Perfect for scripting

Text (--text):

  • Human-readable markdown
  • File paths with metadata
  • Summary statistics
  • Good for terminal viewing

Table (--table):

  • Pretty-printed columns
  • Best for TABLE query results
  • Aligned columns
  • Terminal-optimized

Best Practices

  1. Start with connectivity: Always run status and auth first
  2. Use verbosity wisely: Start with -v, escalate to -vv for debugging
  3. Test queries incrementally: Start simple, add complexity gradually
  4. Pipe JSON output: Use --json | jq for processing results
  5. Save complex queries: Store in files and use --stdin
  6. Check API limitations: No GROUP BY, FLATTEN, or non-TABLE queries
  7. Use contains() for flexibility: Better than exact matches for folders/content
  8. Enable completion: Install shell completion for better UX

Resources