[Examples][Tests] Make the MCP Apps example work over HTTP, and pin it (#439)

* [Examples][Tests] Make the MCP Apps example work over HTTP, and pin it

It was the only example without a session store, so every request under
`php -S` or php-fpm - each its own process - was answered "Session not found
or has expired". It now uses a FileSessionStore like the others.

Inspector snapshots pin what the extension actually puts on the wire: the
ui:// resource's `text/html;profile=mcp-app` MIME type and `ui` marker, and
the `_meta.ui` on the tool that links the two.

* Apply suggestion from @chr-hertel

* Apply suggestion from @chr-hertel
This commit is contained in:
Christopher Hertel 2026-08-18 14:51:34 +02:00 • committed by GitHub
commit 0751a83658
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,50 @@
<?php
/*
* This file is part of the official PHP MCP SDK.
*
* A collaboration between Symfony and the PHP Foundation.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Mcp\Tests\Inspector\Http;
/**
* Snapshots the MCP Apps example as the Inspector sees it.
*
* What the snapshots are actually pinning is the extension's metadata surviving
* registration: the `ui://` resource carrying `text/html;profile=mcp-app` and
* the `ui` marker in its `_meta`, and the tool carrying the `UiToolMeta` that
* links it to that resource. Those are the two halves a host needs to render an
* app, and both travel in `_meta`, where a silent drop would otherwise go
* unnoticed until a host failed to render anything.
*/
final class HttpMcpAppsTest extends HttpInspectorSnapshotTestCase
{
public static function provideMethods(): array
{
return [
...parent::provideMethods(),
'Read the UI resource' => [
'method' => 'resources/read',
'options' => ['uri' => 'ui://weather-app'],
'testName' => 'weather_app',
],
'Call the linked tool' => [
'method' => 'tools/call',
'options' => [
'toolName' => 'get_weather',
'toolArgs' => ['city' => 'london'],
],
'testName' => 'get_weather',
],
];
}
protected function getServerScript(): string
{
return \dirname(__DIR__, 3).'/examples/server/mcp-apps/server.php';
}
}

View file

@ -0,0 +1,3 @@
{
"prompts": []
}

View file

@ -0,0 +1,13 @@
{
"resources": [
{
"name": "weather-app",
"uri": "ui://weather-app",
"description": "Interactive weather dashboard",
"mimeType": "text/html;profile=mcp-app",
"_meta": {
"ui": {}
}
}
]
}

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"resourceTemplates": []
}

View file

@ -0,0 +1,9 @@
{
"content": [
{
"type": "text",
"text": "Weather in london: 15°C, Cloudy, Humidity: 78%"
}
],
"isError": false
}

View file

@ -0,0 +1,28 @@
{
"tools": [
{
"name": "get_weather",
"description": "Get current weather for a city",
"inputSchema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
},
"_meta": {
"ui": {
"resourceUri": "ui://weather-app",
"visibility": [
"model",
"app"
]
}
}
}
]
}