Local OpenAI-compatible proxy for Vercel v0 chats.
It exposes an OpenAI-style edge for clients, persists local conversation mappings in SQLite, and serves a lightweight dashboard from the same server.
- Accepts
POST /v1/chat/completions - Exposes
GET /v1/modelsandGET /v1/models/:model - Uses v0
POST /chatsandPOST /chats/{chatId}/messagesupstream - Stores local conversation state in SQLite
- Serves a dashboard at
/with:OverviewUsageConversations
- If incoming history matches a known local prefix hash, the proxy continues the existing upstream
chatId. - If incoming history does not match, the proxy creates a new upstream chat.
- On that fallback create, the proxy now forwards prior conversation history to v0 by serializing earlier turns into the new chat's
systemcontext and sending the current user turn as the livemessage. - The Conversations dashboard shows a merged transcript view. When an upstream fallback chat only contains the latest turn pair, the dashboard fills in the earlier turns from the proxy's local history snapshot so you can still inspect the full local conversation.
npm install
npm --prefix web installCopy .env.template to .env and set real values:
V0_API_KEY=your_v0_api_key_here
V0_API_BASE_URL=https://api.v0.dev/v1
HOST=127.0.0.1
PORT=3000
OPENAI_API_KEY=local-dev-openai-key
CHAT_STATE_FILE=.data/chat-state.dbNotes:
V0_API_KEYis required.- In the current implementation, clients calling the local proxy should send
Authorization: Bearer $OPENAI_API_KEY. - Use
HOST=0.0.0.0if you want to reach the proxy from another device on your LAN.
Run migrations when setting up a new DB file or after adding migrations:
npm run db:migrateYou do not need to run migrations before every start.
Backend and bundled frontend:
npm run devThis starts the Fastify server on HOST:PORT and serves the built frontend from web/dist.
If you change frontend code and are not running a separate Vite dev server, rebuild the frontend bundle:
npm --prefix web run buildOptional manual frontend dev server:
npm --prefix web run devThat runs Vite separately, usually on http://localhost:5173.
For OpenAI-compatible clients:
- Base URL:
http://localhost:3000/v1 - Chat completions:
http://localhost:3000/v1/chat/completions
If using another device on the network, include the scheme:
http://192.168.x.x:3000/v1
Current local model list:
v0-autov0-miniv0-prov0-maxv0-max-fast
Legacy aliases accepted by the proxy:
gpt-4->v0-progpt-4-turbo->v0-maxgpt-3.5-turbo->v0-mini
curl -X POST http://localhost:3000/v1/chat/completions \
-H "Authorization: Bearer local-dev-openai-key" \
-H "Content-Type: application/json" \
-d '{
"model": "v0-auto",
"messages": [
{ "role": "user", "content": "Hello" }
]
}'Open:
http://localhost:3000/
Pages:
Overviewfor high-level statusUsagefor balance, rate limits, and recent v0 usage eventsConversationsfor local conversation list and transcript inspection
OpenAI-compatible:
GET /v1/modelsGET /v1/models/:modelPOST /v1/chat/completions
Internal:
GET /internal/healthGET /internal/capacityGET /internal/conversationsGET /internal/conversations/:chatId/messagesDELETE /internal/conversations/:chatId
Debug-only internal DB endpoints:
GET /internal/db/schemaPOST /internal/db/query
/internal/db/query is read-only and guarded, but it is still a debug surface, not part of the normal user workflow.
Backend TypeScript build:
npm run buildFrontend bundle build:
npm --prefix web run buildnpm test