365 lines
11 KiB
Markdown
365 lines
11 KiB
Markdown
---
|
|
name: vercel-cli-with-tokens
|
|
description: "Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. \"deploy to vercel\", \"set up vercel\", \"add environment variables to vercel\"."
|
|
risk: safe
|
|
source: "https://github.com/vercel-labs/agent-skills"
|
|
date_added: "2026-06-02"
|
|
---
|
|
|
|
# Vercel CLI with Tokens
|
|
|
|
Deploy and manage projects on Vercel using the CLI with token-based authentication, without relying on `vercel login`.
|
|
|
|
## When to Use
|
|
- Use this skill when the task matches this description: Deploy and manage projects on Vercel using token-based authentication. Use when working with Vercel CLI using access tokens rather than interactive login — e.g. "deploy to vercel", "set up vercel", "add environment variables to vercel".
|
|
|
|
## Step 1: Locate the Vercel Token
|
|
|
|
Before running any Vercel CLI commands, identify where the token is coming from. Work through these scenarios in order:
|
|
|
|
### A) `VERCEL_TOKEN` is already set in the environment
|
|
|
|
```bash
|
|
[ -n "${VERCEL_TOKEN:-}" ] && printf 'VERCEL_TOKEN is set\n'
|
|
```
|
|
|
|
If this reports a configured token, you're ready. Skip to Step 2.
|
|
|
|
### B) Token is in a `.env` file under `VERCEL_TOKEN`
|
|
|
|
```bash
|
|
grep -q '^VERCEL_TOKEN=' .env 2>/dev/null && printf 'VERCEL_TOKEN is present in .env\n'
|
|
```
|
|
|
|
If found, export it:
|
|
|
|
```bash
|
|
VERCEL_TOKEN="$(sed -n 's/^VERCEL_TOKEN=//p' .env | tail -n 1)"
|
|
export VERCEL_TOKEN
|
|
```
|
|
|
|
### C) Token is in a `.env` file under a different name
|
|
|
|
Look for any variable that looks like a Vercel token (Vercel tokens typically start with `vca_`):
|
|
|
|
```bash
|
|
grep -Eio '^[A-Z0-9_]*VERCEL[A-Z0-9_]*(?==)' .env 2>/dev/null
|
|
```
|
|
|
|
Inspect the output to identify which variable holds the token, then export it as `VERCEL_TOKEN`:
|
|
|
|
```bash
|
|
vercel_var="<VARIABLE_NAME>"
|
|
VERCEL_TOKEN="$(sed -n "s/^${vercel_var}=//p" .env | tail -n 1)"
|
|
export VERCEL_TOKEN
|
|
```
|
|
|
|
### D) No token found — ask the user
|
|
|
|
If none of the above yield a token, ask the user to provide one. They can create a Vercel access token at vercel.com/account/tokens.
|
|
|
|
---
|
|
|
|
**Important:** Once `VERCEL_TOKEN` is exported as an environment variable, the Vercel CLI reads it natively — **do not pass it as a `--token` flag**. Putting secrets in command-line arguments exposes them in shell history and process listings.
|
|
|
|
```bash
|
|
# Bad — token visible in shell history and process listings
|
|
vercel deploy --token "vca_abc123"
|
|
|
|
# Good — CLI reads VERCEL_TOKEN from the environment
|
|
[ -n "${VERCEL_TOKEN:-}" ] || { echo "Set VERCEL_TOKEN first" >&2; exit 1; }
|
|
vercel deploy
|
|
```
|
|
|
|
## Step 2: Locate the Project and Team
|
|
|
|
Similarly, check for the project ID and team scope. These let the CLI target the right project without needing `vercel link`.
|
|
|
|
```bash
|
|
# Check environment
|
|
[ -n "${VERCEL_PROJECT_ID:-}" ] && printf 'VERCEL_PROJECT_ID is set\n'
|
|
[ -n "${VERCEL_ORG_ID:-}" ] && printf 'VERCEL_ORG_ID is set\n'
|
|
|
|
# Or check .env
|
|
grep -Eio '^[A-Z0-9_]*VERCEL[A-Z0-9_]*(?==)' .env 2>/dev/null
|
|
```
|
|
|
|
**If you have a project URL** (e.g. `https://vercel.com/my-team/my-project`), extract the team slug:
|
|
|
|
```bash
|
|
# e.g. "my-team" from "https://vercel.com/my-team/my-project"
|
|
echo "$PROJECT_URL" | sed 's|https://vercel.com/||' | cut -d/ -f1
|
|
```
|
|
|
|
**If you have both `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` in your environment**, export them — the CLI will use these automatically and skip any `.vercel/` directory:
|
|
|
|
```bash
|
|
export VERCEL_ORG_ID="<org-id>"
|
|
export VERCEL_PROJECT_ID="<project-id>"
|
|
```
|
|
|
|
Note: `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` must be set together — setting only one causes an error.
|
|
|
|
## CLI Setup
|
|
|
|
Ensure the Vercel CLI is installed and up to date:
|
|
|
|
```bash
|
|
npm install -g vercel
|
|
vercel --version
|
|
```
|
|
|
|
## Deploying a Project
|
|
|
|
Always deploy as **preview** unless the user explicitly requests production. Choose a method based on what you have available.
|
|
|
|
### Quick Deploy (have project ID — no linking needed)
|
|
|
|
When `VERCEL_TOKEN` and `VERCEL_PROJECT_ID` are set in the environment, deploy directly:
|
|
|
|
```bash
|
|
vercel deploy -y --no-wait
|
|
```
|
|
|
|
With a team scope (either via `VERCEL_ORG_ID` or `--scope`):
|
|
|
|
```bash
|
|
vercel deploy --scope <team-slug> -y --no-wait
|
|
```
|
|
|
|
Production (only when explicitly requested):
|
|
|
|
```bash
|
|
vercel deploy --prod --scope <team-slug> -y --no-wait
|
|
```
|
|
|
|
Check status:
|
|
|
|
```bash
|
|
vercel inspect <deployment-url>
|
|
```
|
|
|
|
### Full Deploy Flow (no project ID — need to link)
|
|
|
|
Use this when you have a token and team but no pre-existing project ID.
|
|
|
|
#### Check project state first
|
|
|
|
```bash
|
|
# Does the project have a git remote?
|
|
git remote get-url origin 2>/dev/null
|
|
|
|
# Is it already linked to a Vercel project?
|
|
cat .vercel/project.json 2>/dev/null || cat .vercel/repo.json 2>/dev/null
|
|
```
|
|
|
|
#### Link the project
|
|
|
|
**With git remote (preferred):**
|
|
|
|
```bash
|
|
vercel link --repo --scope <team-slug> -y
|
|
```
|
|
|
|
Reads the git remote and connects to the matching Vercel project. Creates `.vercel/repo.json`. More reliable than plain `vercel link`, which matches by directory name.
|
|
|
|
**Without git remote:**
|
|
|
|
```bash
|
|
vercel link --scope <team-slug> -y
|
|
```
|
|
|
|
Creates `.vercel/project.json`.
|
|
|
|
**Link to a specific project by name:**
|
|
|
|
```bash
|
|
vercel link --project <project-name> --scope <team-slug> -y
|
|
```
|
|
|
|
If the project is already linked, check `orgId` in `.vercel/project.json` or `.vercel/repo.json` to verify it matches the intended team.
|
|
|
|
#### Deploy after linking
|
|
|
|
**A) Git Push Deploy — has git remote (preferred)**
|
|
|
|
Git pushes trigger automatic Vercel deployments.
|
|
|
|
1. **Ask the user before pushing.** Never push without explicit approval.
|
|
2. Commit and push:
|
|
```bash
|
|
git add .
|
|
git commit -m "deploy: <description of changes>"
|
|
git push
|
|
```
|
|
3. Vercel builds automatically. Non-production branches get preview deployments.
|
|
4. Retrieve the deployment URL:
|
|
```bash
|
|
sleep 5
|
|
vercel ls --format json --scope <team-slug>
|
|
```
|
|
Find the latest entry in the `deployments` array.
|
|
|
|
**B) CLI Deploy — no git remote**
|
|
|
|
```bash
|
|
vercel deploy --scope <team-slug> -y --no-wait
|
|
```
|
|
|
|
Check status:
|
|
|
|
```bash
|
|
vercel inspect <deployment-url>
|
|
```
|
|
|
|
### Deploying from a Remote Repository (code not cloned locally)
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone <repo-url>
|
|
cd <repo-name>
|
|
```
|
|
2. Link to Vercel:
|
|
```bash
|
|
vercel link --repo --scope <team-slug> -y
|
|
```
|
|
3. Deploy via git push (if you have push access) or CLI deploy.
|
|
|
|
### About `.vercel/` Directory
|
|
|
|
A linked project has either:
|
|
- `.vercel/project.json` — from `vercel link`. Contains `projectId` and `orgId`.
|
|
- `.vercel/repo.json` — from `vercel link --repo`. Contains `orgId`, `remoteName`, and a `projects` map.
|
|
|
|
Not needed when `VERCEL_ORG_ID` + `VERCEL_PROJECT_ID` are both set in the environment.
|
|
|
|
**Do NOT** run `vercel project inspect` or `vercel link` in an unlinked directory to detect state — they will interactively prompt or silently link as a side-effect. `vercel ls` is safe (in an unlinked directory it defaults to showing all deployments for the scope). `vercel whoami` is safe anywhere.
|
|
|
|
## Managing Environment Variables
|
|
|
|
```bash
|
|
# Set for all environments
|
|
echo "value" | vercel env add VAR_NAME --scope <team-slug>
|
|
|
|
# Set for a specific environment (production, preview, development)
|
|
echo "value" | vercel env add VAR_NAME production --scope <team-slug>
|
|
|
|
# List environment variables
|
|
vercel env ls --scope <team-slug>
|
|
|
|
# Pull env vars to local .env.local file
|
|
vercel env pull --scope <team-slug>
|
|
|
|
# Remove a variable
|
|
vercel env rm VAR_NAME --scope <team-slug> -y
|
|
```
|
|
|
|
## Inspecting Deployments
|
|
|
|
```bash
|
|
# List recent deployments
|
|
vercel ls --format json --scope <team-slug>
|
|
|
|
# Inspect a specific deployment
|
|
vercel inspect <deployment-url>
|
|
|
|
# View build logs (requires Vercel CLI v35+)
|
|
vercel inspect <deployment-url> --logs
|
|
|
|
# View runtime request logs (follows live by default; add --no-follow for a one-shot snapshot)
|
|
vercel logs <deployment-url>
|
|
```
|
|
|
|
## Managing Domains
|
|
|
|
```bash
|
|
# List domains
|
|
vercel domains ls --scope <team-slug>
|
|
|
|
# Add a domain to the project — linked or env-linked directory (1 arg)
|
|
vercel domains add <domain> --scope <team-slug>
|
|
|
|
# Add a domain — unlinked directory (requires <project> positional)
|
|
vercel domains add <domain> <project> --scope <team-slug>
|
|
```
|
|
|
|
## Stripe Projects Plan Changes
|
|
|
|
If this project is managed by Stripe Projects. **Ask the user before running any paid or destructive plan change** — upgrades bill a real card, downgrades remove seats.
|
|
|
|
First run `stripe projects status --json` to confirm the Vercel resource's local name. The examples below assume the default (`vercel-plan`); substitute the actual name if it was renamed at `stripe projects add` time.
|
|
|
|
- **Upgrade to Pro:** `stripe projects add vercel/pro` (or `stripe projects upgrade vercel-plan pro`)
|
|
- **Downgrade to Hobby:** `stripe projects downgrade vercel-plan hobby`
|
|
|
|
### What Pro gives you
|
|
|
|
- $20/month platform fee, includes $20/month of usage credit.
|
|
- Turbo build machines (30 vCPUs, 60 GB memory) by default for new projects — significantly faster builds than Hobby.
|
|
- 1 deploying seat + unlimited free Viewer seats (read-only collaborators, preview comments).
|
|
- Higher included allocations (1 TB Fast Data Transfer, 10M Edge Requests per month).
|
|
- Paid add-ons available: SAML SSO, HIPAA BAA, Flags Explorer, Observability Plus, Speed Insights, Web Analytics Plus.
|
|
|
|
Full details: https://vercel.com/docs/plans/pro-plan
|
|
|
|
## Working Agreement
|
|
|
|
- **Never pass `VERCEL_TOKEN` as a `--token` flag.** Export it as an environment variable and let the CLI read it natively.
|
|
- **Check the environment for tokens before asking the user.** Look in the current env and `.env` files first.
|
|
- **Default to preview deployments.** Only deploy to production when explicitly asked.
|
|
- **Ask before pushing to git.** Never push commits without the user's approval.
|
|
- **Do not modify `.vercel/` files directly.** The CLI manages this directory. Reading them (e.g. to verify `orgId`) is fine.
|
|
- **Do not curl/fetch deployed URLs to verify.** Just return the link to the user.
|
|
- **Use `--format json`** when structured output will help with follow-up steps.
|
|
- **Use `-y`** on commands that prompt for confirmation to avoid interactive blocking.
|
|
|
|
## Troubleshooting
|
|
|
|
### Token not found
|
|
|
|
Check the environment and any `.env` files present:
|
|
|
|
```bash
|
|
env | grep -Eio '^[A-Z0-9_]*VERCEL[A-Z0-9_]*(?==)'
|
|
grep -Eio '^[A-Z0-9_]*VERCEL[A-Z0-9_]*(?==)' .env 2>/dev/null
|
|
```
|
|
|
|
### Authentication error
|
|
|
|
If the CLI fails with `Authentication required`:
|
|
- The token may be expired or invalid.
|
|
- Verify: `vercel whoami` (uses `VERCEL_TOKEN` from environment).
|
|
- Ask the user for a fresh token.
|
|
|
|
### Wrong team
|
|
|
|
Verify the scope is correct:
|
|
|
|
```bash
|
|
vercel whoami --scope <team-slug>
|
|
```
|
|
|
|
### Build failure
|
|
|
|
Check the build logs:
|
|
|
|
```bash
|
|
vercel inspect <deployment-url> --logs
|
|
```
|
|
|
|
Common causes:
|
|
- Missing dependencies — ensure `package.json` is complete and committed.
|
|
- Missing environment variables — add with `vercel env add`.
|
|
- Framework misconfiguration — check `vercel.json`. Vercel auto-detects frameworks (Next.js, Remix, Vite, etc.) from `package.json`; override with `vercel.json` if detection is wrong.
|
|
|
|
### CLI not installed
|
|
|
|
```bash
|
|
npm install -g vercel
|
|
```
|
|
|
|
## Limitations
|
|
- Use this skill only when the task clearly matches the scope described above.
|
|
- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.
|
|
- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.
|