Skip to main content
OpenAI’s ChatGPT Apps platform can consume MCP servers as “Actions”. This guide explains how to package an mcp-agent or FastMCP deployment for ChatGPT, including widget metadata, static assets, and authentication considerations.

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; the bundle should have build output (JS, CSS) at web/build/static or web/dist/static
Example: examples/cloud/chatgpt_apps

1. Build the widget assets

In the example project:
The server serves these assets via FastMCP resources. For initial iteration you can inline HTML/JS inside the MCP resource, but packaging static files yields better caching.

2. Define widget metadata

ChatGPT Apps understand OpenAI-specific tool annotations. The example coin-flip widget uses:
When the tool returns an EmbeddedResource, ChatGPT hydrates the widget using the referenced HTML template.

3. Deploy with --no-auth

Unauthenticated access is mandatory—ChatGPT Apps cannot attach custom headers or bearer tokens yet. The platform still enforces rate limits and observability, but anyone with the URL can access the server. Treat public deployments accordingly. After deployment, update the widget template URI to the final domain:
Redeploy to publish changes.

4. Register the action in ChatGPT Apps

  1. Open developers.openai.com/apps.
  2. Create or open your app, then add a new Action.
  3. Choose MCP as the action type.
  4. 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).
  5. Select Server-Sent Events as the transport (all mcp-agent cloud deployments currently expose SSE endpoints).
  6. 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/toolInvocation strings 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.info to log widget usage; stream via mcp-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

Resources