DEV Community

Ekim Cem Ülger
Ekim Cem Ülger

Posted on

Building a ChatGPT App with VoltAgent and the Apps SDK

This guide shows how to use VoltAgent — a TypeScript framework for creating agents, MCP servers, and workflows — to deploy an MCP (Model Context Protocol) server and connect it to ChatGPT Apps using the Apps SDK. It demonstrates how to go from setup to a working ChatGPT-connected app step by step.


What Are ChatGPT Apps?

OpenAI recently introduced ChatGPT Apps — a new framework that allows developers to build and publish their own tools and services directly inside ChatGPT. Using the Apps SDK, you can connect APIs, workflows, and MCP servers to ChatGPT, turning them into interactive applications that users can access directly from the chat interface.

ChatGPT Apps are the next evolution of the MCP (Model Context Protocol) ecosystem. They allow developers to define capabilities through tools, resources, and prompts, and make them discoverable within ChatGPT itself.

💡 This is my personal perspective: In the future, OpenAI is expected to expand this system into a marketplace — a kind of “App Store for ChatGPT” — where developers can publish and share their MCP-powered apps with millions of users.

This tutorial focuses on building and deploying one of these ChatGPT Apps using VoltAgent.


1. Create the App

Start by creating a new VoltAgent app:

pnpm create voltagent-app my-agent-app
Enter fullscreen mode Exit fullscreen mode

When prompted, select your provider — for now, choose OpenAI.

Then install the MCP server package:

pnpm add @voltagent/mcp-server
Enter fullscreen mode Exit fullscreen mode

2. Basic MCP Server Setup

In your mcp/server.ts file, import and initialize the MCP server:

import { MCPServer } from "@voltagent/mcp-server";

export const mcpServer = new MCPServer({
  name: "voltagent-example",
  version: "0.1.0",
  description: "VoltAgent MCP example",
});
Enter fullscreen mode Exit fullscreen mode

You can keep the configuration simple for now — we’ll update it later.


3. Integrate with VoltAgent

When VoltAgent initializes, it automatically sets up your agent, workflows, and server. To include the MCP server, simply add it to the configuration.

import "dotenv/config";
import { VoltAgent, VoltOpsClient, Agent, Memory } from "@voltagent/core";
import { LibSQLMemoryAdapter } from "@voltagent/libsql";
import { createPinoLogger } from "@voltagent/logger";
import { openai } from "@ai-sdk/openai";
import { honoServer } from "@voltagent/server-hono";
import { expenseApprovalWorkflow } from "./workflows";
import { weatherTool } from "./tools";
import { mcpServer } from "./mcp/server";

// Create a logger instance
const logger = createPinoLogger({
  name: "my-voltagent-app",
  level: "info",
});

// Configure persistent memory (LibSQL / SQLite)
const memory = new Memory({
  storage: new LibSQLMemoryAdapter({
    url: "file:./.voltagent/memory.db",
    logger: logger.child({ component: "libsql" }),
  }),
});

const agent = new Agent({
  name: "my-voltagent-app",
  instructions: "A helpful assistant that can check weather and help with various tasks",
  model: openai("gpt-4o-mini"),
  tools: [weatherTool],
  memory,
});

new VoltAgent({
  agents: {
    agent,
  },
  workflows: {
    expenseApprovalWorkflow,
  },
  mcpServers: {
    mcpServer,
  },
  server: honoServer(),
  logger,
  voltOpsClient: new VoltOpsClient({
    publicKey: process.env.VOLTAGENT_PUBLIC_KEY || "",
    secretKey: process.env.VOLTAGENT_SECRET_KEY || "",
  }),
});
Enter fullscreen mode Exit fullscreen mode

This is the automatically generated initialization code, with the addition of the mcpServers key.


4. Create a Mock MCP Tool

Let’s create a mock weather tool to test the MCP connection.

import { createTool } from "@voltagent/core";
import { MCPServer } from "@voltagent/mcp-server";
import { z } from "zod";

export const getWeatherTool = createTool({
  name: "get_weather",
  description: "Return mock weather data for a given location",
  parameters: z.object({
    location: z.string().describe("Location to fetch weather for"),
  }),
  execute: async (params: any) => {
    const { location } = params;
    return {
      success: true,
      location,
      forecast: "☀️ Sunny, 24°C (mock data)",
      timestamp: new Date().toISOString(),
    };
  },
});

