---
title: Private enterprise agents on Vercel
description: Design private enterprise agents that call internal APIs and databases with Vercel Functions, Secure Compute, AI Gateway, Workflows, and Vercel Connect.
url: "https://vercel.com/kb/guide/private-enterprise-agents-vercel"
published: 2026-09-30
last_updated: 2026-09-30
authors: Vercel
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

On Vercel, a private enterprise agent is a custom agent application where the AI SDK, WorkflowAgent, or eve drives the model, and trusted tool code in Vercel Functions reaches internal APIs and databases through Secure Compute, AWS PrivateLink, or Static IPs. The model never connects to your private systems. It requests a tool call, and your application code decides whether and how to run it.

Teams that need tool calling against internal APIs often assume the whole agent runtime has to live inside their VPC, assembled from LangGraph, an MCP gateway, Temporal, and Kubernetes. On Vercel, the agent loop, durable state, tool execution, and private network path deploy as one project, and only tool traffic enters your network.

## Overview

In this guide, you'll learn how to:

- Map each layer of a private agent to AI Gateway, the AI SDK, Workflows, Vercel Functions, and Vercel Connect
  
- Choose between Secure Compute, AWS PrivateLink, Static IPs, and Vercel Connect for each tool's access path
  
- Keep credentials in trusted tools and out of Vercel Sandbox, prompts, and tool results
  
- Write internal API and private database tools that scope access to the signed-in user
  
- Decide when a LangGraph, Temporal, or self-managed stack is still the better fit
  

## Prerequisites

- Your Vercel team on the Enterprise plan for Secure Compute, or on the Pro or Enterprise plan for AWS PrivateLink or Static IPs
  
- Your internal API or database in an AWS VPC you can peer with, behind an AWS PrivateLink endpoint service, or in Azure, Google Cloud, or an on-premises network that can terminate a site-to-site VPN
  
- Your Next.js app or eve agent deployed to Vercel, using the `ai` package (AI SDK 7) and `zod`
  

## How private tool calls work on Vercel

Model tool calling is a request for your application to run a function. The model picks a tool and supplies arguments, then your application validates them, executes the function, and returns the result. The model never holds credentials or opens a network connection to your internal systems.

Each private tool call on Vercel follows this path:

1. The user signs in and sends a message to your agent's route, which runs as a Vercel Function.
   
2. The agent loop sends the conversation and tool definitions to a model through AI Gateway.
   
3. The model responds with a tool call, such as `lookupOrder` with `{ "orderNumber": "ORD-104233" }`.
   
4. Your tool code validates the arguments and checks what the signed-in user is allowed to see.
   
5. The tool calls the internal API or database. With Secure Compute or AWS PrivateLink, the request travels over a private network path. With Static IPs, it leaves over the public internet from a known IP pair.
   
6. The tool returns only the fields the model needs, and the model writes its answer.
   
7. On WorkflowAgent, a tool whose `execute` function is marked `'use step'` runs as a checkpointed Workflows step that retries on failure and survives restarts. The agent can also suspend a tool call until a person approves it.
   

The rest of the architecture follows from two decisions, where each tool runs and how its traffic reaches the target system.

## Map the private agent architecture to Vercel products

Private agents have seven layers, and each one maps to a Vercel product that deploys in the same project.

