Skip to content
Docs

Manage Vercel projects with a software factory

Add Vercel's hosted MCP to the eve software factory template so Foreman can read build logs, runtime errors, and deployment history for the app your target repository deploys, brokered at app scope through Vercel Connect.

Ben SabicContent Engineer

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.

Deploy now

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:

Agent Prompt

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.

Terminal
npx plugins add vercel/vercel-plugin

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:

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:

ToolWhat Foreman uses it for
get_deployment_build_logsRead the actual build output when a deployment fails
get_runtime_errorsCheck a bug report against the errors firing right now
get_runtime_logsTrace a failing request path or status code
list_deploymentsFind the deployment carrying a branch or commit
get_deploymentRead one deployment's state and metadata
list_projects, get_projectResolve the project the target repository deploys
list_teamsResolve 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 byVercel tools
Labeled issue, red CI on a factory branch, or a scheduleRun without approval
@mention from a maintainer, or a Linear teammateRun without approval
The dev TUI, or a PR from an outside contributorPause 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/:

Terminal
eve add connection/vercel

Copy link to heading2. Create the connector

Link your directory to the Vercel project, then create the Vercel connector:

Terminal
vercel link
vercel connect create vercel --name foreman-agent
vercel env pull

Confirm the UID with vercel connect list, then set three variables in the project's environment variables:

  • VERCEL_CONNECTOR: The connector UID from vercel connect list
  • VERCEL_TEAM_ID: The team that owns the target project
  • VERCEL_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:

agent/lib/constants.ts
export const vercelAuth = connect({
connector: requireEnv("VERCEL_CONNECTOR", "vercel/foreman-agent"),
principalType: "app",
});
export const VERCEL_TEAM_ID = requireEnv("VERCEL_TEAM_ID");
export const VERCEL_PROJECT_ID = requireEnv("VERCEL_PROJECT_ID");

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:

agent/connections/vercel.ts
import { defineMcpClientConnection } from "eve/connections";
import {
VERCEL_PROJECT_ID,
VERCEL_TEAM_ID,
vercelAuth,
} from "../lib/constants.js";
import { isAutonomous, isScheduleAppAuth, isTrusted } from "../lib/trust.js";
export default defineMcpClientConnection({
url: "https://mcp.vercel.com",
description:
"Vercel: build logs, runtime errors, and deployment history for the target repository's app.",
auth: vercelAuth,
approval: (ctx) =>
isAutonomous(ctx.session.auth.current) ||
isTrusted(ctx.session.auth.current) ||
isScheduleAppAuth(ctx.session.auth.current)
? "not-applicable"
: "user-approval",
toolCall: {
providedArguments: {
projectId: VERCEL_PROJECT_ID,
teamId: VERCEL_TEAM_ID,
},
},
tools: {
allow: [
"get_deployment_build_logs",
"get_runtime_errors",
"get_runtime_logs",
"list_deployments",
"get_deployment",
"list_projects",
"get_project",
"list_teams",
],
},
});

With this configuration:

  • allow names the eight read tools and nothing else. deploy_to_vercel and the buy_pro, buy_credits, buy_addon, and buy_domain purchase tools are never discovered, so the model cannot call them, and any tool the server adds later stays out until you name it here.
  • providedArguments sets the team and project itself. eve deletes teamId and projectId from the tool description the model sees, then fills in your values as the call goes out, so a get_runtime_logs call from the model carries only its own filters, like level. 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:

Terminal
pnpm validate
eve info

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 the Vercel check on this PR is red, read the deployment's build log and tell me what broke

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 check whether the 500 in this issue is firing in production right now, and since when

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:

@foreman record in the factory brain that the target app deploys from apps/web, so failures in packages/ui surface in that project's build log

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_logs takes projectId and teamId as parameters, and an issue body reading "check the logs for prj_abc" is an instruction the model can follow. With providedArguments, 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

SymptomLikely causeFix
Vercel tools don't appear under vercel__*The connection file isn't discovered, or the project is on an eve older than v0.25Run 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 listThe tool filter isn't applied, so the connection is running without the allowlistConfirm the connection uses tools: { allow: [...] } rather than block, then re-run npx eve info
The build fails with a VERCEL_CONNECTOR or VERCEL_* errorThe three variables are read at module load, so a misconfigured factory fails discovery instead of producing a connection with no targetSet VERCEL_CONNECTOR, VERCEL_TEAM_ID, and VERCEL_PROJECT_ID in the project's environment and redeploy
Calls return data for the wrong projectVERCEL_PROJECT_ID points at the project Foreman itself runs in, not the one the target repository deploysRead orgId and projectId from the target repository's .vercel/project.json and set the variables to those values
An allowed tool rejects the callConfigured arguments apply to every tool on the connection, and this tool takes neither teamId nor projectIdDrop the tool from the allowlist, or mount it as its own connection without the pin
A Vercel call appears to stall in the dev TUIThe dev principal is untrusted by design, so the approval predicate parks the call on an approval cardApprove 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 environmentSet the three variables in the project's production environment, then redeploy
Reads fail with an authorization errorThe connector's token isn't team-scoped, or the token's creator lacks access to the pinned projectRe-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

Related documentation

More eve guides