Parent epic: #2527
User Story
As a server administrator, I want ContextForge to store and serve MCP Apps UI resources through the generic extension governance layer so that apps can be represented as standard MCP ui:// resources without bypassing security policy.
One-Week Deliverable
Bring UI resource persistence and MCP resource-read serving under extension policy, RBAC/token scoping, plugin hooks, sanitization, and audit.
Acceptance Criteria
- UI resources are stored with
ui:// URI, content metadata, MIME type, CSP config, permissions policy, owner/team visibility, source gateway, and audit fields.
resources/read can return authorized ui:// resource content in MCP resource format only when MCP Apps is enabled and advertised through extension policy.
- Unauthorized, wrong-team, public-only, disabled-extension, and hidden-gateway callers cannot read private/team-inaccessible UI resources.
- Resource responses pass through configured plugin and sanitizer hooks before reaching the host.
- Invalid URI, unsafe MIME type, unsafe metadata, or disallowed external domain declarations are rejected or quarantined according to policy.
- Tests cover create/read/list, visibility scoping, invalid URI handling, disabled extension deny, and sanitizer/plugin denial.
Demo
Register ui://dashboard, read it through resources/read as an authorized caller, then show unauthorized and disabled-extension callers denied.
Parent epic: #2527
User Story
As a server administrator, I want ContextForge to store and serve MCP Apps UI resources through the generic extension governance layer so that apps can be represented as standard MCP
ui://resources without bypassing security policy.One-Week Deliverable
Bring UI resource persistence and MCP resource-read serving under extension policy, RBAC/token scoping, plugin hooks, sanitization, and audit.
Acceptance Criteria
ui://URI, content metadata, MIME type, CSP config, permissions policy, owner/team visibility, source gateway, and audit fields.resources/readcan return authorizedui://resource content in MCP resource format only when MCP Apps is enabled and advertised through extension policy.Demo
Register
ui://dashboard, read it throughresources/readas an authorized caller, then show unauthorized and disabled-extension callers denied.