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

FileChecked reader or commandWhat success does not establish
Root .sonny.yamlRoot configuration inspectionA complete account of every setting; config explain has a separate limited projection.
Model catalogmodels list --models <file> --no-check --json, plus the source catalog loaderProvider authentication, live model support or measured fitness.
User/project hookshooks check --jsonExecution, trust admission or delivery of every accepted event.
mcp.yamlmcp list --mcp-config <file> --format=json without --connectEgress admission, approval, transport availability or a working server.
Reciperecipe validate <file> and Recipe schemaEvery 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 fieldDeclared typeOmit empty on write
idstringNo
familystringYes
releasestringYes
variantstringYes
context_window_tokensintYes
paramsmap[string]stringYes
price*PriceYes
categoriesmap[string]CategoryFitYes

Source: cmd/sonny/category/source.go:419, pinned to the release/source versions above.

category.Catalog
YAML fieldDeclared typeOmit empty on write
versionintNo
categoriesmap[string]CategoryNo
routingRoutingYes
sources[]SourceYes
model_policyModelPolicyYes
models[]CanonicalModelYes

Source: cmd/sonny/category/category.go:80, pinned to the release/source versions above.

category.Category
YAML fieldDeclared typeOmit empty on write
uristringNo
descriptionstringYes

Source: cmd/sonny/category/category.go:50, pinned to the release/source versions above.

category.CategoryFit
YAML fieldDeclared typeOmit empty on write
fitnessfloat64No
settingsmap[string]stringYes
tuning_refstringYes
evidence*FitnessEvidenceYes

Source: cmd/sonny/category/source.go:207, pinned to the release/source versions above.

category.FitnessEvidence
YAML fieldDeclared typeOmit empty on write
samplesintYes
evaluatorstringYes
digeststringYes
observed_attime.TimeYes

Source: cmd/sonny/category/source.go:138, pinned to the release/source versions above.

category.ModelPolicy
YAML fieldDeclared typeOmit empty on write
blockedModelPolicySelectorsYes

Source: cmd/sonny/category/model_policy.go:34, pinned to the release/source versions above.

category.ModelPolicySelectors
YAML fieldDeclared typeOmit empty on write
sources[]stringYes
providers[]stringYes
classes[]stringYes

Source: cmd/sonny/category/model_policy.go:42, pinned to the release/source versions above.

category.Price
YAML fieldDeclared typeOmit empty on write
input_per_mtokfloat64No
output_per_mtokfloat64No
cache_read_per_mtokfloat64Yes
cache_write_per_mtokfloat64Yes

Source: cmd/sonny/category/source.go:117, pinned to the release/source versions above.

category.Revival
YAML fieldDeclared typeOmit empty on write
initial_backofftime.DurationYes
max_backofftime.DurationYes
penalty_half_lifetime.DurationYes
probe_timeouttime.DurationYes

Source: cmd/sonny/category/source.go:81, pinned to the release/source versions above.

category.Routing
YAML fieldDeclared typeOmit empty on write
policystringYes
price_weightfloat64Yes
revivalRevivalYes

Source: cmd/sonny/category/source.go:67, pinned to the release/source versions above.

category.SecretRef
YAML fieldDeclared typeOmit empty on write
mountstringYes
pathstringYes
fieldstringYes

Source: cmd/sonny/category/source.go:471, pinned to the release/source versions above.

category.Source
YAML fieldDeclared typeOmit empty on write
idstringNo
schemestringNo
env_prefixstringYes
base_urlstringYes
api_key_envstringYes
secret_ref*SecretRefYes
pricing_urlstringYes
pricing_formatstringYes
prompt_cache_keyboolYes
models[]SourceModelNo

Source: cmd/sonny/category/source.go:434, pinned to the release/source versions above.

