[Client][Server] Add Roots support - #395
Open
wachterjohannes wants to merge 2 commits into
Open
Conversation
wachterjohannes
requested review from
CodeWithKyrian,
Nyholm,
chr-hertel and
soyuka
as code owners
July 14, 2026 19:27
chr-hertel
requested changes
Jul 14, 2026
wachterjohannes
force-pushed
the
eve/roots
branch
from
July 20, 2026 07:06
290e411 to
3e4eade
Compare
chr-hertel
reviewed
Jul 27, 2026
chr-hertel
reviewed
Jul 27, 2026
chr-hertel
reviewed
Jul 27, 2026
wachterjohannes
force-pushed
the
eve/roots
branch
2 times, most recently
from
August 14, 2026 07:29
7c4b520 to
bdba67f
Compare
Wire up the MCP "roots" capability on both sides: Client (php-sdk as client): - RootsCallbackInterface + ListRootsRequestHandler answer server roots/list requests, mirroring the Sampling handler. - Client::sendRootsListChanged() emits notifications/roots/list_changed. Server (php-sdk as server): - ClientGateway::listRoots() requests the client's roots, and supportsRoots() reports whether the client advertised the capability, normalizing the stored capabilities to an array so an empty capabilities object (\stdClass) doesn't cause a TypeError. - Add ListRootsResult::fromArray() (used by listRoots()). - ListRootsRequestHandler forwards RootsException messages to the server (new Mcp\Exception\RootsException), mirroring SamplingRequestHandler. - Client::sendRootsListChanged() throws when the client did not advertise the roots.listChanged capability. Examples, docs and tests: - examples/README/docs advertise `new ClientCapabilities(roots: true, rootsListChanged: true)` before sending notifications/roots/list_changed. - CHANGELOG entry for Roots (unreleased 0.7.0 section at the time). - Unit tests for capability serialization/round-trip, sendRootsListChanged gating, and RootsException message forwarding. phpunit, php-cs-fixer and phpstan green.
…, connection guard, working example Responds to chr-hertel's review of the Roots support: - ListRootsResult::fromArray() rejects non-array root elements instead of accepting malformed entries silently. - CHANGELOG entry moved to the next unreleased section as the release train advanced past it (0.7.0 -> 0.8.0). - Client::sendRootsListChanged() went straight to Protocol::sendNotification(), which sends via `$this->transport?->send()` -- on a client that is not connected the notification was silently dropped. It now throws a ConnectionException like sendRequest() does. - The stdio example only advertised the roots capability, so the roots/list handler never actually ran. The client-communication demo server gets an `inspect_workspace_roots` tool that calls ClientGateway::supportsRoots()/listRoots(); the example calls it, so the server actually issues roots/list and the client answers it. Dropped the try/catch wrapper from the example. - ClientTest's connected-client mock now goes through setState() so isConnected() reflects a real handshake instead of a stubbed flag. phpunit, php-cs-fixer and phpstan green.
wachterjohannes
force-pushed
the
eve/roots
branch
from
August 14, 2026 07:43
bdba67f to
d6a109e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for the MCP Roots capability, letting a client expose
file://"workspace folders" that the server is allowed to operate on.Client side
ListRootsRequestHandler+RootsCallbackInterface— answer serverroots/listrequests from a user-provided callback (mirrors the existingSamplingRequestHandler/SamplingCallbackInterfacepattern).Client::sendRootsListChanged()— sendnotifications/roots/list_changed. Guarded: it throws unless the client advertised theroots.listChangedcapability, so a misconfigured client can't emit an undeclared notification.Mcp\Exception\RootsException— thrown from a roots callback, its message is forwarded to the server (same contract asSamplingException); any other throwable is logged and returned as a generic internal error.Server side
ClientGateway::listRoots()— request the client's roots (returnsListRootsResult, throwsClientExceptionon an error response).ClientGateway::supportsRoots()— capability-gating helper alongsidesupportsElicitation().Schema
ListRootsResult::fromArray()— parse the client's response;Rootcontinues to enforce thefile://URI scheme required by the spec.Docs / examples / tests
docs/client.mdsections and a runnableexamples/client/stdio_roots.php.file://rejection), capability serialization/round-trip,sendRootsListChanged()gating, and theClientGatewayroots methods.0.7.0.Conformance notes
file://per the current spec.rootscapability presence gatesroots/list;roots.listChangedgates thelist_changednotification.