add logseq tool: query/modify Logseq DB graph via built-in MCP server
- data/tools/logseq: Python wrapper (same pattern as atlassian_cli) - data/tools/logseq.meta: tool metadata with full prompt - data/scripts/logseq-cli: shell bridge using mcp-to-command + mcp-remote - justfile: install logseq tool + logseq-cli script Commands: listPages, getPage, searchBlocks, listTags, listProperties, upsertNodes Transport: streamable-http to http://127.0.0.1:12315/mcp (Logseq 2 DB built-in)
This commit is contained in:
parent
9b087f23d1
commit
c75dc6f6c7
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
for cmd in mcp-to-command mcp-remote; do
|
||||
command -v "$cmd" >/dev/null 2>&1 || { echo "Error: Missing required command: $cmd" >&2; exit 1; }
|
||||
done
|
||||
|
||||
LOGSEQ_MCP_URL="${LOGSEQ_MCP_URL:-http://127.0.0.1:12315}"
|
||||
|
||||
have_timeout=
|
||||
command -v timeout >/dev/null 2>&1 && have_timeout=1
|
||||
|
||||
if [ -n "$have_timeout" ]; then
|
||||
exec timeout 30 mcp-to-command mcp-remote "$LOGSEQ_MCP_URL/mcp" --transport http-first -- "$@" || {
|
||||
if [ $? -eq 124 ]; then
|
||||
echo "Error: timeout exceeded, may want to retry" >&2
|
||||
exit 124
|
||||
else
|
||||
exit $?
|
||||
fi
|
||||
}
|
||||
fi
|
||||
|
||||
exec mcp-to-command mcp-remote "$LOGSEQ_MCP_URL/mcp" --transport http-first -- "$@"
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.environ.get('OLLIE_TOOLS_PATH', os.path.dirname(os.path.abspath(__file__))))
|
||||
from _lib.args import parse_args
|
||||
|
||||
RESERVED_KEYS = {"command"}
|
||||
|
||||
|
||||
def to_flags(raw: dict) -> list[str]:
|
||||
"""Convert all non-reserved keys to --key=value flags."""
|
||||
flags = []
|
||||
|
||||
for key, value in raw.items():
|
||||
if key in RESERVED_KEYS:
|
||||
continue
|
||||
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
if isinstance(parsed, dict):
|
||||
for k, v in parsed.items():
|
||||
flags.append(f"--{k}={v}")
|
||||
continue
|
||||
elif isinstance(parsed, list):
|
||||
for item in parsed:
|
||||
flags.append(f"--{key}={item}")
|
||||
continue
|
||||
except (json.JSONDecodeError, TypeError):
|
||||
pass
|
||||
flags.append(f"--{key}={value}")
|
||||
elif isinstance(value, list):
|
||||
for item in value:
|
||||
flags.append(f"--{key}={item}")
|
||||
elif isinstance(value, bool):
|
||||
if value:
|
||||
flags.append(f"--{key}")
|
||||
elif isinstance(value, dict):
|
||||
flags.append(f"--{key}={json.dumps(value)}")
|
||||
else:
|
||||
flags.append(f"--{key}={value}")
|
||||
|
||||
return flags
|
||||
|
||||
|
||||
args = parse_args()
|
||||
raw = args.raw()
|
||||
command = args.require("command")
|
||||
|
||||
cmd = ["logseq-cli", command] + to_flags(raw)
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
|
||||
if result.stdout:
|
||||
sys.stdout.write(result.stdout)
|
||||
if result.stderr:
|
||||
sys.stderr.write(result.stderr)
|
||||
sys.exit(result.returncode)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"description": "Query and modify your Logseq knowledge graph via the built-in MCP server.",
|
||||
"prompt": "## logseq\n\nQuery and modify your Logseq DB graph via the built-in MCP server.\n\n**Args**: `command` (required), plus any tool parameters as top-level keys.\n\n### Available commands\n\n```\nlogseq(command=\"listPages\")\nlogseq(command=\"listPages\", expand=true)\nlogseq(command=\"getPage\", pageName=\"My Page\")\nlogseq(command=\"searchBlocks\", searchTerm=\"keyword\")\nlogseq(command=\"listTags\")\nlogseq(command=\"listTags\", expand=true)\nlogseq(command=\"listProperties\")\nlogseq(command=\"listProperties\", expand=true)\nlogseq(command=\"upsertNodes\", operations=[...], dry-run=true)\n```\n\n### upsertNodes operations format\n\nEach operation is an object with:\n- `operation`: \"add\" or \"edit\"\n- `entityType`: \"block\", \"page\", \"tag\", or \"property\"\n- `id`: UUID string (required for edit), temp string for add (if referenced later)\n- `data`: object with fields to set:\n - `title`: page/tag/property name or block content\n - `page-id`: page UUID (required when adding a block)\n - `tags`: list of tag UUIDs\n\nExample: add a block to a page:\n```\nlogseq(command=\"upsertNodes\", operations=[{\"operation\":\"add\",\"entityType\":\"block\",\"id\":null,\"data\":{\"page-id\":\"<page-uuid>\",\"title\":\"New block text\"}}])\n```\n\n- Use `dry-run=true` to validate without committing.\n- Before creating a page/tag/property, check if it exists with `getPage`.\n- Every key except `command` becomes a `--key=value` flag.",
|
||||
"args": {
|
||||
"type": "object",
|
||||
"required": ["command"],
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": "string",
|
||||
"description": "Logseq MCP tool name (listPages, getPage, searchBlocks, listTags, listProperties, upsertNodes)"
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
},
|
||||
"tier": "hot",
|
||||
"readOnly": false
|
||||
}
|
||||
4
justfile
4
justfile
|
|
@ -165,6 +165,7 @@ install-data:
|
|||
install -m755 data/tools/route {{cfg}}/tools/route
|
||||
install -m755 data/tools/subagent_generate {{cfg}}/tools/subagent_generate
|
||||
install -m755 data/tools/subagent_spawn {{cfg}}/tools/subagent_spawn
|
||||
install -m755 data/tools/logseq {{cfg}}/tools/logseq
|
||||
install -m755 data/tools/system_logs_dmesg {{cfg}}/tools/system_logs_dmesg
|
||||
install -m755 data/tools/system_logs_journald {{cfg}}/tools/system_logs_journald
|
||||
# Tool metadata (.meta sidecar files)
|
||||
|
|
@ -175,10 +176,11 @@ install-data:
|
|||
install -m755 data/tools/_lib/args.sh {{cfg}}/tools/_lib/args.sh
|
||||
# Help
|
||||
install -m644 doc/help.md {{cfg}}/help.md
|
||||
# Scripts (ollie-remount, ollie-watchdog)
|
||||
# Scripts (ollie-remount, ollie-watchdog, logseq-cli)
|
||||
mkdir -p {{bin}}
|
||||
install -m755 data/scripts/ollie-remount {{bin}}/ollie-remount
|
||||
install -m755 data/scripts/ollie-watchdog {{bin}}/ollie-watchdog
|
||||
install -m755 data/scripts/logseq-cli {{bin}}/logseq-cli
|
||||
|
||||
install-autostart:
|
||||
@echo === Installing autostart files ===
|
||||
|
|
|
|||
Loading…
Reference in New Issue