
A template for building AI-powered coding agents that supports Claude Code, OpenAI's Codex CLI, GitHub Copilot CLI, Cursor CLI, Google Gemini CLI, and opencode with Vercel Sandbox to automatically execute coding tasks on your repositories.
You can deploy your own version of the coding agent template to Vercel with one click:
What happens during deployment:
For detailed setup instructions, see the Local Development Setup section below.
TL;DR:
Or run locally:
git clone https://github.com/vercel-labs/coding-agent-template.gitcd coding-agent-templatepnpm install# Set up .env.local with required variablespnpm db:pushpnpm dev
The maximum duration setting controls how long the Vercel sandbox will stay alive from the moment it's created. You can select timeouts ranging from 5 minutes to 5 hours.
The Keep Alive setting determines what happens to the sandbox after your task completes.
Keep Alive OFF (Default)When Keep Alive is disabled, the sandbox shuts down immediately after the task completes:
Timeline:
Use Keep Alive OFF when:
When Keep Alive is enabled, the sandbox stays alive after task completion for the remaining duration:
Timeline:
npm run dev), it automatically starts in the backgroundUse Keep Alive ON when:
| Setting | Task completes in 10 min | Remaining sandbox time | Can send follow-ups? | Dev server starts? |
|---|---|---|---|---|
| Keep Alive ON | Sandbox stays alive | 50 minutes (until timeout) | Yes | Yes (if available) |
| Keep Alive OFF | Sandbox shuts down | 0 minutes | No | No |
Note: The maximum duration timeout always takes precedence. If you set a 1-hour timeout, the sandbox will expire after 1 hour regardless of the Keep Alive setting. Keep Alive only determines whether the sandbox shuts down early (after task completion) or stays alive until the timeout.
after())The system automatically generates descriptive Git branch names using AI SDK 5 and Vercel AI Gateway. This feature:
after() function to generate names without delaying task creationfeature/user-authentication-A1b2C3 or fix/memory-leak-parser-X9y8Z7feature/add-user-auth-K3mP9n (for "Add user authentication with JWT")fix/resolve-memory-leak-B7xQ2w (for "Fix memory leak in image processing")chore/update-deps-M4nR8s (for "Update all project dependencies")docs/api-endpoints-F9tL5v (for "Document REST API endpoints")Connect MCP Servers to extend Claude Code with additional tools and integrations. Currently only works with Claude Code agent.
ENCRYPTION_KEY is set in your environment variablesNote: ENCRYPTION_KEY is required when using MCP servers with OAuth authentication.
git clone https://github.com/vercel-labs/coding-agent-template.gitcd coding-agent-template
pnpm install
Create a .env.local file with your values:
These are set once by you (the app developer) and are used for core infrastructure:
POSTGRES_URL: Your PostgreSQL connection string (automatically provided when deploying to Vercel via the Neon integration, or set manually for local development)SANDBOX_VERCEL_TOKEN: Your Vercel API token (for creating sandboxes)SANDBOX_VERCEL_TEAM_ID: Your Vercel team ID (for sandbox creation)SANDBOX_VERCEL_PROJECT_ID: Your Vercel project ID (for sandbox creation)JWE_SECRET: Base64-encoded secret for session encryption (generate with: openssl rand -base64 32)ENCRYPTION_KEY: 32-byte hex string for encrypting user API keys and tokens (generate with: openssl rand -hex 32)User Authentication (Required)Note: When deploying to Vercel using the "Deploy with Vercel" button, the database is automatically provisioned via Neon and
POSTGRES_URLis set for you. For local development, you'll need to provide your own database connection string.
You must configure at least one authentication method (Vercel or GitHub):
Configure Enabled ProvidersNEXT_PUBLIC_AUTH_PROVIDERS: Comma-separated list of enabled auth providers
"github" - GitHub only (default)"vercel" - Vercel only"github,vercel" - Both providers enabledExamples:
Provider Configuration# GitHub authentication only (default)NEXT_PUBLIC_AUTH_PROVIDERS=github# Vercel authentication onlyNEXT_PUBLIC_AUTH_PROVIDERS=vercel# Both GitHub and Vercel authenticationNEXT_PUBLIC_AUTH_PROVIDERS=github,vercel
Option 1: Sign in with Vercel (if vercel is in NEXT_PUBLIC_AUTH_PROVIDERS)
NEXT_PUBLIC_VERCEL_CLIENT_ID: Your Vercel OAuth app client ID (exposed to client)VERCEL_CLIENT_SECRET: Your Vercel OAuth app client secretOption 2: Sign in with GitHub (if github is in NEXT_PUBLIC_AUTH_PROVIDERS)
NEXT_PUBLIC_GITHUB_CLIENT_ID: Your GitHub OAuth app client ID (exposed to client)GITHUB_CLIENT_SECRET: Your GitHub OAuth app client secretAPI Keys (Optional - Can be per-user)Note: Only the providers listed in
NEXT_PUBLIC_AUTH_PROVIDERSwill appear in the sign-in dialog. You must provide the OAuth credentials for each enabled provider.
These API keys can be set globally (fallback for all users) or left unset to require users to provide their own:
ANTHROPIC_API_KEY: Anthropic API key for Claude agent (users can override in their profile)AI_GATEWAY_API_KEY: AI Gateway API key for branch name generation and Codex (users can override)CURSOR_API_KEY: For Cursor agent support (users can override)GEMINI_API_KEY: For Google Gemini agent support (users can override)OPENAI_API_KEY: For Codex and OpenCode agents (users can override)GitHub Repository AccessNote: Users can provide their own API keys in their profile settings, which take precedence over global environment variables.
GITHUB_TOKEN: No longer needed! Users authenticate with their own GitHub accounts.
How Authentication Works:
NPM_TOKEN: For private npm packagesMAX_SANDBOX_DURATION: Default maximum sandbox duration in minutes (default: 300 = 5 hours)MAX_MESSAGES_PER_DAY: Maximum number of tasks + follow-ups per user per day (default: 5)Based on your NEXT_PUBLIC_AUTH_PROVIDERS configuration, you'll need to create OAuth apps:
http://localhost:3000 (or your production URL)http://localhost:3000/api/auth/github/callbackNEXT_PUBLIC_GITHUB_CLIENT_IDGITHUB_CLIENT_SECRETRequired Scopes: The app will request repo scope to access repositories.
http://localhost:3000/api/auth/callback/vercelNEXT_PUBLIC_VERCEL_CLIENT_IDVERCEL_CLIENT_SECRETProduction Deployment: Remember to add production callback URLs when deploying (e.g.,
https://yourdomain.com/api/auth/github/callback)
Generate and run database migrations:
pnpm db:generatepnpm db:push
pnpm dev
Open http://localhost:3000 in your browser.
# Generate migrationspnpm db:generate# Push schema changespnpm db:push# Open Drizzle Studiopnpm db:studio
# Developmentpnpm dev# Build for productionpnpm build# Start production serverpnpm start
.env files to version control. All sensitive data should be stored in environment variables.This release introduces user authentication and major security improvements, but contains breaking changes that require migration for existing deployments.
New FeaturesUser Authentication System
Multi-User Support
Security Enhancements
Database Enhancements
users table for user profiles and OAuth accountsaccounts table for linked accounts (e.g., Vercel users connecting GitHub)keys table for user-provided API keysThese changes require action if upgrading from v1.x:
Database Schema Changes
tasks table now requires userId (foreign key to users.id)connectors table now requires userId (foreign key to users.id)connectors.env changed from jsonb to encrypted texttasks.deletedAt for soft deletesAPI Changes
userId in request bodyEnvironment Variables
JWE_SECRET: Base64-encoded secret for session encryption (generate: openssl rand -base64 32)ENCRYPTION_KEY: 32-byte hex string for encrypting sensitive data (generate: openssl rand -hex 32)NEXT_PUBLIC_AUTH_PROVIDERS: Configure which auth providers to enable (github, vercel, or both)NEXT_PUBLIC_GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRETNEXT_PUBLIC_VERCEL_CLIENT_ID, VERCEL_CLIENT_SECRETGITHUB_TOKEN no longer used as fallback in API routesAuthentication Required
If you're upgrading from v1.x to v2.0.0, follow these steps:
Step 1: Backup Your DatabaseStep 2: Add Required Environment Variables# Create a backup of your existing databasepg_dump $POSTGRES_URL > backup-before-v2-migration.sql
Add these new variables to your .env.local or Vercel project settings:
Step 3: Set Up OAuth Applications# Session encryption (REQUIRED)JWE_SECRET=$(openssl rand -base64 32)ENCRYPTION_KEY=$(openssl rand -hex 32)# Configure auth providers (REQUIRED - choose at least one)NEXT_PUBLIC_AUTH_PROVIDERS=github # or "vercel" or "github,vercel"# GitHub OAuth (if using GitHub authentication)NEXT_PUBLIC_GITHUB_CLIENT_ID=your_github_client_idGITHUB_CLIENT_SECRET=your_github_client_secret# Vercel OAuth (if using Vercel authentication)NEXT_PUBLIC_VERCEL_CLIENT_ID=your_vercel_client_idVERCEL_CLIENT_SECRET=your_vercel_client_secret
Create OAuth applications for your chosen authentication provider(s). See the Local Development Setup section for detailed instructions.
Step 4: Prepare Database MigrationBefore running migrations, you need to handle existing data:
Option A: Fresh Start (Recommended for Development)
If you don't have production data to preserve:
# Drop existing tables and start freshpnpm db:push --force# This will create all new tables with proper structure
Option B: Preserve Existing Data (Production)
If you have existing tasks/connectors to preserve:
-- Connect to your database and run:INSERT INTO users (id, provider, external_id, access_token, username, email, created_at, updated_at, last_login_at)VALUES ('system-user-migration','github','system-migration','encrypted-placeholder-token', -- You'll need to encrypt a placeholder'System Migration User',NULL,NOW(),NOW(),NOW());
-- Add userId to existing tasksALTER TABLE tasks ADD COLUMN user_id TEXT;UPDATE tasks SET user_id = 'system-user-migration' WHERE user_id IS NULL;ALTER TABLE tasks ALTER COLUMN user_id SET NOT NULL;ALTER TABLE tasks ADD CONSTRAINT tasks_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;-- Add userId to existing connectorsALTER TABLE connectors ADD COLUMN user_id TEXT;UPDATE connectors SET user_id = 'system-user-migration' WHERE user_id IS NULL;ALTER TABLE connectors ALTER COLUMN user_id SET NOT NULL;ALTER TABLE connectors ADD CONSTRAINT connectors_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;-- Convert connector env from jsonb to encrypted text (requires app-level encryption)-- Note: You'll need to manually encrypt existing env values using your ENCRYPTION_KEY
Step 5: Update Your Codepnpm db:generatepnpm db:push
Pull the latest changes:
Step 6: Test Authenticationgit pull origin mainpnpm install
pnpm devhttp://localhost:3000Confirm that:
GITHUB_TOKEN fallback is being used in API routes