@kody/vercel
Call Vercel REST with a saved access token: teams, projects, deployments, domains, and env metadata.
AGENTS.md
178 lines · 5.9 KB · Markdown@kody/vercel — agent notes
Human setup and intent live in README.md. This file is for agents: import
paths, smoke / dryRun execute snippets, edge cases, and fork setup. Secrets by
name only — never paste token or client-secret values into chat.
Secrets / auth names
| Name | Role |
|---|---|
vercelToken | Default access-token secret (user scope, host api.vercel.com) |
vercelToken-<account> | Alternate token when caller passes account: "<account>" |
custom via secretName | Any saved token name; selects token lane and ignores integrationName |
integration vercel | OAuth lane via integrationName: "vercel" (REST permissions private beta) |
Hosts: api.vercel.com (REST, required), vercel.com (OAuth authorize/dashboard).
Token save URL:
https://kody.codes/account/secrets/new?name=vercelToken&description=Vercel%20access%20token%20(Bearer%20for%20api.vercel.com)&allowedHosts=api.vercel.com&scope=userOAuth connect (prefilled; paste client id in the form, flow=pkce):
https://kody.codes/connect/oauth?provider=vercel&authorizeUrl=https%3A%2F%2Fvercel.com%2Foauth%2Fauthorize&tokenUrl=https%3A%2F%2Fapi.vercel.com%2Flogin%2Foauth%2Ftoken&flow=pkce&pkce=true&scopes=openid%20email%20profile%20offline_access&allowedHosts=api.vercel.com%2Cvercel.com&apiBaseUrl=https%3A%2F%2Fapi.vercel.com&dashboardUrl=https%3A%2F%2Fvercel.com%2Fdocs%2Fsign-in-with-vercel&providerSetupInstructions=Create%20a%20Sign%20in%20with%20Vercel%20app%20and%20register%20redirect%20URI%20exactly%20https%3A%2F%2Fkody.codes%2Fconnect%2Foauth.%20REST%20API%20permissions%20for%20this%20OAuth%20lane%20are%20in%20private%20beta%20%E2%80%94%20prefer%20an%20access%20token%20for%20teams%2C%20projects%2C%20and%20deployments.%20Paste%20the%20client%20id%20into%20this%20form.Reconnect: https://kody.codes/connect/oauth?provider=vercel.
Import paths
| Export | Import |
|---|---|
| dispatcher (defaults to smoke-test) | kody:@kody/vercel |
| request (escape hatch) | kody:@kody/vercel/request |
| get-user | kody:@kody/vercel/get-user |
| list-teams | kody:@kody/vercel/list-teams |
| get-team | kody:@kody/vercel/get-team |
| list-projects | kody:@kody/vercel/list-projects |
| get-project | kody:@kody/vercel/get-project |
| list-deployments | kody:@kody/vercel/list-deployments |
| get-deployment | kody:@kody/vercel/get-deployment |
| create-deployment | kody:@kody/vercel/create-deployment |
| list-domains | kody:@kody/vercel/list-domains |
| add-domain | kody:@kody/vercel/add-domain |
| list-env-vars | kody:@kody/vercel/list-env-vars |
| create-env-var | kody:@kody/vercel/create-env-var |
| smoke-test | kody:@kody/vercel/smoke-test |
Prefer named helpers over request when available.
Smoke test
Dry-run (no live /v2/user call):
import smokeTest from 'kody:@kody/vercel/smoke-test'
export default async function main() {
return await smokeTest({ dryRun: true })
}Or via package root:
import vercel from 'kody:@kody/vercel'
export default async function main() {
return await vercel({ dryRun: true })
}Without vercelToken (and without a connected vercel integration), a live
call still returns { ok: true, live: false } plus setup URLs. With credentials
it reads a trimmed /v2/user profile — no writes.
dryRun / confirm snippets
import addDomain from 'kody:@kody/vercel/add-domain'
export default async function main() {
return await addDomain({
project: 'example-app',
name: 'www.example.com',
dryRun: true,
})
}import createDeployment from 'kody:@kody/vercel/create-deployment'
export default async function main() {
return await createDeployment({
name: 'example-app',
target: 'preview',
dryRun: true,
})
}import createEnvVar from 'kody:@kody/vercel/create-env-var'
export default async function main() {
return await createEnvVar({
project: 'example-app',
key: 'EXAMPLE_FLAG',
value: '1',
target: ['preview'],
dryRun: true,
})
}Live writes need confirm: true in addition to (or instead of) skipping dry-run.
Do not set deployment target: 'production' unless the caller explicitly asked.
Read examples
import listProjects from 'kody:@kody/vercel/list-projects'
export default async function main() {
return await listProjects({ teamSlug: 'acme', search: 'docs' })
}import listDeployments from 'kody:@kody/vercel/list-deployments'
export default async function main() {
return await listDeployments({ projectId: 'prj_…', limit: 10 })
}import listEnvVars from 'kody:@kody/vercel/list-env-vars'
export default async function main() {
return await listEnvVars({ project: 'example-app' })
}import request from 'kody:@kody/vercel/request'
export default async function main() {
return await request({ path: '/v2/user' })
}Edge cases
- Hard-coded retired account aliases (
kent,kentcdodds,epicweb,epic-web,kcd) throw — passsecretNameorintegrationNameinstead. secretNameselects the token lane and ignoresintegrationName.- Env-var dry-run previews redact
value;list-env-varsnever returns values. - Mutating
requestmethods requiredryRun: trueorconfirm: true. - Full-account tokens need
teamId/teamSlugwhen targeting team resources; team-/project-scoped tokens infer scope. - No personal project names or team slugs are hard-coded in this package.
Fork / setup for agents
- Fork this listing into the caller's account (
communityFork/ adopt flow as appropriate). - Save the caller's own
vercelToken(or connect OAuth) and approveapi.vercel.com. - Clear any
pending_secret_package_approvalsafter publish/fork. - Smoke-test with
kody:@kody/vercel/smoke-test(dryRun: truefirst, then live read-only) fromexecute. - Keep
community-icon.svg/icon.svgbranding assets intact unless deliberately updating official Vercel artwork.