[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
2 changed files with 273 additions and 21 deletions

View file

@ -17,14 +17,16 @@ use Mcp\Schema\Extension\Apps\UiResourceContentMeta;
use Mcp\Schema\Extension\Apps\UiResourceCsp;
use Mcp\Schema\Extension\Apps\UiResourcePermissions;
use Mcp\Schema\Extension\Apps\UiToolMeta;
use Mcp\Schema\Extension\ExtensionInterface;
use PHPUnit\Framework\TestCase;
class McpAppsTest extends TestCase
{
public function testServerExtensionInterface(): void
public function testExtensionInterface(): void
{
$extension = new McpApps();
$this->assertInstanceOf(ExtensionInterface::class, $extension);
$this->assertSame('io.modelcontextprotocol/ui', $extension->getId());
$this->assertSame(['mimeTypes' => ['text/html;profile=mcp-app']], $extension->getCapabilities());
}

View file

@ -113,6 +113,17 @@ class CapabilitiesExtensionsTest extends TestCase
$this->assertSame(['a' => ['x' => 1], 'b' => ['y' => 2]], $caps->extensions, 'original is unchanged');
}
public function testClientCapabilitiesWithExtensionsMerges(): void
{
$caps = new ClientCapabilities(elicitation: true, extensions: ['a' => ['x' => 1], 'b' => ['y' => 2]]);
$merged = $caps->withExtensions(['b' => ['y' => 99], 'c' => ['z' => 3]]);
$this->assertTrue($merged->elicitation);
$this->assertSame(['a' => ['x' => 1], 'b' => ['y' => 99], 'c' => ['z' => 3]], $merged->extensions);
$this->assertSame(['a' => ['x' => 1], 'b' => ['y' => 2]], $caps->extensions, 'original is unchanged');
}
public function testClientCapabilitiesWithExtensions(): void
{
$extensions = [