OpenAPI Connections
Purpose and Scope
OpenAPI connections are eve's path for turning an existing HTTP API contract into model-callable capabilities without hand-writing a local tool for every endpoint. An OpenAPI connection points at an OpenAPI 3.x or Swagger 2.0 document, and eve turns each operation in that document into a connection tool. This is useful when the external service already publishes a stable API description and you want the agent to discover and call those operations through eve's connection system rather than embedding URLs, credentials, and request-building logic in model context.
Sources: docs/connections/openapi.mdx, docs/connections/overview.mdx
A connection is different from a local tool and different from a channel. Local tools are functions you author inside the agent project. Channels are the surfaces that receive and deliver messages, such as HTTP routes, WebSockets, Slack, or custom platform adapters. Connections wire the agent to external servers you do not author. The connection runtime owns discovery, auth brokering, and the qualified tool naming scheme, while the model sees only the discoverable tool surface and not the server URL or credentials.
Sources: docs/connections/overview.mdx, docs/channels/custom.mdx
Use OpenAPI when the service publishes an HTTP API contract and you want one generated tool per operation. Use MCP instead when the service already exposes a Model Context Protocol server, when the remote server owns tool schemas dynamically, or when the remote service has richer MCP semantics than its raw HTTP API. In both cases, eve exposes external capabilities through the connection system and the built-in discovery flow, but the ownership of schemas differs: OpenAPI derives them from a static API document, while MCP receives them from the remote server.
Sources: docs/connections/openapi.mdx, docs/connections/mcp.mdx
Relevant Source Files
docs/connections/openapi.mdx- Primary reader-facing documentation fordefineOpenAPIConnection, generated operation names,spec,baseUrl, OpenAPI and Swagger server resolution, Vercel Connect auth, and app-versus-user connector behavior.docs/connections/overview.mdx- Defines the shared connection model, theagent/connections/convention,connection_search, qualified tool names, static-token auth, token caching, and credential ownership.docs/connections/mcp.mdx- Provides the contrast point for when to choose MCP instead of OpenAPI and documents the same connection-auth ideas for remote MCP servers.docs/connections/meta.json- Placesoverview,mcp, andopenapiin the Connections documentation section, which is the intended navigation context for this page.docs/agent-config.md- Grounds how connection files fit beside the rootagent.tsruntime configuration rather than replacing model, reasoning, compaction, and runtime-limit settings.docs/channels/custom.mdx- Grounds the distinction between connections and channels: custom channels define inbound routes and delivery behavior, while connections expose external server capabilities to the model.
Core Primitives
The first primitive is the connection file. OpenAPI connections live under agent/connections/, and the file stem becomes the runtime connection name. For example, agent/connections/petstore.ts registers as petstore. Generated tools are named by qualifying the operation with that connection name, so an operation such as getInventory becomes petstore__getInventory. This convention matters because it gives developers a filesystem-controlled namespace while keeping model-facing capability names stable and understandable.
Sources: docs/connections/openapi.mdx, docs/connections/overview.mdx
The second primitive is defineOpenAPIConnection, imported from eve/connections. Its configuration declares the API document, a model-facing description, optional base URL override, and auth. The description should explain the external system in terms the model can use during discovery, because connections are surfaced through the built-in connection_search flow. The model discovers matching tools and calls them by qualified name; it does not receive the connection's raw URL or credentials in conversation history.
Sources: docs/connections/openapi.mdx, docs/connections/overview.mdx
The third primitive is the OpenAPI spec. The spec may be an HTTPS URL that eve fetches at runtime, or an inline parsed OpenAPI object. Prefer a URL when the provider owns and updates the contract. Prefer an inline object for private APIs, generated specs pinned in source control, or small hand-authored contracts. This choice is operational: a remote URL follows provider changes, while an inline object makes review, versioning, and reproducibility easier inside the agent repository.
Sources: docs/connections/openapi.mdx
Define an OpenAPI Connection
A minimal OpenAPI connection is a single default export. The following example registers a petstore connection because the file path is agent/connections/petstore.ts. The external API document is the Petstore OpenAPI JSON URL, and each operation in that document becomes a generated tool under the petstore__ namespace. The auth callback returns a bearer token, which eve sends as Authorization: Bearer <token> when it calls the API.
Sources: docs/connections/openapi.mdx, docs/connections/overview.mdx
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! }) },
});Operation naming is deterministic. When an OpenAPI operation has an operationId, eve uses that value in the generated tool name, producing names such as petstore__getInventory. When an operation has no operationId, eve derives a deterministic fallback from the HTTP method and sanitized path. That fallback behavior is important for imperfect provider specs: the connection still produces callable tools, but you should prefer explicit operation IDs when you control the contract because they produce clearer names for development and evaluation.
Sources: docs/connections/openapi.mdx
Base URL and Server Resolution
Every generated operation needs a concrete request URL. If you provide baseUrl, eve resolves operation paths against it. If you do not provide baseUrl, eve derives the base URL from the API document. For OpenAPI 3.x documents, it uses the first usable servers entry. For Swagger 2.0 documents, it uses the combination of schemes, host, and basePath. This lets a well-formed public spec work with minimal configuration while still allowing production agents to pin a known environment explicitly.
Sources: docs/connections/openapi.mdx
Use baseUrl when the provider spec is missing server data, points at the wrong environment, uses a relative server URL that is not appropriate for the agent, or needs to be pinned to a specific deployment. In practice, this is common for private APIs with separate staging and production environments, public specs that document multiple environments, or generated specs that are served from a documentation host rather than the actual API host.
Sources: docs/connections/openapi.mdx
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.",
});Authorization and Credential Ownership
OpenAPI connections support static token auth through auth.getToken. The shared connection overview defines getToken as returning a TokenResult shaped like { token, expiresAt? }, and eve sends the token as a bearer credential on every request. Because getToken runs on each connection attempt, it can read from an environment variable, secrets manager, internal vault, or OAuth exchange. If the token has a known lifetime, return expiresAt in milliseconds since epoch so eve can refresh ahead of expiry instead of waiting for a failed request.
Sources: docs/connections/overview.mdx, docs/connections/openapi.mdx
Credential ownership is explicit. When getToken is the only auth configuration, the connection defaults to principalType: "app", meaning one shared app, bot, service, or installation credential. Use principalType: "user" when each end user should bring their own third-party token. User-scoped connection auth depends on the active eve session already having a user principal from route auth or a platform channel; it does not mean eve can ask an unauthenticated human later.
Sources: docs/connections/overview.mdx
For OAuth-backed APIs, the docs recommend Vercel Connect. Connect owns browser consent, encrypted token storage, refresh, and project access, while the connect() helper from @vercel/connect/eve plugs that lifecycle into eve connection auth. By default, connect("...") is user-scoped, so the first operation call for a user depends on that user's authenticated session. If the API should act as the agent itself, use connect({ connector: "github/github", principalType: "app" }).
Sources: docs/connections/openapi.mdx, docs/connections/overview.mdx
npm install @vercel/connect
vercel link
vercel connect create github --name github
vercel connect attach <connector-uid> --yes
vercel env pullimport { 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"),
});System-to-Code Mapping
OpenAPI connection authoring is intentionally filesystem-first. The root agent still uses agent/agent.ts and defineAgent for runtime configuration such as model selection, reasoning effort, compaction, workflow world, and token limits. A connection file does not replace that runtime config; it adds an external capability namespace under agent/connections/. This separation helps keep model/runtime policy in one place and external service wiring in another, matching eve's broader convention that core agent capabilities live in conventional filesystem locations.
Sources: docs/agent-config.md, docs/connections/openapi.mdx
Channels sit on the other side of the execution boundary. A custom channel file under agent/channels/ declares HTTP or WebSocket routes, receives inbound platform events, starts or resumes sessions, streams events, and delivers completed messages back to the owning surface. An OpenAPI connection does not define inbound routes and does not own message delivery. Instead, it is a source of external operations the agent may call during a turn after discovery and authorization have resolved.
Sources: docs/channels/custom.mdx, docs/connections/overview.mdx
Compact Reference
| Concept | Contract | Notes |
|---|---|---|
| File location | agent/connections/<name>.ts | The filename stem becomes the runtime connection name. |
| Definition helper | defineOpenAPIConnection(...) from eve/connections | Default-export the connection definition. |
| Spec input | spec: "https://..." or inline parsed OpenAPI object | Supports OpenAPI 3.x and Swagger 2.0 documents. |
| Tool naming | <connection>__<operation> | Uses operationId when present; otherwise derives a deterministic method-and-path name. |
| Base URL | baseUrl?: string | Overrides spec-derived server data when needed. |
| Static auth | auth: { getToken: async () => ({ token, expiresAt? }) } | Sent as Authorization: Bearer <token>. |
| Connect auth | auth: connect("connector/name") | User-scoped by default; use principalType: "app" for app-scoped credentials. |
| Discovery | connection_search | The model discovers connection tools by description and calls qualified tool names. |
Next Steps
Start by deciding whether the external service should be modeled as OpenAPI or MCP. If the provider owns an MCP server with dynamic tool schemas, read the MCP Connections page first. If the provider publishes an HTTP API contract, add one file under agent/connections/, choose a clear connection filename, write a model-facing description, and decide whether the spec should be fetched from the provider or pinned inline. Then choose app-scoped or user-scoped auth before exposing the connection to production traffic.
Sources: docs/connections/openapi.mdx, docs/connections/mcp.mdx, docs/connections/overview.mdx