#!/usr/bin/env python3 """Logseq tool — queries and modifies Logseq DB graph via the REST API.""" import json import os import subprocess import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _lib.args import parse_args LOGSEQ_URL = os.environ.get("LOGSEQ_MCP_URL", "http://127.0.0.1:12315") TOKEN = os.environ.get("OLLIE_LOGSEQ_TOKEN", "") # Map tool commands to REST API methods and argument shapes. COMMANDS = { "listPages": ("logseq.cli.listPages", lambda a: [{"expand": a.get("expand", False)}]), "getPage": ("logseq.cli.getPageData", lambda a: [a["pageName"]]), "searchBlocks": ("logseq.app.search", lambda a: [a["searchTerm"], {"enable-snippet?": False}]), "listTags": ("logseq.cli.listTags", lambda a: [{"expand": a.get("expand", False)}]), "listProperties": ("logseq.cli.listProperties", lambda a: [{"expand": a.get("expand", False)}]), "upsertNodes": ("logseq.cli.upsertNodes", lambda a: [a["operations"], {"dry-run": a.get("dry-run", False)}]), "getCurrentGraph":("logseq.app.getCurrentGraph", lambda a: []), } def main(): if not TOKEN: print("Error: OLLIE_LOGSEQ_TOKEN not set", file=sys.stderr) sys.exit(1) args = parse_args() raw = args.raw() command = args.require("command") if command not in COMMANDS: print(f"Error: unknown command '{command}'. Available: {', '.join(sorted(COMMANDS.keys()))}", file=sys.stderr) sys.exit(1) method, build_args = COMMANDS[command] # Remove 'command' from raw args before passing to builder. params = {k: v for k, v in raw.items() if k != "command"} try: api_args = build_args(params) except KeyError as e: print(f"Error: missing required argument {e}", file=sys.stderr) sys.exit(1) # Build the REST API request. payload = {"method": method} if api_args: payload["args"] = api_args result = subprocess.run( ["curl", "-s", "-X", "POST", f"{LOGSEQ_URL}/api", "-H", f"Authorization: Bearer {TOKEN}", "-H", "Content-Type: application/json", "-d", json.dumps(payload)], capture_output=True, text=True, timeout=30 ) if result.returncode != 0: print(f"Error: curl failed: {result.stderr}", file=sys.stderr) sys.exit(1) # Output the result. output = result.stdout.strip() if output: # Pretty-print JSON if possible. try: data = json.loads(output) print(json.dumps(data, indent=2, ensure_ascii=False)) except json.JSONDecodeError: print(output) if __name__ == "__main__": main()