• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
laurynas

laurynas

ChatAppSDKStarter

A starter val for building ChatGPT Apps powered by React
Remix of laurynas/tanstackReactHonoExample
Public
Like
1
ChatAppSDKStarter
Home
Code
7
backend
4
frontend
8
shared
3
.vtignore
AGENTS.md
README.md
deno.json
Branches
1
Pull requests
Remixes
5
History
Environment variables
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
10/10/2025
Viewing readonly version of main branch: v63
View latest version
README.md

Val Town ChatGPT App SDK Starter

Full-stack message board with ChatGPT widget integration built for Val Town.

Tech Stack

Backend

  • Hono web framework
  • MCP Lite server (Model Context Protocol)
  • Drizzle ORM with SQLite
  • Deno runtime

Frontend (Message Board)

  • React 19
  • TanStack Router (code-first routing)
  • TanStack Query (server state management)
  • Tailwind CSS
  • TypeScript

ChatGPT Widget

  • React 19 with runtime transpilation
  • TanStack Router for widget navigation
  • OpenAI App SDK integration
  • No build step required

Features

  • Message board with persistent storage
  • ChatGPT integration via MCP server
  • Interactive widgets in ChatGPT conversations
  • Client-side routing
  • Optimistic updates
  • Server-side data injection
  • Type-safe database operations

Project Structure

├── backend/          # Hono server running on Val Town
│   ├── database/     # Drizzle schema, migrations, and queries
│   ├── mcp/          # MCP server with ChatGPT tools and widgets
│   └── index.ts      # Main Hono application
├── frontend/         # Message board React app
│   ├── components/   # React components
│   ├── lib/          # Utilities and hooks
│   └── router.tsx    # TanStack Router configuration
├── widget/           # ChatGPT widget (runtime transpilation)
│   ├── components/   # Widget React components
│   ├── routes.tsx    # Widget router configuration
│   └── index.tsx     # Widget entry point
└── shared/           # Code shared between all parts

API Endpoints

Message Board

  • GET / - Serves the React application with initial data
  • GET /api/messages - Fetch all messages (JSON)
  • POST /api/messages - Create a new message
  • GET /public/** - Static assets (CSS, JS, etc.)

ChatGPT Integration

  • POST /mcp - MCP server endpoint for ChatGPT
  • GET /widget-assets/** - Widget assets (auto-transpiled TSX → JS)

Val Town Constraints

  • Read-only filesystem after deployment
  • ESM imports via esm.sh for npm packages
  • Code-first routing (no file-based routing)
  • Runtime transpilation for TypeScript/TSX (no build step)

Implementation

Router

Create val
const homeRoute = new Route({ getParentRoute: () => rootRoute, path: "/", component: () => <App {...window.__INITIAL_DATA__} /> });

Query

Create val
export function usePostMessage() { return useMutation({ mutationFn: (content: string) => postMessage(content), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["messages"] }); }, }); }

Schema

Create val
export const messages = sqliteTable("messages", { id: integer("id").primaryKey({ autoIncrement: true }), content: text("content").notNull(), timestamp: text("timestamp").notNull().default(new Date().toISOString()), });

ChatGPT Integration

Quick Start

  1. Deploy to Val Town:

    vt push
  2. Get your Val URL:

    https://yourname-projectname.val.run
    
  3. Add MCP server to ChatGPT:

    • Go to ChatGPT settings
    • Add MCP server: https://yourname-projectname.val.run/mcp
  4. Use in ChatGPT:

    User: "List all messages"
    ChatGPT: [Calls list_messages tool]
    [Interactive widget appears showing messages]
    

Available Tools

  • list_messages - Shows interactive message list widget
  • add_message - Adds a message and shows updated list
  • greet - Personalized greeting widget

Widget Architecture

The widget uses runtime transpilation - no build step required:

  1. MCP server returns HTML widget resource
  2. ChatGPT iframe loads widget HTML
  3. Browser requests TSX files from /widget-assets/*
  4. Val Town's serveFile transpiles TSX → JS automatically
  5. React app hydrates with tool output
  6. TanStack Router navigates based on output kind

See widget/README.md for detailed documentation.

Development

Local Development with vt CLI

# Pull from Val Town vt pull # Watch for changes and auto-deploy vt watch # Edit files locally - changes deploy in ~100ms

Web IDE

Alternatively, edit directly on val.town with instant deployment.

FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2025 Val Town, Inc.