Skip to content

Connect an OpenAPI API

An agent reaches an HTTP API by declaring it, not by coding against it. Point a connection at an OpenAPI 3.0 or Swagger 2.0 document and every operation you allow becomes a tool, named after its operationId.

Create a file under connections/:

my-agent/connections/forecast.toml
kind = "openapi"
spec = "open-meteo.json"
operations.allow = ["getForecast"]
Key Type Description
kind string Must be openapi.
spec string An https:// URL, or a path resolved relative to the agent directory.
base_url string Overrides the spec’s own servers/host for the calls tools make. Supports ${VAR} expansion.
operations.allow string[] Surface only these operations. Empty (the default) surfaces all of them.
operations.block string[] Drop these operations. Applied after allow.
headers table Sent with every request. Values support ${VAR} expansion.

Operation ids are matched after sanitizing them to tool-name form, so Journey.Meta in a spec is written Journey_Meta — or either spelling, since both sides are sanitized before comparison.

spec accepts a URL, but a file beside the agent is the better default. A remote spec means the agent cannot list its own tools without a network round trip, and if that host is down the connection degrades quietly to no tools rather than to an error — the agent still starts, just without the capability. Vendoring the document keeps startup deterministic; the calls themselves still go to the live API.

Credentials are referenced by name and resolved from the environment at load time, so the token lives in your secret store rather than in the folder:

kind = "openapi"
spec = "https://api.example.com/openapi.json"
operations.allow = ["listInvoices", "getInvoice"]
headers = { Authorization = "Bearer ${EXAMPLE_API_TOKEN}" }

A ${VAR} with no value in the environment fails the load with the variable’s name, rather than sending an empty header and getting a puzzling 401.

Filter deliberately. A large public spec can carry hundreds of operations, and each one spends room in the model’s tool list and widens what a confused model can reach. operations.allow is the allowlist; operations.block subtracts from whatever survived it.

Only GET-style read operations are safe to expose without thought — an allowed deleteAccount is a tool the model can call.

Connections are established at load time, and maiden logs the resulting tool set:

Terminal window
maiden run my-agent "what is the weather in London?"
# [maiden] agent 'my-agent' tools [getForecast]

From there an OpenAPI tool is dispatched exactly like a WASM tool, an MCP tool or a subagent — see How maiden fits together.