Skip to main content
This guide covers two reference implementations that share the same architecture. Pick the language tab that matches your stack.
Uses Node.js 18+, Express, the MCP TypeScript SDK, React, and Vite with vite-plugin-singlefile to bundle each widget into a standalone HTML file.
1

Initialise the project

Create a new Node.js project:
mkdir my-chatgpt-store && cd my-chatgpt-store
npm init -y
Edit package.json to set the module type and add build scripts:
package.json
{
  "name": "my-chatgpt-store",
  "version": "0.1.0",
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/server/index.ts",
    "build:server": "tsc -p tsconfig.server.json",
    "build:widgets": "tsx scripts/build-widgets.ts",
    "build": "npm run build:widgets && npm run build:server",
    "start": "node dist/server/index.js",
    "tunnel": "ngrok http 3000"
  }
}
2

Install dependencies

Install runtime dependencies:
npm install @modelcontextprotocol/sdk express @gr4vy/sdk zod dotenv uuid
Install dev dependencies (TypeScript, Vite, React, Tailwind, types):
npm install -D typescript tsx vite react react-dom \
  @vitejs/plugin-react vite-plugin-singlefile \
  tailwindcss @tailwindcss/vite \
  @types/express @types/node @types/react @types/react-dom @types/uuid
3

Configure TypeScript

Create tsconfig.json at the project root:
tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "jsx": "react-jsx",
    "lib": ["ES2022", "DOM", "DOM.Iterable"]
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}
Create tsconfig.server.json for server-only compilation:
tsconfig.server.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "dist/server",
    "rootDir": "src/server",
    "jsx": "react-jsx"
  },
  "include": ["src/server/**/*"],
  "exclude": ["node_modules", "dist"]
}
4

Configure environment variables

Create a .env file using the values from your Gr4vy sandbox dashboard:
.env
# Server
PORT=3000
NODE_ENV=development

# Gr4vy
GR4VY_ID=your-gr4vy-id
GR4VY_PRIVATE_KEY_PATH=./your-private-key.pem
GR4VY_MERCHANT_ACCOUNT_ID=your-merchant-account-id
GR4VY_ENVIRONMENT=sandbox

# Gr4vy webhook (for payment verification)
GR4VY_WEBHOOK_SECRET=your-webhook-secret
Place the Gr4vy private key .pem file in your project root. You can download this from your Gr4vy dashboard under Settings → Manage Integrations → Add an API Key.
5

Confirm the project structure

When complete, your project should look like this:
my-chatgpt-store/
├── src/
│   ├── server/
│   │   ├── index.ts              # HTTP transport + session management
│   │   ├── mcp.ts                # MCP tools & resources
│   │   ├── types.ts              # Shared TypeScript interfaces
│   │   ├── data/
│   │   │   └── products.ts       # Your product catalog
│   │   └── services/
│   │       └── purchases.ts      # Gr4vy payment integration
│   └── widgets/
│       ├── shared/
│       │   ├── types.ts          # Shared widget types
│       │   └── openai-bridge.ts  # ChatGPT integration API
│       ├── product-catalog/      # Catalog browsing widget
│       ├── shopping-cart/        # Cart management widget
│       └── checkout/             # Checkout + Gr4vy Embed widget
├── scripts/
│   └── build-widgets.ts          # Widget build orchestrator
├── dist/                         # Compiled output (generated)
├── package.json
├── tsconfig.json
├── tsconfig.server.json
├── vite.config.ts
└── .env
With the project scaffolded, continue to Build the MCP server.