Follow-up to #592. Native TS tools can now return a widget (a ToolResult with a UIPayload), but the TypeScript MCPToolProvider still flattens every MCP result to text — so a widget advertised by an MCP server (_meta.ui / openai/outputTemplate, the ChatGPT-Apps contract) never reaches the caller.
Make MCPToolProvider carry it through, mirroring the Swift and Python (#594) providers:
- Parse each tool's
_meta at connect time (ui resource URI + visibility); app-only tools stay callable but are filtered out of this.tools (never advertised to the model).
- Each MCP tool's
func becomes real (calls the server, returns a ToolResult); callMCPTool reads structuredContent, fetches the advertised UI resource (readResource, cached per client), and builds a UIPayload.
- This also fixes a latent gap:
GroundedAgent captures via the tool's func, which the old dummy-func + toolHandler override bypassed — so MCP tool calls weren't captured at all.
Purely additive: a server that advertises no _meta.ui sends the same text to the model as today. Lets a TS GroundedAgent render the widgets of the same MCP server that backs a ChatGPT App.
Follow-up to #592. Native TS tools can now return a widget (a
ToolResultwith aUIPayload), but the TypeScriptMCPToolProviderstill flattens every MCP result to text — so a widget advertised by an MCP server (_meta.ui/openai/outputTemplate, the ChatGPT-Apps contract) never reaches the caller.Make
MCPToolProvidercarry it through, mirroring the Swift and Python (#594) providers:_metaat connect time (ui resource URI + visibility); app-only tools stay callable but are filtered out ofthis.tools(never advertised to the model).funcbecomes real (calls the server, returns aToolResult);callMCPToolreadsstructuredContent, fetches the advertised UI resource (readResource, cached per client), and builds aUIPayload.GroundedAgentcaptures via the tool'sfunc, which the old dummy-func + toolHandler override bypassed — so MCP tool calls weren't captured at all.Purely additive: a server that advertises no
_meta.uisends the same text to the model as today. Lets a TSGroundedAgentrender the widgets of the same MCP server that backs a ChatGPT App.