@@ -41,6 +41,34 @@ Host calls tool → Server returns result → Host renders resource UI → UI re
4141- Register tools and resources
4242- Configure build system with ` vite-plugin-singlefile `
4343
44+ ### Checking Host UI Support
45+
46+ Not all hosts support MCP Apps. Use ` hasUiSupport() ` to conditionally register UI-enabled tools:
47+
48+ ``` typescript
49+ import { hasUiSupport , registerAppTool } from " @modelcontextprotocol/ext-apps/server" ;
50+
51+ server .oninitialized = ({ clientCapabilities }) => {
52+ if (hasUiSupport (clientCapabilities )) {
53+ // Register tool with UI
54+ registerAppTool (server , " weather" , {
55+ description: " Get weather with interactive dashboard" ,
56+ _meta: { ui: { resourceUri: " ui://weather/dashboard" } },
57+ }, weatherHandler );
58+ } else {
59+ // Register text-only fallback for hosts without UI support
60+ server .registerTool (" weather" , {
61+ description: " Get weather as text" ,
62+ }, textWeatherHandler );
63+ }
64+ };
65+ ```
66+
67+ ** Key points:**
68+ - Check ` clientCapabilities ` in ` oninitialized ` callback
69+ - ` hasUiSupport() ` checks both ` experimental ` and ` extensions ` fields
70+ - Provide text-only fallback for non-UI hosts
71+
4472## Getting Reference Code
4573
4674Clone the SDK repository for working examples and API documentation:
@@ -312,6 +340,30 @@ See `examples/shadertoy-server/` for complete implementation.
3123406 . ** No text fallback** - Always provide ` content ` array for non-UI hosts
3133417 . ** Hardcoded styles** - Use host CSS variables for theme integration
3143428 . ** No streaming for large inputs** - Use ` ontoolinputpartial ` to show progress during generation
343+ 9 . ** Binary/large data in ` content ` or ` structuredContent ` ** - Use ` _meta ` to avoid polluting model context
344+
345+ ## Data Handling: content vs structuredContent vs _ meta
346+
347+ | Field | Goes to model? | Use for |
348+ | -------| ---------------| ---------|
349+ | ` content ` | ✅ YES | Text summary for model |
350+ | ` structuredContent ` | ✅ YES | Structured data for model + UI |
351+ | ` _meta ` | ❌ NO | Binary data, large blobs, UI-only data |
352+
353+ ** Critical** : Binary/large data MUST go in ` _meta ` to avoid wasting tokens and confusing the model.
354+
355+ ``` typescript
356+ // ❌ WRONG - base64 pollutes model context
357+ return {
358+ content: [{ type: " image" , data: base64Image , mimeType: " image/png" }]
359+ };
360+
361+ // ✅ CORRECT - model gets summary, UI gets data from _meta
362+ return {
363+ content: [{ type: " text" , text: " Generated QR code for: example.com" }],
364+ _meta: { imageData: base64Image , mimeType: " image/png" }
365+ };
366+ ```
315367
316368## Testing
317369
0 commit comments