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-X9y8Z7
feature/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_URL
is 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_PROVIDERS
will 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/callback
NEXT_PUBLIC_GITHUB_CLIENT_ID
GITHUB_CLIENT_SECRET
Required Scopes: The app will request repo
scope to access repositories.
http://localhost:3000/api/auth/callback/vercel
NEXT_PUBLIC_VERCEL_CLIENT_ID
VERCEL_CLIENT_SECRET
Production 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 text
tasks.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_SECRET
NEXT_PUBLIC_VERCEL_CLIENT_ID
, VERCEL_CLIENT_SECRET
GITHUB_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 Code
pnpm db:generatepnpm db:push
Pull the latest changes:
Step 6: Test Authentication
git pull origin mainpnpm install
pnpm dev
http://localhost:3000
Confirm that:
GITHUB_TOKEN
fallback is being used in API routes