| Layer                           | What it needs                                                | On Vercel                                                                                                                                                                                                                                     |
| ------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Model access                    | One endpoint for many models, with usage and cost visibility | [AI Gateway](https://vercel.com/docs/ai-gateway)                                                                                                                                                                                              |
| Agent loop and tool definitions | Typed tool schemas and a bounded loop                        | [AI SDK](https://vercel.com/docs/ai-sdk), [WorkflowAgent](https://vercel.com/kb/guide/what-is-workflowagent) from `@ai-sdk/workflow`, or [eve](https://vercel.com/docs/eve) (beta)                                                            |
| Durable orchestration           | Retries, waits, and resume without holding a container open  | [Workflows](https://vercel.com/docs/workflows)                                                                                                                                                                                                |
| Tool execution                  | Trusted compute that holds credentials                       | [Vercel Functions](https://vercel.com/docs/functions) on the Node.js, Python, Go, or Ruby runtime                                                                                                                                             |
| Private network path            | Outbound access to internal APIs and databases               | [Secure Compute](https://vercel.com/docs/networking/secure-compute) on Enterprise, or [AWS PrivateLink](https://vercel.com/docs/networking/privatelink) and [Static IPs](https://vercel.com/docs/networking/static-ips) on Pro and Enterprise |
| Third-party business systems    | Short-lived, scoped credentials for SaaS APIs                | [Vercel Connect](https://vercel.com/docs/connect)                                                                                                                                                                                             |
| Untrusted code execution        | Isolation for model-generated code                           | [Vercel Sandbox](https://vercel.com/docs/sandbox)                                                                                                                                                                                             |

AI Gateway resolves model strings such as `anthropic/claude-sonnet-5.5` for the AI SDK, WorkflowAgent, and eve. Your tool code, workflow steps, and agent routes all run as Vercel Functions, so the project's networking settings cover every private call the agent makes.

### Choose between the AI SDK, WorkflowAgent, and eve

All three options run tool code in Vercel Functions, so the networking and security guidance in this guide applies to each one. They differ in how long an agent run can last and what happens when an invocation ends.

| Option                                   | Use it when                                                                                              | State between tool calls                                                            |
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| AI SDK `generateText` or `ToolLoopAgent` | The agent answers within a single request, such as a support lookup                                      | In memory for one invocation                                                        |
| WorkflowAgent from `@ai-sdk/workflow`    | Tool calls must retry from a checkpoint, wait for approval, or span hours or days                        | Tools marked `'use step'` run as durable Workflows steps; other tools run in memory |
| eve (beta)                               | You want instructions, tools, channels, connections, and a sandbox in one filesystem-first agent project | Workflows persist session state                                                     |

## Choose a private connectivity path for each tool

Choose the path per tool, based on where the target system lives and what your security policy requires. Secure Compute, AWS PrivateLink, and Static IPs control how Vercel Functions reach infrastructure you run, and Vercel Connect controls how tools authenticate to third-party APIs. One agent often uses more than one. Enterprise teams whose policy requires compute to run inside their own AWS account can also scope [Bring Your Own Cloud](https://vercel.com/docs/networking#bring-your-own-cloud), which runs your functions in that account.

| Path            | Reaches                                                                                                                                                                            | Isolation                                                           | Plans                                        | Pricing                                                                                                                                                  |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Secure Compute  | Internal APIs and databases over AWS VPC peering, or over a site-to-site VPN to Azure, Google Cloud, or on-premises networks                                                       | Dedicated VPC and subnet per customer, with a dedicated IP pair     | Enterprise                                   | Custom; Private Data Transfer is $0.15/GB for traffic that leaves over the public internet, and VPC peering traffic has no data transfer charge          |
| AWS PrivateLink | AWS-hosted services that publish a PrivateLink endpoint service, including internal APIs behind a Network Load Balancer, RDS, Aurora, Neon, Redshift, Snowflake, and MongoDB Atlas | Dedicated VPC endpoint and IAM role per team, in a shared VPC       | Pro and Enterprise, with Advanced Networking | First connection included with Advanced Networking; $30/month per additional connection; data transfer is $0.04/GB                                       |
| Static IPs      | Services that accept traffic from an IP allowlist                                                                                                                                  | Shared VPC with subnet-level isolation                              | Pro and Enterprise                           | $100/month per project, plus Private Data Transfer at regional rates                                                                                     |
| Vercel Connect  | Third-party APIs such as Slack, GitHub, Microsoft, Snowflake, and Salesforce, plus OAuth-protected MCP servers                                                                     | Short-lived tokens scoped by project link, environment, and request | Hobby, Pro, and Enterprise                   | Hobby includes 500 token requests and 1,000 triggers per month; Pro is $3.00 per 1,000 token requests and $0.95 per 1,000 triggers; Enterprise is custom |

### Use Secure Compute for dedicated networking and VPC peering

Secure Compute creates a dedicated private network for your Vercel Functions, with a NAT Gateway and a pair of static IPs that don't change. You attach a project to the network per environment in the project's **Settings** → **Networking** page, and every function in that environment routes through it without networking code in your tools. With VPC peering, your database or internal API can keep no public address at all.

Secure Compute applies to Vercel Functions on the Node.js, Python, Go, and Ruby runtimes. The Edge runtime isn't supported, so Routing Middleware and functions that use the `edge` runtime don't send traffic through the network. Projects on Secure Compute don't support the extended max duration, Large Functions, or Container Images betas. The standard 800-second maximum duration and 250 MB bundle limit (500 MB for Python) apply on Pro and Enterprise instead. Each network supports up to 100 projects and 50 VPC peering connections.

Self-service network creation isn't available to every Enterprise team. If you don't see **Create Network** under your team's **Settings** → **Networking**, contact your Vercel account team. For the full peering walkthrough, including route tables and security groups, see [Give your eve agent secure access to your private AWS RDS database](https://vercel.com/kb/guide/give-eve-agent-secure-access-to-aws-rds-database).

### Use AWS PrivateLink for AWS services that publish an endpoint service

AWS PrivateLink connects your functions and builds to an AWS PrivateLink endpoint service over the AWS private network, with no public internet hop and no VPC peering to manage. It fits internal APIs behind an AWS Network Load Balancer, AWS databases such as RDS, Aurora, and Redshift, and SaaS providers such as Snowflake and MongoDB Atlas that expose an endpoint service.

To set it up, enable **Advanced Networking** in the project's **Settings** → **Networking** page and add a connection with the provider's service name and AWS region. The provider then accepts the connection or allowlists the IAM role Vercel assigns to your team, and your tool code connects through the endpoint's DNS name. Enable **Private DNS** on the connection to resolve the provider's own private hostnames instead.

Each PrivateLink connection exists in one AWS region and applies to every environment in the project. PrivateLink supports interface endpoints only, and it doesn't apply to Routing Middleware. The VPC endpoint is dedicated to your team, but the underlying VPC is shared, so use Secure Compute when you need full network isolation. For backends outside AWS, or ones that aren't exposed as an endpoint service, use Secure Compute or Static IPs.

### Use Static IPs when an IP allowlist meets your security policy

Static IPs route outbound traffic through a shared pool of static IP pairs, which your internal service adds to its allowlist. The service still receives that traffic over the public internet, so use this path only when public ingress from known IPs fits your policy. Static IPs apply to every environment in a project, each configured region has its own IP pair, and a project attached to Secure Compute ignores Static IPs.

Secure Compute, AWS PrivateLink, and Static IPs are all outbound paths. They don't give your agent a fixed inbound IP, so internal systems that call the agent, such as a ticketing system that starts a run, use an authenticated Vercel route. IP filtering also doesn't replace authentication, so keep a token, password, or key on every internal call.

### Use Vercel Connect for scoped access to third-party APIs

Vercel Connect issues short-lived provider tokens at runtime, so tools don't store long-lived SaaS secrets in environment variables or a database. You create a connector once for your team, link it to the projects and environments that need it, and call `getToken` from server-side tool code. On Vercel, the SDK authenticates with the deployment's OIDC token, and Vercel Connect checks that token against the connector's project links before it issues anything.

This tool posts an incident summary to Slack with a token scoped to `chat:write`:

```typescript
import { getToken } from '@vercel/connect';
import { tool } from 'ai';
import { z } from 'zod';

export const postIncidentSummary = tool({
  description: 'Post an incident summary to the on-call Slack channel.',
  inputSchema: z.object({ summary: z.string().max(3000) }),
  execute: async ({ summary }) => {
    const token = await getToken('slack/acme-slack', {
      subject: { type: 'app' },
      scopes: ['chat:write'],
    });

    const res = await fetch('https://slack.com/api/chat.postMessage', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ channel: process.env.ONCALL_CHANNEL_ID, text: summary }),
    });

    const data = await res.json();
    return { posted: data.ok === true };
  },
});
```

The SDK caches each token in process until it nears expiry, so an agent that makes many provider calls in one invocation pays for one token request. To act on behalf of a signed-in user instead of the app, request a token with `subject: { type: 'user', id }`. Vercel Connect bills by token requests and by triggers, which are provider webhooks that it verifies and forwards to a linked project. The [Complete Guide to Vercel Connect](https://vercel.com/kb/guide/vercel-connect) covers connector setup, subjects, and error handling.

## Keep secrets and private data in the right execution environment

The execution boundary is the main security decision in a private agent. Vercel's [security guidance for agentic architectures](https://vercel.com/blog/security-boundaries-in-agentic-architectures) treats the orchestration and tool code you deploy as trusted software, and treats the model and any code it generates as untrusted. Credentials belong only where your own reviewed code runs.

### Run internal API and database tools in Vercel Functions

Trusted tools that hold internal credentials run in Vercel Functions. Store those credentials as encrypted environment variables, or request them from Vercel Connect at runtime, and read them inside the tool's `execute` function. The model sees the tool's name, description, input schema, and result, and never the credential.

Return only the fields the model needs from each tool. Workflows records every step's inputs and outputs, and eve shows tool calls in Agent Runs, so a credential or unnecessary personal data in a tool result ends up in run history.

### Run untrusted code in Vercel Sandbox, away from private systems by default

Vercel Sandbox runs model-generated code in an isolated microVM with its own network. By default, a sandbox doesn't join your project's Secure Compute network, so code inside it can't reach your private databases. Keep private queries in trusted tools and pass the results into the sandbox as data.

When generated code must reach a private resource directly, attach the sandbox to your Secure Compute network with its `networkId`, as described in [Using Secure Compute with Sandbox](https://vercel.com/docs/sandbox/concepts/secure-compute). Restrict the sandbox's [egress firewall](https://vercel.com/docs/sandbox/concepts/firewall) to the private range it needs, since the default policy allows all public internet traffic. Use the firewall's credentials brokering to inject secrets into outbound requests so generated code never reads them, and note that traffic to an allowed IP range bypasses credentials brokering.

Two more caveats apply when generated code connects to a private database over an allowed IP range. Allowing only address ranges leaves DNS unrestricted, so add domain rules or use `deny-all` if DNS exfiltration is part of your threat model. Credentials brokering also doesn't work on Postgres connections, so the database credential has to reach the sandbox another way, such as a short-lived, read-only credential that a trusted tool issues.

### Scope every tool to the signed-in user and validate its arguments

Treat every tool argument as untrusted input, because a prompt injection in a document, ticket, or log line can steer the model's choices. These practices contain that risk:

- Take identity from your auth layer, not from the model. Pass the user or tenant ID into the tool through a closure or WorkflowAgent's `toolsContext`, instead of exposing it as an input field the model fills in.
  
- Validate inputs with strict schemas, such as a regular expression for IDs and an enum for actions, before any network call.
  
- Use least-privilege credentials, such as a read-only database role for query tools and a separate service account for each internal API.
  
- Gate mutating actions behind human approval or a policy check, with `toolApproval` in the AI SDK or `needsApproval` in WorkflowAgent, and set an explicit step limit on the agent loop.
  

## Implement trusted internal tools

The three examples below cover a request-scoped read, a durable mutating action, and a private database query. Each one keeps credentials in server-side code and takes identity from your application instead of from the model.

### Call an internal API from an AI SDK tool

This route answers order questions for the signed-in customer. The tool is defined inside the request handler, so it closes over the session and can only read that customer's orders.

Install the packages:

```bash
npm install ai zod
```

Create the route:

```typescript
import { generateText, isStepCount, tool } from 'ai';
import { z } from 'zod';
import { getSession } from '@/lib/auth'; // Your app's auth helper

// Secure Compute, AWS PrivateLink, and Static IPs don't apply to the Edge runtime.
export const runtime = 'nodejs';

export async function POST(request: Request) {
  const session = await getSession(request);
  if (!session) {
    return new Response('Unauthorized', { status: 401 });
  }

  const { prompt } = await request.json();

  const lookupOrder = tool({
    description: "Look up one of the signed-in customer's orders by order number.",
    inputSchema: z.object({
      orderNumber: z.string().regex(/^ORD-\d{6}$/),
    }),
    execute: async ({ orderNumber }) => {
      // The customer ID comes from the session, not from the model.
      const customerId = encodeURIComponent(session.customerId);
      const res = await fetch(
        `${process.env.INTERNAL_API_URL}/customers/${customerId}/orders/${orderNumber}`,
        { headers: { authorization: `Bearer ${process.env.INTERNAL_API_TOKEN}` } },
      );

      if (!res.ok) {
        return { found: false, status: res.status };
      }

      const order = await res.json();
      // Return only what the model needs to answer.
      return { found: true, status: order.status, updatedAt: order.updatedAt };
    },
  });

  const { text } = await generateText({
    model: 'anthropic/claude-sonnet-5.5',
    tools: { lookupOrder },
    stopWhen: isStepCount(5),
    prompt,
  });

  return Response.json({ text });
}
```

Set `INTERNAL_API_URL` to the API's private address and `INTERNAL_API_TOKEN` to a service credential with read-only order access. Sending the prompt "Where is order ORD-104233?" returns a response like this:

```json
{ "text": "Order ORD-104233 shipped on September 18 and is in transit." }
```

Without `stopWhen`, the request stops as soon as the tool runs and returns an empty `text`, because the model never gets a turn to answer from the tool result.

### Gate a mutating internal API call on human approval with WorkflowAgent

Actions that change internal systems need retries that don't double-apply and a reviewer who can approve hours or days later. When a tool's `execute` function is marked `'use step'`, WorkflowAgent runs that tool call as a durable Workflows step that retries on failure (3 attempts by default) and survives restarts. Tools without the directive run in memory with no durability guarantees. Separately, `needsApproval: true` suspends the run until a reviewer responds, and no compute bills while the run waits.

Install the packages. WorkflowAgent requires Workflow 5, which is available under the `beta` tag:

```bash
npm install @ai-sdk/workflow workflow@beta ai zod
```

Define the workflow. The internal API call lives in `applyChangeStep`, a module-level step function marked `'use step'` that takes plain, serializable arguments. `toolsContext` passes the requester's ID from your auth layer to the tool, and `execute` hands it to the step. `experimental_toolApprovalSecret` signs each approval, so a modified client message history can't approve a call:

```typescript
import { WorkflowAgent, type ModelCallStreamPart } from '@ai-sdk/workflow';
import { convertToModelMessages, isStepCount, tool, type UIMessage } from 'ai';
import { FatalError, getWritable } from 'workflow';
import { z } from 'zod';

// A durable step that retries on failure (3 attempts by default)
async function applyChangeStep(changeId: string, requesterId: string) {
  'use step';
  const res = await fetch(`${process.env.INTERNAL_API_URL}/changes/${changeId}/apply`, {
    method: 'POST',
    headers: {
      authorization: `Bearer ${process.env.INTERNAL_API_TOKEN}`,
      'content-type': 'application/json',
      // Lets the internal API ignore a retried request it already applied
      'idempotency-key': changeId,
      'x-requested-by': requesterId,
    },
  });
  if (res.status >= 500) {
    // Throwing makes Workflows retry the step
    throw new Error(`Change API returned ${res.status}`);
  }
  if (!res.ok) {
    // A 4xx won't succeed on retry, so fail the step without retrying
    throw new FatalError(`Change API rejected ${changeId} with ${res.status}`);
  }
  return { applied: true, status: res.status };
}

export async function changeAgent(messages: UIMessage[], requesterId: string) {
  'use workflow';

  const agent = new WorkflowAgent({
    model: 'anthropic/claude-sonnet-5.5',
    instructions: 'You help engineers review and apply configuration changes.',
    experimental_toolApprovalSecret: { environmentVariable: 'TOOL_APPROVAL_SECRET' },
    tools: {
      applyChange: tool({
        description: 'Apply a proposed change through the internal change API.',
        inputSchema: z.object({ changeId: z.string().regex(/^chg_[a-z0-9]+$/) }),
        contextSchema: z.object({ requesterId: z.string() }),
        needsApproval: true, // Suspends the run until a reviewer responds
        execute: ({ changeId }, { context }) => applyChangeStep(changeId, context.requesterId),
      }),
    },
    toolsContext: { applyChange: { requesterId } },
  });

  const result = await agent.stream({
    messages: await convertToModelMessages(messages),
    writable: getWritable<ModelCallStreamPart>(),
    stopWhen: isStepCount(10), // WorkflowAgent has no default step limit
  });

  return { messages: result.messages };
}
```

Start the workflow from an authenticated route:

```typescript
import { createModelCallToUIChunkTransform } from '@ai-sdk/workflow';
import { createUIMessageStreamResponse, type UIMessage } from 'ai';
import { start } from 'workflow/api';
import { getSession } from '@/lib/auth';
import { changeAgent } from '@/workflows/change-agent';

export async function POST(request: Request) {
  const session = await getSession(request);
  if (!session) {
    return new Response('Unauthorized', { status: 401 });
  }

  const { messages }: { messages: UIMessage[] } = await request.json();
  const run = await start(changeAgent, [messages, session.userId]);

  return createUIMessageStreamResponse({
    stream: run.readable.pipeThrough(createModelCallToUIChunkTransform()),
  });
}
```

Set `TOOL_APPROVAL_SECRET` to a random value of at least 32 bytes in every environment that runs the workflow. Keep context values such as `requesterId` serializable, and create database or SDK clients inside the step that uses them. For conditional approval, `needsApproval` also accepts an async function that decides from the tool's input. `needsApproval` on a tool definition is specific to WorkflowAgent. For `generateText`, `streamText`, and `ToolLoopAgent`, configure approval with the `toolApproval` option instead, because `needsApproval` is deprecated there. [Durable agent approval workflows on Vercel](https://vercel.com/kb/guide/agent-approval-workflow-stack-guide) covers the approval console, audit trail, and resume flow.

### Query a private database from an eve tool

eve agents run on Vercel Functions, so a tool in a Secure Compute project reaches a peered database without networking code. Each file in `agent/tools/` is one tool, and its filename becomes the tool name the model sees.

```typescript
import { defineTool } from 'eve/tools';
import { z } from 'zod';
import { Pool } from 'pg';

// Created once and reused across calls
const pool = new Pool({ connectionString: process.env.DATABASE_URL });

export default defineTool({
  description: 'Run a read-only SQL query against the analytics database and return rows.',
  inputSchema: z.object({
    sql: z.string().describe('A single read-only SQL SELECT statement.'),
  }),
  async execute({ sql }) {
    const client = await pool.connect();
    try {
      const { rows } = await client.query(sql);
      return { rowCount: rows.length, rows };
    } finally {
      client.release();
    }
  },
});
```

Point `DATABASE_URL` at a read-only role on the database's private host, with `sslmode=require` for Postgres. The tool description asks for read-only SQL, but the database role is what enforces it. For data that belongs to individual users or tenants, replace free-form SQL with parameterized queries scoped to the signed-in user, or enforce row-level security in the database.

## Operate a private agent in production

### Pin functions and workflow runs near private data sources

Create the Secure Compute network in the region closest to your backend, then deploy your functions to that same region with the `regions` key in `vercel.json`:

```json
{
  "regions": ["iad1"]
}
```

Workflows pins each run to the region of the function that started it, and keeps the run's state, queue dispatch, and streams there for the run's lifetime. To keep run data in a specific region, pass the `region` option to `start()`. For failover, assign each project environment a passive Secure Compute network in a second region, and Vercel switches to it if the primary region becomes unavailable.

### Log tool calls, inputs, decisions, and failures

Workflows records every step, input, output, sleep, and error, and approvals appear as events in the same run history. View runs in your project's **Observability** → **Workflows** page, or run `npx workflow inspect runs` during local development. After a run completes, its history stays available for 1 day on Hobby, 7 days on Pro, and 30 days on Enterprise. When audits need longer retention, export the history to [Vercel Blob](https://vercel.com/docs/vercel-blob) as a final workflow step.

Workflow run data can include tool inputs and outputs, so control who reads it. Team owners can read decrypted run data, and you can grant it to other members with the **Workflow Run Data Viewer** extended permission. eve agents also report sessions, turns, tool calls, and token usage in [Agent Runs](https://vercel.com/docs/eve/agent-runs). Vercel Connect adds an **Observability** tab per connector that records each token request, and you can forward those events to a SIEM with a [Drain](https://vercel.com/docs/drains) on Pro and Enterprise.

### Plan for retries, idempotency, and human approvals

WorkflowAgent retries a failed tool step automatically (3 attempts by default) when its `execute` function is marked `'use step'`, which means a mutating internal API can receive the same request more than once. Send an idempotency key derived from stable input, such as the change ID, if your internal API supports one. Otherwise, have the tool check the current state before it writes.

Workflows retries a step only when it throws. A step that returns an error value, such as `{ applied: false }` for a 500 response, counts as a success and doesn't retry. Throw an `Error` for failures that might succeed on another attempt, such as 5xx responses, and throw `FatalError` from `workflow` for failures that won't, such as a 403 or 404.

Use `needsApproval: true` for actions a person must always review, and an async `needsApproval` function for actions that need review only above a threshold. While a run waits for approval, no compute bills, and stored run state bills as Workflow Data Retained at $0.50 per GB-month ([Workflows pricing](https://vercel.com/docs/workflows/pricing)).

## Troubleshoot private tool calls

### The internal API works locally but fails on Vercel

Local development often succeeds because your machine is on a corporate VPN. On Vercel, check each link in the network path:

1. Confirm the environment is attached. In the project's **Settings** → **Networking** page, each environment that calls private systems, such as Production and Preview, needs an **Active Network**.
   
2. Confirm the AWS route table sends traffic for the Vercel network's CIDR block over the peering connection, and that the CIDR blocks don't overlap.
   
3. Confirm the target's security group allows its port, such as 5432 for Postgres, from the Vercel network's CIDR block.
   
4. Confirm the credentials are set as environment variables for the environment you deployed to.
   

### Tool traffic doesn't use the Secure Compute IPs

Check the runtime first. Code that runs in Routing Middleware or on the `edge` runtime doesn't use Secure Compute, AWS PrivateLink, or Static IPs, so move private calls into a route or tool on the Node.js runtime. Then confirm the deployment's environment has an active network. Preview deployments use the network assigned to Preview, not the one assigned to Production.

### The AWS PrivateLink connection doesn't become available

Each connection stays in the **pending acceptance** state until the provider approves it, unless the endpoint service accepts all principals automatically. Share your team's principal role ARN, shown in the setup dialog, with the provider so it can allowlist that role. If provisioning fails, the endpoint service might not run in at least two Availability Zones that overlap with Vercel's network in that region, so ask the provider to expose it in more zones. Redeploy after the connection becomes available.

### Code in Vercel Sandbox can't reach the private database

This is the expected default, because a sandbox has its own network and doesn't join the project's Secure Compute network. Move the query into a trusted tool and pass the rows to the sandbox. If generated code must connect directly, attach the sandbox with `networkId` and allow only the database's private IP range in the sandbox firewall.

### The internal service rejects requests from allowlisted IPs

Confirm the service allowlists the IP pair for the region where your functions run, because each Static IPs region has its own pair. Then check authentication, since IP filtering alone doesn't authorize a request. If the failing traffic is the internal service calling your agent, the outbound IPs don't apply, and the service needs an authenticated Vercel route instead.

## Decide whether Vercel fits your private agent workload

### Use Vercel when the agent is request-driven, web-facing, or workflow-driven

Vercel fits private agents that serve users through a web app, chat surface, or API, and that reach internal systems over HTTP or database drivers. It fits especially well when these conditions hold:

- The agent, its tools, and its UI are written in TypeScript or Python and deploy together
  
- Durability needs are retries, waits, and human approval rather than long-lived processes
  
- Internal systems accept outbound connections from a peered network, a VPN, an AWS PrivateLink endpoint service, or an IP allowlist
  
- The team wants one deployment target and one identity model for the UI, agent, and tools
  

### What Vercel replaces in a LangGraph, MCP gateway, Temporal, and Kubernetes assembly

Many teams build private agents on a custom stack of several systems that they deploy, secure, and pay for separately. The table maps each concern to the Vercel product that covers it.

| Concern                 | Vercel                                                           | Common custom assembly                             |
| ----------------------- | ---------------------------------------------------------------- | -------------------------------------------------- |
| Model access            | AI Gateway                                                       | Provider SDKs or a separately operated model proxy |
| Agent loop              | AI SDK, WorkflowAgent, or eve                                    | LangGraph                                          |
| Tool interface          | AI SDK or eve tools, or MCP servers deployed as Vercel Functions | An internal MCP gateway                            |
| Durable orchestration   | Workflows, with managed persistence                              | Temporal plus a checkpoint database                |
| Tool execution          | Vercel Functions                                                 | Services on Kubernetes                             |
| Private network path    | Secure Compute, AWS PrivateLink, or Static IPs                   | Self-managed VPC, NAT, and IAM                     |
| Third-party credentials | Vercel Connect                                                   | A secrets manager plus custom OAuth handling       |
| Untrusted code          | Vercel Sandbox                                                   | A separately operated sandbox                      |
| UI and approval console | Next.js in the same project                                      | A separate service and deployment                  |

### Where MCP and LangGraph can still fit

Model Context Protocol (MCP) is a protocol boundary between an agent and its tools, and you can keep it on Vercel. Deploy an MCP server as a Vercel Function in a Secure Compute project, and its tools reach internal systems privately. The AI SDK and eve can both connect to it as clients, and Vercel Connect can authorize OAuth-protected MCP servers. The execution boundary stays the same, because the MCP server is the trusted code that holds credentials.

If your team already writes agent logic in a framework such as LangGraph, the guidance on tool placement, network paths, and credentials still applies to that code. Compare its durability requirements against Workflows before you add a separate checkpoint store and workflow engine.

### When a dedicated engine or self-managed infrastructure is the better choice

Choose a dedicated workflow engine or self-managed stack in these cases:

- Non-web systems, such as Java services, batch jobs, or Business Process Model and Notation (BPMN) process models, must participate as first-class workflow actors
  
- Your organization has a dedicated team that owns Temporal Cloud or a Camunda cluster running the process
  
- Policy requires the agent runtime and its orchestration state to run inside your own VPC or on-premises, not only its tool traffic
  
- Individual tool steps need to run longer than the 800-second maximum that applies on Secure Compute
  

For the in-VPC requirement, check Bring Your Own Cloud before you plan a separate stack. This Enterprise option runs your functions inside your own AWS account while Vercel orchestrates routing and invocation. Plan for a substantial setup project, and confirm with your Vercel account team which parts of the agent stack it covers.

These cases often call for integration rather than migration. Vercel-hosted agents can call Temporal or AWS Step Functions as a step, and an external workflow can start a Vercel Workflow through an HTTP endpoint.

## FAQ

### Can an agent on Vercel call an internal API?

Yes. Put the tool code in a Vercel Function, then choose its outbound path. Use Secure Compute for VPC peering and full network isolation, AWS PrivateLink for AWS services that publish an endpoint service, or Static IPs for an IP allowlist. The model requests the call, and your tool validates and executes it.

### Does Vercel Sandbox inherit Secure Compute or VPC peering?

No. Each sandbox uses its own network and doesn't join the project's Secure Compute network by default. Keep private database and internal API calls in trusted tools, or attach a specific sandbox to the network with `networkId` and restrict its firewall to the private range it needs.

### Do I need Temporal or Kubernetes for a durable enterprise agent on Vercel?

Most web-facing agents don't need either. Workflows and WorkflowAgent provide durable tool steps, retries, sleeps, hooks, and human approval without an idle container, and run state lives in managed persistence. Mark each tool's `execute` function with `'use step'` to make its calls durable. Dedicated engines still fit when non-web systems must participate as first-class workflow actors.

### When should I use Vercel Connect instead of Secure Compute?

Use Vercel Connect when a tool calls a supported third-party API, such as Slack, GitHub, Microsoft, Snowflake, or Salesforce, and needs a short-lived, scoped token. Use Secure Compute, AWS PrivateLink, or Static IPs when the tool reaches infrastructure you run, such as an internal API or database. Many agents use both.

### Do Secure Compute, AWS PrivateLink, and Static IPs give my agent a fixed inbound IP?

No. All three handle outbound traffic only. Internal systems that call your agent use an authenticated Vercel route.

### Is this guide about Vercel Agent?

No. Vercel Agent is the built-in assistant for Vercel projects. This guide covers building your own enterprise agent application on Vercel.

## Next steps

- [Secure Compute](https://vercel.com/docs/networking/secure-compute): create networks, set up VPC peering, and configure region failover
  
- [AWS PrivateLink](https://vercel.com/docs/networking/privatelink): connect to AWS-hosted services through an endpoint service
  
- [Static IPs](https://vercel.com/docs/networking/static-ips): set up the IP allowlist path
  
- [Give your eve agent secure access to your private AWS RDS database](https://vercel.com/kb/guide/give-eve-agent-secure-access-to-aws-rds-database): the complete peering walkthrough for a private database tool
  
- [Durable agent approval workflows on Vercel](https://vercel.com/kb/guide/agent-approval-workflow-stack-guide): approval consoles, audit trails, and Workflows versus Temporal
  
- [AI Gateway tool use](https://vercel.com/docs/ai-gateway/inputs-and-tools/tool-use): tool-calling mechanics across the AI SDK and provider APIs
  
- [WorkflowAgent in the AI SDK](https://ai-sdk.dev/docs/agents/workflow-agent): durable tools, approvals, and `toolsContext`
  
- [Vercel Workflows](https://vercel.com/docs/workflows): runtime behavior, regions, observability, and pricing
  
- [The Complete Guide to Vercel Connect](https://vercel.com/kb/guide/vercel-connect): connectors, token subjects, and error handling
  
- [Using Secure Compute with Sandbox](https://vercel.com/docs/sandbox/concepts/secure-compute): attach a sandbox to a private network when generated code needs it
  
- [OSS Data Analyst Agent reference architecture](https://vercel.com/templates/ai/oss-data-analyst-agent-reference-architecture): a deployable agent template built on the AI SDK and Vercel Sandbox