Requirements
- ChatGPT Apps developer access
- Deployed MCP server with unauthenticated access enabled (
mcp-agent deploy ... --no-auth) - Optional: frontend bundle (React, vanilla JS) if you want rich widgets
Recommended project structure
examples/cloud/chatgpt_app
1. Build the widget assets
In the example project:2. Define widget metadata
ChatGPT Apps understand OpenAI-specific tool annotations. The example coin-flip widget uses:EmbeddedResource, ChatGPT hydrates the widget using the referenced HTML template.
3. Deploy with --no-auth
4. Register the action in ChatGPT Apps
- Open developers.openai.com/apps.
- Create or open your app, then add a new Action.
- Choose MCP as the action type.
- Provide the server URL (
https://<app_id>.deployments.mcp-agent.com).<app_id>matches the hostname shown in the deployment output (for example,app_abc123xyz). - Select Server-Sent Events as the transport (all mcp-agent cloud deployments currently expose SSE endpoints).
- Save and test—ChatGPT will list available tools (
coin-flip) and display widgets declared via annotations.
5. Iterate on the widget
- Cache busting – update
template_uri(include a timestamp or semantic version) whenever you change the HTML so ChatGPT fetches the new template. - State – return structured data from the tool. The client-side widget receives this in
state.result. - Accessibility – provide meaningful
openai/toolInvocationstrings and fallback text for users who cannot render widgets.
6. Optional enhancements
- Hybrid auth – combine a public endpoint with per-user rate limiting by inspecting request metadata (e.g., custom query params) inside your tool and calling your own auth service.
- Telemetry – use
context.logger.infoto log widget usage; stream viamcp-agent cloud logger tail. - Publishing – once stable, add metadata (name, description, icon) when you create the ChatGPT App so users can discover it in the directory.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| ChatGPT cannot reach the server | Deployment still requires auth | Redeploy with --no-auth |
| Widget fails to render | Template URI cached | Bump template_uri with new suffix |
| SSE handshake fails | Wrong transport or missing /sse | Use server URL ending in /sse and ensure tool returns SSE-compatible responses |
| Tool not listed | Server offline or tool registration mismatch | mcp-agent cloud servers describe <id> and mcp-agent cloud logger tail for details |
