[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-aws-labs-migrate-oai-app":3,"mdc-kyvah0-key":36,"related-org-aws-labs-migrate-oai-app":1759,"related-repo-aws-labs-migrate-oai-app":1939},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":26,"repoUrl":27,"updatedAt":28,"license":29,"forks":30,"topics":31,"repo":32,"sourceUrl":34,"mdContent":35},"migrate-oai-app","migrate OpenAI applications to MCP","This skill should be used when the user asks to \"migrate from OpenAI Apps SDK\", \"convert OpenAI App to MCP\", \"port from window.openai\", \"migrate from skybridge\", \"convert openai\u002FoutputTemplate\", or needs guidance on converting OpenAI Apps SDK applications to MCP Apps SDK. Provides step-by-step migration guidance with API mapping tables.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"aws-labs","AWS Labs","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Faws-labs.png","awslabs",[13,17,20,23],{"name":14,"slug":15,"type":16},"Migration","migration","tag",{"name":18,"slug":19,"type":16},"MCP","mcp",{"name":21,"slug":22,"type":16},"OpenAI","openai",{"name":24,"slug":25,"type":16},"API Development","api-development",871,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator","2026-07-12T08:41:42.880724",null,164,[],{"repoUrl":27,"stars":26,"forks":30,"topics":33,"description":29},[],"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fcli-agent-orchestrator\u002Ftree\u002FHEAD\u002Fskills\u002Fvendor\u002Fext-apps\u002Fmigrate-oai-app","---\nname: migrate-oai-app\ndescription: This skill should be used when the user asks to \"migrate from OpenAI Apps SDK\", \"convert OpenAI App to MCP\", \"port from window.openai\", \"migrate from skybridge\", \"convert openai\u002FoutputTemplate\", or needs guidance on converting OpenAI Apps SDK applications to MCP Apps SDK. Provides step-by-step migration guidance with API mapping tables.\n---\n\n# Migrate OpenAI App to MCP\n\nMigrate existing OpenAI Apps SDK applications to the MCP Apps SDK (`@modelcontextprotocol\u002Fext-apps`). The MCP Apps SDK provides a standardized, open protocol for interactive UIs in conversational clients.\n\n## Best Practices\n\n- Use your package manager to add dependencies (e.g., `npm install`, `pnpm add`, `yarn add`) instead of manually writing version numbers. This lets the package manager resolve the latest compatible versions. Never specify version numbers from memory.\n- Preemptively add a final todo item with this exact wording: \"Re-read the 'Before Finishing' checklist in this skill and address each checkbox individually, stating what you did for each one, before marking this todo complete.\"\n\n## Getting Reference Code\n\nClone the SDK repository for complete migration documentation and working examples:\n\n```bash\ngit clone --branch \"v$(npm view @modelcontextprotocol\u002Fext-apps version)\" --depth 1 https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fext-apps.git \u002Ftmp\u002Fmcp-ext-apps\n```\n\n### Migration Reference Guide\n\nRead the migration reference guide with \"before\u002Fafter\" mapping tables: `\u002Ftmp\u002Fmcp-ext-apps\u002Fdocs\u002Fmigrate_from_openai_apps.md`\n\n### API Reference (Source Files)\n\nRead JSDoc documentation directly from `\u002Ftmp\u002Fmcp-ext-apps\u002Fsrc\u002F*`:\n\n| File | Contents |\n|------|----------|\n| `src\u002Fapp.ts` | `App` class, handlers, lifecycle |\n| `src\u002Fserver\u002Findex.ts` | `registerAppTool`, `registerAppResource` |\n| `src\u002Fspec.types.ts` | Type definitions |\n| `src\u002Freact\u002FuseApp.tsx` | `useApp` hook for React apps |\n| `src\u002Freact\u002Fuse*.ts*` | Other `use*` hooks for React apps |\n\n### Front-End Framework Examples\n\nSee `\u002Ftmp\u002Fmcp-ext-apps\u002Fexamples\u002Fbasic-server-{framework}\u002F` for basic SDK usage examples organized by front-end framework:\n\n| Template | Key Files |\n|----------|-----------|\n| `basic-server-vanillajs\u002F` | `server.ts`, `src\u002Fmcp-app.ts`, `mcp-app.html` |\n| `basic-server-react\u002F` | `server.ts`, `src\u002Fmcp-app.tsx` (uses `useApp` hook) |\n| `basic-server-vue\u002F` | `server.ts`, `src\u002FApp.vue` |\n| `basic-server-svelte\u002F` | `server.ts`, `src\u002FApp.svelte` |\n| `basic-server-preact\u002F` | `server.ts`, `src\u002Fmcp-app.tsx` |\n| `basic-server-solid\u002F` | `server.ts`, `src\u002Fmcp-app.tsx` |\n\n## CSP Investigation\n\nMCP Apps HTML is served as an MCP resource, not as a web page, and runs in a sandboxed iframe with no same-origin server. **Every** origin must be declared in CSP—including the origin serving your JS\u002FCSS bundles (`localhost` in dev, your CDN in production). Missing origins fail silently.\n\n**Before writing any migration code**, build the app and investigate all origins it references:\n\n1. Build the app using the existing build command\n2. Search the resulting HTML, CSS, and JS for **every** origin (not just \"external\" origins—every network request will need CSP approval)\n3. For each origin found, trace back to source:\n   - If it comes from a constant → universal (same in dev and prod)\n   - If it comes from an env var or conditional → note the mechanism and identify both dev and prod values\n4. Check for third-party libraries that may make their own requests (analytics, error tracking, etc.)\n\n**Document your findings** as three lists, and note for each origin whether it's universal, dev-only, or prod-only:\n\n- **resourceDomains**: origins serving images, fonts, styles, scripts\n- **connectDomains**: origins for API\u002Ffetch requests\n- **frameDomains**: origins for nested iframes\n\nIf no origins are found, the app may not need custom CSP domains.\n\n## CORS Configuration\n\nMCP clients make cross-origin requests. If using Express, `app.use(cors())` handles this.\n\nFor raw HTTP servers, configure standard CORS and additionally:\n- Allow headers: `mcp-session-id`, `mcp-protocol-version`, `last-event-id`\n- Expose headers: `mcp-session-id`\n\n## Key Conceptual Changes\n\n### Server-Side\n\nUse `registerAppTool()` and `registerAppResource()` helpers instead of raw `server.registerTool()` \u002F `server.registerResource()`. These helpers handle the MCP Apps metadata format automatically.\n\nSee `\u002Ftmp\u002Fmcp-ext-apps\u002Fdocs\u002Fmigrate_from_openai_apps.md` for server-side mapping tables.\n\n### Client-Side\n\nThe fundamental paradigm shift: OpenAI uses a synchronous global object (`window.openai.toolInput`, `window.openai.theme`) that's pre-populated before your code runs. MCP Apps uses an `App` instance with async event handlers.\n\nKey differences:\n- Create an `App` instance and register handlers (`ontoolinput`, `ontoolresult`, `onhostcontextchanged`) **before** calling `connect()`. (Events may fire immediately after connection, so handlers must be registered first.)\n- Access tool data via handlers: `app.ontoolinput` for `window.openai.toolInput`, `app.ontoolresult` for `window.openai.toolOutput`.\n- Access host environment (theme, locale, etc.) via `app.getHostContext()`.\n\nFor React apps, the `useApp` hook manages this lifecycle automatically—see `basic-server-react\u002F` for the pattern.\n\nSee `\u002Ftmp\u002Fmcp-ext-apps\u002Fdocs\u002Fmigrate_from_openai_apps.md` for client-side mapping tables.\n\n### Features Not Yet Available in MCP Apps\n\nThese OpenAI features don't have MCP equivalents yet:\n\n**Server-side:**\n| OpenAI Feature | Status\u002FWorkaround |\n|----------------|-------------------|\n| `_meta[\"openai\u002FtoolInvocation\u002Finvoking\"]` \u002F `_meta[\"openai\u002FtoolInvocation\u002Finvoked\"]` | Progress indicators not yet available |\n| `_meta[\"openai\u002FwidgetDescription\"]` | Use `app.updateModelContext()` for dynamic context |\n\n**Client-side:**\n| OpenAI Feature | Status\u002FWorkaround |\n|----------------|-------------------|\n| `window.openai.widgetState` \u002F `setWidgetState()` | Use `localStorage` or server-side state |\n| `window.openai.uploadFile()` \u002F `getFileDownloadUrl()` | File operations not yet available |\n| `window.openai.requestModal()` \u002F `requestClose()` | Modal management not yet available |\n| `window.openai.view` | Not yet available |\n\n## Before Finishing\n\nSlow down and carefully follow each item in this checklist:\n\n- [ ] Search for and migrate any remaining server-side OpenAI patterns:\n\n    | Pattern | Indicates |\n    |---------|-----------|\n    | `\"openai\u002F` | Old metadata keys → `_meta.ui.*` |\n    | `text\u002Fhtml+skybridge` | Old MIME type → `RESOURCE_MIME_TYPE` constant |\n    | `text\u002Fhtml;profile=mcp-app` | New MIME type, but prefer `RESOURCE_MIME_TYPE` constant |\n    | `_domains\"` or `_domains:` | snake_case CSP → camelCase (`connect_domains` → `connectDomains`) |\n\n- [ ] Search for and migrate any remaining client-side OpenAI patterns:\n\n    | Pattern | Indicates |\n    |---------|-----------|\n    | `window.openai.toolInput` | Old global → `params.arguments` in `ontoolinput` handler |\n    | `window.openai.toolOutput` | Old global → `params.structuredContent` in `ontoolresult` |\n    | `window.openai` | Old global API → `App` instance methods |\n\n- [ ] For each origin from your CSP investigation, show where it appears in the `registerAppResource()` CSP config. **Every** origin from the CSP investigation (universal, dev-only, prod-only) must be included in the CSP config—MCP Apps HTML runs in a sandboxed iframe **with no same-origin server**. If an origin was not included in the CSP config, add it now.\n\n- [ ] For each conditional (dev-only, prod-only) origin from your CSP investigation, show the code where the same configuration setting (env var, config file, etc.) controls both the runtime URL and the CSP entry. If the CSP has a hardcoded origin that should be conditional, fix it now—the app must be production-ready.\n\n## Testing\n\n### Using basic-host\n\nTest the migrated app with the basic-host example:\n\n```bash\n# Terminal 1: Build and run your server\nnpm run build && npm run serve\n\n# Terminal 2: Run basic-host (from cloned repo)\ncd \u002Ftmp\u002Fmcp-ext-apps\u002Fexamples\u002Fbasic-host\nnpm install\nSERVERS='[\"http:\u002F\u002Flocalhost:3001\u002Fmcp\"]' npm run start\n# Open http:\u002F\u002Flocalhost:8080\n```\n\n### Verify Runtime Behavior\n\nOnce the app loads in basic-host, confirm:\n1. App loads without console errors\n2. `ontoolinput` handler fires with tool arguments\n3. `ontoolresult` handler fires with tool result\n",{"data":37,"body":38},{"name":4,"description":6},{"type":39,"children":40},"root",[41,50,65,72,110,116,121,207,214,225,231,244,388,394,407,606,612,633,643,687,697,730,735,741,754,759,797,803,809,846,857,863,890,895,993,1012,1023,1029,1034,1042,1112,1120,1236,1242,1247,1547,1553,1559,1564,1714,1720,1725,1753],{"type":42,"tag":43,"props":44,"children":46},"element","h1",{"id":45},"migrate-openai-app-to-mcp",[47],{"type":48,"value":49},"text","Migrate OpenAI App to MCP",{"type":42,"tag":51,"props":52,"children":53},"p",{},[54,56,63],{"type":48,"value":55},"Migrate existing OpenAI Apps SDK applications to the MCP Apps SDK (",{"type":42,"tag":57,"props":58,"children":60},"code",{"className":59},[],[61],{"type":48,"value":62},"@modelcontextprotocol\u002Fext-apps",{"type":48,"value":64},"). The MCP Apps SDK provides a standardized, open protocol for interactive UIs in conversational clients.",{"type":42,"tag":66,"props":67,"children":69},"h2",{"id":68},"best-practices",[70],{"type":48,"value":71},"Best Practices",{"type":42,"tag":73,"props":74,"children":75},"ul",{},[76,105],{"type":42,"tag":77,"props":78,"children":79},"li",{},[80,82,88,90,96,97,103],{"type":48,"value":81},"Use your package manager to add dependencies (e.g., ",{"type":42,"tag":57,"props":83,"children":85},{"className":84},[],[86],{"type":48,"value":87},"npm install",{"type":48,"value":89},", ",{"type":42,"tag":57,"props":91,"children":93},{"className":92},[],[94],{"type":48,"value":95},"pnpm add",{"type":48,"value":89},{"type":42,"tag":57,"props":98,"children":100},{"className":99},[],[101],{"type":48,"value":102},"yarn add",{"type":48,"value":104},") instead of manually writing version numbers. This lets the package manager resolve the latest compatible versions. Never specify version numbers from memory.",{"type":42,"tag":77,"props":106,"children":107},{},[108],{"type":48,"value":109},"Preemptively add a final todo item with this exact wording: \"Re-read the 'Before Finishing' checklist in this skill and address each checkbox individually, stating what you did for each one, before marking this todo complete.\"",{"type":42,"tag":66,"props":111,"children":113},{"id":112},"getting-reference-code",[114],{"type":48,"value":115},"Getting Reference Code",{"type":42,"tag":51,"props":117,"children":118},{},[119],{"type":48,"value":120},"Clone the SDK repository for complete migration documentation and working examples:",{"type":42,"tag":122,"props":123,"children":128},"pre",{"className":124,"code":125,"language":126,"meta":127,"style":127},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","git clone --branch \"v$(npm view @modelcontextprotocol\u002Fext-apps version)\" --depth 1 https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fext-apps.git \u002Ftmp\u002Fmcp-ext-apps\n","bash","",[129],{"type":42,"tag":57,"props":130,"children":131},{"__ignoreMap":127},[132],{"type":42,"tag":133,"props":134,"children":137},"span",{"class":135,"line":136},"line",1,[138,144,150,155,161,166,171,176,181,186,191,197,202],{"type":42,"tag":133,"props":139,"children":141},{"style":140},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[142],{"type":48,"value":143},"git",{"type":42,"tag":133,"props":145,"children":147},{"style":146},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[148],{"type":48,"value":149}," clone",{"type":42,"tag":133,"props":151,"children":152},{"style":146},[153],{"type":48,"value":154}," --branch",{"type":42,"tag":133,"props":156,"children":158},{"style":157},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[159],{"type":48,"value":160}," \"",{"type":42,"tag":133,"props":162,"children":163},{"style":146},[164],{"type":48,"value":165},"v",{"type":42,"tag":133,"props":167,"children":168},{"style":157},[169],{"type":48,"value":170},"$(",{"type":42,"tag":133,"props":172,"children":173},{"style":140},[174],{"type":48,"value":175},"npm",{"type":42,"tag":133,"props":177,"children":178},{"style":146},[179],{"type":48,"value":180}," view @modelcontextprotocol\u002Fext-apps version",{"type":42,"tag":133,"props":182,"children":183},{"style":157},[184],{"type":48,"value":185},")\"",{"type":42,"tag":133,"props":187,"children":188},{"style":146},[189],{"type":48,"value":190}," --depth",{"type":42,"tag":133,"props":192,"children":194},{"style":193},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[195],{"type":48,"value":196}," 1",{"type":42,"tag":133,"props":198,"children":199},{"style":146},[200],{"type":48,"value":201}," https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fext-apps.git",{"type":42,"tag":133,"props":203,"children":204},{"style":146},[205],{"type":48,"value":206}," \u002Ftmp\u002Fmcp-ext-apps\n",{"type":42,"tag":208,"props":209,"children":211},"h3",{"id":210},"migration-reference-guide",[212],{"type":48,"value":213},"Migration Reference Guide",{"type":42,"tag":51,"props":215,"children":216},{},[217,219],{"type":48,"value":218},"Read the migration reference guide with \"before\u002Fafter\" mapping tables: ",{"type":42,"tag":57,"props":220,"children":222},{"className":221},[],[223],{"type":48,"value":224},"\u002Ftmp\u002Fmcp-ext-apps\u002Fdocs\u002Fmigrate_from_openai_apps.md",{"type":42,"tag":208,"props":226,"children":228},{"id":227},"api-reference-source-files",[229],{"type":48,"value":230},"API Reference (Source Files)",{"type":42,"tag":51,"props":232,"children":233},{},[234,236,242],{"type":48,"value":235},"Read JSDoc documentation directly from ",{"type":42,"tag":57,"props":237,"children":239},{"className":238},[],[240],{"type":48,"value":241},"\u002Ftmp\u002Fmcp-ext-apps\u002Fsrc\u002F*",{"type":48,"value":243},":",{"type":42,"tag":245,"props":246,"children":247},"table",{},[248,267],{"type":42,"tag":249,"props":250,"children":251},"thead",{},[252],{"type":42,"tag":253,"props":254,"children":255},"tr",{},[256,262],{"type":42,"tag":257,"props":258,"children":259},"th",{},[260],{"type":48,"value":261},"File",{"type":42,"tag":257,"props":263,"children":264},{},[265],{"type":48,"value":266},"Contents",{"type":42,"tag":268,"props":269,"children":270},"tbody",{},[271,295,323,340,363],{"type":42,"tag":253,"props":272,"children":273},{},[274,284],{"type":42,"tag":275,"props":276,"children":277},"td",{},[278],{"type":42,"tag":57,"props":279,"children":281},{"className":280},[],[282],{"type":48,"value":283},"src\u002Fapp.ts",{"type":42,"tag":275,"props":285,"children":286},{},[287,293],{"type":42,"tag":57,"props":288,"children":290},{"className":289},[],[291],{"type":48,"value":292},"App",{"type":48,"value":294}," class, handlers, lifecycle",{"type":42,"tag":253,"props":296,"children":297},{},[298,307],{"type":42,"tag":275,"props":299,"children":300},{},[301],{"type":42,"tag":57,"props":302,"children":304},{"className":303},[],[305],{"type":48,"value":306},"src\u002Fserver\u002Findex.ts",{"type":42,"tag":275,"props":308,"children":309},{},[310,316,317],{"type":42,"tag":57,"props":311,"children":313},{"className":312},[],[314],{"type":48,"value":315},"registerAppTool",{"type":48,"value":89},{"type":42,"tag":57,"props":318,"children":320},{"className":319},[],[321],{"type":48,"value":322},"registerAppResource",{"type":42,"tag":253,"props":324,"children":325},{},[326,335],{"type":42,"tag":275,"props":327,"children":328},{},[329],{"type":42,"tag":57,"props":330,"children":332},{"className":331},[],[333],{"type":48,"value":334},"src\u002Fspec.types.ts",{"type":42,"tag":275,"props":336,"children":337},{},[338],{"type":48,"value":339},"Type definitions",{"type":42,"tag":253,"props":341,"children":342},{},[343,352],{"type":42,"tag":275,"props":344,"children":345},{},[346],{"type":42,"tag":57,"props":347,"children":349},{"className":348},[],[350],{"type":48,"value":351},"src\u002Freact\u002FuseApp.tsx",{"type":42,"tag":275,"props":353,"children":354},{},[355,361],{"type":42,"tag":57,"props":356,"children":358},{"className":357},[],[359],{"type":48,"value":360},"useApp",{"type":48,"value":362}," hook for React apps",{"type":42,"tag":253,"props":364,"children":365},{},[366,375],{"type":42,"tag":275,"props":367,"children":368},{},[369],{"type":42,"tag":57,"props":370,"children":372},{"className":371},[],[373],{"type":48,"value":374},"src\u002Freact\u002Fuse*.ts*",{"type":42,"tag":275,"props":376,"children":377},{},[378,380,386],{"type":48,"value":379},"Other ",{"type":42,"tag":57,"props":381,"children":383},{"className":382},[],[384],{"type":48,"value":385},"use*",{"type":48,"value":387}," hooks for React apps",{"type":42,"tag":208,"props":389,"children":391},{"id":390},"front-end-framework-examples",[392],{"type":48,"value":393},"Front-End Framework Examples",{"type":42,"tag":51,"props":395,"children":396},{},[397,399,405],{"type":48,"value":398},"See ",{"type":42,"tag":57,"props":400,"children":402},{"className":401},[],[403],{"type":48,"value":404},"\u002Ftmp\u002Fmcp-ext-apps\u002Fexamples\u002Fbasic-server-{framework}\u002F",{"type":48,"value":406}," for basic SDK usage examples organized by front-end framework:",{"type":42,"tag":245,"props":408,"children":409},{},[410,426],{"type":42,"tag":249,"props":411,"children":412},{},[413],{"type":42,"tag":253,"props":414,"children":415},{},[416,421],{"type":42,"tag":257,"props":417,"children":418},{},[419],{"type":48,"value":420},"Template",{"type":42,"tag":257,"props":422,"children":423},{},[424],{"type":48,"value":425},"Key Files",{"type":42,"tag":268,"props":427,"children":428},{},[429,464,500,527,554,580],{"type":42,"tag":253,"props":430,"children":431},{},[432,441],{"type":42,"tag":275,"props":433,"children":434},{},[435],{"type":42,"tag":57,"props":436,"children":438},{"className":437},[],[439],{"type":48,"value":440},"basic-server-vanillajs\u002F",{"type":42,"tag":275,"props":442,"children":443},{},[444,450,451,457,458],{"type":42,"tag":57,"props":445,"children":447},{"className":446},[],[448],{"type":48,"value":449},"server.ts",{"type":48,"value":89},{"type":42,"tag":57,"props":452,"children":454},{"className":453},[],[455],{"type":48,"value":456},"src\u002Fmcp-app.ts",{"type":48,"value":89},{"type":42,"tag":57,"props":459,"children":461},{"className":460},[],[462],{"type":48,"value":463},"mcp-app.html",{"type":42,"tag":253,"props":465,"children":466},{},[467,476],{"type":42,"tag":275,"props":468,"children":469},{},[470],{"type":42,"tag":57,"props":471,"children":473},{"className":472},[],[474],{"type":48,"value":475},"basic-server-react\u002F",{"type":42,"tag":275,"props":477,"children":478},{},[479,484,485,491,493,498],{"type":42,"tag":57,"props":480,"children":482},{"className":481},[],[483],{"type":48,"value":449},{"type":48,"value":89},{"type":42,"tag":57,"props":486,"children":488},{"className":487},[],[489],{"type":48,"value":490},"src\u002Fmcp-app.tsx",{"type":48,"value":492}," (uses ",{"type":42,"tag":57,"props":494,"children":496},{"className":495},[],[497],{"type":48,"value":360},{"type":48,"value":499}," hook)",{"type":42,"tag":253,"props":501,"children":502},{},[503,512],{"type":42,"tag":275,"props":504,"children":505},{},[506],{"type":42,"tag":57,"props":507,"children":509},{"className":508},[],[510],{"type":48,"value":511},"basic-server-vue\u002F",{"type":42,"tag":275,"props":513,"children":514},{},[515,520,521],{"type":42,"tag":57,"props":516,"children":518},{"className":517},[],[519],{"type":48,"value":449},{"type":48,"value":89},{"type":42,"tag":57,"props":522,"children":524},{"className":523},[],[525],{"type":48,"value":526},"src\u002FApp.vue",{"type":42,"tag":253,"props":528,"children":529},{},[530,539],{"type":42,"tag":275,"props":531,"children":532},{},[533],{"type":42,"tag":57,"props":534,"children":536},{"className":535},[],[537],{"type":48,"value":538},"basic-server-svelte\u002F",{"type":42,"tag":275,"props":540,"children":541},{},[542,547,548],{"type":42,"tag":57,"props":543,"children":545},{"className":544},[],[546],{"type":48,"value":449},{"type":48,"value":89},{"type":42,"tag":57,"props":549,"children":551},{"className":550},[],[552],{"type":48,"value":553},"src\u002FApp.svelte",{"type":42,"tag":253,"props":555,"children":556},{},[557,566],{"type":42,"tag":275,"props":558,"children":559},{},[560],{"type":42,"tag":57,"props":561,"children":563},{"className":562},[],[564],{"type":48,"value":565},"basic-server-preact\u002F",{"type":42,"tag":275,"props":567,"children":568},{},[569,574,575],{"type":42,"tag":57,"props":570,"children":572},{"className":571},[],[573],{"type":48,"value":449},{"type":48,"value":89},{"type":42,"tag":57,"props":576,"children":578},{"className":577},[],[579],{"type":48,"value":490},{"type":42,"tag":253,"props":581,"children":582},{},[583,592],{"type":42,"tag":275,"props":584,"children":585},{},[586],{"type":42,"tag":57,"props":587,"children":589},{"className":588},[],[590],{"type":48,"value":591},"basic-server-solid\u002F",{"type":42,"tag":275,"props":593,"children":594},{},[595,600,601],{"type":42,"tag":57,"props":596,"children":598},{"className":597},[],[599],{"type":48,"value":449},{"type":48,"value":89},{"type":42,"tag":57,"props":602,"children":604},{"className":603},[],[605],{"type":48,"value":490},{"type":42,"tag":66,"props":607,"children":609},{"id":608},"csp-investigation",[610],{"type":48,"value":611},"CSP Investigation",{"type":42,"tag":51,"props":613,"children":614},{},[615,617,623,625,631],{"type":48,"value":616},"MCP Apps HTML is served as an MCP resource, not as a web page, and runs in a sandboxed iframe with no same-origin server. ",{"type":42,"tag":618,"props":619,"children":620},"strong",{},[621],{"type":48,"value":622},"Every",{"type":48,"value":624}," origin must be declared in CSP—including the origin serving your JS\u002FCSS bundles (",{"type":42,"tag":57,"props":626,"children":628},{"className":627},[],[629],{"type":48,"value":630},"localhost",{"type":48,"value":632}," in dev, your CDN in production). Missing origins fail silently.",{"type":42,"tag":51,"props":634,"children":635},{},[636,641],{"type":42,"tag":618,"props":637,"children":638},{},[639],{"type":48,"value":640},"Before writing any migration code",{"type":48,"value":642},", build the app and investigate all origins it references:",{"type":42,"tag":644,"props":645,"children":646},"ol",{},[647,652,664,682],{"type":42,"tag":77,"props":648,"children":649},{},[650],{"type":48,"value":651},"Build the app using the existing build command",{"type":42,"tag":77,"props":653,"children":654},{},[655,657,662],{"type":48,"value":656},"Search the resulting HTML, CSS, and JS for ",{"type":42,"tag":618,"props":658,"children":659},{},[660],{"type":48,"value":661},"every",{"type":48,"value":663}," origin (not just \"external\" origins—every network request will need CSP approval)",{"type":42,"tag":77,"props":665,"children":666},{},[667,669],{"type":48,"value":668},"For each origin found, trace back to source:\n",{"type":42,"tag":73,"props":670,"children":671},{},[672,677],{"type":42,"tag":77,"props":673,"children":674},{},[675],{"type":48,"value":676},"If it comes from a constant → universal (same in dev and prod)",{"type":42,"tag":77,"props":678,"children":679},{},[680],{"type":48,"value":681},"If it comes from an env var or conditional → note the mechanism and identify both dev and prod values",{"type":42,"tag":77,"props":683,"children":684},{},[685],{"type":48,"value":686},"Check for third-party libraries that may make their own requests (analytics, error tracking, etc.)",{"type":42,"tag":51,"props":688,"children":689},{},[690,695],{"type":42,"tag":618,"props":691,"children":692},{},[693],{"type":48,"value":694},"Document your findings",{"type":48,"value":696}," as three lists, and note for each origin whether it's universal, dev-only, or prod-only:",{"type":42,"tag":73,"props":698,"children":699},{},[700,710,720],{"type":42,"tag":77,"props":701,"children":702},{},[703,708],{"type":42,"tag":618,"props":704,"children":705},{},[706],{"type":48,"value":707},"resourceDomains",{"type":48,"value":709},": origins serving images, fonts, styles, scripts",{"type":42,"tag":77,"props":711,"children":712},{},[713,718],{"type":42,"tag":618,"props":714,"children":715},{},[716],{"type":48,"value":717},"connectDomains",{"type":48,"value":719},": origins for API\u002Ffetch requests",{"type":42,"tag":77,"props":721,"children":722},{},[723,728],{"type":42,"tag":618,"props":724,"children":725},{},[726],{"type":48,"value":727},"frameDomains",{"type":48,"value":729},": origins for nested iframes",{"type":42,"tag":51,"props":731,"children":732},{},[733],{"type":48,"value":734},"If no origins are found, the app may not need custom CSP domains.",{"type":42,"tag":66,"props":736,"children":738},{"id":737},"cors-configuration",[739],{"type":48,"value":740},"CORS Configuration",{"type":42,"tag":51,"props":742,"children":743},{},[744,746,752],{"type":48,"value":745},"MCP clients make cross-origin requests. If using Express, ",{"type":42,"tag":57,"props":747,"children":749},{"className":748},[],[750],{"type":48,"value":751},"app.use(cors())",{"type":48,"value":753}," handles this.",{"type":42,"tag":51,"props":755,"children":756},{},[757],{"type":48,"value":758},"For raw HTTP servers, configure standard CORS and additionally:",{"type":42,"tag":73,"props":760,"children":761},{},[762,787],{"type":42,"tag":77,"props":763,"children":764},{},[765,767,773,774,780,781],{"type":48,"value":766},"Allow headers: ",{"type":42,"tag":57,"props":768,"children":770},{"className":769},[],[771],{"type":48,"value":772},"mcp-session-id",{"type":48,"value":89},{"type":42,"tag":57,"props":775,"children":777},{"className":776},[],[778],{"type":48,"value":779},"mcp-protocol-version",{"type":48,"value":89},{"type":42,"tag":57,"props":782,"children":784},{"className":783},[],[785],{"type":48,"value":786},"last-event-id",{"type":42,"tag":77,"props":788,"children":789},{},[790,792],{"type":48,"value":791},"Expose headers: ",{"type":42,"tag":57,"props":793,"children":795},{"className":794},[],[796],{"type":48,"value":772},{"type":42,"tag":66,"props":798,"children":800},{"id":799},"key-conceptual-changes",[801],{"type":48,"value":802},"Key Conceptual Changes",{"type":42,"tag":208,"props":804,"children":806},{"id":805},"server-side",[807],{"type":48,"value":808},"Server-Side",{"type":42,"tag":51,"props":810,"children":811},{},[812,814,820,822,828,830,836,838,844],{"type":48,"value":813},"Use ",{"type":42,"tag":57,"props":815,"children":817},{"className":816},[],[818],{"type":48,"value":819},"registerAppTool()",{"type":48,"value":821}," and ",{"type":42,"tag":57,"props":823,"children":825},{"className":824},[],[826],{"type":48,"value":827},"registerAppResource()",{"type":48,"value":829}," helpers instead of raw ",{"type":42,"tag":57,"props":831,"children":833},{"className":832},[],[834],{"type":48,"value":835},"server.registerTool()",{"type":48,"value":837}," \u002F ",{"type":42,"tag":57,"props":839,"children":841},{"className":840},[],[842],{"type":48,"value":843},"server.registerResource()",{"type":48,"value":845},". These helpers handle the MCP Apps metadata format automatically.",{"type":42,"tag":51,"props":847,"children":848},{},[849,850,855],{"type":48,"value":398},{"type":42,"tag":57,"props":851,"children":853},{"className":852},[],[854],{"type":48,"value":224},{"type":48,"value":856}," for server-side mapping tables.",{"type":42,"tag":208,"props":858,"children":860},{"id":859},"client-side",[861],{"type":48,"value":862},"Client-Side",{"type":42,"tag":51,"props":864,"children":865},{},[866,868,874,875,881,883,888],{"type":48,"value":867},"The fundamental paradigm shift: OpenAI uses a synchronous global object (",{"type":42,"tag":57,"props":869,"children":871},{"className":870},[],[872],{"type":48,"value":873},"window.openai.toolInput",{"type":48,"value":89},{"type":42,"tag":57,"props":876,"children":878},{"className":877},[],[879],{"type":48,"value":880},"window.openai.theme",{"type":48,"value":882},") that's pre-populated before your code runs. MCP Apps uses an ",{"type":42,"tag":57,"props":884,"children":886},{"className":885},[],[887],{"type":48,"value":292},{"type":48,"value":889}," instance with async event handlers.",{"type":42,"tag":51,"props":891,"children":892},{},[893],{"type":48,"value":894},"Key differences:",{"type":42,"tag":73,"props":896,"children":897},{},[898,947,981],{"type":42,"tag":77,"props":899,"children":900},{},[901,903,908,910,916,917,923,924,930,932,937,939,945],{"type":48,"value":902},"Create an ",{"type":42,"tag":57,"props":904,"children":906},{"className":905},[],[907],{"type":48,"value":292},{"type":48,"value":909}," instance and register handlers (",{"type":42,"tag":57,"props":911,"children":913},{"className":912},[],[914],{"type":48,"value":915},"ontoolinput",{"type":48,"value":89},{"type":42,"tag":57,"props":918,"children":920},{"className":919},[],[921],{"type":48,"value":922},"ontoolresult",{"type":48,"value":89},{"type":42,"tag":57,"props":925,"children":927},{"className":926},[],[928],{"type":48,"value":929},"onhostcontextchanged",{"type":48,"value":931},") ",{"type":42,"tag":618,"props":933,"children":934},{},[935],{"type":48,"value":936},"before",{"type":48,"value":938}," calling ",{"type":42,"tag":57,"props":940,"children":942},{"className":941},[],[943],{"type":48,"value":944},"connect()",{"type":48,"value":946},". (Events may fire immediately after connection, so handlers must be registered first.)",{"type":42,"tag":77,"props":948,"children":949},{},[950,952,958,960,965,966,972,973,979],{"type":48,"value":951},"Access tool data via handlers: ",{"type":42,"tag":57,"props":953,"children":955},{"className":954},[],[956],{"type":48,"value":957},"app.ontoolinput",{"type":48,"value":959}," for ",{"type":42,"tag":57,"props":961,"children":963},{"className":962},[],[964],{"type":48,"value":873},{"type":48,"value":89},{"type":42,"tag":57,"props":967,"children":969},{"className":968},[],[970],{"type":48,"value":971},"app.ontoolresult",{"type":48,"value":959},{"type":42,"tag":57,"props":974,"children":976},{"className":975},[],[977],{"type":48,"value":978},"window.openai.toolOutput",{"type":48,"value":980},".",{"type":42,"tag":77,"props":982,"children":983},{},[984,986,992],{"type":48,"value":985},"Access host environment (theme, locale, etc.) via ",{"type":42,"tag":57,"props":987,"children":989},{"className":988},[],[990],{"type":48,"value":991},"app.getHostContext()",{"type":48,"value":980},{"type":42,"tag":51,"props":994,"children":995},{},[996,998,1003,1005,1010],{"type":48,"value":997},"For React apps, the ",{"type":42,"tag":57,"props":999,"children":1001},{"className":1000},[],[1002],{"type":48,"value":360},{"type":48,"value":1004}," hook manages this lifecycle automatically—see ",{"type":42,"tag":57,"props":1006,"children":1008},{"className":1007},[],[1009],{"type":48,"value":475},{"type":48,"value":1011}," for the pattern.",{"type":42,"tag":51,"props":1013,"children":1014},{},[1015,1016,1021],{"type":48,"value":398},{"type":42,"tag":57,"props":1017,"children":1019},{"className":1018},[],[1020],{"type":48,"value":224},{"type":48,"value":1022}," for client-side mapping tables.",{"type":42,"tag":208,"props":1024,"children":1026},{"id":1025},"features-not-yet-available-in-mcp-apps",[1027],{"type":48,"value":1028},"Features Not Yet Available in MCP Apps",{"type":42,"tag":51,"props":1030,"children":1031},{},[1032],{"type":48,"value":1033},"These OpenAI features don't have MCP equivalents yet:",{"type":42,"tag":51,"props":1035,"children":1036},{},[1037],{"type":42,"tag":618,"props":1038,"children":1039},{},[1040],{"type":48,"value":1041},"Server-side:",{"type":42,"tag":245,"props":1043,"children":1044},{},[1045,1061],{"type":42,"tag":249,"props":1046,"children":1047},{},[1048],{"type":42,"tag":253,"props":1049,"children":1050},{},[1051,1056],{"type":42,"tag":257,"props":1052,"children":1053},{},[1054],{"type":48,"value":1055},"OpenAI Feature",{"type":42,"tag":257,"props":1057,"children":1058},{},[1059],{"type":48,"value":1060},"Status\u002FWorkaround",{"type":42,"tag":268,"props":1062,"children":1063},{},[1064,1088],{"type":42,"tag":253,"props":1065,"children":1066},{},[1067,1083],{"type":42,"tag":275,"props":1068,"children":1069},{},[1070,1076,1077],{"type":42,"tag":57,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":48,"value":1075},"_meta[\"openai\u002FtoolInvocation\u002Finvoking\"]",{"type":48,"value":837},{"type":42,"tag":57,"props":1078,"children":1080},{"className":1079},[],[1081],{"type":48,"value":1082},"_meta[\"openai\u002FtoolInvocation\u002Finvoked\"]",{"type":42,"tag":275,"props":1084,"children":1085},{},[1086],{"type":48,"value":1087},"Progress indicators not yet available",{"type":42,"tag":253,"props":1089,"children":1090},{},[1091,1100],{"type":42,"tag":275,"props":1092,"children":1093},{},[1094],{"type":42,"tag":57,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":48,"value":1099},"_meta[\"openai\u002FwidgetDescription\"]",{"type":42,"tag":275,"props":1101,"children":1102},{},[1103,1104,1110],{"type":48,"value":813},{"type":42,"tag":57,"props":1105,"children":1107},{"className":1106},[],[1108],{"type":48,"value":1109},"app.updateModelContext()",{"type":48,"value":1111}," for dynamic context",{"type":42,"tag":51,"props":1113,"children":1114},{},[1115],{"type":42,"tag":618,"props":1116,"children":1117},{},[1118],{"type":48,"value":1119},"Client-side:",{"type":42,"tag":245,"props":1121,"children":1122},{},[1123,1137],{"type":42,"tag":249,"props":1124,"children":1125},{},[1126],{"type":42,"tag":253,"props":1127,"children":1128},{},[1129,1133],{"type":42,"tag":257,"props":1130,"children":1131},{},[1132],{"type":48,"value":1055},{"type":42,"tag":257,"props":1134,"children":1135},{},[1136],{"type":48,"value":1060},{"type":42,"tag":268,"props":1138,"children":1139},{},[1140,1171,1195,1219],{"type":42,"tag":253,"props":1141,"children":1142},{},[1143,1159],{"type":42,"tag":275,"props":1144,"children":1145},{},[1146,1152,1153],{"type":42,"tag":57,"props":1147,"children":1149},{"className":1148},[],[1150],{"type":48,"value":1151},"window.openai.widgetState",{"type":48,"value":837},{"type":42,"tag":57,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":48,"value":1158},"setWidgetState()",{"type":42,"tag":275,"props":1160,"children":1161},{},[1162,1163,1169],{"type":48,"value":813},{"type":42,"tag":57,"props":1164,"children":1166},{"className":1165},[],[1167],{"type":48,"value":1168},"localStorage",{"type":48,"value":1170}," or server-side state",{"type":42,"tag":253,"props":1172,"children":1173},{},[1174,1190],{"type":42,"tag":275,"props":1175,"children":1176},{},[1177,1183,1184],{"type":42,"tag":57,"props":1178,"children":1180},{"className":1179},[],[1181],{"type":48,"value":1182},"window.openai.uploadFile()",{"type":48,"value":837},{"type":42,"tag":57,"props":1185,"children":1187},{"className":1186},[],[1188],{"type":48,"value":1189},"getFileDownloadUrl()",{"type":42,"tag":275,"props":1191,"children":1192},{},[1193],{"type":48,"value":1194},"File operations not yet available",{"type":42,"tag":253,"props":1196,"children":1197},{},[1198,1214],{"type":42,"tag":275,"props":1199,"children":1200},{},[1201,1207,1208],{"type":42,"tag":57,"props":1202,"children":1204},{"className":1203},[],[1205],{"type":48,"value":1206},"window.openai.requestModal()",{"type":48,"value":837},{"type":42,"tag":57,"props":1209,"children":1211},{"className":1210},[],[1212],{"type":48,"value":1213},"requestClose()",{"type":42,"tag":275,"props":1215,"children":1216},{},[1217],{"type":48,"value":1218},"Modal management not yet available",{"type":42,"tag":253,"props":1220,"children":1221},{},[1222,1231],{"type":42,"tag":275,"props":1223,"children":1224},{},[1225],{"type":42,"tag":57,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":48,"value":1230},"window.openai.view",{"type":42,"tag":275,"props":1232,"children":1233},{},[1234],{"type":48,"value":1235},"Not yet available",{"type":42,"tag":66,"props":1237,"children":1239},{"id":1238},"before-finishing",[1240],{"type":48,"value":1241},"Before Finishing",{"type":42,"tag":51,"props":1243,"children":1244},{},[1245],{"type":48,"value":1246},"Slow down and carefully follow each item in this checklist:",{"type":42,"tag":73,"props":1248,"children":1251},{"className":1249},[1250],"contains-task-list",[1252,1398,1509,1538],{"type":42,"tag":77,"props":1253,"children":1256},{"className":1254},[1255],"task-list-item",[1257,1263,1265],{"type":42,"tag":1258,"props":1259,"children":1262},"input",{"disabled":1260,"type":1261},true,"checkbox",[],{"type":48,"value":1264}," Search for and migrate any remaining server-side OpenAI patterns:",{"type":42,"tag":245,"props":1266,"children":1267},{},[1268,1284],{"type":42,"tag":249,"props":1269,"children":1270},{},[1271],{"type":42,"tag":253,"props":1272,"children":1273},{},[1274,1279],{"type":42,"tag":257,"props":1275,"children":1276},{},[1277],{"type":48,"value":1278},"Pattern",{"type":42,"tag":257,"props":1280,"children":1281},{},[1282],{"type":48,"value":1283},"Indicates",{"type":42,"tag":268,"props":1285,"children":1286},{},[1287,1310,1335,1358],{"type":42,"tag":253,"props":1288,"children":1289},{},[1290,1299],{"type":42,"tag":275,"props":1291,"children":1292},{},[1293],{"type":42,"tag":57,"props":1294,"children":1296},{"className":1295},[],[1297],{"type":48,"value":1298},"\"openai\u002F",{"type":42,"tag":275,"props":1300,"children":1301},{},[1302,1304],{"type":48,"value":1303},"Old metadata keys → ",{"type":42,"tag":57,"props":1305,"children":1307},{"className":1306},[],[1308],{"type":48,"value":1309},"_meta.ui.*",{"type":42,"tag":253,"props":1311,"children":1312},{},[1313,1322],{"type":42,"tag":275,"props":1314,"children":1315},{},[1316],{"type":42,"tag":57,"props":1317,"children":1319},{"className":1318},[],[1320],{"type":48,"value":1321},"text\u002Fhtml+skybridge",{"type":42,"tag":275,"props":1323,"children":1324},{},[1325,1327,1333],{"type":48,"value":1326},"Old MIME type → ",{"type":42,"tag":57,"props":1328,"children":1330},{"className":1329},[],[1331],{"type":48,"value":1332},"RESOURCE_MIME_TYPE",{"type":48,"value":1334}," constant",{"type":42,"tag":253,"props":1336,"children":1337},{},[1338,1347],{"type":42,"tag":275,"props":1339,"children":1340},{},[1341],{"type":42,"tag":57,"props":1342,"children":1344},{"className":1343},[],[1345],{"type":48,"value":1346},"text\u002Fhtml;profile=mcp-app",{"type":42,"tag":275,"props":1348,"children":1349},{},[1350,1352,1357],{"type":48,"value":1351},"New MIME type, but prefer ",{"type":42,"tag":57,"props":1353,"children":1355},{"className":1354},[],[1356],{"type":48,"value":1332},{"type":48,"value":1334},{"type":42,"tag":253,"props":1359,"children":1360},{},[1361,1378],{"type":42,"tag":275,"props":1362,"children":1363},{},[1364,1370,1372],{"type":42,"tag":57,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":48,"value":1369},"_domains\"",{"type":48,"value":1371}," or ",{"type":42,"tag":57,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":48,"value":1377},"_domains:",{"type":42,"tag":275,"props":1379,"children":1380},{},[1381,1383,1389,1391,1396],{"type":48,"value":1382},"snake_case CSP → camelCase (",{"type":42,"tag":57,"props":1384,"children":1386},{"className":1385},[],[1387],{"type":48,"value":1388},"connect_domains",{"type":48,"value":1390}," → ",{"type":42,"tag":57,"props":1392,"children":1394},{"className":1393},[],[1395],{"type":48,"value":717},{"type":48,"value":1397},")",{"type":42,"tag":77,"props":1399,"children":1401},{"className":1400},[1255],[1402,1405,1407],{"type":42,"tag":1258,"props":1403,"children":1404},{"disabled":1260,"type":1261},[],{"type":48,"value":1406}," Search for and migrate any remaining client-side OpenAI patterns:",{"type":42,"tag":245,"props":1408,"children":1409},{},[1410,1424],{"type":42,"tag":249,"props":1411,"children":1412},{},[1413],{"type":42,"tag":253,"props":1414,"children":1415},{},[1416,1420],{"type":42,"tag":257,"props":1417,"children":1418},{},[1419],{"type":48,"value":1278},{"type":42,"tag":257,"props":1421,"children":1422},{},[1423],{"type":48,"value":1283},{"type":42,"tag":268,"props":1425,"children":1426},{},[1427,1458,1485],{"type":42,"tag":253,"props":1428,"children":1429},{},[1430,1438],{"type":42,"tag":275,"props":1431,"children":1432},{},[1433],{"type":42,"tag":57,"props":1434,"children":1436},{"className":1435},[],[1437],{"type":48,"value":873},{"type":42,"tag":275,"props":1439,"children":1440},{},[1441,1443,1449,1451,1456],{"type":48,"value":1442},"Old global → ",{"type":42,"tag":57,"props":1444,"children":1446},{"className":1445},[],[1447],{"type":48,"value":1448},"params.arguments",{"type":48,"value":1450}," in ",{"type":42,"tag":57,"props":1452,"children":1454},{"className":1453},[],[1455],{"type":48,"value":915},{"type":48,"value":1457}," handler",{"type":42,"tag":253,"props":1459,"children":1460},{},[1461,1469],{"type":42,"tag":275,"props":1462,"children":1463},{},[1464],{"type":42,"tag":57,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":48,"value":978},{"type":42,"tag":275,"props":1470,"children":1471},{},[1472,1473,1479,1480],{"type":48,"value":1442},{"type":42,"tag":57,"props":1474,"children":1476},{"className":1475},[],[1477],{"type":48,"value":1478},"params.structuredContent",{"type":48,"value":1450},{"type":42,"tag":57,"props":1481,"children":1483},{"className":1482},[],[1484],{"type":48,"value":922},{"type":42,"tag":253,"props":1486,"children":1487},{},[1488,1497],{"type":42,"tag":275,"props":1489,"children":1490},{},[1491],{"type":42,"tag":57,"props":1492,"children":1494},{"className":1493},[],[1495],{"type":48,"value":1496},"window.openai",{"type":42,"tag":275,"props":1498,"children":1499},{},[1500,1502,1507],{"type":48,"value":1501},"Old global API → ",{"type":42,"tag":57,"props":1503,"children":1505},{"className":1504},[],[1506],{"type":48,"value":292},{"type":48,"value":1508}," instance methods",{"type":42,"tag":77,"props":1510,"children":1512},{"className":1511},[1255],[1513,1516,1518,1523,1525,1529,1531,1536],{"type":42,"tag":1258,"props":1514,"children":1515},{"disabled":1260,"type":1261},[],{"type":48,"value":1517}," For each origin from your CSP investigation, show where it appears in the ",{"type":42,"tag":57,"props":1519,"children":1521},{"className":1520},[],[1522],{"type":48,"value":827},{"type":48,"value":1524}," CSP config. ",{"type":42,"tag":618,"props":1526,"children":1527},{},[1528],{"type":48,"value":622},{"type":48,"value":1530}," origin from the CSP investigation (universal, dev-only, prod-only) must be included in the CSP config—MCP Apps HTML runs in a sandboxed iframe ",{"type":42,"tag":618,"props":1532,"children":1533},{},[1534],{"type":48,"value":1535},"with no same-origin server",{"type":48,"value":1537},". If an origin was not included in the CSP config, add it now.",{"type":42,"tag":77,"props":1539,"children":1541},{"className":1540},[1255],[1542,1545],{"type":42,"tag":1258,"props":1543,"children":1544},{"disabled":1260,"type":1261},[],{"type":48,"value":1546}," For each conditional (dev-only, prod-only) origin from your CSP investigation, show the code where the same configuration setting (env var, config file, etc.) controls both the runtime URL and the CSP entry. If the CSP has a hardcoded origin that should be conditional, fix it now—the app must be production-ready.",{"type":42,"tag":66,"props":1548,"children":1550},{"id":1549},"testing",[1551],{"type":48,"value":1552},"Testing",{"type":42,"tag":208,"props":1554,"children":1556},{"id":1555},"using-basic-host",[1557],{"type":48,"value":1558},"Using basic-host",{"type":42,"tag":51,"props":1560,"children":1561},{},[1562],{"type":48,"value":1563},"Test the migrated app with the basic-host example:",{"type":42,"tag":122,"props":1565,"children":1567},{"className":124,"code":1566,"language":126,"meta":127,"style":127},"# Terminal 1: Build and run your server\nnpm run build && npm run serve\n\n# Terminal 2: Run basic-host (from cloned repo)\ncd \u002Ftmp\u002Fmcp-ext-apps\u002Fexamples\u002Fbasic-host\nnpm install\nSERVERS='[\"http:\u002F\u002Flocalhost:3001\u002Fmcp\"]' npm run start\n# Open http:\u002F\u002Flocalhost:8080\n",[1568],{"type":42,"tag":57,"props":1569,"children":1570},{"__ignoreMap":127},[1571,1580,1617,1626,1635,1650,1663,1705],{"type":42,"tag":133,"props":1572,"children":1573},{"class":135,"line":136},[1574],{"type":42,"tag":133,"props":1575,"children":1577},{"style":1576},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[1578],{"type":48,"value":1579},"# Terminal 1: Build and run your server\n",{"type":42,"tag":133,"props":1581,"children":1583},{"class":135,"line":1582},2,[1584,1588,1593,1598,1603,1608,1612],{"type":42,"tag":133,"props":1585,"children":1586},{"style":140},[1587],{"type":48,"value":175},{"type":42,"tag":133,"props":1589,"children":1590},{"style":146},[1591],{"type":48,"value":1592}," run",{"type":42,"tag":133,"props":1594,"children":1595},{"style":146},[1596],{"type":48,"value":1597}," build",{"type":42,"tag":133,"props":1599,"children":1600},{"style":157},[1601],{"type":48,"value":1602}," &&",{"type":42,"tag":133,"props":1604,"children":1605},{"style":140},[1606],{"type":48,"value":1607}," npm",{"type":42,"tag":133,"props":1609,"children":1610},{"style":146},[1611],{"type":48,"value":1592},{"type":42,"tag":133,"props":1613,"children":1614},{"style":146},[1615],{"type":48,"value":1616}," serve\n",{"type":42,"tag":133,"props":1618,"children":1620},{"class":135,"line":1619},3,[1621],{"type":42,"tag":133,"props":1622,"children":1623},{"emptyLinePlaceholder":1260},[1624],{"type":48,"value":1625},"\n",{"type":42,"tag":133,"props":1627,"children":1629},{"class":135,"line":1628},4,[1630],{"type":42,"tag":133,"props":1631,"children":1632},{"style":1576},[1633],{"type":48,"value":1634},"# Terminal 2: Run basic-host (from cloned repo)\n",{"type":42,"tag":133,"props":1636,"children":1638},{"class":135,"line":1637},5,[1639,1645],{"type":42,"tag":133,"props":1640,"children":1642},{"style":1641},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[1643],{"type":48,"value":1644},"cd",{"type":42,"tag":133,"props":1646,"children":1647},{"style":146},[1648],{"type":48,"value":1649}," \u002Ftmp\u002Fmcp-ext-apps\u002Fexamples\u002Fbasic-host\n",{"type":42,"tag":133,"props":1651,"children":1653},{"class":135,"line":1652},6,[1654,1658],{"type":42,"tag":133,"props":1655,"children":1656},{"style":140},[1657],{"type":48,"value":175},{"type":42,"tag":133,"props":1659,"children":1660},{"style":146},[1661],{"type":48,"value":1662}," install\n",{"type":42,"tag":133,"props":1664,"children":1666},{"class":135,"line":1665},7,[1667,1673,1678,1683,1688,1692,1696,1700],{"type":42,"tag":133,"props":1668,"children":1670},{"style":1669},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[1671],{"type":48,"value":1672},"SERVERS",{"type":42,"tag":133,"props":1674,"children":1675},{"style":157},[1676],{"type":48,"value":1677},"=",{"type":42,"tag":133,"props":1679,"children":1680},{"style":157},[1681],{"type":48,"value":1682},"'",{"type":42,"tag":133,"props":1684,"children":1685},{"style":146},[1686],{"type":48,"value":1687},"[\"http:\u002F\u002Flocalhost:3001\u002Fmcp\"]",{"type":42,"tag":133,"props":1689,"children":1690},{"style":157},[1691],{"type":48,"value":1682},{"type":42,"tag":133,"props":1693,"children":1694},{"style":140},[1695],{"type":48,"value":1607},{"type":42,"tag":133,"props":1697,"children":1698},{"style":146},[1699],{"type":48,"value":1592},{"type":42,"tag":133,"props":1701,"children":1702},{"style":146},[1703],{"type":48,"value":1704}," start\n",{"type":42,"tag":133,"props":1706,"children":1708},{"class":135,"line":1707},8,[1709],{"type":42,"tag":133,"props":1710,"children":1711},{"style":1576},[1712],{"type":48,"value":1713},"# Open http:\u002F\u002Flocalhost:8080\n",{"type":42,"tag":208,"props":1715,"children":1717},{"id":1716},"verify-runtime-behavior",[1718],{"type":48,"value":1719},"Verify Runtime Behavior",{"type":42,"tag":51,"props":1721,"children":1722},{},[1723],{"type":48,"value":1724},"Once the app loads in basic-host, confirm:",{"type":42,"tag":644,"props":1726,"children":1727},{},[1728,1733,1743],{"type":42,"tag":77,"props":1729,"children":1730},{},[1731],{"type":48,"value":1732},"App loads without console errors",{"type":42,"tag":77,"props":1734,"children":1735},{},[1736,1741],{"type":42,"tag":57,"props":1737,"children":1739},{"className":1738},[],[1740],{"type":48,"value":915},{"type":48,"value":1742}," handler fires with tool arguments",{"type":42,"tag":77,"props":1744,"children":1745},{},[1746,1751],{"type":42,"tag":57,"props":1747,"children":1749},{"className":1748},[],[1750],{"type":48,"value":922},{"type":48,"value":1752}," handler fires with tool result",{"type":42,"tag":1754,"props":1755,"children":1756},"style",{},[1757],{"type":48,"value":1758},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1760,"total":1938},[1761,1782,1803,1813,1824,1837,1847,1857,1878,1893,1908,1923],{"slug":1762,"name":1762,"fn":1763,"description":1764,"org":1765,"tags":1766,"stars":1779,"repoUrl":1780,"updatedAt":1781},"agentcore-investigation","investigate Bedrock AgentCore runtime sessions","Investigate Bedrock AgentCore runtime sessions via CloudWatch Logs Insights — resolve session\u002Ftrace IDs, query OTEL spans, filter noise, build timelines. Use when debugging AgentCore agent sessions, tracing tool calls, or analyzing latency.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1767,1770,1773,1776],{"name":1768,"slug":1769,"type":16},"AWS","aws",{"name":1771,"slug":1772,"type":16},"Debugging","debugging",{"name":1774,"slug":1775,"type":16},"Logs","logs",{"name":1777,"slug":1778,"type":16},"Observability","observability",9427,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fmcp","2026-07-12T08:37:22.601527",{"slug":1783,"name":1784,"fn":1785,"description":1786,"org":1787,"tags":1788,"stars":1779,"repoUrl":1780,"updatedAt":1802},"amazon-aurora-dsql","amazon aurora dsql","build applications with Aurora DSQL","Build with Aurora DSQL — manage schemas, execute queries, handle migrations, diagnose query plans, load data, and develop applications with a serverless, distributed SQL database. Covers IAM auth, multi-tenant patterns, MySQL-to-DSQL and PostgreSQL-to-DSQL schema conversion, FK replacement code generation, OCC retry patterns, ORM migration (Django\u002FHibernate\u002FRails), DDL operations, query plan explainability, SQL compatibility validation, and bulk data loading. Triggers on phrases like: DSQL, Aurora DSQL, create DSQL table, DSQL schema, migrate to DSQL, distributed SQL database, serverless PostgreSQL-compatible database, DSQL query plan, DSQL EXPLAIN ANALYZE, why is my DSQL query slow, DSQL foreign key, DSQL OCC retry, DSQL multi-region, load into DSQL, load CSV into DSQL, bulk load DSQL, aurora-dsql-loader.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1789,1792,1793,1796,1799],{"name":1790,"slug":1791,"type":16},"Aurora","aurora",{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},"Database","database",{"name":1797,"slug":1798,"type":16},"Serverless","serverless",{"name":1800,"slug":1801,"type":16},"SQL","sql","2026-07-12T08:36:45.053393",{"slug":1804,"name":1805,"fn":1785,"description":1786,"org":1806,"tags":1807,"stars":1779,"repoUrl":1780,"updatedAt":1812},"aurora-dsql","aurora dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1808,1809,1810,1811],{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},{"name":1797,"slug":1798,"type":16},{"name":1800,"slug":1801,"type":16},"2026-07-12T08:36:42.694299",{"slug":1814,"name":1815,"fn":1785,"description":1786,"org":1816,"tags":1817,"stars":1779,"repoUrl":1780,"updatedAt":1823},"aws-dsql","aws dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1818,1819,1820,1821,1822],{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},{"name":14,"slug":15,"type":16},{"name":1797,"slug":1798,"type":16},{"name":1800,"slug":1801,"type":16},"2026-07-12T08:36:38.584057",{"slug":1825,"name":1826,"fn":1785,"description":1786,"org":1827,"tags":1828,"stars":1779,"repoUrl":1780,"updatedAt":1836},"distributed-postgres","distributed postgres",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1829,1830,1831,1834,1835],{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},{"name":1832,"slug":1833,"type":16},"PostgreSQL","postgresql",{"name":1797,"slug":1798,"type":16},{"name":1800,"slug":1801,"type":16},"2026-07-12T08:36:46.530743",{"slug":1838,"name":1839,"fn":1785,"description":1786,"org":1840,"tags":1841,"stars":1779,"repoUrl":1780,"updatedAt":1846},"distributed-sql","distributed sql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1842,1843,1844,1845],{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},{"name":1797,"slug":1798,"type":16},{"name":1800,"slug":1801,"type":16},"2026-07-12T08:36:48.104182",{"slug":1848,"name":1848,"fn":1785,"description":1786,"org":1849,"tags":1850,"stars":1779,"repoUrl":1780,"updatedAt":1856},"dsql",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1851,1852,1853,1854,1855],{"name":1768,"slug":1769,"type":16},{"name":1794,"slug":1795,"type":16},{"name":14,"slug":15,"type":16},{"name":1797,"slug":1798,"type":16},{"name":1800,"slug":1801,"type":16},"2026-07-12T08:36:36.374512",{"slug":1858,"name":1858,"fn":1859,"description":1860,"org":1861,"tags":1862,"stars":1875,"repoUrl":1876,"updatedAt":1877},"cost-efficiency-analyzer","analyze cost efficiency and expenses","Analyzes cost structure, cost efficiency, and expense management from P&L data. Use when the user asks about costs, expenses, COGS, operating expenses, cost ratios, cost control, spending efficiency, margin compression from cost side, or wants to understand where money is going. Also use for \"are we spending too much\", \"cost breakdown\", \"expense analysis\", or \"how efficient are our operations\". NOT for revenue or top-line analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1863,1866,1869,1872],{"name":1864,"slug":1865,"type":16},"Accounting","accounting",{"name":1867,"slug":1868,"type":16},"Analytics","analytics",{"name":1870,"slug":1871,"type":16},"Cost Optimization","cost-optimization",{"name":1873,"slug":1874,"type":16},"Finance","finance",3176,"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Fagentcore-samples","2026-07-12T08:40:03.29555",{"slug":1879,"name":1879,"fn":1880,"description":1881,"org":1882,"tags":1883,"stars":1875,"repoUrl":1876,"updatedAt":1892},"executive-financial-briefing","generate executive financial briefings","Generates a concise executive-level financial briefing or summary suitable for a CEO, CFO, or board presentation. Use when the user asks for a summary, briefing, executive summary, board update, financial overview, financial health check, or \"how is the business doing\". Covers the full P&L picture in one page. Also use for \"give me the highlights\", \"what do I need to know\", or \"quick financial update\".",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1884,1885,1886,1889],{"name":1768,"slug":1769,"type":16},{"name":1873,"slug":1874,"type":16},{"name":1887,"slug":1888,"type":16},"Management","management",{"name":1890,"slug":1891,"type":16},"Reporting","reporting","2026-07-12T08:40:02.066471",{"slug":1894,"name":1894,"fn":1895,"description":1896,"org":1897,"tags":1898,"stars":1875,"repoUrl":1876,"updatedAt":1907},"multi-quarter-trend-analysis","analyze multi-quarter financial trends","Analyzes financial trends across multiple quarters by comparing P&L metrics over time. Use when the user wants to see trends, patterns, trajectories, or directional movement across 3 or more quarters. Also use for \"how are we trending\", \"show me the trend\", \"track performance over time\", \"quarter over quarter comparison across all quarters\", or any multi-period longitudinal analysis.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1899,1900,1901,1904],{"name":1867,"slug":1868,"type":16},{"name":1873,"slug":1874,"type":16},{"name":1902,"slug":1903,"type":16},"Financial Statements","financial-statements",{"name":1905,"slug":1906,"type":16},"Variance Analysis","variance-analysis","2026-07-12T08:40:00.79141",{"slug":1909,"name":1909,"fn":1910,"description":1911,"org":1912,"tags":1913,"stars":1875,"repoUrl":1876,"updatedAt":1922},"pdf","process and manipulate PDF documents","Use this skill whenever the user wants to do anything with PDF files. This includes reading or extracting text\u002Ftables from PDFs, combining or merging multiple PDFs into one, splitting PDFs apart, rotating pages, adding watermarks, creating new PDFs, filling PDF forms, encrypting\u002Fdecrypting PDFs, extracting images, and OCR on scanned PDFs to make them searchable. If the user mentions a .pdf file or asks to produce one, use this skill.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1914,1917,1920],{"name":1915,"slug":1916,"type":16},"Automation","automation",{"name":1918,"slug":1919,"type":16},"Documents","documents",{"name":1921,"slug":1909,"type":16},"PDF","2026-07-12T08:41:44.135656",{"slug":1924,"name":1924,"fn":1925,"description":1926,"org":1927,"tags":1928,"stars":1875,"repoUrl":1876,"updatedAt":1937},"quarterly-kpi-calculator","calculate quarterly financial KPIs","Calculates quarterly financial KPIs from P&L data. P&L figures can be provided directly by the user or fetched from the financial data MCP server. Use when the user wants KPI calculations such as Gross Margin %, EBITDA Margin %, Operating Expense Ratio, or Revenue Growth % QoQ. Also use for quarterly performance review, P&L analysis, or interpreting financial ratios against benchmarks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1929,1930,1933,1934],{"name":1864,"slug":1865,"type":16},{"name":1931,"slug":1932,"type":16},"Data Analysis","data-analysis",{"name":1873,"slug":1874,"type":16},{"name":1935,"slug":1936,"type":16},"KPI","kpi","2026-07-12T08:39:59.54971",150,{"items":1940,"total":2037},[1941,1958,1973,1985,1999,2012,2026],{"slug":1942,"name":1942,"fn":1943,"description":1944,"org":1945,"tags":1946,"stars":26,"repoUrl":27,"updatedAt":1957},"add-app-to-server","add interactive UI to MCP servers","This skill should be used when the user asks to \"add an app to my MCP server\", \"add UI to my MCP server\", \"add a view to my MCP tool\", \"enrich MCP tools with UI\", \"add interactive UI to existing server\", \"add MCP Apps to my server\", or needs to add interactive UI capabilities to an existing MCP server that already has tools. Provides guidance for analyzing existing tools and adding MCP Apps UI resources.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1947,1950,1951,1954],{"name":1948,"slug":1949,"type":16},"Frontend","frontend",{"name":18,"slug":19,"type":16},{"name":1952,"slug":1953,"type":16},"Plugin Development","plugin-development",{"name":1955,"slug":1956,"type":16},"UI Components","ui-components","2026-07-12T08:41:40.4008",{"slug":1959,"name":1959,"fn":1960,"description":1961,"org":1962,"tags":1963,"stars":26,"repoUrl":27,"updatedAt":1972},"agui-author","emit interactive dashboard UI components","Author live dashboard UI from an agent via the `emit_ui` MCP tool. Emit one of six allow-listed components (approval_card, choice_prompt, diff_summary, progress, metric, agent_card) with JSON props and it renders in any AG-UI client watching the fleet. Use when you want the operator to see a decision, a diff, or a status readout instead of scrolling terminal text. Arbitrary HTML\u002Fmarkup is refused.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1964,1967,1970,1971],{"name":1965,"slug":1966,"type":16},"Agents","agents",{"name":1968,"slug":1969,"type":16},"Dashboards","dashboards",{"name":18,"slug":19,"type":16},{"name":1955,"slug":1956,"type":16},"2026-07-22T05:35:50.851108",{"slug":1974,"name":1974,"fn":1975,"description":1976,"org":1977,"tags":1978,"stars":26,"repoUrl":27,"updatedAt":1984},"cao-agent-routing","route tasks to appropriate CAO agents","Find and select the best installed CAO agent profile for a task before delegating with assign or handoff. Use when a supervisor needs to route coding, documentation, infrastructure, review, research, or other specialist work and the user has not already chosen an agent profile.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1979,1980,1981],{"name":1965,"slug":1966,"type":16},{"name":1768,"slug":1769,"type":16},{"name":1982,"slug":1983,"type":16},"Orchestration","orchestration","2026-07-25T05:56:34.255071",{"slug":1986,"name":1986,"fn":1987,"description":1988,"org":1989,"tags":1990,"stars":26,"repoUrl":27,"updatedAt":1998},"cao-learning","report task outcomes and distill lessons","Report task outcomes and distill lessons so the team improves across runs — report_outcome after each unit of work, retrospector handoffs at natural boundaries, and applying injected lessons. Use in workflows that run repeatedly over similar work items. Requires memory.learning_enabled; degrade silently when the tools report disabled.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1991,1992,1995],{"name":71,"slug":68,"type":16},{"name":1993,"slug":1994,"type":16},"Engineering","engineering",{"name":1996,"slug":1997,"type":16},"Operations","operations","2026-07-29T06:00:28.147989",{"slug":2000,"name":2000,"fn":2001,"description":2002,"org":2003,"tags":2004,"stars":26,"repoUrl":27,"updatedAt":2011},"cao-mcp-apps","operate CAO MCP application surfaces","Enable, operate, and extend CAO's MCP Apps surface — the host-rendered fleet dashboard visible inside MCP App hosts (Claude Desktop, ChatGPT, VS Code Copilot, Goose, Postman). Use when the user says \"enable MCP Apps in CAO\", \"the ui:\u002F\u002Fcao views aren't rendering\", \"rebuild MCP Apps bundles\", \"add a new ui:\u002F\u002Fcao\u002F* view\", or \"configure the MCP Apps OAuth scope layer\". Operates on the CAO_MCP_APPS_ENABLED surface and cao_mcp_apps\u002F build system. Not for the localhost:9889 browser dashboard, not for plugins, providers, or session management.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2005,2006,2009,2010],{"name":1965,"slug":1966,"type":16},{"name":2007,"slug":2008,"type":16},"CLI","cli",{"name":18,"slug":19,"type":16},{"name":1955,"slug":1956,"type":16},"2026-07-22T05:35:52.952289",{"slug":2013,"name":2013,"fn":2014,"description":2015,"org":2016,"tags":2017,"stars":26,"repoUrl":27,"updatedAt":2025},"cao-memory","manage durable agent memory and preferences","Store, recall, and forget durable facts with CAO memory — user preferences, project conventions, decisions, and corrections that should persist across sessions and agents. Use proactively to check memory before asking the user, and to save anything worth remembering. Distinct from any provider-native memory.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2018,2019,2022],{"name":1965,"slug":1966,"type":16},{"name":2020,"slug":2021,"type":16},"Memory","memory",{"name":2023,"slug":2024,"type":16},"Productivity","productivity","2026-07-12T08:37:03.180421",{"slug":2027,"name":2027,"fn":2028,"description":2029,"org":2030,"tags":2031,"stars":26,"repoUrl":27,"updatedAt":2036},"cao-plugin","scaffold CAO agent plugins","Create a new CAO (CLI Agent Orchestrator) plugin. Use this skill whenever the user wants to add a plugin that reacts to CAO lifecycle or messaging events, scaffold a plugin package, understand plugin requirements, or integrate an external system (Discord, Slack, dashboards, logging, metrics) with CAO. Also use when the user asks what plugin events are available, how plugin discovery works, or how to install a plugin into a CAO environment.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2032,2033,2034,2035],{"name":1965,"slug":1966,"type":16},{"name":1915,"slug":1916,"type":16},{"name":2007,"slug":2008,"type":16},{"name":1952,"slug":1953,"type":16},"2026-07-12T08:36:49.784639",16]