Skip to content

Configuration reference

This page lists every setting of the runtime, the configuration file, and the tool servers functions may call. The runtime reads its settings once, when it starts. Change a setting, then restart the server.

How settings are read

  • Every setting is an environment variable. Keys and other secrets go in the environment alone.
  • A container takes its variables from its platform, or from a file of them with docker run --env-file.
  • npx @on.auto/runtime also reads .env in the folder it starts in. A variable set in the shell wins over .env.
  • Settings that are lists or maps can also go in a YAML configuration file: model_gateways, model_aliases, declared_models, allowed_models, tool_servers, connections, api_keys and allowed_origins.
  • CONFIG_FILE names that file. npx @on.auto/runtime reads auto-runtime.yaml in the folder it starts in when it is there, unless .env or the shell sets CONFIG_FILE. A container reads a file only when CONFIG_FILE names it, as Use a configuration file shows.
  • Each key of the file stands for the environment variable of the same name in upper case. A variable that is set wins over the key, whole: MODEL_GATEWAYS replaces the file's model_gateways, and the two are not merged.
  • Precedence, highest first: the shell, .env (with npx), the configuration file, the default.
  • At start, the server logs which settings it read from the file, and which of them the environment set too.
  • A value the server cannot read stops it at start. The message names the setting and what it expects, and never the value.

Write the configuration file

Copy auto-runtime.example.yaml to start one. auto-runtime.schema.json is the file's JSON Schema, so an editor with the YAML language server completes and checks it.

yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/BeOnAuto/runtime/main/auto-runtime.schema.json
model_gateways:
  - name: gateway
    base_url: https://gateway.example.com/v1
    api_key: ${GATEWAY_API_KEY}
