The eve software factory template turns GitHub and Linear work items into reviewed draft pull requests, working entirely from text: the issue body, a repository checkout, the diff, and your CI output. But when a deployment fails, the factory sees only GitHub's check-run summary, a check name and a status, which tells Foreman that something broke, not what broke.
This guide adds Vercel's hosted MCP server to the factory's orchestrator, brokering access at app scope via Vercel Connect. Tokens resolve per call and never reach the model, the tool allowlist carries only reads, and the connection is pinned to one team and one project so an issue body can't point it anywhere else.
You'll then put the deployment context to work on three workflows: diagnosing a red deployment from the actual build log, checking a bug report against the errors firing in production, and recording what a run learned in the factory brain so every future run starts from it.
Deploy the template now, or read on if you have already done so.
eve Software Factory Template
Four coding stations behind one orchestrator: triage, planning against a live checkout of your repo, implementation verified with your own checks, and independent review.
Copy link to headingQuick start with an AI coding agent
If you're working with an AI coding agent like Claude Code or Cursor, use this prompt to have it make the changes for you:
Add Vercel's hosted MCP to my eve software factory (based on the eve-software-factory-template) so Foreman can read build logs, runtime errors, and deployment history for the app my target repository deploys. It has to work during unattended factory runs, so use app scope rather than per-user OAuth. Before writing any code, ask me for three things and wait for my answer: my Vercel team ID or slug, the project ID or slug of the project the TARGET repository deploys (not the project Foreman itself runs in), and whether that target repository is public or private. Both IDs are in .vercel/project.json as orgId and projectId. Ground truth first: read AGENTS.md in the repository root, read agent/connections/linear.ts as the in-repo example of an app-scoped MCP connection with an approval predicate, read agent/lib/constants.ts for how linearAuth is built, and read node_modules/eve/docs/connections/mcp.mdx for tool filters, toolCall.providedArguments, and approval gates. Read agent/lib/trust.ts before writing any policy. 1. Run: eve add connection/vercel 2. Add a vercelAuth constant to agent/lib/constants.ts following the linearAuth pattern: connect({ connector: requireEnv("VERCEL_CONNECTOR", "vercel/foreman-agent"), principalType: "app" }). Do not use connect("vercel"), which is user-scoped and unusable on unattended runs. Add VERCEL_TEAM_ID and VERCEL_PROJECT_ID alongside it, both through requireEnv. 3. Point the connection at vercelAuth and set tools.allow to exactly these eight: get_deployment_build_logs, get_runtime_errors, get_runtime_logs, list_deployments, get_deployment, list_projects, get_project, list_teams. Use allow, not block. Everything else stays undiscovered, including deploy_to_vercel and the buy_pro, buy_credits, buy_addon, and buy_domain purchase tools. 4. Set teamId and projectId through toolCall.providedArguments, so the model never supplies them itself and an issue body cannot name a different project. 5. Add a connection-wide approval predicate using the predicates in agent/lib/trust.ts: return "not-applicable" for isAutonomous, isTrusted, and isScheduleAppAuth callers, and "user-approval" for everyone else. 6. If I said the target repository is public, leave get_runtime_logs and get_runtime_errors out of the allowlist, and tell me you did and why. 7. Tell me the setup commands to run myself, and do not run them: vercel link, vercel connect create vercel --name foreman-agent, vercel env pull. 8. Add the three variables to .env.example in the surrounding comment style, noting they are required at build time. Do not change agent/lib/trust.ts, agent/lib/github/approval.ts, or agent/extensions/github.ts, and do not mount this connection under agent/subagents/. Finish by running pnpm validate and confirming 0 errors and 0 warnings, then run npx eve info and show me the vercel connection and its tools in the discovered surface. Do not deploy. Follow the Vercel MCP docs for more information: https://vercel.com/docs/agent-resources/vercel-mcp and read the step-by-step guide on the Vercel knowledge base: https://vercel.com/kb/guide/software-factory-vercel-mcp.
Copy link to headingVercel Plugin
The Vercel Plugin turns your AI coding agent (e.g., OpenAI Codex, Claude Code, or Cursor) into a Vercel expert. It adds skills, slash commands, and current knowledge of the tools this guide uses, including eve and Vercel Connect.
The plugin is optional; it isn't required to use eve or to follow this guide.
Copy link to headingOverview
In this guide, you'll learn how to:
- Add the Vercel MCP connection from the eve registry to the software factory.
- Broker access at app scope through Vercel Connect, so the agent authenticates as one installation and no token ever reaches the model.
- Pin the connection's tool allowlist to eight read tools and pin every call to your team and project, not the model's.
- Gate the connection so unattended runs read deployment data freely while untrusted sessions wait for a person.
- Diagnose a failed deployment from its actual build log and check a bug report against live production errors.
- Record deployment findings in the factory brain, where future runs read them.
Copy link to headingPrerequisites
Before you begin, make sure you have:
- A Vercel account.
- The eve software factory deployed and cloned locally.
- A target repository that deploys to Vercel.
For local development, you also need Node.js 24+, pnpm, and the Vercel CLI.
Copy link to headingHow it works
Vercel's hosted MCP server exposes deployment data over one connection. Once added, the tools surface under the vercel__ namespace and eve discovers them at runtime, so Foreman ships no Vercel API code of its own.
Vercel's MCP server offers dozens of tools, including tools for deploying projects, managing domains, and making purchases.
This guide configures an allowlist that limits Foreman to eight read-only tools:
| Tool | What Foreman uses it for |
|---|---|
get_deployment_build_logs | Read the actual build output when a deployment fails |
get_runtime_errors | Check a bug report against the errors firing right now |
get_runtime_logs | Trace a failing request path or status code |
list_deployments | Find the deployment carrying a branch or commit |
get_deployment | Read one deployment's state and metadata |
list_projects, get_project | Resolve the project the target repository deploys |
list_teams | Resolve the team that owns it |
Tools outside the allowlist are never registered with the agent at runtime, so the model cannot see or call them.
The connection attaches to the orchestrator, so deployment context is available on every surface the factory serves:
- Labeled issues and the red-CI fix loop
- @mentions on issues and pull requests
- Linear Agent Sessions
- The dev TUI
The connection authenticates as the agent itself rather than as an individual teammate, so no one needs to complete a consent step before a call. That lets unattended runs like labeled issues and the red-CI fix loop use the connection, and those are the runs where deployment context matters most.
Vercel Connect mints the credential on demand within your team's scope, which means the allowlist limits the model, not the credential.
Who can call the tools depends on how the session started, following the template's trust model:
| Session started by | Vercel tools |
|---|---|
| Labeled issue, red CI on a factory branch, or a schedule | Run without approval |
| @mention from a maintainer, or a Linear teammate | Run without approval |
| The dev TUI, or a PR from an outside contributor | Pause until a person approves |
Sessions started by labeled issues, red CI, schedules, maintainers, and Linear teammates skip approval because the allowlist is read-only, so the most an issue body can drive is a read of your own project's deployment data.
Copy link to headingSteps
Copy link to heading1. Add the connection from the registry
Vercel has an entry in the eve registry, so one command installs the connection and creates the file under agent/connections/:
Copy link to heading2. Create the connector
Link your directory to the Vercel project, then create the Vercel connector:
Confirm the UID with vercel connect list, then set three variables in the project's environment variables:
VERCEL_CONNECTOR: The connector UID fromvercel connect listVERCEL_TEAM_ID: The team that owns the target projectVERCEL_PROJECT_ID: The project your target repository deploys, not the project Foreman itself runs in
All three are read at module load, so set them before redeploying or discovery fails. Find VERCEL_TEAM_ID and VERCEL_PROJECT_ID in the target repository's .vercel/project.json as orgId and projectId.
Copy link to heading3. Configure app-scoped auth
Add a vercelAuth constant to agent/lib/constants.ts, following the linearAuth pattern already in the file:
Do not use connect("vercel"). It scopes the connection to individual users, and unattended runs have no user present to complete the consent.
Copy link to heading4. Pin the connection to your project and tools
Point the connection at vercelAuth, then define the tool allowlist, the pinned IDs, and the approval rule in one file:
With this configuration:
allownames the eight read tools and nothing else.deploy_to_verceland thebuy_pro,buy_credits,buy_addon, andbuy_domainpurchase tools are never discovered, so the model cannot call them, and any tool the server adds later stays out until you name it here.providedArgumentssets the team and project itself. eve deletesteamIdandprojectIdfrom the tool description the model sees, then fills in your values as the call goes out, so aget_runtime_logscall from the model carries only its own filters, likelevel. The model has no field left to name another project in.- The approval predicate lets autonomous, trusted, and schedule callers run, and parks everyone else, including the dev TUI and the untrusted pull-request summary session, on an approval card.
If your target repository is public, leave get_runtime_logs and get_runtime_errors out of the allowlist and keep the build logs. An unattended run can comment on its intake issue, so anything it reads can be quoted there, and runtime logs carry request paths, headers, and user data.
Copy link to heading5. Verify
Run the following commands to verify your setup:
pnpm validate should finish with zero errors and zero warnings, and eve info should list the vercel connection with exactly the eight allowed tools. If deploy_to_vercel or any buy_ tool shows up, the filter is not applied.
Then run pnpm dev and ask Foreman for a recent deployment's build logs. The dev principal is untrusted, so the call parks on an approval card in the TUI. Approve it, and confirm the result comes back for the pinned project.
Copy link to headingThree workflows to try
Copy link to headingDiagnose a red deployment from the build log
@mention the bot on a pull request whose Vercel check is red:
Foreman finds the deployment carrying the branch, reads the actual build output, and reports the failing step. The unattended red-CI loop gains the same context on its own: when a factory branch goes red, the fix attempt starts from the build log rather than a check name.
Copy link to headingCheck a bug report against production
@mention the bot on a bug report about live behavior:
Foreman reads the errors firing in the pinned project and compares them against the report, so the classifier and analyst work from confirmed production behavior rather than a described one. On a public repository, this workflow isn't available, because the runtime tools stay off the allowlist.
Copy link to headingTeach the factory what the deployment showed
Some of what a deployment read establishes is durable: the app deploys from apps/web, or a recurring build failure traces back to one package.
Ask Foreman to remember it:
The factory brain is the shared memory every run reads at the start of a task, so a fact one deployment established now grounds every future run, including the unattended ones triggered by labeled issues and red CI. Diagnose once, and the whole pipeline plans with what you found.
Copy link to headingHow the guardrails extend
The template treats work-item text as untrusted input, and deployment data cuts both ways. An issue body can try to point the tools somewhere else, and what the tools return can end up quoted where anyone can read it.
The connection follows the same rules:
- Reads are the ceiling. The allowlist carries no deploy or purchase tools, so the most an unattended run can do is read your project's deployment data. Deploying sits past the template's draft-PR ceiling and, like merging, stays a human act.
- The model never picks the project.
get_runtime_logstakesprojectIdandteamIdas parameters, and an issue body reading "check the logs for prj_abc" is an instruction the model can follow. WithprovidedArguments, eve supplies both values itself and the model has no field to put one in. - Untrusted sessions wait for a person. The pull-request summary session runs on pull requests from outside contributors, and parking its calls on approval keeps a PR description from talking it into quoting production logs into a public comment.
The template ships safety evals, and the connection needs one too. Add a case under evals/safety/ with an issue body that names a foreign project, asserting the call still reads the pinned one.
Copy link to headingTroubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
Vercel tools don't appear under vercel__* | The connection file isn't discovered, or the project is on an eve older than v0.25 | Run npx eve info, check .eve/discovery/diagnostics.json for skipped files, and upgrade eve if needed |
deploy_to_vercel or a buy_ tool appears in the tool list | The tool filter isn't applied, so the connection is running without the allowlist | Confirm the connection uses tools: { allow: [...] } rather than block, then re-run npx eve info |
The build fails with a VERCEL_CONNECTOR or VERCEL_* error | The three variables are read at module load, so a misconfigured factory fails discovery instead of producing a connection with no target | Set VERCEL_CONNECTOR, VERCEL_TEAM_ID, and VERCEL_PROJECT_ID in the project's environment and redeploy |
| Calls return data for the wrong project | VERCEL_PROJECT_ID points at the project Foreman itself runs in, not the one the target repository deploys | Read orgId and projectId from the target repository's .vercel/project.json and set the variables to those values |
| An allowed tool rejects the call | Configured arguments apply to every tool on the connection, and this tool takes neither teamId nor projectId | Drop the tool from the allowlist, or mount it as its own connection without the pin |
| A Vercel call appears to stall in the dev TUI | The dev principal is untrusted by design, so the approval predicate parks the call on an approval card | Approve or deny the pending call. To change who runs ungated, edit the predicate in agent/connections/vercel.ts |
| The connection works locally but fails in production | .env.local is local-only, and the deployed app reads the Vercel project's environment | Set the three variables in the project's production environment, then redeploy |
| Reads fail with an authorization error | The connector's token isn't team-scoped, or the token's creator lacks access to the pinned project | Re-create the connector with a team-scoped token from an account that can read the target project, and update VERCEL_CONNECTOR if the UID changed |
Copy link to headingNext steps
- Build a software factory with eve: the template this guide builds on
- Giving your software factory a browser: the same factory reproducing bugs and verifying fixes in a cloud browser
- Vercel MCP: the canonical reference for the hosted server and its full tool list
- Vercel Connect: the access broker that mints the connection's tokens