chore: import upstream snapshot with attribution
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Has been cancelled
Deploy Docs / deploy-docs (push) Failing after 1s
Conformance Tests / client-conformance (push) Failing after 3s
Conformance Tests / server-conformance (push) Failing after 1s
GitHub Actions Security Analysis / zizmor (push) Failing after 1s
CI / checks (push) Failing after 59m20s
CI / all-green (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# roots
|
||||
|
||||
> **Deprecated** in the 2026-07-28 protocol (SEP-2577); functional through the
|
||||
> deprecation window. Migration: accept directory paths as ordinary tool
|
||||
> parameters or resource URIs instead of relying on `roots/list`.
|
||||
> TODO(maxisbey): revisit before beta.
|
||||
|
||||
The client passes a `list_roots_callback` returning the filesystem locations it
|
||||
is willing to expose; a server tool calls `ctx.session.list_roots()` mid-request
|
||||
and the client's callback answers it. Passing the callback is what makes the
|
||||
client advertise the `roots` capability — there is no separate flag.
|
||||
|
||||
## Run it
|
||||
|
||||
```bash
|
||||
# stdio (default — the client spawns the server as a subprocess)
|
||||
uv run python -m stories.roots.client
|
||||
|
||||
# HTTP — the client self-hosts the server on a free port, runs, then tears it down
|
||||
uv run python -m stories.roots.client --http --legacy
|
||||
# same, against the lowlevel-API server variant
|
||||
uv run python -m stories.roots.client --http --legacy --server server_lowlevel
|
||||
```
|
||||
|
||||
## What to look at
|
||||
|
||||
- `client.py` `main` — the
|
||||
`Client(target, mode=mode, list_roots_callback=list_roots)` construction is
|
||||
the whole client-side story: the callback is wired in as a constructor
|
||||
argument, and that alone advertises the capability.
|
||||
- `client.py` `list_roots` — the callback takes a `ClientRequestContext` and
|
||||
returns `ListRootsResult`.
|
||||
- `server.py` — `await ctx.session.list_roots()` inside the tool body: a
|
||||
server→client request that blocks until the callback answers.
|
||||
- `server_lowlevel.py` — the same call from `ServerRequestContext.session`,
|
||||
with the `CallToolResult` built by hand.
|
||||
|
||||
## Caveats
|
||||
|
||||
- **Legacy-era only.** `roots/list` is a server-initiated request with no
|
||||
2026-07-28 wire carrier, so this story runs with `era = "legacy"` and the
|
||||
harness pins the handshake path.
|
||||
- `ctx.session.list_roots()` is `@deprecated`; the
|
||||
`# pyright: ignore[reportDeprecated]` is deliberate. The non-deprecated
|
||||
replacement is to accept directory paths as ordinary tool parameters (see the
|
||||
banner above) — there is no successor server→client call.
|
||||
- `ctx.session.*` is the interim 2-hop path; a later release will shorten it.
|
||||
- `notifications/roots/list_changed` is intentionally not shown — removed in
|
||||
2026-07-28 (SEP-2575) and deprecated on the legacy path.
|
||||
|
||||
## Spec
|
||||
|
||||
[Roots — client features](https://modelcontextprotocol.io/specification/2025-11-25/client/roots)
|
||||
|
||||
## See also
|
||||
|
||||
`legacy_elicitation/`, `sampling/` — sibling stories that exercise the same
|
||||
legacy server→client request shape.
|
||||
Reference in New Issue
Block a user