Skip to Content
AgentCapability YAML

Capability YAML

capability.yaml is the agent-side source of truth. It defines what can be called, what input is accepted, what SQL is executed, and which output columns may leave the database boundary.

Structure

service: title: Example CRM Capabilities version: 0.1.0 description: Agent-defined capabilities for a legacy CRM database. runtime: max_concurrent_requests: 16 gateway: url: "wss://customer-abc.example.com/ws/agent" agent_private_key: "base64url-ed25519-private-key" database: driver: postgres host: localhost port: 5432 name: legacy_db user: readonly_user password: "" tls: mode: verify-full ca_file: /etc/onprest/db-ca.pem cert_file: /etc/onprest/db-client.pem key_file: /etc/onprest/db-client-key.pem server_name: db.internal.example.com logging: max_size: 10MB max_files: 3 defaults: readonly: true timeout: 30s max_rows: 1000 max_bytes: 1MB capabilities: get_customer: description: "Fetch one customer by id" sql: select id, name, email from customers where id = :customer_id params: customer_id: type: integer required: true minimum: 1 description: "Customer ID" policy: readonly: true timeout: 5s max_rows: 1 max_bytes: 256KB expose_in_openapi: true result: id: type: integer description: "Customer ID" name: type: string description: "Customer name" email: type: string description: "Email address"

Top-Level Sections

SectionPurpose
serviceOpenAPI info metadata
runtimeagent request execution limits
gatewaygateway WebSocket URL and agent private key
databaseDB driver and connection settings
loggingagent local detail log rotation settings
defaultsdefault policy values used by capabilities
capabilitiesexternally callable operations

Supported database drivers are postgres, mysql, sqlserver, and oracle.

Capability names must match ^[a-zA-Z][a-zA-Z0-9_.-]{0,127}$.

Descriptions

description fields are optional but recommended. They are public metadata used to make generated OpenAPI and MCP tools understandable to API users and AI agents.

Descriptions do not grant permissions, change validation, affect SQL execution, or bypass policy / result enforcement. Security behavior is defined by capability names, API key authorization, params validation, policy, SQL, and result allow-lists.

LocationRequiredPurpose
service.descriptionNoOpenAPI service-level documentation
capabilities.<name>.descriptionNoCapability / operation / MCP tool description
params.<name>.descriptionNoPublic input parameter documentation
result.<column>.descriptionNoPublic output field documentation

For AI/MCP use, write descriptions as stable business-facing contract text. Do not put secrets, internal-only incident detail, DB credentials, or sensitive operational notes in descriptions because they can appear in OpenAPI and MCP metadata.

Service

service provides the OpenAPI info metadata for the generated spec. All fields are optional.

FieldRequiredDefaultDescription
titleNoOnprest AgentOpenAPI service title
versionNo0.1.0OpenAPI service version
descriptionNoemptyOpenAPI service-level documentation

When title or version is empty, the agent fills in the default shown above at startup.

Runtime

FieldRequiredDefaultDescription
max_concurrent_requestsNo16Maximum capability requests executed concurrently on one gateway connection

The value must be a positive integer. The agent has the same number of bounded waiting slots in addition to the running slots. Waiting requests do not reach the database early, and the WebSocket reader continues processing ping/pong while the execution limit is saturated. If both running and waiting slots are full, the request fails with AGENT_BUSY instead of growing memory without a bound. One response writer sends WebSocket frames in sequence. Once a frame write starts, it must finish within five seconds; this is not a query timeout or a limit on time spent waiting for the writer. Higher values can increase throughput but also increase simultaneous database work and connection-pool demand. Unknown YAML fields and multiple YAML documents are rejected at startup so a misspelled limit cannot silently fall back to 16. Restart the agent to apply a change.

Gateway

FieldRequiredDescription
urlYesGateway WebSocket URL, usually ending in /ws/agent
agent_private_keyYesbase64url Ed25519 private key generated by onprest-gateway create-agent-secret
allow_insecure_non_loopback_wsNoDevelopment-only acknowledgement for non-loopback ws://; defaults to false and must remain false in production

url must use the exact /ws/agent path without credentials, a query, or a fragment. Non-loopback addresses require wss:// unless the development-only insecure acknowledgement is explicitly enabled. Loopback ws://localhost, ws://127.0.0.1, and ws://[::1] remain available for local development.

Database

FieldRequiredDescription
driverYespostgres, mysql, sqlserver, or oracle
hostYesDB hostname or IP address
portYesDB port
nameYesDatabase, service, or schema name used by the driver
userYesDB username
passwordNoDB password; keep this only on the agent side
tls.modeNoTLS mode described below; defaults to disable
tls.ca_fileNoPEM CA certificate used to verify the DB server
tls.cert_fileNoPostgreSQL PEM client certificate for mutual TLS
tls.key_fileNoPostgreSQL PEM client private key; required together with cert_file
tls.server_nameNoSQL Server certificate hostname override; otherwise host is verified

