mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-09-11 21:39:01 +00:00
342a564113
* feat(mcp): read-only resource templates for items / dashboard / collections (TASK-946)
Four MCP resource templates expose pad workspace state to agents
without requiring a tool invocation:
pad://workspace/{ws}/items/{ref} → single item markdown
pad://workspace/{ws}/items → list of items (JSON)
pad://workspace/{ws}/dashboard → project dashboard (JSON)
pad://workspace/{ws}/collections → collections + schemas (JSON)
Why resources, not tools: agents can `resources/read` a URI and
ingest the body directly into context without going through a
tool-call round-trip. Useful for "load TASK-5 then plan" workflows
where the agent shouldn't need to pick a tool.
Implementation:
- internal/mcp/resources.go (new) — RegisterResources installs all
four templates on an MCPServer; ResourceFetcher interface +
ExecResourceFetcher shell-out (separate from Dispatcher because
resource handlers return raw bytes, not CallToolResult).
- parsePadURI extracts (workspace, kind, arg) from pad:// URIs;
defensive guards reject mismatched URIs at each handler.
- rootFlagsToArgs forwards startup --url to every fetched call
(same contract as TASK-945's tool dispatch).
- cmd/pad/mcp.go wires RegisterResources after the tool registry
in mcpServeCmd.
15 new unit tests:
- parsePadURI: all 4 forms + 4 malformed inputs
- each handler: dispatches correct CLI args + MIME type
- readItem rejects mismatched URI (defensive)
- fetch errors propagate as Go errors (so MCP returns JSON-RPC
error rather than empty contents)
- root flag forwarding via the resources path
- ExecResourceFetcher: missing binary, stdout capture, non-zero
exit folds stderr into error
Live verified:
- resources/templates/list returns 4 templates with correct mime
types and uri patterns.
- resources/read pad://workspace/docapp/items/TASK-944 returns
1764 bytes of markdown.
Parent: PLAN-942.
* fix(mcp): compose full item markdown from JSON in resource path (Codex round 1)
Codex flagged: pad://workspace/{ws}/items/{ref} fetched
`pad item show --format markdown` which prints only item.Content
(see cmd/pad/main.go:2562). The resource description promised
"Full markdown content … includes title, fields, body, and links",
so clients reading the URI lost ref/title/metadata/parent and
couldn't reliably identify the item.
Fix scoped to the resource path (rather than changing the CLI's
markdown output, which other callers may parse): readItem fetches
`--format json` and a new formatItemAsMarkdown composes the
document — heading with ref + title, optional parent link, sorted
metadata fields, then the content body.
3 new unit tests + the existing readItem test rewritten:
- Full-shape JSON → exact markdown layout (deterministic via sorted keys)
- Missing fields → heading-only doc, no panic
- Empty `{}` fields → no stray list section
- Invalid JSON → error propagates
Live verified: pad://workspace/docapp/items/TASK-944 now returns
"# TASK-944: <title>\n\n**Parent:** PLAN-942 — ...\n\n- **priority:**
high\n- **status:** done\n\n<body>" — full identification + traversable
parent link, body intact.
Parent: PLAN-942.