* fix(types): forbid csp/permissions on McpUiToolMeta via never
Hosts read _meta.ui.csp and _meta.ui.permissions from the resource
(resources/read content item, with resources/list entry as fallback),
never from the tool. Typing them as `never` on McpUiToolMeta gives
TypeScript users a compile-time error pointing at McpUiResourceMeta
instead of silently accepting and ignoring them.
Companion to anthropics/apps#38705 (host-side console.warn).
Refs anthropics/claude-ai-mcp#40.
* drop misleading #40 link from McpUiToolMeta.csp JSDoc
* feat: MCP app sampling support via stock SDK types
Alternative to #477. Instead of forking a stripped-down sampling schema,
this reuses the stock `CreateMessageRequest` / `CreateMessageResult` /
`CreateMessageResultWithTools` types from `@modelcontextprotocol/sdk`
directly — same pattern already used for `tools/call`.
- Spec: `sampling/createMessage` listed under `### Standard MCP Messages`,
`sampling?: { tools?: {} }` added to `HostCapabilities` (mirrors MCP
`ClientCapabilities.sampling` shape for easy pass-through).
- SDK: `App.createSamplingMessage()` with overloads that narrow the return
type based on whether `params.tools` is set; `AppBridge.oncreatesamplingmessage`
setter; `CreateMessageRequest`/`CreateMessageResult*` added to the
`AppRequest`/`AppResult` unions.
- Picks up SEP-1577 tool-calling support (`tools`, `toolChoice`, `tool_use`
content blocks, `stopReason: "toolUse"`, array content) for free — unblocks
the "nested agents" use case motivated by the original PR.
https://claude.ai/code/session_01ENGWTtsfcyP4S6fTWtUMAh
* feat(app): guard createSamplingMessage before handshake completes
---------
Co-authored-by: Claude <noreply@anthropic.com>
The generated schemas compose with schemas imported from
@modelcontextprotocol/sdk/types.js (e.g. z.array(ContentBlockSchema)).
The SDK constructs its schemas via `import * as z from 'zod/v4'`, but
our generated schema.ts used `import { z } from "zod"` — which returns
the v3 API when the consumer has zod 3.25.x installed.
Mixing v3-created and v4-created schema instances throws at parse time
with errors like `keyValidator._parse is not a function` because zod v4
dropped the `_parse` / `_parseSync` internals that v3 wrappers call.
This was masked before #534 because zod was bundled — all schema
creation shared the same inlined zod copy. Externalizing zod exposed
the mismatch on consumers pinned to zod 3.x (e.g. anthropics/apps).
The `zod/v4` subpath is exported by both zod 3.25+ and zod 4.x, so the
existing peerDependency range `^3.25.0 || ^4.0.0` is preserved.
https://claude.ai/code/session_013xQUegrvVGct5xpqeSL5av
Co-authored-by: Claude <noreply@anthropic.com>
Replace custom {filename, content, mimeType, encoding} params with
standard MCP resource types: EmbeddedResource for inline content and
ResourceLink for host-resolved references.
New params shape:
params: { contents: (EmbeddedResource | ResourceLink)[] }
This reuses existing MCP primitives instead of inventing new ones,
and enables hosts to show resource 'bubbles' or resolve ResourceLink
URIs via resources/read on the MCP server.
Add a new ui/download-file JSON-RPC request that allows MCP App views to
request file downloads through the host. Since MCP Apps run in sandboxed
iframes where direct downloads are blocked (allow-downloads not set),
this provides a host-mediated mechanism for file exports.
Spec changes (draft):
- Add ui/download-file request to Requests (View → Host) section
- Add downloadFile capability to HostCapabilities
- Document host behavior requirements (confirmation dialog, filename
sanitization, base64 decoding, size limits)
SDK changes:
- Add McpUiDownloadFileRequest/Result interfaces to spec.types.ts
- Add downloadFile() method to App class
- Add ondownloadfile setter to AppBridge class
- Add DOWNLOAD_FILE_METHOD constant
- Generate Zod schemas
Example:
- Add download demo to integration-server (exports JSON with server time)
- Capability check: only shows download button when host advertises
downloadFile capability
Based on developer feedback requesting file export capabilities for
visualization tools, document editors, and data analysis apps.
The term "external" is misleading for MCP Apps because developers
typically interpret it as "third-party." However, MCP App HTML runs in
a sandboxed iframe with no same-origin server, so *all* origins must be
declared—including where your own bundled JS/CSS is served from. Using
"network" instead avoids this confusion and aligns with the detailed
explanations in `patterns.md` and `spec.types.ts`.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: add stable spec release 2026-01-26
- Use git mv to copy specification from draft to specification/2026-01-26/apps.mdx (preserves history)
- Update status from 'Draft' to 'Stable (2026-01-26)'
- Add specification version table to README
- Update Resources section with links to both stable and draft specs
* chore: bump version to 1.0.0
- Update main package version from 0.4.2 to 1.0.0
- Update all example package versions to 1.0.0
- Regenerate package-lock.json
* prettier
* chore: align protocol version with spec release 2026-01-26
- Add 'Protocol Version: 2026-01-26' to spec header
- Update LATEST_PROTOCOL_VERSION from '2025-11-21' to '2026-01-26'
- Update spec examples to use '2026-01-26' protocol version
- Add '2025-11-21' to SUPPORTED_PROTOCOL_VERSIONS for backwards compatibility
* chore: update spec references to stable 2026-01-26
- Update typedoc.config.mjs navigation link
- Update docs/overview.md spec links (10 occurrences)
- Update plugins/mcp-apps/skills/create-mcp-app/SKILL.md spec link
- Update src/spec.types.ts @see links
- Update AGENTS.md spec path
- Regenerate src/generated/schema.ts with updated links
* chore: simplify versioning - first stable release
- Remove backwards compatibility version (2025-11-21) - this is the first stable release
- Remove redundant 'Protocol Version' header - spec version IS the protocol version
* chore: add history reference comment to stable spec
* Add appCapabilities.availableDisplayModes documentation to spec
Document the availableDisplayModes field in McpUiAppCapabilities that allows
apps to declare which display modes they support. This enables hosts to
compute the intersection of host and app capabilities and only offer
appropriate display mode controls.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Address PR review feedback
- Change "Guest UI" to "View" terminology
- Add "View" prefix to availableDisplayModes heading for disambiguation
- Remove intersection logic - host only checks its own supported modes
- Remove assumption that apps must support inline mode
- Simplify host behavior to honor/reject based on its own capabilities
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add appCapabilities.availableDisplayModes to types
- Add `availableDisplayModes` field to `McpUiAppCapabilities` so apps can
declare which display modes they support
- Change `HostContext.availableDisplayModes` type from `string[]` to
`McpUiDisplayMode[]` for type safety
- Regenerate schemas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Address Olivier's feedback - consolidate display mode docs
- Remove separate "App Capabilities" section for availableDisplayModes
- Add display mode requirements to existing ui/request-display-mode section:
- Host MUST NOT switch View to mode not in appCapabilities.availableDisplayModes
- Host MAY decline requests from Views that didn't declare modes
- View MUST declare supported modes during initialization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Restore McpUiAppCapabilities docs and fix display mode clause
- Restore McpUiAppCapabilities interface documentation with availableDisplayModes
- Restore "View MUST check if the requested mode is in availableDisplayModes
from host context" clause that was accidentally removed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Create unified Display Modes section
Consolidate all display mode documentation into a single section:
- Display mode types (inline, fullscreen, pip)
- Declaring support from View (appCapabilities.availableDisplayModes)
- Declaring support from Host (HostContext.availableDisplayModes)
- Requesting changes (ui/request-display-mode)
- Notifying changes (ui/notifications/host-context-changed)
- All MUST/SHOULD requirements for View and Host behavior
The ui/request-display-mode in Requests section now references
the Display Modes section for behavior details.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Remove mode coercion clause from display modes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Regenerate schemas with correct version
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* feat(server): add hasUiSupport/getUiCapability for experimental+extensions
Support double-tagging for MCP Apps capability negotiation:
- Check both experimental and extensions fields in client capabilities
- Add hasUiSupport() to easily check if client supports MCP Apps
- Add getUiCapability() to retrieve the capability settings
- Update spec to document both capability locations
This enables forward compatibility as MCP transitions from experimental
to the extensions field (SEP-1724).
Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 0
Claude-Permission-Prompts: 0
Claude-Escapes: 0
* fix: update @types/node version in package-lock.json
Replace invalid 22.19.5/22.19.6/22.19.7 versions with valid 22.19.3
* docs(spec): clarify hosts SHOULD double-tag, servers SHOULD check both
- Hosts SHOULD advertise capabilities in both experimental and extensions
- Servers SHOULD check both locations, preferring extensions when present
- Updated example to show double-tagging pattern
* chore: remove double-tagging recommendation, keep hasUiSupport helper
Reverts the spec changes that recommended clients double-tag capabilities
in both experimental and extensions fields. The helper functions remain
as they're useful for checking capability in either location.
* refactor(server): simplify to only getUiCapability, remove hasUiSupport
- Remove hasUiSupport function (use getUiCapability directly)
- Remove double-tagging logic (only check extensions field)
- Add ClientCapabilitiesWithExtensions type using SDK's ClientCapabilities
- Update spec to use getUiCapability
- Simplify tests
* fix: update @see link to getUiCapability
* refactor(server): inline ClientCapabilitiesWithExtensions type in getUiCapability
* refactor: move McpUiClientCapabilities to spec.types.ts
* docs: standardize UI terminology to use "view" consistently
Replaces "widget" and "Guest UI" terminology with "view" across
the codebase as decided in the community survey.
This change updates:
- Specification document
- SDK source code and JSDoc comments
- Example servers and documentation
- Plugin documentation and skills
Closes#71
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add explicit backtick-wrapped display text to all `{@link}` tags for
monospace rendering in TypeDoc output. This improves readability by:
- Using monospace font for code references (types, methods, functions)
- Stripping module prefixes from display text (e.g., `app!App.connect`
displays as `App.connect`)
Updated files across the SDK including `App`, `AppBridge`,
`PostMessageTransport`, React hooks, server helpers, types, and
documentation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Key improvements:
- Add `{@link}` cross-references throughout the codebase to make API
documentation navigable and help AI models understand relationships
- Use `{@link module!Export}` syntax for cross-module references
- Add backticks for inline code formatting (`ResizeObserver`, `App`, etc)
- Fix `PostMessageTransport` examples to show required two-argument form
- Clarify `onteardown` callback return type requirement
- Document React hooks cleanup behavior and Strict Mode considerations
- Add tool visibility example for `registerAppTool`
- Add CSP example for `registerAppResource`
- Fix notification direction documentation in `spec.types.ts`
TypeDoc config migrated from `typedoc.json` to `typedoc.config.mjs` to:
- Support custom `@description` block tag
- Add `intentionallyNotExported` for internal types
- Include `src/server/index.ts` entry point
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add transcript-server example with live speech transcription
- New example: transcript-server with Web Speech API transcription
- Start/stop recording with timer display
- Live transcript with interim results
- Send button to send transcript as ui/message to host
- Copy button to copy full transcript
- Sent messages marked with divider, greyed out
- Experimental ui/update-model-context for live context updates
- Transparent background, respects host theme
- Enable microphone and clipboard in basic-host sandbox iframes
- Add allow="microphone; clipboard-write" to both outer and inner iframes
- Required for Web Speech API, audio capture, and clipboard access
- Add alert popup in basic-host for ui/message from apps
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* style: format transcript-server files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test: add e2e test and golden for transcript-server
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: use @types/dom-speech-recognition instead of hand-rolled types
Removes ~50 lines of manually defined Web Speech API types in favor of
the community-maintained type package.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: add newlines between transcript chunks when copying to clipboard
* refactor: unify transcript formatting with timestamps
- Add formatEntry() helper that includes [timestamp] prefix
- Add formatEntries() helper that joins entries with newlines
- Use same format for clipboard copy, send message, and model context
- DRY up duplicate code in send button handler
* fix: log model context update failures instead of silently swallowing
* fix: log model context updates for debugging
* refactor: pass permissions through loadSandboxProxy like csp
- Add permissions parameter to loadSandboxProxy in implementation.ts
- Build iframe allow attribute from permissions instead of hardcoding
- Update sandbox.ts to not hardcode allow attribute (set via notification)
- Add microphone + clipboardWrite permissions to transcript-server resource
- Update README to reflect permission configuration via resource _meta.ui
* fix(transcript-server): auto-expand instead of scroll
- Remove min-height: 100vh and overflow-y: auto
- Let content grow naturally with autoResize (default)
- Remove unnecessary scrollTop calls
* test: remove transcript timer mask (no longer dynamic)
* refactor: pass permissions through loadSandboxProxy like csp
* docs: document updateModelContext for transitional speech
* test: update e2e screenshots
* refactor: use app.updateModelContext() instead of raw request
* package-lock.json
* src/generated/schema.json
* test: update e2e screenshots from CI
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a new MCP App example that renders ShaderToy-compatible GLSL
fragment shaders in real-time using WebGL 2.0 and ShaderToyLite.js.
Features:
- Standard ShaderToy uniforms (`iTime`, `iResolution`, `iMouse`, etc.)
- Multi-pass rendering with buffers A-D for feedback effects
- Shader compilation error overlay
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* fix: Move CSP to HTTP headers + add worker-src, frameDomains, baseUriDomains, permissions
Security improvements:
- CSP is now set via HTTP headers in serve.ts instead of meta tags
(meta tag CSP can be tampered with by same-origin content)
- CSP passed as query param to sandbox.html for header-based enforcement
New CSP/permissions features (borrowed from PR #158):
- frameDomains: control frame-src directive for nested iframes
- baseUriDomains: control base-uri directive
- permissions: camera, microphone, geolocation via iframe allow attribute
WebGL fix:
- Use document.write() instead of srcdoc for inner iframe content
(srcdoc creates opaque origin that breaks WebGL canvas updates)
- Add worker-src directive with blob: support (critical for WebGL apps
like CesiumJS/Three.js that use workers for tile decoding, terrain
processing, image processing)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: Remove permissions support (defer to PR #158)
Keep this PR focused on CSP security fixes only.
Permissions (camera, microphone, geolocation) will be
handled in #158.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* cleanup McpUiResourceCsp type usage / duplicate defs
* fix: guard against CSP injection in domain parameters
Validate CSP domain entries to reject characters that could:
- Break out of CSP directives (semicolons, newlines)
- Inject CSP keywords like 'unsafe-eval' (quotes)
- Inject multiple sources in one entry (spaces)
This prevents injection attacks where malicious domains could
override the security policy.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* feat: publish example servers to npm
Make example MCP App servers publishable to npm under the
@modelcontextprotocol scope:
- server-basic-react
- server-basic-vanillajs
- server-budget-allocator
- server-cohort-heatmap
- server-customer-segmentation
- server-scenario-modeler
- server-system-monitor
- server-threejs
- server-wiki-explorer
Changes:
- Remove `private: true` from example package.json files
- Add proper npm metadata (description, repository, license, files)
- Update ext-apps dependency from relative to ^0.2.2
- Copy server-utils.ts into each package for standalone use
- Add publish-examples job to npm-publish.yml workflow
The examples will be published automatically when a GitHub release
is created, after the main SDK package is published.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: publish examples with pkg-pr-new for PR testing
* feat: export createServer from example servers
* style: format integration-server/server.ts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: update e2e snapshots for basic-server examples
Update golden screenshots for basic-react and basic-vanillajs after
the tool output was simplified from JSON to plain text in #182.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* merge
* refactor: update sheet-music-server and video-resource-server to new publishing pattern
- Move server-utils.ts from src/ to root level
- Add npm publishing metadata (scoped name, repository, license, files)
- Change ext-apps dependency from local to versioned ^0.2.2
- Update server.ts to handle stdio mode inline
* update package-lock
* fix: update package-lock.json for renamed server packages
* feat: add NASA public domain video to video-resource-server
Added 'nasa-earth' option - NASA ISS Earth observations (6.4MB).
Source: archive.org/details/NASA-Ultra-High-Definition (public domain)
* fix: add default videoId for video-resource-server
* fix: use existing bunny-1mb as default video, remove nasa-earth
* refactor: update new framework examples to publishing pattern
Add publishing metadata for:
- @modelcontextprotocol/server-basic-preact
- @modelcontextprotocol/server-basic-solid
- @modelcontextprotocol/server-basic-svelte
- @modelcontextprotocol/server-basic-vue
Changes:
- Move server-utils.ts from src/ to root
- Add npm publishing metadata
- Update ext-apps dep to versioned ^0.2.2
- Add stdio mode support in main()
* fix: add missing @rollup/rollup-win32-arm64-msvc to optionalDependencies
This fixes the Windows ARM64 CI build failure caused by npm's optional
dependency bug. The package.json was missing this platform-specific
rollup binding.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
The spec (apps.mdx) defines toolInfo.id as optional (id?: RequestId),
but the TypeScript types and generated schemas had it as required.
This allows hosts to pass just the tool definition without needing
a request ID, which is useful when the tool name is the primary
information needed by the widget.
* feat: make generated Zod schemas version-agnostic (v3.25+/v4)
- Change generated schema imports from `zod/v4` to standard `zod`
- Replace v4-only `z.looseObject()` with `z.object().passthrough()`
- Works with both Zod v3.25+ and v4, matching MCP TS SDK approach
- Bump version to 0.2.2
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: regenerate package-lock.json in Docker
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* refactor: rename request methods to remove send prefix
Following the MCP TS SDK convention where request methods don't have
the "send" prefix (reserved for notifications):
- App.sendMessage() → App.message()
- App.sendOpenLink() → App.openLink()
- AppBridge.sendResourceTeardown() → AppBridge.resourceTeardown()
The old method names are kept as deprecated aliases for backwards
compatibility.
Updated all examples to use the new method names.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add tests for deprecated method aliases
- Update existing tests to use new method names (message, openLink)
- Add tests verifying deprecated aliases are same reference as new methods
- Add tests verifying deprecated aliases still work functionally
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor: rename message→sendMessage, resourceTeardown→teardownResource
- App.message() → App.sendMessage() (with deprecated message alias)
- AppBridge.resourceTeardown() → AppBridge.teardownResource() (with deprecated aliases)
This better follows the pattern where methods that send data have 'send' or action verb prefix.
* fix: update examples to use sendMessage instead of message
* fix: update basic-host to use teardownResource
* fix: update threejs-server to use sendMessage
* refactor: remove deprecated app.message alias
The app.message alias was removed since sendMessage is the correct name.
sendResourceTeardown already exists in AppBridge.
* refactor: remove resourceTeardown alias, keep only sendResourceTeardown
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs: add tool visibility and restructure _meta.ui
- Restructure tool metadata: `_meta["ui/resourceUri"]` → `_meta.ui.resourceUri`
- Add `visibility` array field: ["model"], ["apps"], or ["model", "apps"]
- Default ["model"] preserves standard MCP behavior
- ["apps"] enables widget-only tools hidden from agent
- Add McpUiToolMeta interface for type safety
- Add Design Decision #4 explaining approach vs OpenAI's two-field model
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* address PR review comments
- Change default visibility to ["model", "apps"]
- Add deprecation notice for flat ui/resourceUri format
- Add McpUiToolMeta and McpUiToolVisibility to spec.types.ts
- Improve tools/list and tools/call behavior wording
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: regenerate schemas for McpUiToolMeta types
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: tool visibility and nested _meta.ui format
- Rename visibility "apps" → "app" in McpUiToolVisibility type
- Add _meta.ui.resourceUri nested format (deprecate flat format)
- Add getToolUiResourceUri() utility with backward compatibility
- Add visibility demo to system-monitor-server:
- get-system-stats: visibility ["model"] with resourceUri
- refresh-stats: visibility ["app"] (app-only polling)
- Update all example servers to use new _meta.ui format
- Add 11 unit tests for getToolUiResourceUri()
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* chore: regenerate schemas with updated dependencies
* feat: export McpUiToolMeta type and add type annotations
- Export McpUiToolMeta and McpUiToolVisibility types from types.ts
- Export corresponding Zod schemas (McpUiToolMetaSchema, McpUiToolVisibilitySchema)
- Add `as McpUiToolMeta` type annotations to all example servers
- Update docs/quickstart.md with proper typing
Ensures type safety for `_meta.ui` tool metadata across the codebase.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: add server helpers and optional connect() transport
Add `src/server/` with convenience functions for registering MCP App tools
and resources:
- `registerAppTool(server, name, config, handler)`
- `registerAppResource(server, name, uri, config, callback)`
The `transport` parameter in `App.connect()` is now optional, defaulting to
`PostMessageTransport(window.parent)`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update src/server/index.ts
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
* feat: update McpUiAppToolConfig to support both _meta.ui and flat formats
* refactor: simplify server helper imports
* docs: add deprecation notice and improve resourceUri documentation
* feat: add backward compat normalization in registerAppTool
- If _meta.ui.resourceUri is set, also set legacy flat key
- If legacy flat key is set, also set _meta.ui.resourceUri
- Preserves existing visibility when merging
- Does not overwrite if both formats already set
* refactor: avoid mutating config arg in registerAppTool
* style: format with prettier
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Updated screenshots to reflect UI changes from styles addition.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>