[Schema][Client][Server] Close MCP Apps gaps: extension negotiation checks (#429)

* [Schema][Client][Server] Close MCP Apps gaps: extension negotiation checks

Add ClientGateway::supportsExtension(), Client\Builder::enableExtension() and
ClientCapabilities::withExtensions(); introduce side-agnostic ExtensionInterface
and deprecate ServerExtensionInterface; document attribute-based UI linkage.

* Drop ServerExtensionInterface in favour of ExtensionInterface
This commit is contained in:
Christopher Hertel 2026-08-18 01:46:53 +02:00 • committed by GitHub
commit 6f58fe596a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -18,6 +18,7 @@ use Mcp\Schema\Elicitation\ElicitationSchema;
use Mcp\Schema\Elicitation\StringSchemaDefinition;
use Mcp\Schema\Enum\ElicitAction;
use Mcp\Schema\Enum\ElicitationMode;
use Mcp\Schema\Extension\Apps\McpApps;
use Mcp\Schema\JsonRpc\Error;
use Mcp\Schema\JsonRpc\Request;
use Mcp\Schema\JsonRpc\Response;
@ -86,6 +87,17 @@ final class ClientGatewayTest extends TestCase
$this->assertTrue($this->gatewayFor((array) $capabilities)->supportsSamplingTools());
}
public function testSupportsExtensionReflectsTheNegotiatedExtensions(): void
{
$this->assertTrue($this->gatewayFor(['extensions' => [McpApps::EXTENSION_ID => ['mimeTypes' => [McpApps::MIME_TYPE]]]])->supportsExtension(McpApps::EXTENSION_ID));
$this->assertFalse($this->gatewayFor(['extensions' => ['io.example/other' => []]])->supportsExtension(McpApps::EXTENSION_ID));
$this->assertFalse($this->gatewayFor([])->supportsExtension(McpApps::EXTENSION_ID));
// Live sessions hold the serialized object shape.
$capabilities = (new ClientCapabilities(extensions: [McpApps::EXTENSION_ID => (new McpApps())->getCapabilities()]))->jsonSerialize();
$this->assertTrue($this->gatewayFor((array) $capabilities)->supportsExtension(McpApps::EXTENSION_ID));
}
public function testSupportsElicitationUrlReflectsTheSubCapability(): void
{
$this->assertTrue($this->gatewayFor(['elicitation' => ['url' => []]])->supportsElicitationUrl());