Connections

OpenAPI Connections

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 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 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>.

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: { 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.

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, then attach the returned connector UID to the OpenAPI connection:

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, Headers, and 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:

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:

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: { 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.

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.

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 for the helpers and Human-in-the-loop for policy behavior.