export const mcpServer = new MCPServer({
  id: "voltagent-example",
  name: "voltagent-example",
  version: "0.1.0",
  description: "VoltAgent MCP example with a mock Get Weather tool",
  tools: {
    getWeather: getWeatherTool,
  },
});
Enter fullscreen mode Exit fullscreen mode

Then start the development server:

pnpm run dev
Enter fullscreen mode Exit fullscreen mode

If successful, your terminal should display:

══════════════════════════════════════════════════
  VOLTAGENT SERVER STARTED SUCCESSFULLY
══════════════════════════════════════════════════
  ✓ HTTP Server:  http://localhost:3141
  ✓ Swagger UI:   http://localhost:3141/ui

  ✓ Registered Endpoints: 10 total

    MCP Endpoints
      GET    /mcp/servers
      GET    /mcp/servers/{serverId}
      GET    /mcp/servers/{serverId}/tools
      GET    /mcp/servers/{serverId}/prompts
      GET    /mcp/servers/{serverId}/prompts/{promptName}
      GET    /mcp/servers/{serverId}/resources
      GET    /mcp/servers/{serverId}/resources/contents
      GET    /mcp/servers/{serverId}/resource-templates
      POST   /mcp/servers/{serverId}/tools/{toolName}
      POST   /mcp/servers/{serverId}/logging/level

  Test your agents with VoltOps Console: https://console.voltagent.dev
══════════════════════════════════════════════════
Enter fullscreen mode Exit fullscreen mode

5. Testing Locally with VoltOps Console

Visit https://console.voltagent.dev/mcp.

Enter your local HTTP server URL:

http://localhost:3141
Enter fullscreen mode Exit fullscreen mode

URL Input field on VoltOps Console

You should see your get-weather tool listed. Try clicking it and typing a random location — you’ll get a mock weather response.

💡 Don’t forget to adjust the MCP server description to match your tool’s purpose (e.g., mention weather forecasting).


6. Exposing a Public Endpoint

ChatGPT requires an HTTPS endpoint. During development, you can use ngrok to expose your local server.

Install ngrok (see ngrok.com) and then, in a separate terminal window, run:

ngrok http 3141
# Forwarding: https://<subdomain>.ngrok.app -> http://127.0.0.1:3141
Enter fullscreen mode Exit fullscreen mode

Your VoltAgent Hono service runs on port 3141 by default.


7. Connect Your MCP Server to ChatGPT

  1. Open ChatGPT Settings → Click your avatar (bottom-left)Settings → Go to Apps.

ChatGPT UI

  1. Enable Developer Mode
  • Request access from your OpenAI partner contact or workspace admin.
  • Then toggle: Settings → Connectors → Advanced → Developer Mode.
  • Once enabled, you’ll see a Create button under Settings → Connectors.
  1. Create a Connector
  • Ensure your MCP server is reachable over HTTPS (via ngrok).
  • In ChatGPT: go to Settings → Connectors → Create.
  • Fill in:

    • Connector Name: VoltAgent Example Server
    • Description: Provides example tools via VoltAgent MCP server.
    • Connector URL: https://<subdomain>.ngrok.app/mcp/voltagent-example/mcp
  • Click Create.

  1. Disable Authentication (for testing)
  • Disable auth during local testing; re-enable for production.
  1. Verify the Integration
  • If successful, you’ll see your get-weather tool listed in ChatGPT.
  • You can now call your MCP tool directly from within ChatGPT — your VoltAgent app is live!

Discussion

Now that OpenAI is opening the door to custom ChatGPT Apps built with the Apps SDK, we’re at the start of a new developer ecosystem around MCP. Using VoltAgent makes it easier to structure these apps with agents, workflows, and tools.

👉 What do you think? Which types of apps do you believe will perform best in a future ChatGPT marketplace — productivity tools, automations, educational helpers, or something else? And what are your own plans for building and sharing MCP-based apps?

If you run into any issues while following this guide or during development, feel free to share your questions or problems here — happy to help troubleshoot and improve together! 🚀

Top comments (0)