Support multiple tool responses and embedded resources
Edit: This not only is a way to support MCP UI, but more importantly "Multiple content items of different types" and "Embedded Resources" are part of the MCP tool result spec.
In the current version, it looks like it is not possible to implement MCP UI (as opposed to OpenAI Apps SDK). MCP UI requires you return a text response as well as a resource. Here an example from the Shopify get_product_details tool (MCP URL: https://mcpstorefront.com/?store=demostore.mock.shop)
{
"content": [
{
"type": "text",
"text": "{\"product\":{...}},\"instructions\":\"Use markdown to render product titles as links to their respective product pages using the URL property.\\nPay attention to the selected variant specified in the response.\\n\"}"
},
{
"type": "resource",
"resource": {
"uri": "ui://product/gid://shopify/Product/7983595290646",
"mimeType": "text/uri-list",
"text": "https://cdn.shopify.com/storefront/product.component?store_domain=demostore.mock.shop&inline=true&product_handle=black-sunnies"
}
}
],
"isError": false
}
For what I have seen, it currently is not possible to return multiple responses, and it's also not possible to return resources from a tool.
I tried to make it work with a few extends but failed because of the way the CallTool is set up. I got it to work with OpenAI's App SDK, but it would be great if we could also implement MCP UI using this package.
You can return any payload what you need by building the payload yourself. Here is a sample of what I did with JsonResource
return Response::text(
json_encode(
new CustomJsonResource($object),
JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT,
)
);
If i try that the response is:
{
"content": [
{
"type": "text",
"text": "[{\"type\":\"text\",\"text\":\"Test response\"},{\"type\":\"resource\",\"resource\":{\"uri\":\"ui:\/\/base\/list-widget\",\"mimeType\":\"text\/html\",\"text\":\"<ul><li>item 1<\/li><\/ul>\"}}]"
}
],
"isError": false
}
Context:
return Response::text(json_encode([
[
'type' => 'text',
'text' => 'Test response',
],
[
'type' => 'resource',
'resource' => [
'uri' => 'ui://base/list-widget',
'mimeType' => 'text/html',
'text' => '<ul><li>item 1</li></ul>',
],
]
]));
What is exactly MCP UI you are referring to ?
I'm referring to https://mcpui.dev/guide/introduction
Here is Shopify's blog about it: https://shopify.engineering/mcp-ui-breaking-the-text-wall
Thanks, well to me it seems to be a MCP UI related question and this project only aims at MCP protocol itself.
It looks like you're returning resources within tools but shouldn't you be implement directly resources instead ?
"Multiple content items of different types" and "Embedded Resources" are part of the MCP spec: https://modelcontextprotocol.info/specification/2024-11-05/server/tools/#tool-result
So I feel this should be part of this package.
"Multiple content items of different types" and "Embedded Resources" are part of the MCP spec: https://modelcontextprotocol.info/specification/2024-11-05/server/tools/#tool-result
So I feel this should be part of this package.
The Response class is macro able, so you could add your own Response::resource($array) method to make this work.
// In AppServiceProvider.php
Response::macro('resource', function (array $data): static {
return new static(new Resource($data));
});
Take a look at the Laravel\Mcp\Server\Content\Text class for an example of how to set up your Resource class