[Schema][Client][Server] Deprecate Roots, Sampling and Logging (SEP-2577) (#427)

* [Schema][Client][Server] Deprecate Roots, Sampling and Logging (SEP-2577)

* Emit runtime deprecation notices and document the migration (SEP-2596)
This commit is contained in:
Christopher Hertel 2026-08-18 01:23:32 +02:00 • committed by GitHub
commit 590afb575b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 120 additions and 0 deletions

View file

@ -5,6 +5,7 @@ All notable changes to `mcp/sdk` will be documented in this file.
0.8.0 0.8.0
----- -----
* Deprecate the Roots, Sampling and Logging features per SEP-2577 (protocol revision `2026-07-28`, earliest removal `2027-07-28`): the schema, client and server classes that make them up are marked `@deprecated` with the suggested migration (tool arguments or resource URIs instead of roots; an LLM provider's API instead of sampling; stderr or OpenTelemetry instead of logging), and exercising them — `ClientGateway::log()` / `sample()` / `listRoots()`, or registering a client-side `SamplingRequestHandler`, `ListRootsRequestHandler` or `LoggingNotificationHandler` — triggers a silenced `E_USER_DEPRECATED` via `symfony/deprecation-contracts`. Everything remains fully functional until removal.
* Always emit `{}` for empty tool schemas: `Tool` recursively normalizes every empty sub-schema — `properties`, `items`, `additionalProperties`, `$defs`, combinators and the other draft-07 to 2020-12 schema keywords — in the constructor, for both `inputSchema` and `outputSchema`, so an object position is never serialized as `[]`. * Always emit `{}` for empty tool schemas: `Tool` recursively normalizes every empty sub-schema — `properties`, `items`, `additionalProperties`, `$defs`, combinators and the other draft-07 to 2020-12 schema keywords — in the constructor, for both `inputSchema` and `outputSchema`, so an object position is never serialized as `[]`.
* Prompt generators returning content as typed arrays (`['type' => 'text', ...]` etc.) no longer lose the optional fields: `annotations` on every content type, and `_meta` and an explicit `mimeType` on embedded resource contents, now carry through to the resulting `PromptMessage` instead of being silently dropped. A missing resource `mimeType` still defaults to `text/plain`/`application/octet-stream` as before. * Prompt generators returning content as typed arrays (`['type' => 'text', ...]` etc.) no longer lose the optional fields: `annotations` on every content type, and `_meta` and an explicit `mimeType` on embedded resource contents, now carry through to the resulting `PromptMessage` instead of being silently dropped. A missing resource `mimeType` still defaults to `text/plain`/`application/octet-stream` as before.
* Add `annotations` support to `ImageContent` (constructor, `fromArray()`, `fromFile()`, `fromString()`, `jsonSerialize()`), matching `TextContent` and `AudioContent`. * Add `annotations` support to `ImageContent` (constructor, `fromArray()`, `fromFile()`, `fromString()`, `jsonSerialize()`), matching `TextContent` and `AudioContent`.

View file

@ -32,6 +32,7 @@
"psr/http-server-handler": "^1.0", "psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0", "psr/http-server-middleware": "^1.0",
"psr/log": "^1.0 || ^2.0 || ^3.0", "psr/log": "^1.0 || ^2.0 || ^3.0",
"symfony/deprecation-contracts": "^2.5 || ^3.0",
"symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0" "symfony/uid": "^5.4 || ^6.4 || ^7.3 || ^8.0"
}, },
"suggest": { "suggest": {

View file

@ -471,6 +471,8 @@ The client can receive requests and notifications from the server when configure
### Logging Notifications ### Logging Notifications
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Logging keeps working until then; new integrations should log to stderr (stdio) or use OpenTelemetry instead.
Receive structured log messages from the server: Receive structured log messages from the server:
```php ```php
@ -504,6 +506,8 @@ $client->setLoggingLevel(LoggingLevel::Info);
### Sampling (LLM Requests) ### Sampling (LLM Requests)
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Sampling keeps working until then; new integrations should call an LLM provider's API directly instead.
Handle server requests for LLM completions: Handle server requests for LLM completions:
```php ```php
@ -673,6 +677,8 @@ elicitation demo server.
### Roots ### Roots
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Roots keep working until then; new integrations should pass directories or files through tool arguments, resource URIs or server configuration instead.
Roots let the client expose a list of `file://` "workspace folders" that the server Roots let the client expose a list of `file://` "workspace folders" that the server
is allowed to operate on. Advertise the `roots` capability and register a handler is allowed to operate on. Advertise the `roots` capability and register a handler
that answers server `roots/list` requests: that answers server `roots/list` requests:

View file

@ -601,6 +601,8 @@ public function generatePrompt(string $topic, string $style): array
## Logging ## Logging
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Logging keeps working until then; new integrations should log to stderr (stdio) or use OpenTelemetry instead.
The SDK provides support to send structured log messages to clients. All standard PSR-3 log levels are supported. The SDK provides support to send structured log messages to clients. All standard PSR-3 log levels are supported.
Level **warning** as the default level. Level **warning** as the default level.

View file

@ -43,6 +43,8 @@ if ($context->getProtocolVersion()->isAtLeast(ProtocolVersion::V2026_07_28)) {
## Sampling ## Sampling
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Sampling keeps working until then; new integrations should call an LLM provider's API directly instead.
With [sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling) servers can request clients to With [sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling) servers can request clients to
execute "completions" or "generations" with a language model for them: execute "completions" or "generations" with a language model for them:
@ -90,6 +92,8 @@ Use `$result->getContentBlocks()` to iterate the response regardless of whether
## Logging ## Logging
> **Deprecated** since protocol revision `2026-07-28` ([SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577)), earliest removal `2027-07-28`. Logging keeps working until then; new integrations should log to stderr (stdio) or use OpenTelemetry instead.
The [Logging](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging) utility enables servers The [Logging](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/logging) utility enables servers
to send structured log messages as notification to clients: to send structured log messages as notification to clients:

View file

@ -22,6 +22,9 @@ use Psr\Log\AbstractLogger;
* *
* @author Adam Jamiu <jamiuadam120@gmail.com> * @author Adam Jamiu <jamiuadam120@gmail.com>
* @author Tobias Nyholm <tobias.nyholm@gmail.com> * @author Tobias Nyholm <tobias.nyholm@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Log to stderr (stdio) or use OpenTelemetry instead.
*/ */
final class ClientLogger extends AbstractLogger final class ClientLogger extends AbstractLogger
{ {

View file

@ -18,6 +18,9 @@ use Mcp\Schema\Notification\LoggingMessageNotification;
* Handler for logging message notifications from the server. * Handler for logging message notifications from the server.
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Log to stderr (stdio) or use OpenTelemetry instead.
*/ */
class LoggingNotificationHandler implements NotificationHandlerInterface class LoggingNotificationHandler implements NotificationHandlerInterface
{ {
@ -27,6 +30,7 @@ class LoggingNotificationHandler implements NotificationHandlerInterface
public function __construct( public function __construct(
private readonly mixed $callback, private readonly mixed $callback,
) { ) {
trigger_deprecation('mcp/sdk', '0.8', 'MCP logging is deprecated since protocol revision 2026-07-28 (SEP-2577); log to stderr or use OpenTelemetry instead.');
} }
public function supports(Notification $notification): bool public function supports(Notification $notification): bool

View file

@ -30,6 +30,10 @@ use Psr\Log\NullLogger;
* @implements RequestHandlerInterface<ListRootsResult> * @implements RequestHandlerInterface<ListRootsResult>
* *
* @author Johannes Wachter <johannes@sulu.io> * @author Johannes Wachter <johannes@sulu.io>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Pass directories or files through tool arguments, resource
* URIs or server configuration instead.
*/ */
class ListRootsRequestHandler implements RequestHandlerInterface class ListRootsRequestHandler implements RequestHandlerInterface
{ {
@ -37,6 +41,7 @@ class ListRootsRequestHandler implements RequestHandlerInterface
private readonly RootsCallbackInterface $callback, private readonly RootsCallbackInterface $callback,
private readonly LoggerInterface $logger = new NullLogger(), private readonly LoggerInterface $logger = new NullLogger(),
) { ) {
trigger_deprecation('mcp/sdk', '0.8', 'MCP roots are deprecated since protocol revision 2026-07-28 (SEP-2577); pass directories through tool arguments or resource URIs instead.');
} }
public function supports(Request $request): bool public function supports(Request $request): bool

View file

@ -21,6 +21,10 @@ use Mcp\Schema\Result\ListRootsResult;
* requested by the server. * requested by the server.
* *
* @author Johannes Wachter <johannes@sulu.io> * @author Johannes Wachter <johannes@sulu.io>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Pass directories or files through tool arguments, resource
* URIs or server configuration instead.
*/ */
interface RootsCallbackInterface interface RootsCallbackInterface
{ {

View file

@ -18,6 +18,9 @@ use Mcp\Schema\Result\CreateSamplingMessageResult;
* Contract for callbacks used by SamplingRequestHandler. * Contract for callbacks used by SamplingRequestHandler.
* *
* Implementations perform the actual LLM sampling when requested by the server. * Implementations perform the actual LLM sampling when requested by the server.
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
interface SamplingCallbackInterface interface SamplingCallbackInterface
{ {

View file

@ -30,6 +30,9 @@ use Psr\Log\NullLogger;
* @implements RequestHandlerInterface<CreateSamplingMessageResult> * @implements RequestHandlerInterface<CreateSamplingMessageResult>
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
class SamplingRequestHandler implements RequestHandlerInterface class SamplingRequestHandler implements RequestHandlerInterface
{ {
@ -37,6 +40,7 @@ class SamplingRequestHandler implements RequestHandlerInterface
private readonly SamplingCallbackInterface $callback, private readonly SamplingCallbackInterface $callback,
private readonly LoggerInterface $logger = new NullLogger(), private readonly LoggerInterface $logger = new NullLogger(),
) { ) {
trigger_deprecation('mcp/sdk', '0.8', 'MCP sampling is deprecated since protocol revision 2026-07-28 (SEP-2577); integrate with an LLM provider\'s API directly instead.');
} }
public function supports(Request $request): bool public function supports(Request $request): bool

View file

@ -31,6 +31,9 @@ use Mcp\Schema\Enum\Role;
* } * }
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
class SamplingMessage extends Content class SamplingMessage extends Content
{ {

View file

@ -20,6 +20,9 @@ use Mcp\Exception\InvalidArgumentException;
* {@see \Mcp\Schema\Result\CallToolResult} does. * {@see \Mcp\Schema\Result\CallToolResult} does.
* *
* @phpstan-type ToolResultBlock TextContent|ImageContent|AudioContent|ResourceLink|EmbeddedResource * @phpstan-type ToolResultBlock TextContent|ImageContent|AudioContent|ResourceLink|EmbeddedResource
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
final class ToolResultContent extends Content final class ToolResultContent extends Content
{ {

View file

@ -15,6 +15,9 @@ use Mcp\Exception\InvalidArgumentException;
/** /**
* A request from the assistant to call a tool. * A request from the assistant to call a tool.
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
final class ToolUseContent extends Content final class ToolUseContent extends Content
{ {

View file

@ -18,6 +18,9 @@ namespace Mcp\Schema\Enum;
* https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1 * https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Log to stderr (stdio) or use OpenTelemetry instead.
*/ */
enum LoggingLevel: string enum LoggingLevel: string
{ {

View file

@ -11,6 +11,15 @@
namespace Mcp\Schema\Enum; namespace Mcp\Schema\Enum;
/**
* Which servers' context a sampling request asks the client to attach.
*
* `thisServer` and `allServers` are themselves deprecated since 2025-11-25
* (SEP-2596): omit the field or use `none`.
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/
enum SamplingContext: string enum SamplingContext: string
{ {
case NONE = 'none'; case NONE = 'none';

View file

@ -11,6 +11,12 @@
namespace Mcp\Schema\Enum; namespace Mcp\Schema\Enum;
/**
* How the model may use the tools offered on a sampling request.
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/
enum ToolChoiceMode: string enum ToolChoiceMode: string
{ {
case Auto = 'auto'; case Auto = 'auto';

View file

@ -17,6 +17,9 @@ namespace Mcp\Schema;
* Keys not declared here are currently left unspecified by the spec and are up to the client to interpret. * Keys not declared here are currently left unspecified by the spec and are up to the client to interpret.
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
class ModelHint implements \JsonSerializable class ModelHint implements \JsonSerializable
{ {

View file

@ -34,6 +34,9 @@ use Mcp\Exception\InvalidArgumentException;
* } * }
* *
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Integrate with an LLM provider's API directly instead.
*/ */
class ModelPreferences implements \JsonSerializable class ModelPreferences implements \JsonSerializable
{ {

View file

@ -17,6 +17,9 @@ use Mcp\Schema\JsonRpc\Notification;
/** /**
* @author Kyrian Obikwelu <koshnawaza@gmail.com> * @author Kyrian Obikwelu <koshnawaza@gmail.com>
*
* @deprecated since protocol revision 2026-07-28 (SEP-2577), earliest removal 2027-07-28.
* Log to stderr (stdio) or use OpenTelemetry instead.
*/ */
class LoggingMessageNotification extends Notification class LoggingMessageNotification extends Notification
{ {

Some files were not shown because too many files have changed in this diff Show more