---
title: OpenAPI Connections
description: Turn an OpenAPI 3.x or Swagger 2.0 document into eve connection tools, authorize calls, and control which operations the model can discover.
---

# OpenAPI Connections



OpenAPI connections turn an OpenAPI 3.x or Swagger 2.0 document into connection tools, one per operation. Use OpenAPI when a service publishes an HTTP API contract and you want eve to derive model-facing tools from that contract.

Use an [MCP connection](./mcp) instead when the service already exposes an MCP server, when the server should own tool schemas dynamically, or when the remote service has richer MCP semantics than its raw HTTP API.

## Define an OpenAPI connection

Create one file under `agent/connections/`. The filename becomes the runtime connection name, so `agent/connections/petstore.ts` registers as `petstore`, and generated operation tools are called as `petstore__<operation>`.

```ts title="agent/connections/petstore.ts"
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  spec: "https://petstore3.swagger.io/api/v3/openapi.json",
  description: "Pet store inventory and orders.",
  auth: {
    credentialOwner: "app",
    getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }),
  },
});
```

Each operation becomes `<connection>__<operationId>`, for example `petstore__getInventory`. When an operation has no `operationId`, eve derives a deterministic `<method>_<sanitized-path>` name instead.

`spec` can be a URL that eve fetches at runtime, or an inline parsed OpenAPI object. A spec URL must use `https` (plain `http` is allowed only for loopback hosts such as `localhost` during local development), and eve re-checks the transport after any redirects. Prefer a URL when the provider owns the contract and updates it; prefer an inline object for private APIs, generated specs you pin in source control, or small hand-authored contracts.

## Base URL and servers

eve resolves operation paths against `baseUrl` when you provide one. Otherwise, it derives the base URL from the spec:

* OpenAPI 3.x: the first usable `servers` entry
* Swagger 2.0: `schemes`, `host`, and `basePath`

Use `baseUrl` when the spec is missing server data, points at the wrong environment, uses a relative server URL you do not want, or needs to be pinned for this agent.

The resolved base URL must use `https` too (loopback hosts may use `http` for local development), since operation calls carry the connection's credentials.

```ts title="agent/connections/crm.ts"
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  spec: "https://api.example.com/openapi.json",
  baseUrl: "https://api.example.com",
  description: "CRM accounts, contacts, and opportunities.",
});
```

## Use Vercel Connect for OAuth

For an OAuth-backed API, follow the shared [Vercel Connect setup](../connections#interactive-oauth-via-vercel-connect), then attach the returned connector UID to the OpenAPI connection:

```ts title="agent/connections/github.ts"
import { connect } from "@vercel/connect/eve";
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  spec: "https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json",
  baseUrl: "https://api.github.com",
  description: "GitHub repositories, issues, pull requests, and users.",
  auth: connect("github/github"),
});
```

`connect("...")` is user-scoped by default and requires an authenticated user on the active session. Use `connect({ connector, principalType: "app" })` when the API should act as the agent instead. Configure provider-specific scopes, audiences, or authorization details through `tokenParams` on `connect(...)`.

## Static tokens and headers

OpenAPI connections accept the shared connection `auth` and `headers` options. Use `auth.getToken` for a bearer token, `headers` for another scheme or API version, and resolver functions when credentials or routing depend on the caller. See [Static-token auth](../connections#static-token-auth), [Headers](../connections#headers), and [Per-caller auth and headers](../connections#per-caller-auth-and-headers) for the canonical examples and token-lifecycle behavior.

## Application-provided operation arguments

Some APIs declare operation parameters that should come from the application rather than the model, such as a tenant or organization ID. Configure those values with `toolCall.providedArguments`:

```ts title="agent/connections/crm.ts"
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  spec: "https://api.example.com/openapi.json",
  description: "CRM accounts, contacts, and opportunities.",
  toolCall: {
    providedArguments: {
      tenantId: ({ session }) => String(session.auth.current?.attributes.tenant ?? ""),
    },
  },
});
```

Values may be JSON values, promises, or callbacks. Callbacks receive the active session context, the bare operation `toolName`, and a replay-stable `callId` that is unique to the tool call. Use `callId` when the API needs an idempotency key.

eve removes configured keys from every operation's model-facing input schema and adds their resolved values immediately before constructing the HTTP request. Values apply to every operation on the connection and replace any conflicting model value. The keys correspond to the generated top-level operation inputs: path, query, header, and cookie parameter names, plus `body` for a request body.

Use `headers` for transport-wide headers that are not operation inputs. Use `providedArguments` when the OpenAPI document declares the value as an operation parameter and it should remain outside model control. Approval policies continue to receive only the model-authored input.

## Operation filters

Most OpenAPI specs describe far more than the model should use. Narrow generated tools with exactly one of `operations.allow` or `operations.block`:

```ts title="agent/connections/petstore.ts"
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  spec: "https://petstore3.swagger.io/api/v3/openapi.json",
  description: "Pet store inventory and orders.",
  auth: {
    credentialOwner: "app",
    getToken: async () => ({ token: process.env.PETSTORE_TOKEN! }),
  },
  operations: { allow: ["getInventory", "placeOrder"] },
});
```

Filters match `operationId`. If an operation does not declare one, use the deterministic name eve derives from the method and path.

## Path parameters

When an operation path contains dynamic segments, the spec must declare matching OpenAPI path parameters. eve exposes path, query, header, and cookie parameters as top-level tool inputs, then substitutes `in: "path"` values into the matching `{name}` placeholder before making the request.

```ts title="agent/connections/cart.ts"
import { defineOpenAPIConnection } from "eve/connections";

export default defineOpenAPIConnection({
  baseUrl: "https://api.example.com",
  description: "Cart and checkout API.",
  spec: {
    openapi: "3.0.3",
    info: { title: "Cart API", version: "1.0.0" },
    paths: {
      "/api/{cartId}/items/{itemId}": {
        get: {
          operationId: "getCartItem",
          parameters: [
            {
              name: "cartId",
              in: "path",
              required: true,
              schema: { type: "string" },
            },
            {
              name: "itemId",
              in: "path",
              required: true,
              schema: { type: "string" },
            },
          ],
          responses: { "200": { description: "OK" } },
        },
      },
    },
  },
});
```

The parameter `name` must exactly match the placeholder inside the path. If the spec omits an `in: "path"` parameter, the generated tool has no input for that segment and eve cannot fill it in from query parameters.

## Schema annotations

eve removes `default` and `example` annotations when their values conflict with the declared schema type. For example, a boolean property with `default: "false"` loses that annotation, while `default: false` is retained. This prevents invalid examples from guiding model input; eve does not coerce annotation values.

## Approval gates

Generated operations can mutate state like authored tools. Use the shared connection `approval` option for human approval, and combine it with `operations.allow` for the smallest practical surface. See [Per-connection approval](../connections#per-connection-approval) for the helpers and [Human-in-the-loop](../human-in-the-loop#approvals) for policy behavior.

## What to read next

* [Connections](../connections): shared auth, headers, approval, and per-caller patterns.
* [MCP connections](./mcp): connect to remote MCP servers.
* [Authentication](../guides/auth-and-route-protection): establish the caller identity required by user-scoped auth.
* [Security model](../concepts/security-model): how connection credentials stay out of the model's reach.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)