TLS support is driver-specific:

DriverSupported tls.modeBehavior
PostgreSQLdisable, require, verify-ca, verify-fullUses lib/pq TLS settings. Set ca_file for a private CA; client certificate and key are optional but must be supplied together.
SQL Serverdisable, require, verify-fullrequire encrypts while trusting the presented server certificate. verify-full verifies the certificate trust chain plus server_name or host; set ca_file for a private CA.
MySQL / Oracledisable onlyNon-disabled TLS is rejected at startup; this avoids silently pretending that the generated connection is verified.

Do not set TLS CA, certificate, key, or server-name fields when mode: disable. cert_file and key_file are PostgreSQL-only; server_name is SQL Server-only. Prefer a verified mode on networks where the database connection can be intercepted.

Logging

FieldDefaultDescription
max_size10MBSize threshold for rotating the local detail log
max_files3Number of rotated files to retain

max_size accepts a non-negative integer followed by an optional B, KB, MB, or GB suffix, such as 10MB. A bare integer is treated as bytes. Fractions, unknown suffixes, trailing text, and values that overflow int64 are rejected.

The local detail log path is the agent executable path plus .log, for example onprest-agent.log.

Defaults

defaults is optional. It supplies policy defaults for capabilities, and each capability’s own policy values take precedence.

If neither defaults nor capability policy sets a value, the implementation defaults are:

FieldDefault
readonlytrue
timeout5s
max_rows100
max_bytes1MB
expose_in_openapitrue

Capabilities

Each entry under capabilities defines one externally callable operation. At least one capability is required; the agent rejects a file with no capabilities at startup.

FieldRequiredDescription
descriptionNoPublic operation text used by OpenAPI and MCP tools
sqlYesSQL executed by the agent after validation
paramsNoInput contract; unknown provided params are rejected
policyNoExecution limits; missing values use defaults or implementation defaults
resultNoOutput allow-list; omitted result means row object fields are not returned

Params

params defines the input contract.

FieldDescription
typestring, integer, number, or boolean
requiredwhether the caller must provide the value
defaultvalue applied when omitted
enumallowed values
minimum / maximumnumeric bounds
minLength / maxLengthstring length bounds
patternregular expression
formatone of email, uuid, date, date-time, uri
descriptionpublic documentation text

Unknown params are rejected.

minimum and maximum are integer-valued bounds and apply to integer and number params. JSON integer tokens are converted exactly through signed 64-bit integers, including values above JavaScript’s 2^53 precision boundary; fractional and int64-overflow values are rejected. number also rejects non-finite values.

format accepts only the five values listed above; any other value is rejected at startup. minLength and maxLength must be 0 or greater, and minLength must not exceed maxLength.

Policy

policy limits execution.

FieldDescription
readonlytrue accepts one statement beginning with SELECT, including nested SELECT subqueries
timeoutexecution timeout, such as 5s
max_rowsmaximum rows returned
max_bytesmaximum response size, such as 256KB
expose_in_openapiwhether to include the capability in OpenAPI and MCP tools/list

Use read-only DB users for read capabilities. YAML policy is an application guard; DB privileges should still enforce least privilege.

timeout accepts a Go duration string such as 5s or 500ms. max_bytes uses the same exact non-negative integer byte-size grammar as logging.max_size.

When readonly is true, startup lint rejects another statement after the first, such as SELECT 1; UPDATE customers SET .... One trailing semicolon is allowed. Quote scanning follows the configured driver: ordinary SQL strings use doubled quotes and never treat backslash as a quote escape; PostgreSQL explicit E'...' strings support backslash escaping; PostgreSQL dollar quotes, SQL Server bracket identifiers, MySQL backticks, and Oracle alternative q'...' quotes are recognized. This conservative rule also prevents SELECT '\'; UPDATE ... from bypassing lint when a server or SQL mode treats the backslash literally. Statements beginning with WITH are rejected, including read-only CTEs. timeout, max_rows, and max_bytes are enforced during capability execution.

Result Allow-List

result is the output allow-list.

  • Columns not listed in result are removed from the response.
  • If SQL does not return a column listed in result, execution fails.
  • If result is omitted, row object fields are not returned.
  • Even with SELECT *, only result-listed columns can leave the agent boundary.

This is the final guard that prevents accidental exposure of extra columns.

Supported result column types are string, integer, number, and boolean.