Repository navigation
Conversation
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
May 27, 2026 09:37
b2659e8 to
cdcf2d6
Compare
apappascs
marked this pull request as draft
May 27, 2026 09:37
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
May 27, 2026 09:43
cdcf2d6 to
cae74b5
Compare
Contributor
Author
|
Reference Links for Reviewers ( @tzolov )
|
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
June 12, 2026 12:22
0e82b86 to
92eb063
Compare
apappascs
marked this pull request as ready for review
June 15, 2026 08:52
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
August 31, 2026 11:16
2cef31a to
cf8e066
Compare
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
October 13, 2026 07:39
4016a92 to
edc116b
Compare
Add SEP-1865 (MCP Apps) support to the mcp-annotations module so Spring AI MCP servers can expose interactive UI widgets next to their tools, using the existing `@McpTool` and `@McpResource` programming model. - add `resourceUri` and `visibility` to `@McpTool`, emitted as `_meta.ui.resourceUri` and `_meta.ui.visibility` (plus the flat `ui/resourceUri` alias); visibility is emitted even without a `resourceUri` so app-only tools stay hidden from the model - add the `Visibility` enum and the `@McpCsp` annotation with `connectDomains`, `resourceDomains`, `frameDomains` and `baseUriDomains` - add `csp`, `permissions`, `domain` and `prefersBorder` to `@McpResource`, with `McpPermission` and `PrefersBorder`, emitted as `_meta.ui` on the listed resource, template and read contents (the CSP is not defined on a tool's `_meta`) - add `McpAppResult`, splitting text into `content[]` for the model and `structuredContent` for the widget, and exclude it from output schema generation - add `MetaUtils` helpers to build and merge `_meta.ui`; when a `metaProvider` also supplies `ui`, the maps are merged per key and the provider wins on conflict - merge the UI metadata in all four tool and resource providers (sync and async, stateful and stateless) - add `ResourceAdapter` validation of the `ui://` URI and the `text/html;profile=mcp-app` MIME type pairing; this pairing is documented but not validated for annotation-based resources - document MCP Apps in the MCP annotations server reference - add unit and provider tests for all of the above Signed-off-by: Alexandros Pappas <apappascs@gmail.com>
apappascs
force-pushed
the
feature/mcp-apps-sep-1865
branch
from
October 13, 2026 09:32
edc116b to
87a32dc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add SEP-1865 (MCP Apps) support to the
mcp-annotationsmodule, enabling Spring AI MCP servers to expose interactive UI widgets alongside their tools.What's included
@McpToolextensions —resourceUriandvisibilityfields to link tools to UI resources and control visibility (model-only, app-only, or both);visibilityis emitted under_meta.uieven without aresourceUri, so app-only tools stay hidden from the modelVisibilityenum —MODELandAPPvisibility scopes@McpCspannotation — declare Content Security Policy domains (connectDomains,resourceDomains,frameDomains,baseUriDomains) for widget sandboxing, set via@McpResource(csp = @McpCsp(...))on the UI resource; the spec readscspfrom the UI resource (_meta.ui.cspof theresources/readcontent; the current draft also reads it from theresources/listentry)@McpResourceUI attributes —permissions(McpPermission: camera, microphone, geolocation, clipboardWrite),domainandprefersBorder(PrefersBordertri-state), emitted under_meta.uion the listed resource, template and read contentsMcpAppResult— convenience return type that splitstext→content[](for the LLM) andstructuredContent(for the widget UI)MetaUtils—buildUiMeta(),buildCspMeta(),getResourceMeta()andmergeMeta()helpers to construct_meta.uiblocks per the SEP-1865 specResourceAdapter— validates theui://URI andtext/html;profile=mcp-appMIME type pairing when its factory methods are used. The annotation-based resource providers do not use it, so the pairing is documented but not validated for@McpResourcebeans; enforcing it in the providers could be a follow-upMcpAppResultTests,ResourceAdapterTests,MetaUtilsTest, tool and resource provider tests (sync/async × stateful/stateless)Changes since initial version
@McpToolto@McpResource: the spec readscspfrom the UI resource (_meta.ui.cspof theresources/readcontent; the current draft also reads it from theresources/listentry), and tool_metaonly carriesresourceUriandvisibility;cspis not defined on a tool's_meta. When bothcspand ametaProvidersupply_meta.ui, they are merged per key and themetaProviderwins on conflict.redirectDomainswas removed because it is not a SEP-1865 field (it exists only in ChatGPT's legacyopenai/widgetCSP.redirect_domains, which can still be set viametaProvider).frameDomainsandbaseUriDomainswere added.Example usage
And the matching UI resource, which carries the CSP:
The CSP is attached to the read contents automatically when the method returns
StringorList<String>; methods returningResourceContentsorReadResourceResultmust set_meta.ui.cspon the contents themselves.Context
SEP-1865 defines how MCP servers expose interactive UIs (widgets) that render inside AI chat clients (ChatGPT, Claude, etc.). This PR adds first-class annotation support so Spring AI developers can build MCP Apps with the same
@McpTool/@McpResourcepatterns they already use.Test plan
McpAppResultTests— verifies text/structuredContent splitResourceAdapterTests— validates ui:// URI and MIME type handling, and CSP emission on listed resources and templatesMetaUtilsTest— tests meta construction (including the four CSP fields, empty-CSP omission) and merging; exact-keys assertions on the CSP map ensure noredirectDomains(or any other undeclared key) is emittedui.resourceUri/visibility(exact-keys assertions, so noui.csp)_meta.ui.cspon the listed resource and read contents, empty CSP omitted, merge withmetaProvider