Research-Stack/5-Applications/plugins/substack-connector/scripts/substack_mcp_server.py
2026-05-11 22:18:31 -05:00

75 lines
2.3 KiB
Python
Executable file

#!/usr/bin/env python3
"""Tiny JSON-RPC tool surface for the repo-local Substack helper.
This implements just enough MCP-style JSON-RPC for future local plugin use.
The CLI helper remains the canonical path in normal shell workflows.
"""
from __future__ import annotations
import json
import sys
from pathlib import Path
from prepare_substack_post import prepare
TOOLS = [
{
"name": "prepare_substack_post",
"description": "Prepare a local Markdown draft and assets for Substack import.",
"inputSchema": {
"type": "object",
"properties": {
"markdown_path": {"type": "string"},
"output_dir": {"type": "string"},
},
"required": ["markdown_path"],
},
}
]
def respond(request_id, result=None, error=None) -> None:
payload = {"jsonrpc": "2.0", "id": request_id}
if error is not None:
payload["error"] = {"code": -32000, "message": str(error)}
else:
payload["result"] = result
print(json.dumps(payload), flush=True)
def handle(message: dict) -> None:
method = message.get("method")
request_id = message.get("id")
params = message.get("params") or {}
try:
if method == "initialize":
respond(request_id, {"protocolVersion": "2024-11-05", "serverInfo": {"name": "substack-connector", "version": "0.1.0"}, "capabilities": {"tools": {}}})
elif method == "tools/list":
respond(request_id, {"tools": TOOLS})
elif method == "tools/call":
name = params.get("name")
args = params.get("arguments") or {}
if name != "prepare_substack_post":
raise ValueError(f"unknown tool: {name}")
output_dir = Path(args["output_dir"]) if args.get("output_dir") else None
data = prepare(Path(args["markdown_path"]), output_dir)
respond(request_id, {"content": [{"type": "text", "text": json.dumps(data, indent=2)}]})
else:
respond(request_id, {})
except Exception as exc:
respond(request_id, error=exc)
def main() -> int:
for line in sys.stdin:
if not line.strip():
continue
handle(json.loads(line))
return 0
if __name__ == "__main__":
raise SystemExit(main())