Documentation
¶
Overview ¶
Package ui provides the MCP Apps extension (io.modelcontextprotocol/ui) for mcpkit servers. It declares the extension in the initialize response so clients know the server supports interactive HTML UIs.
This is a separate Go module (github.com/panyam/mcpkit/ext/ui) so that the core mcpkit module stays zero-deps. Import this package to advertise MCP Apps support on your server.
Usage:
srv := server.NewServer(info,
server.WithExtension(ui.UIExtension{}),
)
Index ¶
- Constants
- Variables
- func AppShellHTML(title string, bodyHTML string, cfg ...*BridgeConfig) string
- func BridgeTemplateDef() string
- func ElicitWithApp(ctx context.Context, req core.ElicitationRequest, ui *core.UIMetadata) (core.ElicitationResult, error)
- func InjectAppBridge(html string, cfg ...*BridgeConfig) string
- func RegisterAppTool(reg ToolResourceRegistrar, cfg AppToolConfig)
- func RegisterTypedAppTool[In, Out any](reg ToolResourceRegistrar, cfg TypedAppToolConfig[In, Out])
- func RequestDisplayMode(ctx context.Context, mode core.DisplayMode)
- func SampleWithApp(ctx context.Context, req core.CreateMessageRequest, ui *core.UIMetadata) (core.CreateMessageResult, error)
- func ServeBridge() http.Handler
- func ToBytes(v any) ([]byte, error)
- type AppBridge
- type AppHost
- func (h *AppHost) CallAppTool(ctx context.Context, name string, args map[string]any) (*core.ToolResult, error)
- func (h *AppHost) Close() error
- func (h *AppHost) ListAllTools(ctx context.Context) ([]core.ToolDef, error)
- func (h *AppHost) ListAppTools(ctx context.Context) ([]core.ToolDef, error)
- func (h *AppHost) RefreshAppTools(ctx context.Context) error
- func (h *AppHost) Start(ctx context.Context) error
- type AppHostOption
- type AppToolConfig
- type BridgeConfig
- type BridgeData
- type CollisionHandler
- type InProcessAppBridge
- func (b *InProcessAppBridge) Close() error
- func (b *InProcessAppBridge) RegisterTool(name string, def core.ToolDef, handler func(args map[string]any) (any, error))
- func (b *InProcessAppBridge) RemoveTool(name string)
- func (b *InProcessAppBridge) Send(ctx context.Context, req *core.Request) (*core.Response, error)
- func (b *InProcessAppBridge) SendToHost(ctx context.Context, method string, params any) (*core.Response, error)
- func (b *InProcessAppBridge) SetNotificationHandler(fn func(method string, params json.RawMessage))
- func (b *InProcessAppBridge) SetRequestHandler(fn func(ctx context.Context, req *core.Request) *core.Response)
- func (b *InProcessAppBridge) Start() error
- type RegisteredTool
- type RegistryOption
- type ServerRegistry
- func (r *ServerRegistry) Add(ctx context.Context, id string, c *client.Client) error
- func (r *ServerRegistry) AddWithBridge(ctx context.Context, id string, c *client.Client, bridge AppBridge) error
- func (r *ServerRegistry) AllTools(ctx context.Context) ([]RegisteredTool, error)
- func (r *ServerRegistry) CallTool(ctx context.Context, name string, args map[string]any) (*core.ToolResult, error)
- func (r *ServerRegistry) CallToolOn(ctx context.Context, serverID, name string, args map[string]any) (*core.ToolResult, error)
- func (r *ServerRegistry) Close() error
- func (r *ServerRegistry) Remove(id string) error
- func (r *ServerRegistry) Servers() []string
- type ToolResolver
- type ToolResourceRegistrar
- type TypedAppToolConfig
- type UIExtension
Constants ¶
const BridgePath = "/_mcpkit/mcp-app-bridge.js"
BridgePath is the default URL path used by ServeBridge.
Variables ¶
var AppBridgeScript string
AppBridgeScript is the compiled MCP App Bridge JS. Source: assets/mcp-app-bridge.ts.
Functions ¶
func AppShellHTML ¶ added in v0.2.18
func AppShellHTML(title string, bodyHTML string, cfg ...*BridgeConfig) string
AppShellHTML generates a minimal HTML5 document with the bridge pre-injected. Use this in resource handlers that build HTML programmatically rather than from template files.
An optional BridgeConfig sets the app identity for the ui/initialize handshake. Pass nil to use defaults.
func BridgeTemplateDef ¶ added in v0.2.18
func BridgeTemplateDef() string
BridgeTemplateDef returns the raw text of the "mcpkit-bridge" named template definition. Parse it into your template set:
tmpl := template.Must(template.New("page").Parse(pageHTML))
template.Must(tmpl.Parse(ui.BridgeTemplateDef()))
Then use it in your HTML:
{{ template "mcpkit-bridge" .Bridge }}
func ElicitWithApp ¶ added in v0.1.31
func ElicitWithApp(ctx context.Context, req core.ElicitationRequest, ui *core.UIMetadata) (core.ElicitationResult, error)
ElicitWithApp sends an elicitation/create request with MCP Apps metadata. This is a convenience wrapper around core.Elicit that populates _meta.ui so the host can render a UI resource during input collection.
func InjectAppBridge ¶ added in v0.2.18
func InjectAppBridge(html string, cfg ...*BridgeConfig) string
InjectAppBridge inserts the MCP App Bridge <script> block before </body> in the provided HTML. If no </body> is found, the script is appended to the end.
An optional BridgeConfig sets the app identity for the ui/initialize handshake. Pass nil to use the bridge's built-in defaults.
The call is idempotent — if the sentinel comment is already present in html, the original string is returned unchanged.
func RegisterAppTool ¶
func RegisterAppTool(reg ToolResourceRegistrar, cfg AppToolConfig)
RegisterAppTool registers both a tool (with _meta.ui metadata) and its matching ui:// resource in one call. Ensures the tool's resourceUri and the resource URI are consistent, and sets the correct MIME type automatically.
Example:
ui.RegisterAppTool(srv, ui.AppToolConfig{
Name: "build_deck",
Description: "Build a slide deck",
InputSchema: map[string]any{"type": "object"},
ResourceURI: "ui://decks/view",
ToolHandler: buildDeckHandler,
ResourceHandler: serveDeckHTML,
})
func RegisterTypedAppTool ¶ added in v0.2.26
func RegisterTypedAppTool[In, Out any](reg ToolResourceRegistrar, cfg TypedAppToolConfig[In, Out])
RegisterTypedAppTool registers a typed tool + resource pair. It auto-derives InputSchema from the In type parameter and wraps the typed handler, then delegates to RegisterAppTool for all the app-specific wiring (UI metadata, template detection, resource registration, concrete fallback generation).
Example:
type addTaskInput struct {
Title string `json:"title" jsonschema:"required,description=Task title"`
Priority string `json:"priority,omitempty" jsonschema:"enum=low,enum=medium,enum=high"`
}
ui.RegisterTypedAppTool(srv, ui.TypedAppToolConfig[addTaskInput, string]{
Name: "add_task",
Description: "Add a task to the board",
Handler: func(ctx core.ToolContext, input addTaskInput) (string, error) {
return fmt.Sprintf("Added task: %s", input.Title), nil
},
ResourceURI: "ui://tasks/board",
ResourceHandler: serveBoardHTML,
})
func RequestDisplayMode ¶ added in v0.1.31
func RequestDisplayMode(ctx context.Context, mode core.DisplayMode)
RequestDisplayMode sends a display mode change notification to the client. Call this from a tool handler to request the host to change how the app is displayed (e.g., switch from inline to fullscreen).
The notification is fire-and-forget; the host may ignore it if the requested mode is not supported.
func SampleWithApp ¶ added in v0.1.31
func SampleWithApp(ctx context.Context, req core.CreateMessageRequest, ui *core.UIMetadata) (core.CreateMessageResult, error)
SampleWithApp sends a sampling/createMessage request with MCP Apps metadata. This is a convenience wrapper around core.Sample that populates _meta.ui so the host can associate the sampling request with a UI resource.
func ServeBridge ¶ added in v0.2.18
ServeBridge returns an http.Handler that serves the compiled bridge JS. Mount it on your mux alongside MCP and REST handlers:
mux.Handle(ui.BridgePath, ui.ServeBridge())
HTML can then reference it via <script src="/_mcpkit/mcp-app-bridge.js">. Note: sandboxed iframes need the serving origin in their CSP connect-src or resource-src for this to work. For simplest setup, use InjectAppBridge to inline the script instead.
Types ¶
type AppBridge ¶ added in v0.2.41
type AppBridge interface {
// Send sends a JSON-RPC request to the app and waits for the response.
// Used by AppHost to call tools/list and tools/call on the app.
Send(ctx context.Context, req *core.Request) (*core.Response, error)
// SetRequestHandler registers a handler for app→host requests
// (e.g., tools/call, resources/read forwarded to the MCP server).
// Must be called before Start.
SetRequestHandler(fn func(ctx context.Context, req *core.Request) *core.Response)
// SetNotificationHandler registers a handler for app→host notifications
// (e.g., notifications/tools/list_changed, ui/log).
// Must be called before Start.
SetNotificationHandler(fn func(method string, params json.RawMessage))
// Start begins the bridge's communication loop.
Start() error
// Close shuts down the bridge.
Close() error
}
AppBridge abstracts the bidirectional communication channel between the host (AppHost) and the app (iframe JS or in-process Go handler). The protocol is JSON-RPC 2.0, mirroring the postMessage protocol defined in mcp-app-bridge.ts.
type AppHost ¶ added in v0.2.41
type AppHost struct {
// contains filtered or unexported fields
}
AppHost wraps an MCP Client and an AppBridge, mediating between an MCP App (running in a browser iframe or in-process) and an MCP server.
It provides:
- Host→App: ListAppTools and CallAppTool forward requests to the app
- App→Host: app requests (tools/call, resources/read) are forwarded to the server
- Cache: app tool list is cached and refreshed on notifications/tools/list_changed
- Aggregation: ListAllTools merges server and app tools for LLM presentation
func NewAppHost ¶ added in v0.2.41
func NewAppHost(c *client.Client, bridge AppBridge, opts ...AppHostOption) *AppHost
NewAppHost creates an AppHost that mediates between the given MCP Client (connected to a server) and AppBridge (connected to an app).
Call Start() after creating to wire up request/notification routing.
func (*AppHost) CallAppTool ¶ added in v0.2.41
func (h *AppHost) CallAppTool(ctx context.Context, name string, args map[string]any) (*core.ToolResult, error)
CallAppTool invokes a tool registered by the app via the bridge.
func (*AppHost) Close ¶ added in v0.2.41
Close shuts down the bridge. The caller is responsible for closing the underlying Client separately — AppHost does not own the Client lifetime.
func (*AppHost) ListAllTools ¶ added in v0.2.41
ListAllTools returns tools from both the MCP server and the app, suitable for presenting to an LLM. Server tools come first, then app tools.
func (*AppHost) ListAppTools ¶ added in v0.2.41
ListAppTools returns the tools registered by the app. Returns the cached list; the cache is refreshed automatically on notifications/tools/list_changed.
func (*AppHost) RefreshAppTools ¶ added in v0.2.41
RefreshAppTools sends tools/list to the app and updates the cached tool list.
type AppHostOption ¶ added in v0.2.41
type AppHostOption func(*AppHost)
AppHostOption configures an AppHost.
func WithTracerProvider ¶ added in v0.2.47
func WithTracerProvider(tp core.TracerProvider) AppHostOption
WithTracerProvider opts the AppHost into SEP-414 instrumentation of the app→host forward path: when an app sends a request via the bridge (MCPApp.callTool / readResource / sendMessage), AppHost extracts any inbound `params._meta.traceparent` (relayed across the postMessage boundary by the JS bridge's setTraceContextProvider hook) and wraps the forward to the MCP server in an `apps.host.forward` span with that trace context as parent.
Nil and core.NoopTracerProvider{} both skip the install entirely — zero overhead on the unconfigured path. The bridge envelope itself preserves caller-set `_meta.traceparent` regardless of this option; it only governs whether AppHost emits a span around the forward.
type AppToolConfig ¶
type AppToolConfig struct {
// Name is the tool identifier used in tools/call.
Name string
// Title is an optional human-readable display name. Per MCP spec hosts
// SHOULD prefer Title for user-facing surfaces; Name is the machine
// identifier passed to tools/call.
Title string
// Description is a human-readable summary of what the tool does.
Description string
// InputSchema is the JSON Schema for the tool's arguments.
InputSchema any
// OutputSchema is the optional JSON Schema for the tool's
// structuredContent output. When set, the host knows the tool's
// response shape and can validate / render structured results.
OutputSchema any
// Execution declares task-execution metadata for this tool. Most
// non-tasks-v2 tools set this to &core.ToolExecution{TaskSupport:
// "forbidden"} to explicitly signal they don't participate in async
// task flow.
Execution *core.ToolExecution
// ResourceURI is the ui:// URI for the app's HTML resource.
ResourceURI string
// ToolHandler handles tool invocations.
ToolHandler core.ToolHandler
// ResourceHandler serves the HTML content for the ui:// resource.
ResourceHandler core.ResourceHandler
// Visibility controls who can see/call this tool.
// Nil means default (both model and app).
Visibility []core.UIVisibility
// CSP declares external domains the app needs.
CSP *core.UICSPConfig
// Permissions declares Permission-Policy capabilities the App needs.
// See core.UIPermissions for the wire shape. Note that per the MCP Apps
// spec, permissions belong on the UI resource's _meta.ui — set this
// field on your ResourceHandler's per-content Meta to take effect.
// Setting it here flows into the tool's _meta.ui for symmetry, but
// basic-host does not read permissions from tool meta.
Permissions *core.UIPermissions
// PrefersBorder hints whether the host should draw a visible border.
PrefersBorder *bool
// Domain requests a dedicated sandbox origin for the app.
Domain string
// SupportedDisplayModes declares which display modes this app supports.
// Nil means the host decides.
SupportedDisplayModes []core.DisplayMode
// TemplateHandler serves HTML content for a ui:// resource template.
// Required when ResourceURI contains "{" (template variable).
// When set, RegisterAppTool registers a resource template instead of
// a concrete resource.
TemplateHandler core.TemplateHandler
// ResourceDescription is the optional human-readable description for
// the registered ui:// resource (the `description` field on
// resources/list responses). Distinct from `Description` which
// describes the tool. When empty, the resource is registered with
// no description — matches the pre-field behavior. Per
// conformance/RESOURCES_META_AUDIT.md, upstream's per-fixture
// resources/list responses include a description string ("Dashboard
// UI", "PDF Viewer UI", etc.); set this field to surface those for
// parity with upstream.
ResourceDescription string
}
AppToolConfig configures a tool + resource pair for RegisterAppTool.
type BridgeConfig ¶ added in v0.2.18
type BridgeConfig struct {
// App name sent as appInfo.name in ui/initialize. Default: "mcp-app".
Name string
// App version sent as appInfo.version. Default: "0.0.0".
Version string
// Protocol version. Default: "2026-01-26" (current MCP Apps spec).
ProtocolVersion string
}
BridgeConfig customizes the bridge's app identity sent during the ui/initialize handshake with the host.
type BridgeData ¶ added in v0.2.18
type BridgeData struct {
AppName string // App name for ui/initialize handshake
AppVersion string // App version
ProtocolVersion string // MCP Apps spec version (default: "2026-01-26")
BridgeJS template.JS // The bridge runtime JS (trusted, unescaped)
}
BridgeData is the template data for the "mcpkit-bridge" template. Use with html/template — BridgeJS is typed as template.JS so it passes through without escaping; string fields are auto-escaped.
func NewBridgeData ¶ added in v0.2.18
func NewBridgeData(appName, appVersion string) BridgeData
NewBridgeData creates BridgeData with the bridge JS pre-loaded. ProtocolVersion defaults to "2026-01-26" (current MCP Apps spec).
type CollisionHandler ¶ added in v0.2.41
CollisionHandler is called when Add or a tools/list_changed notification creates a new tool name collision. Informational — lets the host log, alert, or adjust its resolver strategy proactively.
type InProcessAppBridge ¶ added in v0.2.41
type InProcessAppBridge struct {
// contains filtered or unexported fields
}
InProcessAppBridge implements AppBridge for testing by dispatching to registered Go handler functions. No iframe, no postMessage — tool registration and dispatch happen entirely in-process.
func NewInProcessAppBridge ¶ added in v0.2.41
func NewInProcessAppBridge() *InProcessAppBridge
NewInProcessAppBridge creates a bridge for testing app-provided tools without an iframe or postMessage transport.
func (*InProcessAppBridge) Close ¶ added in v0.2.41
func (b *InProcessAppBridge) Close() error
Close implements AppBridge.
func (*InProcessAppBridge) RegisterTool ¶ added in v0.2.41
func (b *InProcessAppBridge) RegisterTool(name string, def core.ToolDef, handler func(args map[string]any) (any, error))
RegisterTool simulates app-side tool registration (the Go equivalent of MCPApp.registerTool in the bridge JS). It adds a tool and fires a notifications/tools/list_changed notification to the host.
func (*InProcessAppBridge) RemoveTool ¶ added in v0.2.41
func (b *InProcessAppBridge) RemoveTool(name string)
RemoveTool unregisters a tool and fires notifications/tools/list_changed.
func (*InProcessAppBridge) Send ¶ added in v0.2.41
Send implements AppBridge. It dispatches tools/list and tools/call to the internal tool registry, mirroring handleHostRequest in mcp-app-bridge.ts.
func (*InProcessAppBridge) SendToHost ¶ added in v0.2.41
func (b *InProcessAppBridge) SendToHost(ctx context.Context, method string, params any) (*core.Response, error)
SendToHost simulates an app→host request (e.g., MCPApp.callTool() calling a server-side tool). The request is forwarded to the handler set by AppHost.
func (*InProcessAppBridge) SetNotificationHandler ¶ added in v0.2.41
func (b *InProcessAppBridge) SetNotificationHandler(fn func(method string, params json.RawMessage))
SetNotificationHandler implements AppBridge.
func (*InProcessAppBridge) SetRequestHandler ¶ added in v0.2.41
func (b *InProcessAppBridge) SetRequestHandler(fn func(ctx context.Context, req *core.Request) *core.Response)
SetRequestHandler implements AppBridge.
func (*InProcessAppBridge) Start ¶ added in v0.2.41
func (b *InProcessAppBridge) Start() error
Start implements AppBridge. For in-process bridges this is a no-op.
type RegisteredTool ¶ added in v0.2.41
type RegisteredTool struct {
core.ToolDef
ServerID string `json:"serverId"` // which server owns this tool
Source string `json:"source"` // "server" or "app"
}
RegisteredTool is a tool with routing metadata attached. The tool name stays clean (no server ID prefix) — routing is via ServerID sidecar.
type RegistryOption ¶ added in v0.2.41
type RegistryOption func(*ServerRegistry)
RegistryOption configures a ServerRegistry.
func WithCollisionHandler ¶ added in v0.2.41
func WithCollisionHandler(fn CollisionHandler) RegistryOption
WithCollisionHandler sets a callback for tool name collision notifications.
func WithRegistryNotificationHandler ¶ added in v0.2.41
func WithRegistryNotificationHandler(fn func(serverID, method string, params any)) RegistryOption
WithRegistryNotificationHandler sets a unified notification handler that receives notifications from all servers, tagged with the server ID.
func WithToolResolver ¶ added in v0.2.41
func WithToolResolver(fn ToolResolver) RegistryOption
WithToolResolver sets the resolver for ambiguous tool names.
type ServerRegistry ¶ added in v0.2.41
type ServerRegistry struct {
// contains filtered or unexported fields
}
ServerRegistry manages connections to multiple MCP servers and provides unified tool aggregation and routing. Each server can have its own auth, app bridge, and reconnection policy.
func NewServerRegistry ¶ added in v0.2.41
func NewServerRegistry(opts ...RegistryOption) *ServerRegistry
NewServerRegistry creates a registry for managing multiple MCP server connections with unified tool routing.
func (*ServerRegistry) Add ¶ added in v0.2.41
Add registers a connected MCP client under the given server ID. The client must already be connected (via client.Connect). The caller owns client construction and auth configuration — the registry only manages routing.
func (*ServerRegistry) AddWithBridge ¶ added in v0.2.41
func (r *ServerRegistry) AddWithBridge(ctx context.Context, id string, c *client.Client, bridge AppBridge) error
AddWithBridge registers a connected MCP client with an app bridge. The bridge enables app-provided tool aggregation and host↔app request routing.
func (*ServerRegistry) AllTools ¶ added in v0.2.41
func (r *ServerRegistry) AllTools(ctx context.Context) ([]RegisteredTool, error)
AllTools returns all tools from all servers with routing metadata. Server tools come first (grouped by server ID), then app tools.
func (*ServerRegistry) CallTool ¶ added in v0.2.41
func (r *ServerRegistry) CallTool(ctx context.Context, name string, args map[string]any) (*core.ToolResult, error)
CallTool routes a tool call by name. If the name is unambiguous (only one server has it), routes directly. If ambiguous, invokes the ToolResolver. If no resolver is set, returns a descriptive error listing candidates.
func (*ServerRegistry) CallToolOn ¶ added in v0.2.41
func (r *ServerRegistry) CallToolOn(ctx context.Context, serverID, name string, args map[string]any) (*core.ToolResult, error)
CallToolOn routes a tool call to a specific server, bypassing resolution.
func (*ServerRegistry) Close ¶ added in v0.2.41
func (r *ServerRegistry) Close() error
Close shuts down all servers in the registry. Closes app bridges but not the underlying clients (caller owns client lifetime).
func (*ServerRegistry) Remove ¶ added in v0.2.41
func (r *ServerRegistry) Remove(id string) error
Remove disconnects and removes a server. Closes the app bridge if present. Does NOT close the underlying client — the caller owns client lifetime.
func (*ServerRegistry) Servers ¶ added in v0.2.41
func (r *ServerRegistry) Servers() []string
Servers returns the IDs of all registered servers, sorted alphabetically.
type ToolResolver ¶ added in v0.2.41
type ToolResolver func(ctx context.Context, name string, candidates []RegisteredTool, args map[string]any) (serverID string, err error)
ToolResolver is called when CallTool hits an ambiguous tool name (same name registered by multiple servers). It receives the candidates and the call arguments, and returns the server ID to route to.
Implementations can use any strategy: static priority, arg-based routing, LLM sampling, user elicitation, round-robin, etc.
type ToolResourceRegistrar ¶
type ToolResourceRegistrar interface {
RegisterTool(def core.ToolDef, handler core.ToolHandler)
RegisterResource(def core.ResourceDef, handler core.ResourceHandler)
RegisterResourceTemplate(def core.ResourceTemplate, handler core.TemplateHandler)
}
ToolResourceRegistrar is the interface needed by RegisterAppTool to register tools, resources, and resource templates. Satisfied by *server.Server without importing it.
type TypedAppToolConfig ¶ added in v0.2.26
type TypedAppToolConfig[In, Out any] struct { // Name is the tool identifier used in tools/call. Name string // Title is an optional human-readable display name. Per MCP spec hosts // SHOULD prefer Title for user-facing surfaces; Name remains the // machine identifier passed to tools/call. Title string // Description is a human-readable summary of what the tool does. Description string // Execution declares task-execution metadata for this tool. Most // non-tasks-v2 tools set this to &core.ToolExecution{TaskSupport: // "forbidden"} to explicitly signal they don't participate in async // task flow. Execution *core.ToolExecution // InputSchemaOverride replaces the InputSchema that would otherwise be // auto-derived from the In type parameter. Use when struct-tag-based // reflection can't produce the exact schema you need — e.g., defaults or // descriptions containing commas (invopop's tag parser truncates at the // first comma; see issue 542), schemas using JSON Schema 2020-12 // features (if/then/else, $anchor, complex allOf composition), or // fixtures that need byte-for-byte parity with an external reference // schema. // // When set, the handler still unmarshals into In, so the override must // stay compatible with In's wire shape (same field names + types). Pass // a json.RawMessage or any value that marshals to the desired JSON // Schema. InputSchemaOverride any // OutputSchemaOverride is the symmetric mirror of InputSchemaOverride for // the OutputSchema field. Use when Out's auto-derived schema can't be // made byte-identical to an external reference — common cases are // nullable types (upstream's `z.string().nullable()` wants // `{"type": ["string", "null"]}` which Go reflection won't produce), // `interface{}` / `any` fields that invopop reflects to schemas strict // MCP-SDK clients reject, or apps/compat fixtures that need byte-for-byte // parity with an upstream reference. // // The override is preserved as-is on the wire. The handler still returns // Out, so the override must stay compatible with Out's wire shape. OutputSchemaOverride any // InputSchemaPatch runs against the reflected input schema after // generation. The patch fn sees a SchemaBuilder over the live map // and edits in place (e.g., `s.Prop("url").Desc(...).Default(...)`). // Lighter-weight than InputSchemaOverride for the common case of // "tweak a few fields"; falls back to Override-style replacement // via `PropertyBuilder.Replace(...)` for the irreducible cases // (nullable, anyOf, record-of-union). Precedence: if both // InputSchemaOverride and InputSchemaPatch are set, Override wins // and Patch is silently skipped. Issue 556. InputSchemaPatch func(*core.SchemaBuilder) // OutputSchemaPatch is the symmetric mirror for the output schema. // Skipped when Out is `string` / `core.ToolResult` / `core.ToolResponse` // (those don't generate an output schema). Same Override/Patch // precedence rule as InputSchemaPatch. Issue 556. OutputSchemaPatch func(*core.SchemaBuilder) // Handler handles tool invocations with typed input. Handler func(ctx core.ToolContext, input In) (Out, error) // ResourceURI is the ui:// URI for the app's HTML resource. ResourceURI string // ResourceHandler serves the HTML content for the ui:// resource. ResourceHandler core.ResourceHandler // Visibility controls who can see/call this tool. Visibility []core.UIVisibility // CSP declares external domains the app needs. CSP *core.UICSPConfig // Permissions declares Permission-Policy capabilities the App needs. // See core.UIPermissions for the wire shape. Note that per the MCP Apps // spec, permissions belong on the UI resource's _meta.ui — set this // field on your ResourceHandler's per-content Meta to take effect. // Setting it here flows into the tool's _meta.ui for symmetry, but // basic-host does not read permissions from tool meta. Permissions *core.UIPermissions // PrefersBorder hints whether the host should draw a visible border. PrefersBorder *bool // Domain requests a dedicated sandbox origin for the app. Domain string // SupportedDisplayModes declares which display modes this app supports. SupportedDisplayModes []core.DisplayMode // TemplateHandler serves HTML content for a ui:// resource template. TemplateHandler core.TemplateHandler // ResourceDescription is the human-readable description for the ui:// // resource registered alongside the tool (the `description` field on // resources/list responses). Distinct from `Description` which describes // the tool. Set this to surface per-fixture descriptions on // resources/list (matches upstream's per-fixture convention; documented // in conformance/RESOURCES_META_AUDIT.md). ResourceDescription string }
TypedAppToolConfig configures a typed tool + resource pair for RegisterTypedAppTool. It replaces AppToolConfig's InputSchema and ToolHandler with a typed handler — the schema is auto-derived from the In type parameter, and the handler receives typed input.
type UIExtension ¶
type UIExtension struct{}
UIExtension declares support for the MCP Apps extension. Register it on the server to advertise UI rendering capability in the initialize response. Also validates that tools referencing ui:// resources have matching resource registrations (via RefValidator).
func (UIExtension) Extension ¶
func (UIExtension) Extension() core.Extension
Extension returns the MCP Apps extension metadata.
func (UIExtension) ValidateRefs ¶
func (UIExtension) ValidateRefs(tools []core.ToolDef, resourceURIs []string, templateURIs []string) []string
ValidateRefs checks that all tools with _meta.ui.resourceUri reference a registered resource or matching template. Returns warnings for unresolvable references. Implements core.RefValidator.