The most common owner operation in a bot world is granting an agent access to a specific resource. Today, that requires the owner (or a delegated tool) to:
`read_resource` the existing `.acl` (which is JSON-LD)
Parse it
Add a new `acl:Authorization` block with the right `acl:agent` / `acl:mode` shape
`write_resource` the modified `.acl` back
For the headline ergonomic — delegation to an agent is one ACL edit — that pipeline is ergonomically painful. It's also error-prone (hand-rolled JSON-LD is the #1 thing humans get wrong about WAC).
Two convenience tools eliminate this.
What
```
read_acl — Return the effective ACL for a resource, including inherited
rules from parent containers. Returns a structured form:
{ authorizations: [{ agents, agentClasses, modes, isDefault }] }
write_acl — Write a structured ACL to a resource. Accepts the same
shape read_acl returns. Server serializes to JSON-LD.
arguments:
path: string
authorizations: array of { agent | agentClass, modes, isDefault }
```
The structured form abstracts away the JSON-LD-quirks: `acl:agent` vs `acl:agentClass`, `acl:Read|Write|Append|Control` mode URIs, `acl:default` propagation. Bots can grant/revoke without ever touching turtle or JSON-LD syntax.
Scope
Both tools in `src/mcp/tools.js`
Structured ↔ JSON-LD round-trip using existing `src/wac/parser.js`
WAC check: `acl:Control` required to write_acl
Test: read_acl an existing resource, grant a new agent, verify they now have access
Doc with worked example
Estimated ~100-150 lines including tests.
Why structured (not just `write_resource` to `.acl`)
Three reasons:
Discoverability — agents see `write_acl` in the tool list and know to use it for delegation. Without it, they'd `write_resource` to a path that happens to be an ACL.
Correctness — the existing JSON-LD parsers in `src/wac/` already handle the corner cases; surfacing that as a tool means bots don't reinvent them badly.
Future-proofing — if WAC evolves (Append vs Write distinction, new agent classes, conditional rules), the tool surface stays stable while the JSON-LD shape evolves.
Activity
feat(mcp): subscribe, read_acl/write_acl, call_remote_pod (closes #494 …