Skip to content

feat: MCP server — pod as a tool surface for agents (#490)#491

Merged
melvincarvalho merged 1 commit into
gh-pagesfrom
issue-490-mcp
May 18, 2026
Merged

feat: MCP server — pod as a tool surface for agents (#490)#491
melvincarvalho merged 1 commit into
gh-pagesfrom
issue-490-mcp

Conversation

@melvincarvalho
Copy link
Copy Markdown
Contributor

Closes #490.

Adds `jss start --mcp` exposing `POST /mcp` (MCP Streamable HTTP, protocol `2025-03-26`). Any MCP-compatible client — Claude Desktop, Cursor, custom agents — registers a JSS pod as a tool surface and reads/writes resources under the same WAC rules as any HTTP endpoint.

What lands

12 tools across 4 surfaces:

Surface Tools
CRUD `list_resources`, `read_resource`, `write_resource`, `create_resource`, `delete_resource`, `head_resource`
Skills `list_skills`, `get_skill`, `get_pod_skill`
Docs `list_docs`, `read_docs` (JSS-builtin docs)
Introspect `pod_info`

Skill discovery walks conventional paths (`/SKILL.md`, `/public/apps//SKILL.md`, `/private/bots//SKILL.md`) and supports both `SKILL.md` and `SKILL.jsonld`. New formats plug in via `skill:format` declaration — discovery stays stable, payload evolves.

Auth reuses JSS's existing chain (Bearer / DPoP / NIP-98 / LWS-CID). Tool calls are WAC-gated against the inbound WebID. No new auth code, no separate MCP auth layer. `acl:agent did:nostr:bot` for a bot is the same operation as for a human.

What's deferred (follow-ups on #490)

  • `update_resource` (PATCH / SPARQL Update / N3) — read-modify-write through CRUD is the workaround for now
  • `subscribe` (SSE wrapping JSS's WebSocket notifications)
  • `call_remote_pod` (federation primitive for bot-to-bot)
  • Explicit `read_acl` / `write_acl` tools — `.acl` files are readable/writable via regular CRUD today

Tests

17 tests covering:

  • handshake (`initialize`, `tools/list`)
  • all 12 tools (success + error paths)
  • WAC enforcement (anonymous write denied, owner write allowed)
  • path-traversal rejection in `read_docs`
  • unknown-method / unknown-tool error envelopes
  • disabled-flag case (no `/mcp` route registered)

```
ℹ pass 17
ℹ fail 0
```

Docs

New `docs/mcp.md` — quick start, curl smoke tests, tool reference, auth notes, Claude Desktop wiring instructions. Linked from README.

Test plan

  • All 17 MCP tests pass
  • Config tests still pass (no regression in flag handling)
  • Wire Claude Desktop against a running `jss start --mcp` pod end-to-end
  • Smoke against `solid-apps/charlie` once it's built (separate PR)

Adds 'jss start --mcp' which exposes POST /mcp speaking the Model Context
Protocol (Streamable HTTP transport, protocol version 2025-03-26).

Any MCP-compatible client — Claude Desktop, Cursor, custom agents,
solid-apps/charlie — can register a JSS pod as a tool surface and read /
write resources under the same WAC rules as any HTTP endpoint.

Tools shipped:

  CRUD       — list_resources, read_resource, write_resource,
               create_resource, delete_resource, head_resource
  Skills     — list_skills, get_skill, get_pod_skill
  Docs       — list_docs, read_docs (JSS-builtin)
  Introspect — pod_info

Skill discovery walks conventional paths:

  <pod>/SKILL.md                       pod-wide
  <pod>/public/apps/<name>/SKILL.md    per-app
  <pod>/private/bots/<name>/SKILL.md   per-bot

Both SKILL.md (Anthropic markdown) and SKILL.jsonld (typed JSON-LD) are
first-class — the discovery channel is stable, new formats plug in via
the skill:format declaration in the index.

Auth reuses JSS's existing chain (Bearer / DPoP / NIP-98 / LWS-CID). The
MCP server extracts the WebID from the inbound request and every tool
call is WAC-gated against that identity. No separate MCP auth layer —
granting an agent access to /private/notes/ is the same operation as
granting a human.

Deferred (follow-ups on #490): update_resource (PATCH), subscribe (SSE),
call_remote_pod (federation), write_acl.

Tests: 17 covering handshake, all 12 tools, WAC enforcement
(anonymous denied, owner allowed), unknown-method / unknown-tool error
paths, path-traversal rejection in read_docs, and the disabled-flag case.
@melvincarvalho melvincarvalho merged commit 2cb34c6 into gh-pages May 18, 2026
1 check passed
@melvincarvalho melvincarvalho deleted the issue-490-mcp branch May 18, 2026 07:03
melvincarvalho added a commit to JavaScriptSolidServer/docs that referenced this pull request May 18, 2026
Mirrors the in-repo docs/mcp.md from
JavaScriptSolidServer/JavaScriptSolidServer#491. Lays out the thesis,
auth model, full tool reference, Claude Desktop wiring, and the
Charlie use case.

Slotted at sidebar_position: 15, after Git Integration and App Install
in the Features category.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: expose JSS as an MCP server (--mcp) — proposed v0.0.200

1 participant