Skip to main content
Glama

ChatGPT Apps MCP Server

README.md5.94 kB
# 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 ```bash # Install root dependencies (React, Vite, Tailwind) npm install # Install server dependencies (MCP SDK) cd server && npm install && cd .. ``` ### 2. Build Components ```bash npm run build ``` This generates bundled React components in the `assets/` directory. ## Running the Server ### Start the MCP Server ```bash 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**: ```bash npm run server ``` 2. **Expose with ngrok**: ```bash 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**: ```bash 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) ```bash npm run dev ``` Visit `http://localhost:4444` to preview components. ### Adding New Components 1. **Create component** in `web/src/your-component/index.tsx`: ```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 />); ``` 2. **Update Vite config** (`vite.config.ts`): ```typescript input: { calculator: path.resolve(__dirname, "web/src/calculator/index.tsx"), "your-component": path.resolve(__dirname, "web/src/your-component/index.tsx"), }, ``` 3. **Update post-build script** (`scripts/post-build.js`): ```javascript const components = ["calculator", "your-component"]; ``` 4. **Add widget to server** (`server/src/server.ts`): ```typescript 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!", }, ]; ``` 5. **Build and test**: ```bash npm run build npm run server ``` ## Key Features ### window.openai API Components have access to: ```typescript 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 ```typescript // 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 - [OpenAI Apps SDK Documentation](https://developers.openai.com/apps-sdk) - [MCP Specification](https://modelcontextprotocol.io) - [Example Apps Gallery](https://github.com/openai/openai-apps-sdk-examples) ## License ISC

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