ViteHub is still experimental. Expect bugs and breaking changes.

OpenAPI

Expose selected OpenAPI operations as bounded Agent tools or a generated Capability CLI.

openapi() turns selected OpenAPI operationIds into bounded HTTP operations. Use it when an Agent should call a known API contract instead of a hand-written fetch() tool for each endpoint.

Attaching the Capability is the opt-in. Channel, customer, or tenant admission belongs in access(), Agent Trigger routing, or separate Agent Definitions, not in openapi().

Installation

Import the Capability factory from @vite-hub/agent/capabilities and add it to defineAgent({ capabilities }).

server/agents/support.ts
import { defineAgent } from '@vite-hub/agent'
import { access, openapi } from '@vite-hub/agent/capabilities'

export default defineAgent({
  driver: { model },
  capabilities: [
    access({
      chat: {
        resolve({ invoker }) {
          return invoker.kind === 'portal'
        },
      },
    }),
    openapi({
      spec: 'https://portal.example.com/_openapi.json',
      operations: ['portalProductSearch', 'portalPurchaseOrders'],
    }),
  ],
})

What it adds

By default, openapi() creates one model-facing tool per selected operation. Each tool uses the OpenAPI request path, query parameters, request body schema, operation summary, and response parser.

When cli is set, ViteHub replaces those operation tools with one Capability CLI tool. The generated CLI has one subcommand per selected operation and can also run through vitehub agent dev --cli.

Select operations

Always pass the operation allowlist directly. ViteHub does not expose every operation by default.

server/agents/support.ts
openapi({
  spec: 'https://billing.example.com/openapi.json',
  operations: ['billingListCustomers', 'billingGetInvoice'],
})

Unsupported HTTP methods are ignored unless the operation is selected. In v1, selected operations can use GET, HEAD, or POST.

Configure requests

ViteHub derives the request server from the OpenAPI document by default:

  1. servers[0].url
  2. the OpenAPI spec URL origin

Use request.onRequest for runtime auth, cookies, tenant values, body additions, query additions, and timeout changes. The hook receives the selected operation, Agent Capability context, visible model input, and a mutable draft request.

server/agents/support.ts
openapi({
  spec: 'https://portal.example.com/_openapi.json',
  operations: ['portalProductSearch', 'portalPurchaseOrders'],
  request: {
    hidden: {
      body: ['cubeToken'],
      path: ['tenantId'],
    },
    async onRequest({ context, operation, request }) {
      const session = context.get<{
        cubeToken: string
        tenantId: string
        token: string
      }>('portalSession')
      if (!session) throw new Error('Portal session missing.')

      request.headers.set('authorization', `Bearer ${session.token}`)
      request.path.tenantId = session.tenantId

      if (operation.id === 'portalPurchaseOrders') {
        request.body = {
          cubeToken: session.cubeToken,
          ...(request.body as Record<string, unknown> | undefined),
        }
      }
    },
  },
})

request.hidden removes host-supplied fields from the model-facing tool schema and generated Capability CLI input schema. Use it only for fields the host supplies inside onRequest.

For a broken, missing, or environment-neutral servers entry, use server as an override escape hatch. server can also be a callback when the override comes from the current Agent Invocation context.

server/agents/support.ts
openapi({
  spec: './openapi.json',
  server: 'https://preview.example.com/api',
  operations: ['listCustomers'],
})

Generate a Capability CLI

Use cli when agents and developers should call the same operation catalog through a command-shaped surface.

server/agents/support.ts
openapi({
  spec: 'https://billing.example.com/openapi.json',
  operations: ['billingListCustomers', 'billingGetInvoice'],
  cli: {
    name: 'billing',
    description: 'Inspect live billing API data.',
  },
})

Run the generated CLI through the Agent Dev Loop.

Terminal
pnpm vitehub agent dev --url http://localhost:3000 --agent support --cli billing -- list-customers --json

Shape responses

Use transformResponse when the raw API response contains transport fields or verbose provider-specific rows.

server/agents/support.ts
openapi({
  spec: 'https://billing.example.com/openapi.json',
  operations: ['billingGetInvoice'],
  transformResponse(response, { operation, response: http }) {
    return {
      operationId: operation.id,
      status: http.status,
      data: response,
    }
  },
})

Migrate from the old shape

Old optionNew shape
enabledAttach openapi() only to Agents that should have the ability. Use access(), Agent Trigger routing, or separate Agent Definitions for channel or customer gating.
operations: { allow: [...] }operations: [...]
baseUrlUse the OpenAPI servers entry. Use server only when the spec has no usable server.
headersSet headers in request.onRequest.
defaultsMutate request.body, request.path, or request.query in request.onRequest.
input.omitUse request.hidden for host-supplied fields that request.onRequest fills.

Driver support

Agent DriverSupport
Model-backedReceives selected OpenAPI tools, or one generated Capability CLI tool when cli is set.
Harness-backedRuntime requirements apply; model-facing OpenAPI tools are not passed by default.
Custom-run-backedReceives prepared context; driver.run decides whether to call API operations directly.

Options

OptionTypeDefaultDescription
specstring | URL | object | functionrequiredOpenAPI document URL, inline document, or invocation-scoped document resolver.
operationsreadonly string[]requiredSelected OpenAPI operationIds exposed by this Capability.
requestfunction | { hidden, onRequest }noneFetch-style request preparation hook for runtime headers, cookies, path, query, body, and timeout values.
request.hidden{ body?, path?, query? }noneFields removed from model and generated CLI input because the host supplies them in onRequest.
serverstring | URL | functionOpenAPI serverOverride escape hatch for specs without a usable servers[0].url or spec URL origin.
clifalse | { name, description? }falseGenerates a Capability CLI instead of one model-facing tool per operation.
responseType"json" | "text""json"Response parser for operation results.
transformResponse(response, context) => outputnoneMaps parsed operation responses before returning them to the Agent.
specHeadersRecord<string, string>noneHeaders used only when fetching the OpenAPI document.
timeoutnumbernoneDefault request timeout in milliseconds.

Reference

Copyright © 2026