Choose the format before validating a file. A root .sonny.yaml, model
catalog, hook file, MCP sidecar and Recipe each have different readers and
rules. This reference targets Sonny 0.12.7, source/build
192e590345c6a4bf1ef8f72b043b318084ea84d6, with devnw.dev/llm v0.46.6.
Download the source-derived field inventory . It records reachable YAML declarations, including nested types. It is a lookup index, not a substitute JSON Schema validator. Custom decoders, cross-file resolution, trust and runtime admission still apply. The Recipe has a separate emitted JSON Schema and field reference .
“Omit empty on write” describes serialization, not permission to omit a
required input. For example, a canonical model’s family carries that tag
but the actual validator refused it when missing. Conversely, hooks accept an
omitted schema_version as version 1. Use the format’s validation rules and
inspected results, rather than treating every field tag as an optionality rule.
Which check answers the question
| File | Checked reader or command | What success does not establish |
|---|---|---|
Root .sonny.yaml | Root configuration inspection | A complete account of every setting; config explain has a separate limited projection. |
| Model catalog | models list --models <file> --no-check --json, plus the source catalog loader | Provider authentication, live model support or measured fitness. |
| User/project hooks | hooks check --json | Execution, trust admission or delivery of every accepted event. |
mcp.yaml | mcp list --mcp-config <file> --format=json without --connect | Egress admission, approval, transport availability or a working server. |
| Recipe | recipe validate <file> and Recipe schema | Every input binding, client/runtime permission or task outcome. |
The installed checks used private HOME/XDG directories and owned synthetic
files. Model inspection used --no-check; MCP inspection did not request a
connection; hook checking did not dispatch actions. The source checks exercised
the same pinned parser/validator packages. These are configuration tests,
separate from the executed MCP connections
and
hook lifecycle checks
.
Their JSON outputs also differ. The tested model command used the
sonny.cli/v1 envelope. MCP listing returned a servers object, while hooks
checking returned ok, active_ids, digest, sources and its own
schema_version: "1". That hook-file version is not the CLI envelope version.
Model catalogs
The loader accepted versions 1–4, including source-backed fixtures under
each version. These version numbers describe format evolution; the pinned
reader is not four isolated parsers with mutually exclusive fields. A missing
version or version 99, fitness outside [0,1], duplicate source IDs, an
unknown routing policy and unsupported typed category settings were refused.
The tested unknown root member was accepted and ignored. This is not a
universal typo detector. Typed category objects are stricter: an unknown member
or unsupported settings key was refused, while temp and max_tokens in the
supported typed shape loaded. Supported setting names include temp,
temperature, max_tokens, max_output_tokens, top_p, presence_penalty,
frequency_penalty, seed, reasoning_effort, chat_template_kwargs and
verbosity; this does not prove every provider honors them.
Per-file and merged validation are different stages. A well-shaped source
model with a dangling canonical ref passed the source per-file loader. The
installed merged-catalog command refused the same input with exit 3. A complete
canonical fixture with its required family, source model, ref and
api_model loaded and appeared in the inspected category result. Do not judge
an unresolved cross-file reference from a single-file parse alone.
Inspect the synthetic canonical-model fixture . It points to an intentionally unused loopback endpoint and has a synthetic model name. It is an offline parsing example, not a ready provider connection. For catalog layering, credential routing and live availability, use model catalogs and choosing models .
category.CanonicalModel
| YAML field | Declared type | Omit empty on write |
|---|---|---|
id | string | No |
family | string | Yes |
release | string | Yes |
variant | string | Yes |
context_window_tokens | int | Yes |
params | map[string]string | Yes |
price | *Price | Yes |
categories | map[string]CategoryFit | Yes |
Source: cmd/sonny/category/source.go:419, pinned to the release/source versions above.
category.Catalog
| YAML field | Declared type | Omit empty on write |
|---|---|---|
version | int | No |
categories | map[string]Category | No |
routing | Routing | Yes |
sources | []Source | Yes |
model_policy | ModelPolicy | Yes |
models | []CanonicalModel | Yes |
Source: cmd/sonny/category/category.go:80, pinned to the release/source versions above.
category.Category
| YAML field | Declared type | Omit empty on write |
|---|---|---|
uri | string | No |
description | string | Yes |
Source: cmd/sonny/category/category.go:50, pinned to the release/source versions above.
category.CategoryFit
| YAML field | Declared type | Omit empty on write |
|---|---|---|
fitness | float64 | No |
settings | map[string]string | Yes |
tuning_ref | string | Yes |
evidence | *FitnessEvidence | Yes |
Source: cmd/sonny/category/source.go:207, pinned to the release/source versions above.
category.FitnessEvidence
| YAML field | Declared type | Omit empty on write |
|---|---|---|
samples | int | Yes |
evaluator | string | Yes |
digest | string | Yes |
observed_at | time.Time | Yes |
Source: cmd/sonny/category/source.go:138, pinned to the release/source versions above.
category.ModelPolicy
| YAML field | Declared type | Omit empty on write |
|---|---|---|
blocked | ModelPolicySelectors | Yes |
Source: cmd/sonny/category/model_policy.go:34, pinned to the release/source versions above.
category.ModelPolicySelectors
| YAML field | Declared type | Omit empty on write |
|---|---|---|
sources | []string | Yes |
providers | []string | Yes |
classes | []string | Yes |
Source: cmd/sonny/category/model_policy.go:42, pinned to the release/source versions above.
category.Price
| YAML field | Declared type | Omit empty on write |
|---|---|---|
input_per_mtok | float64 | No |
output_per_mtok | float64 | No |
cache_read_per_mtok | float64 | Yes |
cache_write_per_mtok | float64 | Yes |
Source: cmd/sonny/category/source.go:117, pinned to the release/source versions above.
category.Revival
| YAML field | Declared type | Omit empty on write |
|---|---|---|
initial_backoff | time.Duration | Yes |
max_backoff | time.Duration | Yes |
penalty_half_life | time.Duration | Yes |
probe_timeout | time.Duration | Yes |
Source: cmd/sonny/category/source.go:81, pinned to the release/source versions above.
category.Routing
| YAML field | Declared type | Omit empty on write |
|---|---|---|
policy | string | Yes |
price_weight | float64 | Yes |
revival | Revival | Yes |
Source: cmd/sonny/category/source.go:67, pinned to the release/source versions above.
category.SecretRef
| YAML field | Declared type | Omit empty on write |
|---|---|---|
mount | string | Yes |
path | string | Yes |
field | string | Yes |
Source: cmd/sonny/category/source.go:471, pinned to the release/source versions above.
category.Source
| YAML field | Declared type | Omit empty on write |
|---|---|---|
id | string | No |
scheme | string | No |
env_prefix | string | Yes |
base_url | string | Yes |
api_key_env | string | Yes |
secret_ref | *SecretRef | Yes |
pricing_url | string | Yes |
pricing_format | string | Yes |
prompt_cache_key | bool | Yes |
models | []SourceModel | No |
Source: cmd/sonny/category/source.go:434, pinned to the release/source versions above.
category.SourceModel
| YAML field | Declared type | Omit empty on write |
|---|---|---|
model | string | No |
provider | string | Yes |
classes | []string | Yes |
enabled | *bool | Yes |
ref | string | Yes |
api_model | string | Yes |
aliases | []string | Yes |
context_window_tokens | int | Yes |
params | map[string]string | Yes |
price | *Price | Yes |
categories | map[string]CategoryFit | No |
modalities | []string | Yes |
tools_with_reasoning | ToolsWithReasoning | Yes |
Source: cmd/sonny/category/source.go:258, pinned to the release/source versions above.
category.ToolsWithReasoning
Declared value shape: string.
Source: cmd/sonny/category/tools_reasoning.go:16, pinned to the release/source versions above.
User and project hooks
The checked format accepts an omitted schema version as 1, at most 32
hooks per source, unique IDs, known events and exactly one action among
command, inject and goal. It refused unsupported versions, unknown keys
or events, duplicate IDs, invalid match expressions, multiple actions and a
goal_set hook that sets a goal. A matcher uses Go’s regular-expression rules.
The parser and installed checker accepted the first document of a multi-document YAML input and ignored the second in the fixture. Keep hook files to one reviewed document; checking the first does not validate an appended document. This failed strictness assertion is retained in the evidence.
A timeout_seconds: 999 command definition also parsed successfully and the
source load preserved 999. The dispatch code applies the runtime limit:
positive values are capped at 60 seconds; zero or negative values use the
10-second default. This parsing test did not execute that command or time a
60-second hook. The hook guide
retains the separate one-second
runtime timeout, logging, veto and disable qualification.
round_budget_exhausted remains an accepted legacy event name; acceptance does
not prove the current turn engine emits it. Other runtime limitations, including
command-output injection and event payload fields, remain in the hook guide.
Inspect the static-injection shape
before using
it. hooks check reads the selected user/project files rather than an arbitrary
--file argument; use an owned isolated configuration/workspace for experiments.
hooks.Def
| YAML field | Declared type | Omit empty on write |
|---|---|---|
id | string | No |
events | []string | No |
match | string | Yes |
command | []string | Yes |
inject_output | bool | Yes |
inject | string | Yes |
goal | string | Yes |
timeout_seconds | int | Yes |
Source: cmd/sonny/hooks/hooks.go:79, pinned to the release/source versions above.
hooks.File
| YAML field | Declared type | Omit empty on write |
|---|---|---|
schema_version | string | No |
hooks | []Def | No |
Source: cmd/sonny/hooks/schema.go:53, pinned to the release/source versions above.
MCP sidecar
The strict sidecar shape is servers: [...]. It accepted the tested process
environment allowlist, explicit full-inheritance flag and duration value.
It refused unknown fields, inline-only oauth and schema_version, duplicate
server names, a stdio server without a command, stdio egress, wrong remote host
policy and multiple YAML documents. Omitted enabled and auto_connect values
are defaulted to true; set auto_connect: false for a definition you do not
intend a session to connect automatically.
A remote definition without egress policy parsed and listed successfully.
The separate library registration validator refused it because remote
egress.allow_hosts is required. The definition still needs Sonny’s own trust,
transport and session admission after those checks. Likewise, the tested
streamable_http definition passed parsing and the library configuration
validator, while the installed Sonny connection qualification refused that
transport. A listed definition or upstream transport type is not a working
Sonny connection.
Inspect the stdio parsing fixture
. Its
/bin/false command and auto_connect: false make its purpose explicit; the
checks did not execute it. It is not a usable MCP service. Follow
connect an MCP server
for the public APIC server and its
real read/denial checks. Authentication references and environment inheritance
need separate review before activating any definition.
llm_schema.MCPAuthConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
type | MCPAuthType | No |
api_key | string | Yes |
api_key_header | string | Yes |
api_key_env_var | string | Yes |
token | string | Yes |
username | string | Yes |
password | string | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:272, pinned to the release/source versions above.
llm_schema.MCPAuthType
Declared value shape: string.
Source: devnw.dev/[email protected]/schema/mcp.go:71, pinned to the release/source versions above.
llm_schema.MCPEgressPolicy
| YAML field | Declared type | Omit empty on write |
|---|---|---|
allow_hosts | []string | Yes |
allow_ports | []int | Yes |
deny_private_networks | bool | Yes |
allow_private_networks | bool | Yes |
allow_plain_http | bool | Yes |
proxy_url | string | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:394, pinned to the release/source versions above.
llm_schema.MCPServerType
Declared value shape: string.
Source: devnw.dev/[email protected]/schema/mcp.go:20, pinned to the release/source versions above.
mcpconfig.rawConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
servers | []rawServer | No |
Source: cmd/sonny/mcpconfig/load.go:60, pinned to the release/source versions above.
mcpconfig.rawServer
| YAML field | Declared type | Omit empty on write |
|---|---|---|
name | string | No |
type | llmschema.MCPServerType | No |
command | string | Yes |
args | []string | Yes |
url | string | Yes |
work_dir | string | Yes |
env | map[string]string | Yes |
env_allowlist | []string | Yes |
env_inherit_all | bool | Yes |
auth | llmschema.MCPAuthConfig | Yes |
enabled | *bool | Yes |
auto_connect | *bool | Yes |
timeout | time.Duration | Yes |
egress | *llmschema.MCPEgressPolicy | Yes |
integration | string | Yes |
metadata | map[string]string | Yes |
from_pack | string | Yes |
Source: cmd/sonny/mcpconfig/load.go:64, pinned to the release/source versions above.
Recipe inline MCP
A Recipe’s pack.mcp.servers uses the upstream MCP configuration shape. The
sidecar adds its own integration, metadata and from_pack fields while
omitting upstream members such as oauth, TLS, headers and protocol options.
Copying fields between the two formats can therefore fail validation or change
meaning. Use the Recipe’s emitted schema
for that document
and the MCP trust model
for effective access.
This inventory exposes declarations; it does not qualify OAuth, TLS overrides, protocol ranges or any other field as working in every Sonny client. The connection guide identifies the installed transport boundary.
llm_schema.MCPAuthConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
type | MCPAuthType | No |
api_key | string | Yes |
api_key_header | string | Yes |
api_key_env_var | string | Yes |
token | string | Yes |
username | string | Yes |
password | string | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:272, pinned to the release/source versions above.
llm_schema.MCPAuthType
Declared value shape: string.
Source: devnw.dev/[email protected]/schema/mcp.go:71, pinned to the release/source versions above.
llm_schema.MCPCapabilityDigest
Declared value shape: string.
Source: devnw.dev/[email protected]/schema/mcp.go:96, pinned to the release/source versions above.
llm_schema.MCPCompatFlags
| YAML field | Declared type | Omit empty on write |
|---|---|---|
accept_legacy_sse | bool | Yes |
omit_protocol_version_header | bool | Yes |
allow_unauthenticated_discovery | bool | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:456, pinned to the release/source versions above.
llm_schema.MCPEgressPolicy
| YAML field | Declared type | Omit empty on write |
|---|---|---|
allow_hosts | []string | Yes |
allow_ports | []int | Yes |
deny_private_networks | bool | Yes |
allow_private_networks | bool | Yes |
allow_plain_http | bool | Yes |
proxy_url | string | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:394, pinned to the release/source versions above.
llm_schema.MCPOAuthConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
resource_metadata_url | string | Yes |
authorization_server | string | Yes |
client_id_ref | string | Yes |
client_secret_ref | string | Yes |
scopes | []string | Yes |
audience | string | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:331, pinned to the release/source versions above.
llm_schema.MCPServerConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
name | string | No |
schema_version | string | Yes |
type | MCPServerType | No |
command | string | Yes |
args | []string | Yes |
url | string | Yes |
work_dir | string | Yes |
env | map[string]string | Yes |
env_allowlist | []string | Yes |
env_inherit_all | bool | Yes |
auth | MCPAuthConfig | Yes |
enabled | bool | No |
timeout | time.Duration | Yes |
auto_connect | bool | Yes |
headers | map[string]string | Yes |
min_protocol_version | string | Yes |
max_protocol_version | string | Yes |
disable_standalone_sse | bool | Yes |
max_retries | int | Yes |
oauth | *MCPOAuthConfig | Yes |
tls | *MCPTLSConfig | Yes |
egress | *MCPEgressPolicy | Yes |
capability_digest | MCPCapabilityDigest | Yes |
compat | MCPCompatFlags | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:99, pinned to the release/source versions above.
llm_schema.MCPServerType
Declared value shape: string.
Source: devnw.dev/[email protected]/schema/mcp.go:20, pinned to the release/source versions above.
llm_schema.MCPTLSConfig
| YAML field | Declared type | Omit empty on write |
|---|---|---|
min_version | string | Yes |
server_name | string | Yes |
ca_bundle_ref | string | Yes |
pinned_sha256 | []string | Yes |
insecure_skip_verify | bool | Yes |
insecure_acknowledged | bool | Yes |
Source: devnw.dev/[email protected]/schema/mcp.go:352, pinned to the release/source versions above.