Skip to content

Connect OpenAPI services

Connect a service that publishes an OpenAPI specification to a ToolRegistry, so each operation becomes a tool the agent can call.

  • A ToolRegistry, or a manifest you are about to create, attached to an AgentRuntime through spec.toolRegistryRef. See Adding tools to agents.
  • A PromptPack you can edit. The pack decides which tools the model is offered.
  • A specification URL (OpenAPI v2 or v3) that serves JSON and that the runtime can fetch when the agent starts. YAML specifications are not parsed.

An openapi handler is self-describing. You give it the specification URL and the runtime builds one tool per operation, named after the operation ID. An operation with no ID is named <method>_<path>, for example get_users_id. You do not write a tool definition.

apiVersion: omnia.altairalabs.ai/v1alpha1
kind: ToolRegistry
metadata:
name: api-tools
spec:
handlers:
- name: petstore
type: openapi
openAPIConfig:
specURL: https://petstore.swagger.io/v2/swagger.json
baseURL: https://petstore.swagger.io/v2

baseURL overrides the server URL in the specification. Without it, the runtime uses the first servers URL (OpenAPI 3) or scheme://host plus basePath (Swagger 2, scheme defaults to https), and fails to connect if neither exists.

An empty operationFilter exposes every operation. List operation IDs to expose only those:

openAPIConfig:
specURL: https://petstore.swagger.io/v2/swagger.json
baseURL: https://petstore.swagger.io/v2
operationFilter:
- getPetById
- findPetsByStatus

Each tool’s input schema lists the operation’s parameters and the top-level properties of its JSON request body. The runtime sends each argument where the specification declares it:

Declared asSent as
in: pathSubstituted into the path, URL-escaped. . and .. are refused
in: queryA query-string parameter
in: headerA request header of the same name
Anything elseThe JSON request body for POST, PUT and PATCH; query-string parameters for other methods

For PUT /pets/{petId}, the arguments {"petId": "7", "name": "Rex"} become PUT /pets/7 with the body {"name": "Rex"}.

A pack that declares its own schema for the tool can nest the request body under a single body argument instead: {"petId": "7", "body": {"name": "Rex"}} sends the same request. The runtime unwraps body only when it is an object, it is the only argument that is not a declared parameter, and the operation declares no parameter or body property named body.

The runtime offers the model only the tools that a PromptPack prompt lists in tools. It does not add ToolRegistry tools to the pack, so an openapi handler on its own offers the model nothing. List each operation ID the prompt may call:

"prompts": {
"main": {
"id": "main",
"tools": ["getPetById", "findPetsByStatus"]
}
}

Publish the change as described in PromptPack. For a pack held in a ConfigMap, re-apply the ConfigMap. The operator rolls the agent pod when the pack content changes.

A ToolRegistry holds any mix of handler types. Each handler keeps its own configuration:

spec:
handlers:
- name: search
type: http
httpConfig:
endpoint: https://api.search.com/query
method: POST
tool:
name: web_search
description: "Search the web"
inputSchema:
type: object
properties:
query:
type: string
required: [query]
- name: code-assistant
type: mcp
mcpConfig:
transport: sse
endpoint: http://mcp-code.tools.svc.cluster.local/sse
- name: weather-api
type: openapi
openAPIConfig:
specURL: https://api.weather.com/openapi.json
Terminal window
kubectl get toolregistry api-tools -o jsonpath='{.status.phase}'

The phase is Ready when every handler validates and every discovered tool is available. An openapi handler reports one placeholder entry in status.discoveredTools, named after the handler. The individual operations are discovered when the agent starts, so check the runtime logs for the OpenAPI adapter connected line to see how many operations loaded.

A registry tool that no prompt lists in tools is not offered to the model. The runtime logs it once at startup, and sets the AgentRuntime condition PackContentValid to False:

Terminal window
kubectl logs deployment/<agent> -c runtime | grep "NOT declared by the pack"
kubectl get agentruntime <agent> -o jsonpath='{.status.conditions[?(@.type=="PackContentValid")].message}'

The log line reads ToolRegistry tools are NOT declared by the pack and will not be offered to the model and lists the tool names under tools. The condition message names the same tools. When every tool is declared, PackContentValid is True.