This folder contains all backend code for the MCP server and widget serving.
index.ts
- Main Hono application entrypointdatabase/
- SQLite database schema and queriesmcp/
- MCP server with ChatGPT tools and widget resources
This app uses Hono as the web framework. Hono is designed for serverless environments like Val Town and Cloudflare Workers. If you're familiar with Express, Flask, or Sinatra, Hono follows similar patterns.
The backend serves three types of content:
Serves the setup instructions page with the dynamically injected MCP endpoint URL.
The Model Context Protocol server endpoint that ChatGPT connects to. This handles:
- Tool discovery and execution
- Widget resource serving
- Streaming HTTP transport for MCP messages
Serves the React widget files with automatic TypeScript/TSX transpilation. The backend maps requests from /widget-assets/*
to /frontend/widgets/*
and uses Val Town's serveFile
utility to:
- Read project files across branches and forks
- Automatically transpile TSX → JS
- Set correct content-types
Example: GET /widget-assets/widget.tsx
→ serves transpiled JS from /frontend/widgets/widget.tsx
The MCP server (backend/mcp/server.ts
) defines:
- Widget Resource - The HTML template that ChatGPT loads in an iframe
- Tools - Functions that ChatGPT can call (list_messages, add_message, get_message)
- Widget Metadata - Configuration for widget behavior, CSP, loading states
Each tool returns structured data with a kind
discriminator that the widget router uses for navigation.
The widget HTML template (frontend/widgets/index.html
) contains __VAL_TOWN_URL__
placeholders that get replaced with the actual deployment URL when the widget resource is requested. This ensures widget assets load from the correct domain across forks and branches.
By default, Hono swallows errors and returns "Internal Server Error". We override this behavior to see full stack traces:
app.onError((err, c) => {
throw err;
});
This makes debugging easier during development. You can customize this for production.