model_aliases:
  anthropic/*: gateway/anthropic/*

A secret is never written in the file. The file refers to the variable that holds it:

  • ${NAME} takes the value of the variable NAME;
  • ${NAME:-default} takes default when NAME is not set;
  • $$ stands for a literal $.

The server stops at start with one line that names the file, the line, the column and the key, never a value, when:

  • it cannot use the file;
  • the file holds a key the server does not know;
  • a value is one its setting refuses;
  • a reference names a variable that is not set;
  • a credential is written out instead of referenced.

A value counts as a credential written out when:

  • its key names a credential, such as api_key, Authorization, client_secret, password or token, and it holds no reference. credential_kinds of the connections section names sorts of credential and not one, so its values are judged by their shape alone;
  • the text written out in it has the shape of one, such as Bearer ..., an sk-... provider key or an abk_... API key;
  • it is a URL with a password, whose user or query value has that shape, or whose query names a parameter as a key that names a credential does, such as ?api_key=..., and holds no reference there;
  • it is an argument whose part after its = has that shape.

Inside an argument, only the value is judged, never the name the argument gives it.

What to set for what

To useSetSee
A provider's own APIANTHROPIC_API_KEY, OPENAI_API_KEY or GOOGLE_GENERATIVE_AI_API_KEYDirect API keys
An OpenAI-compatible gatewaymodel_gateways in the file, a list whose name becomes the prefix, gateway/<model>A gateway
Amazon BedrockAWS_REGION, with the AWS default credential chainBedrock
Azure OpenAIAZURE_RESOURCE_NAME and AZURE_API_KEYAzure
Google Vertex AIGOOGLE_VERTEX_PROJECT and GOOGLE_VERTEX_LOCATIONVertex
Your own names for modelsmodel_aliases in the fileModel aliases
Another provider's models, through your gatewaymodel_aliases: {anthropic/*: gateway/anthropic/*} in the fileModel aliases
The models listed for Bedrock, Azure or Vertexdeclared_models in the file, a list of model ids for each provider prefixDeclared models
Only some modelsallowed_models in the file, such as [anthropic/*, gateway/llama-3.3-70b]Allowed models
An outbound proxy or a private certificate authorityNODE_USE_ENV_PROXY=1, HTTPS_PROXY and NODE_EXTRA_CA_CERTSProxy and CA
The ledger in Amazon RDS without a database passwordDATABASE_URL without a password and DATABASE_CREDENTIALS=aws-iamWithout a password
Secrets sealed under a key of your ownSECRETS_KEY, and SECRETS_KEY_PREVIOUS while it replaces anotherSecrets at rest
Content kept in an object store instead of the ledgerCONTENT_STORE_URL, an s3://bucket/prefix URLObject storage
Tools that functions may calltool_servers in the file, each entry's allowed to allow only some of its toolsTool servers
People who sign in through the Auto identity servicePUBLIC_URL, which turns sign-in on, and IDENTITY_ISSUER for a development instance of the serviceLet people sign in
Machines and pipelines that call the APIAPI_KEYS, with an entry the key command prints for eachAPI keys
The requests interaction functions may keep openINTERACTION_OPEN_REQUESTSInteraction functions
The model processes and the builds of prediction functionsPREDICTION_PROCESSES, PREDICTION_PROCESS_MEMORY, PREDICTION_BUILDS_AT_ONCE, PREDICTION_BUILDS_PER_DAY and PREDICTION_MAX_FUNCTIONSPrediction functions
The folder prediction functions keep model files inPREDICTION_CACHE_DIRPrediction functions

list_models (GET /v1/orgs/{org}/models, and the MCP tool of the same name) shows the models the server can call, leaving out what allowed_models does not allow. Listing the models sets out how it builds the list, and Allowed models what a definition that names a model outside allowed_models returns.

Settings

Every setting is an environment variable. The tables below group them by area.

Server and logs

VariableDefaultPurpose
PORT5555The port the server listens on
HOST0.0.0.0 in the image, 127.0.0.1 with npxThe interface the server binds to. On a loopback address with neither PUBLIC_URL nor API_KEYS, the server is in local mode. On any other address it needs one of them to start
CONFIG_FILEnone; auto-runtime.yaml with npx when it is in the folderThe configuration file, absolute or relative to the working directory
LOG_FORMATjson, console with npxjson: one JSON object per line on stderr. pretty: lines of text for a person. console: a time, a mark for the level and the message, in color at a terminal
LOG_LEVELinfo, error with npxThe least level logged: debug, info, warn or error

Sign-in and access

Authentication and security sets out how these work together.

VariableDefaultPurpose
PUBLIC_URLnoneThe URL at which callers reach the runtime. Set, it turns sign-in through the Auto identity service on, and every access token names it as its audience. Let people sign in gives the URLs it accepts
IDENTITY_ISSUERhttps://clerk.on.autoThe identity service that people sign in through, an https URL with no path, query or fragment. A development runtime names the development instance of the service
API_KEYSnoneThe API keys the server accepts, as a compact JSON array of the entries the key command prints; api_keys in the file. See API keys
ALLOWED_ORIGINSnoneComma-separated origins a browser page may call the API from, besides Auto Studio's; allowed_origins in the file. See Calling from a browser

Storage

VariableDefaultPurpose
LEDGER_FILEdata/ledger.db, which in the image is on the /data volume; ~/.auto-runtime/ledger.db with npxThe SQLite file of the ledger, absolute or relative to the working directory. Its folder is created when missing
DATABASE_URLnoneA PostgreSQL URL. When set, the ledger is kept in that database instead, and setting LEDGER_FILE too stops the server at start. Environment only, since it holds a password. See Use PostgreSQL
DATABASE_CREDENTIALSurlHow the server signs in to that database: url, with the password the URL holds, or aws-iam, with a token signed for each connection. See Without a password, on Amazon RDS
SECRETS_KEYsecrets.key beside a SQLite ledger file, made at the first startThe key the secrets kept in the ledger's database are sealed under: the base64 of 32 random bytes, as openssl rand -base64 32 prints it. Without it, a SQLite ledger keeps a key in that file, which only its owner may read. A ledger in PostgreSQL needs it, and a container sets it. The server also derives from it the key that signs the state an MCP client sends back when it retries a call, so every server that shares it answers that retry. Environment only. See Secrets at rest
SECRETS_KEY_PREVIOUSnoneThe key that SECRETS_KEY replaces, in the same form and only beside it. At start the server reads with it what it sealed and seals that again under SECRETS_KEY, after which it can go. While it is set, the server also answers the retry of an MCP call whose state a server signed under the key it replaces. See Rotate the secrets key
CONTENT_STORE_URLnoneAn s3://bucket/prefix URL. When set, content is kept in that bucket instead of the ledger's database. Content kept before a change is not moved; see Keep content on object storage

Models

Reasoning functions call language models with these settings, all optional. Set up a model provider says which to set for what, and how to check them in the start-up line. A provider whose settings are absent is not configured, and a definition that names it is rejected as unavailable when it runs. The model settings reference holds the rules for the lists and maps below.

VariablePurpose
ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URLAnthropic (anthropic/...)
OPENAI_API_KEY, OPENAI_BASE_URL, OPENAI_APIOpenAI (openai/...). OPENAI_API=chat_completions for endpoints without the Responses API
GOOGLE_GENERATIVE_AI_API_KEYGemini API (google/...)
AWS_REGION, AWS_BEARER_TOKEN_BEDROCK, AWS_ENDPOINT_URL_BEDROCK_RUNTIME, AWS_ENDPOINT_URLAmazon Bedrock (bedrock/..., bedrock-anthropic/...), with the AWS default credential chain
AZURE_RESOURCE_NAME or AZURE_BASE_URL, AZURE_API_KEY, AZURE_API_VERSIONAzure OpenAI (azure/...). Without a key, Microsoft Entra ID, in an image built with --build-arg AZURE_IDENTITY=true
GOOGLE_VERTEX_PROJECT, GOOGLE_VERTEX_LOCATIONVertex AI (vertex/..., vertex-anthropic/...), with Google application default credentials
MODEL_GATEWAYSA list of OpenAI-compatible gateways, each its own provider prefix; model_gateways in the file
MODEL_ALIASESA map from one model reference to another. A trailing * on both sides covers every model of a provider; model_aliases in the file
DECLARED_MODELSThe models list_models shows for a provider that does not list its own, and for a gateway whose list cannot be read, by provider prefix; declared_models in the file
ALLOWED_MODELSThe only model references a definition may give, by name or through an alias, and that list_models shows; every model when not set; allowed_models in the file
NODE_USE_ENV_PROXY, HTTPS_PROXY, NO_PROXY, NODE_EXTRA_CA_CERTSNode's own switches for an outbound proxy and a private certificate authority
REASONING_MAX_INPUT_TOKENSThe most input tokens the model calls of one run of a reasoning function may add up to, from 10,000 to 9,999,999, 2,000,000 unless set. Past it, the model replies from what it has, without its tools

Workflows

Workflow storage and failover sets out how the server uses these.

VariableDefaultPurpose
WORKFLOW_MAX_DURATIONP30DThe most a run may last, an ISO 8601 duration from PT2H to P365D
WORKFLOW_NESTED_RUNS32How many calls the server runs at once, from 1 to 1000, shared by every org
WORKFLOW_MAX_OPEN_CALLS1000How many calls may wait under one run at the top of a tree, from 1 to 9999
WORKFLOW_SWEEP_INTERVALPT1SHow often the server checks its waiting runs (a sweep), an ISO 8601 duration from PT0.01S to PT1M

Telemetry

OTEL_EXPORTER_OTLP_ENDPOINT turns telemetry on, and TELEMETRY_CONTENT=true records content. Send telemetry lists these and the other OTEL_ settings the server reads. Each is read from the environment only.

Computation and recall functions

Each run of a computation function, and each run and view of a recall function, runs in a worker thread the server keeps between runs.

  • The server never keeps more workers alive than COMPUTATION_WORKERS.
  • It folds the views of recall functions in at most half of the workers at once, and at least one.
  • It ends a worker after a run that ran past its time, used too much memory, was cancelled or broke.
  • It also ends a worker after its thousandth run, and after a minute without one.
  • A worker has a stack of 64 MiB and is stopped when its heap grows past 256 MiB. Plan memory sizes them.
VariableDefaultPurpose
COMPUTATION_WORKERS4The most worker threads the server keeps, and so the most runs it takes at once, from 1 to 64. A run that finds none free within 10 seconds is unavailable
RECALL_MAX_FUNCTIONS32How many active recall functions a playbook may keep, from 1 to 1000. Lowering it below what a playbook already keeps refuses only that playbook's saves
RECALL_MAX_REBUILDS4How many views of one playbook are built at once, from 1 to 64. The others wait in the order they were saved
RECALL_PLAYBOOKS_AT_ONCE4How many playbooks the server folds at once, from 1 to 64

Interaction functions

An interaction function needs nothing configured beyond its tool server in tool_servers. It does one of these:

  • calls the tool it names under call, and returns its result;
  • sends its request through the tool it names under deliver;
  • leaves its request in the playbook's inbox.

It may also read the replies to what it sent through another tool of that server.

  • The entry's allowed names the tools its functions may use. It is checked again at every call, every attempt and every read.
  • The entry's record_content, on unless the entry turns it off, keeps what they send and what the tool returns.
VariableDefaultPurpose
INTERACTION_OPEN_REQUESTS10000The most requests a playbook may have open at once, from 1 to 1,000,000. A run past it is unavailable with the kind requests_full

Prediction functions

A prediction function's content is kept by the playbook: its uploaded datasets, the rows and the brief of each build, and the model file each version holds. That content is in the ledger's database or, with CONTENT_STORE_URL, in the object store, where a build's candidates are also staged until the build ends.

Its model processes load models and read a build's rows from files the server keeps on its own disk. The server writes a file again from the playbook's content whenever one is missing, so the folder needs no volume and loses nothing when it is emptied.

Each setting is read with its range and logged at start. A value outside its range stops the server at start, naming the setting. Plan memory sets out how much the processes take.

VariableDefaultPurpose
PREDICTION_MAX_FUNCTIONS32The most active prediction functions a playbook may keep, from 1 to 1,000. A save past it is refused
PREDICTION_PROCESSES4The most model processes that run at once, from 2 to 64
PREDICTION_PROCESS_MEMORY1280The data each model process may reserve, in MiB, from 768 to 16,384. A process that reaches it is ended, and its job ends out of memory
PREDICTION_BUILDS_AT_ONCE2The most builds the server scores at once, from 1 to 63, and below PREDICTION_PROCESSES so that a question always finds a process. A build past it is unavailable with the kind builds_full
PREDICTION_BUILDS_PER_DAY4The most builds a prediction function may ask in the trailing 24 hours, from 1 to 100. A build past it is unavailable with the kind builds_full and the because field builds_of_the_day
PREDICTION_CACHE_DIR/var/tmp/auto-runtimeThe absolute path of the folder the model files are kept in

The folder of PREDICTION_CACHE_DIR follows these rules:

  • At start, the server creates the folder when it is missing, readable only by its own user, and does the same for each folder within it.
  • It refuses to start, naming the setting, when the folder cannot be made, belongs to another user, or other users may write to it. A folder another user may write to would let that user change a model before it is loaded.
  • The files found in the folder at start are read again, and kept only when their bytes match the digest in their name.
  • Each server keeps at most 1 GiB of model files and 1 GiB of rows, by its own count. Give two servers on one machine a folder each.

Tool servers

A tool server gives functions tools to call. It comes from one of two places: an entry under tool_servers in the configuration file, which this section describes, or a connection a person added to an org. Add an entry under tool_servers; TOOL_SERVERS, the same list as JSON, wins over it. Add a tool server walks through adding one and checking it.

  • A reasoning function that lists tools calls the tools of these servers.
  • An interaction function calls the tool it names in call, or sends its request through the tool it names in deliver.
  • The key of an entry is the name a function writes in server/tool. Nothing in a function says which kind of server it names.

Each entry is one of three types. When type is left out, it is taken from the field that names the server:

TypeNamed byWhat it is
mcpurlA remote MCP server, spoken to over Streamable HTTP
stdiocommandAn MCP server the runtime runs as a process
openapidocumentAn HTTP API described by an OpenAPI document, 3.0 or 3.1, read once at start. Each of its operations is one tool
yaml
tool_servers:
  graph:
    url: https://gateway.example.com/mcp
    headers:
      Authorization: Bearer ${GRAPH_API_KEY}
    org: acme
    playbooks: [sales, support]
    allowed: [search, introspect, validate, dry_run, execute]
  notes:
    command: /usr/local/bin/notes-mcp-server
    args: [--read-only]
    env:
      PATH: /usr/local/bin:/usr/bin
      NOTES_API_KEY: ${NOTES_API_KEY}
    org: acme
  billing:
    document: https://billing.example.com/openapi.json
    base_url: https://billing.example.com/v2
    security:
      apiKeyAuth: ${BILLING_API_KEY} # the scheme the document declares under components.securitySchemes
    headers:
      X-Tenant: acme-eu # outside the document's schemes
    org: [acme, globex]
    allowed: [listInvoices, getInvoice]

Fields of an entry

FieldForWhat it holds
typeevery typemcp, stdio or openapi. Taken from url, command or document when left out
urlmcpThe server, spoken to over Streamable HTTP
headersmcp, openapiHeaders sent with every request. For an mcp server, its credential. For an openapi server, only what its document's security schemes do not place, such as a tenant. The value of a reference is a secret; a value written out is not
authmcp, openapiOAuth client credentials instead of a header: issuer, client_id, client_secret or private_key with algorithm, and scope. For an openapi server, what satisfies the document's oauth2 and openIdConnect schemes; refused when it declares neither. See Sign in to a server with OAuth
commandstdioAn installed, pinned command, started when a run or a listing first needs it and stopped with the server
argsstdioIts arguments
envstdioIts whole environment. The value of a reference is a secret; a value written out is not. It inherits nothing else from the server, so give PATH or an absolute command
documentopenapiThe OpenAPI document of the API, 3.0 or 3.1, in JSON or YAML: an https URL, an http URL on a loopback address, or a path relative to the directory of this file that stays inside it
base_urlopenapiThe URL the calls go to, in place of the first server the document names. Required when the document names none or names it relative to a file. An https URL, or an http URL on a loopback address
query_paramsopenapiQuery parameters sent with every call that the document's security schemes do not place, such as a tenant. The value of a reference is a secret; a value written out is not
securityopenapiThe credential for each of the document's security schemes that the entry gives, by the scheme's name, placed where the scheme says. Always a reference, such as ${BILLING_API_KEY} or ada:${BILLING_PASSWORD}. See The credentials of an HTTP API
orgevery typeRequired. The org whose functions may use the server, a list of orgs, or * for every org of the runtime. One entry serves each org under one name, with one credential and one connection, and each org sees the same tools
playbooksevery typeThe playbooks that may use it within each org it names, by id, the same list in each. Every playbook of each org when left out. Refused beside *, since a playbook id belongs to one org
allowedevery typeThe tools of the server that a function may name and that a call made by hand with execute may call, each named as the server lists it, without the server's name and without *. Every tool of the server when left out
record_contentevery typeWhether the arguments and results of calls are kept whole, scrubbed of secrets, in the playbook's ledger, where anyone who may read the playbook reads them. true when left out; false keeps their sizes alone
request_idevery typeThe response header, or for an MCP server the key of a result's metadata, in which the server returns its own id of a request, recorded with each call

Keep secrets out of the file

Only headers, query_params, security, env and auth may hold a reference. A reference in url, command, args, document or base_url stops the server at start: an argument shows in the machine's list of processes, and the URL of a server or of a document is no place for a credential.

A secret is one of these, and nothing else:

  • a value a ${NAME} reference takes from the environment;
  • a credential of an auth block;
  • a token minted from one.

A value of security, which always holds a reference, is a secret as a whole, and so is the value of its reference. A header whose reference takes a scheme and a credential, such as Authorization: ${GRAPH_HEADER} with GRAPH_HEADER set to Bearer <key>, is a secret whole, and so is the credential after its scheme, <key>, so it is scrubbed where a server echoes the key alone. Each secret counts once, however many places hold it. A header written out, such as X-Region: production-eu, is not a secret, so it is never scrubbed.

The server scrubs every secret from every message, event and result:

  • as written;
  • inside JSON, where a quote, a backslash or a line break in it is escaped;
  • as an address carries it, form-encoded in a query and percent-encoded in a path;
  • in base64, as a Basic credential carries it.

There is one exception: a value shorter than 8 characters is not scrubbed, since scrubbing it would erase ordinary words. Give a server a key at least that long.

One set of secrets serves all the tool servers, for runs and for calls made by hand with execute alike, so a token minted for a run is scrubbed from a call made by hand too. A minted token is scrubbed until the token after the one that replaces it is minted, since a call in flight as a token is renewed may still carry the one before it in a result recorded a moment later.

Run a server as a process

  • Write command as an installed program. Never use a package downloaded at start, such as npx -y, which would run whatever that package is the day the process starts. The MCP entry of the quick start is the one exception: it is Auto Runtime itself, pinned to one release, and you choose when to move it to another.
  • The process runs under the server's user.
  • env is the process's whole environment, so give it PATH or write command as an absolute path.

Sign in to a server with OAuth

An auth block gives an mcp or openapi server OAuth client credentials instead of a header.

  • The server mints tokens from the client credentials, once for every run that needs one.
  • It renews them before they expire, and mints once more when the server responds with 401.
  • It sends the credentials only to an authorization server whose metadata names the issuer.
  • An mcp server's authorization server is found through the server's own protected-resource metadata.
  • An openapi server's authorization server is the issuer itself. Its metadata is read by OAuth authorization server metadata or OpenID Connect discovery, since an HTTP API publishes none of its own.

The credentials of an HTTP API

Give an HTTP API's credential under security, by the name of the security scheme its document declares. The server places it as the scheme says.

An OpenAPI document declares its security schemes under components.securitySchemes, each saying where its credential goes. Each operation names the schemes it requires under security, or takes the document's own security when it names none.

SchemeWhat security givesWhat a call sends
apiKey in a headerthe keythe scheme's header
apiKey in the querythe keythe scheme's query parameter
http with the scheme bearerthe tokenAuthorization: Bearer <token>
http with the scheme basicuser:passwordAuthorization: Basic and their base64
oauth2 or openIdConnectnothing: the entry's auth blockthe token the block mints, as a bearer

Use security for what the document's schemes describe, and headers and query_params for what they do not, such as a tenant.

Which credentials a call sends:

  • A requirement is a list of alternatives. Each alternative is a set of schemes that must all be given.
  • An operation is offered as a tool when the entry gives one of its alternatives.
  • A call sends the credentials of the first alternative the entry gives, in the document's order, and no other.
  • An operation whose requirement is empty, or of a document that declares none, sends none.
  • An operation for which the entry gives none of the alternatives is not offered as a tool. At start, the server logs a warning that names the schemes it needs.
  • The scopes an oauth2 requirement names are the operation's. The auth block asks for its own scope, so set it to cover what the operations require.

The server stops at start, naming the entry, when:

  • a name under security is not a scheme the document declares;
  • a name under security is an apiKey the document places in a cookie;
  • a name under security is an http scheme other than bearer and basic;
  • a name under security is a mutualTLS scheme;
  • a name under security is an oauth2 or openIdConnect scheme with a value, since the credential for those schemes comes from the auth block;
  • a basic value is not user:password;
  • headers or query_params holds a header or query parameter that a scheme given under security also places;
  • an entry has an auth block, and its document declares no oauth2 or openIdConnect scheme.

How an HTTP API becomes tools

At start the server reads each openapi entry's document: at most 4 MiB and 500 operations, within 10 seconds. It stops, naming the entry, when:

  • it cannot read the document;
  • the document's URL responds with a redirect, which the server does not follow;
  • the document is Swagger 2.0, or of another version than 3.0 or 3.1;
  • a part it reads is not of the shape the specification gives it (the message names the place in the document);
  • two operations would share a tool name;
  • a path does not begin with /, which would join the host or the port of base_url;
  • a path holds a . or .. segment, a ? or a #;
  • its tools take more than 16 MiB when listed;
  • a reference does not resolve inside the document. This includes a reference to an http, https or file address, which the server never fetches;
  • its calls would have nowhere to go: no base_url and no server, or a server that is neither https nor on a loopback address.

Trailing slashes on base_url or on the server's URL are dropped.

Each operation becomes one tool:

  • Its name is the operationId, with any character a tool name cannot hold as _. Without one, it is the method and the path in lower case, such as get_invoices_id for GET /invoices/{id}.
  • Its description is the operation's summary and description.
  • Its input is one object: each path and query parameter by its name, and body for a JSON request body, each required when the document says so. The schemas of components they refer to are held inside it, so a function's model reads one schema whole.
  • GET and HEAD are read-only, DELETE destructive, and GET, HEAD, PUT and DELETE idempotent. So allowed, search and a run's read-only calls read an API's tools as they read an MCP server's.

Some operations are not offered as tools. At start, the server logs a warning for each operation it leaves out, naming the entry and the reason. It leaves out an operation that:

  • needs a header or a cookie;
  • takes an object in its query;
  • takes a body that is not JSON;
  • is a TRACE, or a GET or HEAD that takes a body;
  • has a path parameter of a style other than simple;
  • has a query parameter of a style other than form, or with explode: false;
  • has an input schema of more than 64 KiB.

A call:

  • fills the path and the query, with an array sent as repeated keys;
  • refuses a path argument that is empty, holds a /, or is . or ..;
  • sends nothing to an address that would leave the origin or the path of base_url;
  • sends the body as JSON, with the entry's headers and query parameters.

The response is read as the result of an MCP server's call is read, within the same bounds:

The API responds withThe call's result
JSONThe tool's structured content, and its text
TextText
Any other media typeNoted, and not shown
401A key the server refused
429Waits out a Retry-After that fits
5xxA failing server
A redirectAn error result with its status. It is not followed, so the entry's headers and token go to no address but its own
Any other response, including 404An error result carrying the API's response

Listing an HTTP API's tools asks the API nothing: the document is the list.

Limit the tools a function may use

allowed narrows what a function may name, as allowed_models narrows the models. A server's own policy remains the hard boundary.

  • A function's server/* offers exactly the tools its server's entry allows.
  • allowed is the one list of a server's tools. The five operations over the playbook's tool servers, search, introspect, validate, dry_run and execute, show and call the tools it allows and no other.

Try the tools by hand

An agent or a person can look at a server's tools, and call one, before a function names it.

  • search shows anyone who may read a playbook the entries that serve it, with the tools that each entry lets functions name. At the org level, a caller who may read every playbook of the org (with org:read or playbook:read) sees every entry that serves the org, whether the entry names the org in org or uses *. Each comes with its playbooks (["*"] when they are left out).
  • search and dry_run say whether the server marks a tool read-only (readOnlyHint).
  • search and introspect add no header, environment value, URL, command or credential of their own. What a server writes is passed on with the secrets above scrubbed out, except values shorter than 8 characters.
  • execute calls one tool as a run would, under the entry's credential, which is the playbook's. So it needs playbook:write whatever the tool does, and it is live.
  • While a tool server is configured, execute is marked destructive, so a client that honours the MCP hints asks the person before a call.
  • Every call made with execute is recorded in the playbook's history under the caller, with its content where the entry keeps it.

Tool servers in the HTTP reference sets out the routes, fields and permissions of the five tools.

What the server checks at start

The server checks every entry at start. It stops at any of these, naming the setting and the place but never a value:

  • an entry with none of url, command and document, or with more than one;
  • the fields of another type;
  • a name that is not 1 to 32 lowercase letters, digits and hyphens starting with a letter;
  • a name with two hyphens together or one at the end, which would blur where the server's name ends in the server__tool a model sees;
  • the name of a model provider or gateway;
  • a missing org;
  • a credential written out instead of referenced. This includes a password in a url, and a user, a query value or the part of an argument after its = that looks like a credential, such as --key=sk-live-.... The value is judged, never the name it is given;
  • a reference outside headers, query_params, security, env and auth;
  • a value of security written out instead of referenced;
  • an Authorization header beside an auth block;
  • a header the runtime sets itself;
  • an issuer, a base_url or a document URL that is neither https nor on a loopback address;
  • a base_url, or a first server of a document, with a query or a fragment;
  • a document path that leaves the directory of this file;
  • in allowed, an empty list, a name listed twice, a *, or a name that is not a tool name of 1 to 128 letters, digits, underscores, hyphens and dots (such as graph/search).

An unknown key in an entry is refused, like any other unknown key.

The server does not connect to an MCP server or start a process until a run needs one, or until search, introspect, validate, dry_run or execute asks it for its tools. The servers' messages, a process's output on stderr and every failed call go to the server's log, scrubbed of the entry's secrets.

Connections

A connection is a tool server that a person adds to an org through their agent, which every playbook of the org may use, or the playbooks it names; a function names it by name/tool as it names an entry of tool_servers, and calls it in the same way. Let people add connections sets out how a person adds and approves one, and what a connection that is not ready answers. The connections section of the configuration file says what people may add; CONNECTIONS, the same object as JSON, wins over it. Every rule has a default, so leaving the section out lets people add any connection but one of the credential reference, which names no variable until variables lists it.

yaml
connections:
  people_may_add: true
  allowed_hosts: ['*.example.com', 'crm.example.com']
  credential_kinds: [none, reference, secret, client_credentials]
  variables: [CRM_API_KEY]
KeyDefaultPurpose
people_may_addtruefalse refuses every new connection, and the runtime uses none already added, though list_connections still lists them as they are
allowed_hostsevery hostThe hosts a connection may reach, each a host or *. and a host for every host under it; the host of an mcp connection's url, of an openapi connection's document and base_url, and of the issuer of client credentials. Left out, a connection may reach every host, addresses inside your network such as localhost or 10.0.0.5 among them
credential_kindsevery kindThe kinds of credential a connection may take: none, reference, secret and client_credentials
variablesnoneThe environment variables a reference credential may name, such as CRM_API_KEY. None of them may be a variable the runtime reads for itself: any variable this page lists, such as SECRETS_KEY, API_KEYS, PUBLIC_URL or a provider's key; a credential the cloud libraries read, such as AWS_SECRET_ACCESS_KEY, AZURE_CLIENT_SECRET, AZURE_CLIENT_CERTIFICATE_PASSWORD or AZURE_PASSWORD; a gateway's api_key_env; or a variable that a reference of this file or of TOOL_SERVERS names

add_connection refuses with 403 a connection one of these rules does not take, with the sentence of the rule, and with 409 a connection named as an entry of tool_servers. A key the section does not know, a pattern that is not a host, a kind there is not and a variable the runtime reads for itself stop the server at start, naming the line.

The rules are read at start, and checked again when a connection is first used after it, so a rule you change reaches a running server when it starts again: a connection a rule no longer takes is refused with the rule's sentence, which search shows, and with people_may_add: false the runtime uses no connection already added, in the sentence This runtime uses no connection: its operator sets up its tool servers itself. allowed_hosts holds every request a connection makes, not only those to the addresses it names: the server an openapi connection's document names, where base_url is left out, is checked once the document is read, and every request is checked before it is sent, those to an authorization server and those a redirect leads to among them. A call of an HTTP API follows no redirect, and the MCP client follows one only within the origin it asked. The value of each variable variables lists is read at start too, so a variable you set reaches a running server when it starts again.