-
Notifications
You must be signed in to change notification settings - Fork 251
feat: add dynamic resource template support #54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- align template URI handling across node and python demos - add pizzaz toppings and detail tools returning parameterized widgets - inline dev/CDN asset handling with template metadata - update readme and env samples for SSR resource templates Fixes: openai#47
Hi @Obad94 How are you testing this? I gave it a try, and although I defined the resource template, it is never used by ChatGPT.
And at no point are ResourceTemplates called, but it is masked and may go unnoticed, because of the Resource resource which is identical to the ResourceTemplate. In my understanding this seems to be a limitation in the OpenAI/ChatGPT server side, or an intended limitation, and I would like input from @katia-openai, if nothing else at least where I should file a ticket to get an answer on this matter. |
@rinormaloku, in my implementation, the MCP server advertises templated URIs, returns Inspector proof and logsServer Logs
List toolsnpx @modelcontextprotocol/inspector --cli https://1e1216949a29.ngrok-free.app/mcp \
--transport sse --method tools/list Key output: {
"name": "pizza-list",
"title": "Show Pizza List",
"_meta": {
"openai/outputTemplate": "ui://widget/pizza-list/{pizzaTopping}.html?v=dev-hgxti",
"openai/toolInvocation/invoking": "Hand-tossing a list",
"openai/toolInvocation/invoked": "Served a fresh list",
"openai/widgetAccessible": true,
"openai/resultCanProduceWidget": true,
"openai/outputTemplateSchema": {
"pizzaTopping": {
"type": "string",
"description": "Name of the topping to highlight in the list."
}
}
}
} Call the tool with a parameternpx @modelcontextprotocol/inspector --cli https://1e1216949a29.ngrok-free.app/mcp \
--transport sse \
--method tools/call \
--tool-name pizza-list \
--tool-arg pizzaTopping=mushroom Result: {
"_meta": {
"openai/outputTemplate": "ui://widget/pizza-list/{pizzaTopping}.html?v=dev-hgxti",
"openai/outputTemplateValues": { "pizzaTopping": "mushroom" },
"openai/outputTemplateResolved": "ui://widget/pizza-list/mushroom.html?v=dev-hgxti"
},
"content": [
{ "type": "text", "text": "Rendered a pizza list! Filtered by “mushroom”." }
],
"structuredContent": {
"pizzaTopping": "mushroom",
"availableToppings": [
"basil", "bianca", "burrata", "deep-dish", "detroit",
"four-cheese", "margherita", "marinara", "mozzarella",
"mushroom", "pepperoni", "prosciutto", "sausage",
"seasonal", "sourdough", "spinach", "truffle", "veggie", "white"
],
"filterApplied": true,
"requestedTopping": "mushroom"
}
} Read the resolved resourcenpx @modelcontextprotocol/inspector --cli https://1e1216949a29.ngrok-free.app/mcp \
--transport sse \
--method resources/read \
--uri ui://widget/pizza-list/mushroom.html?v=dev-hgxti Output: {
"contents": [
{
"uri": "ui://widget/pizza-list/mushroom.html?v=dev-hgxti",
"mimeType": "text/html+skybridge",
"_meta": {
"openai/outputTemplate": "ui://widget/pizza-list/{pizzaTopping}.html?v=dev-hgxti",
"openai/outputTemplateValues": { "pizzaTopping": "mushroom" },
"openai/outputTemplateResolved": "ui://widget/pizza-list/mushroom.html?v=dev-hgxti"
},
"text": "<div id=\"pizzaz-list-root\"></div>\n<link rel=\"stylesheet\" href=\"http://localhost:4444/pizzaz-list.css\">\n<script type=\"module\" src=\"http://localhost:4444/pizzaz-list.js\"></script>\n<script>window.__PIZZAZ_TEMPLATE_PARAMS__ = {\"pizzaTopping\":\"mushroom\"};</script>"
}
]
} Conclusion
|
Implements parametrized resource URIs for MCP widgets, enabling runtime template resolution and SSR-like functionality.
Changes
meta.openai/outputTemplate*
fieldsHow it works
Tools can now return parametrized templates like
ui://widget/pizza-list/{pizzaTopping}
that get resolved dynamically at runtime instead of being statically cached.Fixes #47