category.SourceModel
YAML fieldDeclared typeOmit empty on write
modelstringNo
providerstringYes
classes[]stringYes
enabled*boolYes
refstringYes
api_modelstringYes
aliases[]stringYes
context_window_tokensintYes
paramsmap[string]stringYes
price*PriceYes
categoriesmap[string]CategoryFitNo
modalities[]stringYes
tools_with_reasoningToolsWithReasoningYes

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 fieldDeclared typeOmit empty on write
idstringNo
events[]stringNo
matchstringYes
command[]stringYes
inject_outputboolYes
injectstringYes
goalstringYes
timeout_secondsintYes

Source: cmd/sonny/hooks/hooks.go:79, pinned to the release/source versions above.

hooks.File
YAML fieldDeclared typeOmit empty on write
schema_versionstringNo
hooks[]DefNo

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 fieldDeclared typeOmit empty on write
typeMCPAuthTypeNo
api_keystringYes
api_key_headerstringYes
api_key_env_varstringYes
tokenstringYes
usernamestringYes
passwordstringYes

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 fieldDeclared typeOmit empty on write
allow_hosts[]stringYes
allow_ports[]intYes
deny_private_networksboolYes
allow_private_networksboolYes
allow_plain_httpboolYes
proxy_urlstringYes

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 fieldDeclared typeOmit empty on write
servers[]rawServerNo

Source: cmd/sonny/mcpconfig/load.go:60, pinned to the release/source versions above.

mcpconfig.rawServer
YAML fieldDeclared typeOmit empty on write
namestringNo
typellmschema.MCPServerTypeNo
commandstringYes
args[]stringYes
urlstringYes
work_dirstringYes
envmap[string]stringYes
env_allowlist[]stringYes
env_inherit_allboolYes
authllmschema.MCPAuthConfigYes
enabled*boolYes
auto_connect*boolYes
timeouttime.DurationYes
egress*llmschema.MCPEgressPolicyYes
integrationstringYes
metadatamap[string]stringYes
from_packstringYes

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 fieldDeclared typeOmit empty on write
typeMCPAuthTypeNo
api_keystringYes
api_key_headerstringYes
api_key_env_varstringYes
tokenstringYes
usernamestringYes
passwordstringYes

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 fieldDeclared typeOmit empty on write
accept_legacy_sseboolYes
omit_protocol_version_headerboolYes
allow_unauthenticated_discoveryboolYes

Source: devnw.dev/[email protected]/schema/mcp.go:456, pinned to the release/source versions above.

llm_schema.MCPEgressPolicy
YAML fieldDeclared typeOmit empty on write
allow_hosts[]stringYes
allow_ports[]intYes
deny_private_networksboolYes
allow_private_networksboolYes
allow_plain_httpboolYes
proxy_urlstringYes

Source: devnw.dev/[email protected]/schema/mcp.go:394, pinned to the release/source versions above.

llm_schema.MCPOAuthConfig
YAML fieldDeclared typeOmit empty on write
resource_metadata_urlstringYes
authorization_serverstringYes
client_id_refstringYes
client_secret_refstringYes
scopes[]stringYes
audiencestringYes

Source: devnw.dev/[email protected]/schema/mcp.go:331, pinned to the release/source versions above.

llm_schema.MCPServerConfig
YAML fieldDeclared typeOmit empty on write
namestringNo
schema_versionstringYes
typeMCPServerTypeNo
commandstringYes
args[]stringYes
urlstringYes
work_dirstringYes
envmap[string]stringYes
env_allowlist[]stringYes
env_inherit_allboolYes
authMCPAuthConfigYes
enabledboolNo
timeouttime.DurationYes
auto_connectboolYes
headersmap[string]stringYes
min_protocol_versionstringYes
max_protocol_versionstringYes
disable_standalone_sseboolYes
max_retriesintYes
oauth*MCPOAuthConfigYes
tls*MCPTLSConfigYes
egress*MCPEgressPolicyYes
capability_digestMCPCapabilityDigestYes
compatMCPCompatFlagsYes

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 fieldDeclared typeOmit empty on write
min_versionstringYes
server_namestringYes
ca_bundle_refstringYes
pinned_sha256[]stringYes
insecure_skip_verifyboolYes
insecure_acknowledgedboolYes

Source: devnw.dev/[email protected]/schema/mcp.go:352, pinned to the release/source versions above.