Skip to main content
Use model context to give the next model turn the information it needs. Tool results establish the initial context. useViewState and ModelContext describe the view. useModelContext manages selected native attachments. Keep each piece of evidence in one context channel.

Choose the right channel

Attach evidence to the next turn

Use useModelContext() to add selected text, images, resource links, or embedded resources to the next model turn. The hook shares one attachment collection across the view. You can add, replace, remove, and clear attachments with stable application keys. Read Attach evidence with ChatGPT Plugin Extensions for complete examples, image inputs, and error handling. The guide also explains host removals and how to combine the hook with useViewState and ModelContext.

Keep structured choices in view state

Use useViewState for selections, filters, drafts, and progress that future model turns should understand.
The root state value must be a JSON-serializable object. All components in one mounted view share it. Separate view instances remain isolated. By default, ChatGPT restores state through window.openai.widgetState. Other MCP Apps hosts keep state for the current iframe lifetime. After useModelContext activates native delivery, OpenAI host context can restore model-visible state and attachments. Private UI persistence remains separate.

Describe visible UI

Use ModelContext for natural-language descriptions that follow the React component lifecycle.
Nested components serialize into an indented tree:
For descriptions from event handlers or other callbacks, store the description in React state and render it with ModelContext:

Understand the merged snapshot

The runtime merges structured state and the serialized context tree into one complete object:
_uiContext is a reserved model-visible field. useViewState filters it from application state and rejects developer state with the same key. Every write sends the complete snapshot. On MCP Apps hosts, mcp-use sends the object as structuredContent and a JSON text block as content through ui/update-model-context. On ChatGPT, views without useModelContext write the object to modelContent with window.openai.setWidgetState. Views with useModelContext use the shared native writer described in ChatGPT Plugin Extensions.

Keep ephemeral values local

Use React useState for transient details that the model does not need, such as hover state, open tooltips, or animation progress.

Next steps