Skip to main content
Glama

ChatGPT Apps MCP Server

MCP Server for ChatGPT Apps

A Model Context Protocol (MCP) server with interactive React components for ChatGPT Apps.

What is This?

This project implements an MCP server that works with ChatGPT Apps SDK, featuring:

  • SSE-based MCP server - HTTP server using Server-Sent Events

  • Interactive React widgets - Components that render inline in ChatGPT

  • Calculator example - A fully functional calculator with history

  • Modern build system - Vite + React + TypeScript + Tailwind CSS

Project Structure

mcp-server/ ├── server/ │ └── src/ │ └── server.ts # MCP server with SSE transport ├── web/ │ └── src/ │ ├── calculator/ # Calculator React component │ ├── types.ts # TypeScript definitions for window.openai │ ├── use-openai-global.ts # Hook for ChatGPT state │ ├── use-widget-state.ts # Hook for widget persistence │ └── index.css # Global styles ├── assets/ # Built components (generated) ├── scripts/ │ └── post-build.js # HTML generation script ├── vite.config.ts # Vite build configuration ├── tailwind.config.ts # Tailwind CSS config └── package.json # Root dependencies

Installation

1. Install Dependencies

# Install root dependencies (React, Vite, Tailwind) npm install # Install server dependencies (MCP SDK) cd server && npm install && cd ..

2. Build Components

npm run build

This generates bundled React components in the assets/ directory.

Running the Server

Start the MCP Server

npm run server

The server will start on http://localhost:8000 with these endpoints:

  • GET /mcp - SSE stream

  • POST /mcp/messages?sessionId=... - Message handler

Testing with ChatGPT

Option 1: Local Testing with ngrok

  1. Start the server:

    npm run server
  2. Expose with ngrok:

    ngrok http 8000
  3. Add to ChatGPT:

    • Go to ChatGPT Settings > Connectors

    • Add connector with URL: https://YOUR-ID.ngrok-free.app/mcp

  4. Use in ChatGPT:

    • Add the connector to your conversation

    • Ask: "Show me a calculator" or "Open calculator"

    • The interactive calculator widget will appear!

Option 2: Production Deployment

  1. Set base URL for assets:

    export BASE_URL=https://your-cdn.com npm run build
  2. Deploy:

    • Upload assets/ to a CDN or static hosting (with CORS enabled)

    • Deploy the MCP server with HTTPS

    • Register in ChatGPT with your server URL

Available Tools

1. Calculator (with React UI)

  • Tool: calculator

  • Description: Interactive calculator widget with history

  • Features:

    • Basic arithmetic operations

    • Calculation history (last 5 calculations)

    • Dark/light theme support

    • State persistence across turns

2. Get Current Time

  • Tool: get_current_time

  • Returns: Current time in ISO format

3. Echo

  • Tool: echo

  • Returns: Echoes back your message

Development

Run Dev Server (with hot reload)

npm run dev

Visit http://localhost:4444 to preview components.

Adding New Components

  1. Create component in web/src/your-component/index.tsx:

import React from "react"; import { createRoot } from "react-dom/client"; import { useOpenAiGlobal } from "../use-openai-global"; function App() { const toolOutput = useOpenAiGlobal("toolOutput"); const theme = useOpenAiGlobal("theme"); return ( <div className={theme === "dark" ? "dark" : ""}> <h1>Your Component</h1> {/* Your UI */} </div> ); } createRoot(document.getElementById("your-component-root")!).render(<App />);
  1. Update Vite config (vite.config.ts):

input: { calculator: path.resolve(__dirname, "web/src/calculator/index.tsx"), "your-component": path.resolve(__dirname, "web/src/your-component/index.tsx"), },
  1. Update post-build script (scripts/post-build.js):

const components = ["calculator", "your-component"];
  1. Add widget to server (server/src/server.ts):

const widgets: Widget[] = [ // ... existing widgets { id: "your-component", title: "Your Component", templateUri: "ui://widget/your-component.html", invoking: "Loading your component", invoked: "Component ready", html: readWidgetHtml("your-component"), responseText: "Component rendered!", }, ];
  1. Build and test:

npm run build npm run server

Key Features

window.openai API

Components have access to:

window.openai.theme // "light" | "dark" window.openai.displayMode // "inline" | "pip" | "fullscreen" window.openai.toolOutput // Data from tool call window.openai.widgetState // Persisted component state window.openai.callTool(name, args) // Call MCP tools window.openai.sendFollowUpMessage({ prompt }) // Send to ChatGPT

Custom Hooks

// Subscribe to ChatGPT state const theme = useOpenAiGlobal("theme"); // Persist component state const [state, setState] = useWidgetState({ count: 0 });

Troubleshooting

"Widget assets not found"

Run npm run build to generate component bundles.

CORS errors

Ensure your server has CORS enabled (already configured in server.ts).

Components not rendering

  1. Check browser console for errors

  2. Verify assets are accessible at BASE_URL

  3. Ensure HTML files reference correct JS/CSS paths

Resources

License

ISC

-
security - not tested
F
license - not found
-
quality - not tested

hybrid server

The server is able to function both locally and remotely, depending on the configuration or use case.

Enables interactive React components to render inline in ChatGPT conversations, featuring a calculator widget with history and demonstrating how to build custom UI components for ChatGPT Apps.

  1. What is This?
    1. Project Structure
      1. Installation
        1. 1. Install Dependencies
        2. 2. Build Components
      2. Running the Server
        1. Start the MCP Server
      3. Testing with ChatGPT
        1. Option 1: Local Testing with ngrok
        2. Option 2: Production Deployment
      4. Available Tools
        1. 1. Calculator (with React UI)
        2. 2. Get Current Time
        3. 3. Echo
      5. Development
        1. Run Dev Server (with hot reload)
        2. Adding New Components
      6. Key Features
        1. window.openai API
        2. Custom Hooks
      7. Troubleshooting
        1. "Widget assets not found"
        2. CORS errors
        3. Components not rendering
      8. Resources
        1. License

          MCP directory API

          We provide all the information about MCP servers via our MCP API.

          curl -X GET 'https://glama.ai/api/mcp/v1/servers/BruceWilliamChen/mcp-server'

          If you have feedback or need assistance with the MCP directory API, please join our Discord server