Skip to content

Manifest Schema Reference

Complete field-by-field reference for agent.yaml. Every field listed here is enforced by the Zod schema in packages/sdk/src/schema/manifest.schema.ts.


Overview

An AgentSpec manifest has four top-level keys:

yaml
apiVersion: agentspec.io/v1
kind: AgentSpec
metadata: ...
spec: ...
FieldTypeRequiredDescription
apiVersion"agentspec.io/v1"YesAlways this literal value
kind"AgentSpec"YesAlways this literal value
metadataobjectYesIdentity and versioning
specobjectYesAll runtime configuration

Reference Syntax

Many string fields accept a reference instead of a literal value:

SyntaxResolves toFails if missing
$env:VAR_NAMEEnvironment variableYes
$secret:nameSecret manager (Vault / AWS / GCP / Azure)Yes
$file:pathFile path relative to agent.yamlYes
$func:now_isoBuilt-in functionYes (unknown func)

Fields that accept references are noted as refOrLiteral in this document.


metadata

Required. Identifies the agent and its version.

FieldTypeRequiredConstraintsExample
namestringYesLowercase slug /^[a-z0-9-]+$/gymcoach
versionstringYesSemver /^\d+\.\d+\.\d+$/1.0.0
descriptionstringYesMin length 1"AI fitness coaching assistant"
tagsstring[]No[fitness, coaching]
authorstringNo"Acme Corp"
licensestringNoMIT
yaml
metadata:
  name: gymcoach
  version: 1.0.0
  description: "AI fitness coaching assistant"
  tags: [fitness, coaching]
  author: "Acme Corp"
  license: MIT

spec.model

Required. The primary LLM configuration.

FieldTypeRequiredConstraintsExample
providerstringYesopenai
idstringYesgpt-4o-mini
apiKeyrefOrLiteralYes$env:OPENAI_API_KEY
parametersobjectNoSee below
fallbackobjectNoSee below
costControlsobjectNoSee below

spec.model.parameters

FieldTypeRequiredConstraintsExample
temperaturenumberNo0..20.7
maxTokensintegerNoMin 12048
topPnumberNo0..10.9
frequencyPenaltynumberNo0.0
presencePenaltynumberNo0.0

spec.model.fallback

Activated when the primary model fails. Supports automatic retry logic.

FieldTypeRequiredConstraintsExample
providerstringYesazure
idstringYesgpt-4
apiKeyrefOrLiteralYes$env:AZURE_OPENAI_API_KEY
triggerOnenum[]Norate_limit, timeout, error_5xx, error_4xx[rate_limit, timeout]
maxRetriesintegerNo0..102

spec.model.costControls

FieldTypeRequiredConstraintsExample
maxMonthlyUSDnumberNoPositive200
alertAtUSDnumberNoPositive150
yaml
spec:
  model:
    provider: groq
    id: llama-3.3-70b-versatile
    apiKey: $env:GROQ_API_KEY
    parameters:
      temperature: 0.3
      maxTokens: 500
    fallback:
      provider: azure
      id: gpt-4
      apiKey: $env:AZURE_OPENAI_API_KEY
      triggerOn: [rate_limit, timeout, error_5xx]
      maxRetries: 2
    costControls:
      maxMonthlyUSD: 200
      alertAtUSD: 150

spec.prompts

Required. System prompt configuration with hot-reload and variable injection.

FieldTypeRequiredDefaultConstraintsExample
systemrefOrLiteralYes$file:prompts/system.md
fallbackstringNo"Sorry, I'm unavailable."
hotReloadbooleanNofalsetrue
variablesobject[]NoSee below

spec.prompts.variables[]

Injects values into the system prompt at runtime.

FieldTypeRequiredExample
namestringYescurrent_date
valuerefOrLiteralYes$func:now_iso
yaml
spec:
  prompts:
    system: $file:prompts/system.md
    fallback: "I'm experiencing difficulties. Please try again."
    hotReload: true
    variables:
      - name: current_date
        value: "$func:now_iso"
      - name: unit_system
        value: $env:UNIT_SYSTEM

spec.tools[]

Optional. List of function tools the agent can call.

FieldTypeRequiredConstraintsExample
namestringYesLowercase slug /^[a-z0-9-]+$/log-workout
typeenumYesfunction, mcp, builtinfunction
descriptionstringYes"Retrieve training sessions"
modulestringNoTypically a $file: reference$file:tools/impl.py
functionstringNolog_workout
annotationsobjectNoSee below

spec.tools[].annotations

MCP-compatible hints about tool behaviour. Adapters use these to generate guardrail wrappers.

FieldTypeRequiredDefaultDescription
readOnlyHintbooleanNoTool does not modify state
destructiveHintbooleanNoTool may delete or overwrite data
idempotentHintbooleanNoRepeated calls have the same effect
openWorldHintbooleanNoTool interacts with external systems
yaml
spec:
  tools:
    - name: delete-workout
      type: function
      description: "Delete a logged training session"
      module: $file:tools/impl.py
      function: delete_workout
      annotations:
        readOnlyHint: false
        destructiveHint: true
        idempotentHint: false

spec.mcp

Optional. Model Context Protocol server configuration.

FieldTypeRequiredDescription
serversobject[]Yes (if present)List of MCP servers

spec.mcp.servers[]

FieldTypeRequiredConstraintsExample
namestringYespostgres-db
transportenumYesstdio, sse, httpstdio
commandstringNoRequired for stdio transportnpx
argsstring[]No[-y, "@modelcontextprotocol/server-postgres"]
urlstringNoValid URL; required for sse/http transporthttps://mcp.example.com
envrecordNoValues are refOrLiteralDATABASE_URL: $env:DATABASE_URL
healthCheckobjectNoSee below

spec.mcp.servers[].healthCheck

FieldTypeRequiredDefaultConstraintsExample
timeoutSecondsintegerNo51..6010
yaml
spec:
  mcp:
    servers:
      - name: postgres-db
        transport: stdio
        command: npx
        args: [-y, "@modelcontextprotocol/server-postgres"]
        env:
          DATABASE_URL: $env:DATABASE_URL
        healthCheck:
          timeoutSeconds: 5

spec.memory

Optional. Short-term conversation memory, long-term persistence, and vector search.

spec.memory.shortTerm

FieldTypeRequiredConstraintsExample
backendenumYesin-memory, redis, sqliteredis
maxTurnsintegerNoMin 120
maxTokensintegerNoMin 18000
ttlSecondsintegerNoMin 03600
connectionrefOrLiteralNo$env:REDIS_URL

spec.memory.longTerm

FieldTypeRequiredConstraintsExample
backendenumYespostgres, sqlite, mongodbpostgres
connectionStringrefOrLiteralYes$env:DATABASE_URL
tablestringNoagent_sessions
ttlDaysintegerNoMin 190

spec.memory.vector

FieldTypeRequiredConstraintsExample
backendenumYespgvector, pinecone, weaviate, qdrant, chromapgvector
connectionStringrefOrLiteralNo$env:DATABASE_URL
apiKeyrefOrLiteralNo$env:PINECONE_API_KEY
dimensionintegerYesMin 11536
topKintegerNoMin 15
namespacestringNogymcoach-docs

spec.memory.hygiene

FieldTypeRequiredDefaultExample
piiScrubFieldsstring[]No[ssn, credit_card, bank_account]
auditLogbooleanNofalsetrue
retentionPolicystringNo"90d"
yaml
spec:
  memory:
    shortTerm:
      backend: redis
      maxTurns: 20
      maxTokens: 8000
      ttlSeconds: 3600
      connection: $env:REDIS_URL
    longTerm:
      backend: postgres
      connectionString: $env:DATABASE_URL
      table: agent_sessions
      ttlDays: 90
    vector:
      backend: pgvector
      connectionString: $env:DATABASE_URL
      dimension: 1536
      topK: 5
    hygiene:
      piiScrubFields: [ssn, credit_card, bank_account]
      auditLog: true
      retentionPolicy: "90d"

spec.subagents[]

Optional. Delegates work to other agents, either local manifests or remote A2A endpoints.

FieldTypeRequiredDefaultConstraintsExample
namestringYesobserver
refobjectYesSee below
invocationenumYesparallel, sequential, on-demandparallel
passContextbooleanNofalsetrue
triggerKeywordsstring[]No[report, analyze]

spec.subagents[].ref — local file

yaml
ref:
  agentspec: ./agents/observer.yaml

spec.subagents[].ref — remote A2A

FieldTypeRequiredConstraintsExample
a2a.urlrefOrLiteralYeshttps://agents.example.com/observer
a2a.auth.typeenumNobearer, apikey, nonebearer
a2a.auth.tokenrefOrLiteralNo$env:OBSERVER_TOKEN
a2a.auth.headerstringNoAuthorization
yaml
spec:
  subagents:
    - name: observer
      ref:
        agentspec: ./agents/observer.yaml
      invocation: parallel
      passContext: true
    - name: remote-classifier
      ref:
        a2a:
          url: https://agents.example.com/classifier
          auth:
            type: bearer
            token: $env:CLASSIFIER_TOKEN
      invocation: on-demand
      triggerKeywords: [classify, categorize]

spec.api

Optional. Exposes the agent as an API endpoint.

FieldTypeRequiredDefaultConstraintsExample
typeenumYesrest, mcp, grpc, websocketrest
portintegerNo1..655358000
pathPrefixstringNo/api/v1
authobjectNoSee below
rateLimitobjectNoSee below
streamingbooleanNofalsetrue
healthEndpointstringNo/health
metricsEndpointstringNo/metrics
corsOriginsstring[]No["https://app.example.com"]
chatEndpointobjectNoSee below

spec.api.auth

FieldTypeRequiredConstraintsExample
typeenumYesjwt, apikey, oauth2, nonejwt
jwksUrirefOrLiteralNoUsed with jwt$env:JWKS_URI
headerstringNoX-API-Key

spec.api.rateLimit

FieldTypeRequiredConstraintsExample
requestsPerMinuteintegerNoMin 160
requestsPerHourintegerNoMin 11000

spec.api.chatEndpoint

Configures the standard chat interface. Defaults to an OpenAI-compatible endpoint at /v1/chat.

FieldTypeRequiredDefaultConstraintsExample
pathstringNo/v1/chat/v1/chat
protocolenumNoopenai-compatibleopenai-compatible, customopenai-compatible
streamingbooleanNotruetrue
sessionModeenumNostatefulstateful, statelessstateful
threadIdHeaderstringNoX-Thread-IdX-Thread-Id

sessionMode: stateful causes the agent to read and write conversation history keyed by the value in threadIdHeader. sessionMode: stateless treats every request as a new conversation.

yaml
spec:
  api:
    type: rest
    port: 8000
    pathPrefix: /api/v1
    auth:
      type: jwt
      jwksUri: $env:JWKS_URI
    rateLimit:
      requestsPerMinute: 60
      requestsPerHour: 1000
    streaming: true
    healthEndpoint: /health
    metricsEndpoint: /metrics
    corsOrigins:
      - "https://app.example.com"
    chatEndpoint:
      path: /v1/chat
      protocol: openai-compatible
      streaming: true
      sessionMode: stateful
      threadIdHeader: X-Thread-Id

spec.skills[]

Optional. Declares AgentSkill capabilities the agent exposes (used in A2A AgentCard export).

FieldTypeRequiredExample
idstringYesworkout-tracking
versionstringNo1.0.0
yaml
spec:
  skills:
    - id: workout-tracking
      version: 1.0.0
    - id: budget-reporting

spec.guardrails

Optional. Input and output filters that run before and after every model call.

spec.guardrails.input[]

Each entry is one of the following discriminated types, selected by type.

type: topic-filter

Blocks requests about specified topics.

FieldTypeRequiredConstraintsExample
type"topic-filter"Yestopic-filter
blockedTopicsstring[]Yes[illegal_activity, violence]
actionenumYesreject, warn, logreject
messagestringNo"I can only help with fitness topics."

type: pii-detector

Detects and optionally scrubs personally identifiable information.

FieldTypeRequiredConstraintsExample
type"pii-detector"Yespii-detector
actionenumYesscrub, reject, warnscrub
fieldsstring[]No[ssn, credit_card]

type: prompt-injection

Detects and blocks prompt injection attempts.

FieldTypeRequiredConstraintsExample
type"prompt-injection"Yesprompt-injection
actionenumYesreject, warnreject
sensitivityenumNolow, medium, highhigh

type: custom (input)

Calls a user-supplied function.

FieldTypeRequiredConstraintsExample
type"custom"Yescustom
modulestringYes$file:guardrails/custom.py
functionstringYesrun_input_check
actionenumYesreject, warn, logreject

spec.guardrails.output[]

Each entry is one of the following discriminated types.

type: hallucination-detector

FieldTypeRequiredConstraintsExample
type"hallucination-detector"Yeshallucination-detector
thresholdnumberYes0..10.8
actionenumYesreject, retry, warnretry
maxRetriesintegerNo1..52

type: toxicity-filter

FieldTypeRequiredConstraintsExample
type"toxicity-filter"Yestoxicity-filter
thresholdnumberYes0..10.7
actionenumYesreject, warnreject

type: pii-detector (output)

Same shape as the input variant — scrubs PII from model responses before returning to the caller.

FieldTypeRequiredConstraintsExample
type"pii-detector"Yespii-detector
actionenumYesscrub, reject, warnscrub
fieldsstring[]No[ssn, credit_card]

type: custom (output)

FieldTypeRequiredConstraintsExample
type"custom"Yescustom
modulestringYes$file:guardrails/custom.py
functionstringYesrun_output_check
actionenumYesreject, warn, logwarn
yaml
spec:
  guardrails:
    input:
      - type: topic-filter
        blockedTopics: [illegal_activity, violence]
        action: reject
        message: "I can only help with fitness and training topics."
      - type: pii-detector
        action: scrub
        fields: [ssn, credit_card]
      - type: prompt-injection
        action: reject
        sensitivity: high
    output:
      - type: hallucination-detector
        threshold: 0.8
        action: retry
        maxRetries: 2
      - type: toxicity-filter
        threshold: 0.7
        action: reject
      - type: pii-detector
        action: scrub
        fields: [ssn, credit_card]

spec.humanInTheLoop

Optional. Pauses agent execution for human review before sensitive actions are taken.

FieldTypeRequiredDefaultConstraintsExample
enabledbooleanNofalsetrue
approvalRequiredenum[]NoSee values below[before-destructive-tool]
timeoutSecondsintegerNo3001..3600300
timeoutActionenumNorejectreject, proceed, escalatereject
notifyViaenum[]Noslack, email, webhook, console[slack]
webhookUrlrefOrLiteralNo$env:APPROVAL_WEBHOOK_URL

approvalRequired values

ValueTriggers approval when...
before-destructive-toolA tool with annotations.destructiveHint: true is about to be called
before-external-callThe agent is about to make an outbound HTTP / MCP call
on-low-confidenceThe model's response confidence falls below an internal threshold
on-high-costThe estimated token cost for the current turn exceeds costControls.alertAtUSD
alwaysEvery agent action, regardless of type

timeoutAction values

ValueBehaviour when the approval window expires
rejectAbort the action and return an error to the caller (default)
proceedContinue without approval — treat as auto-approved
escalateEscalate to the next notifyVia channel and extend the timeout
yaml
spec:
  humanInTheLoop:
    enabled: true
    approvalRequired:
      - before-destructive-tool
      - on-high-cost
    timeoutSeconds: 300
    timeoutAction: reject
    notifyVia:
      - slack
      - webhook
    webhookUrl: $env:APPROVAL_WEBHOOK_URL

spec.evaluation

Optional. Evaluation framework and quality gate configuration.

FieldTypeRequiredDefaultConstraintsExample
frameworkenumYesdeepeval, braintrust, langsmith, ragas, customdeepeval
datasetsobject[]NoSee below
metricsenum[]NoSee values below[faithfulness, hallucination]
thresholdsrecordNoValues 0..1faithfulness: 0.85
ciGatebooleanNofalsetrue

spec.evaluation.datasets[]

FieldTypeRequiredExample
namestringYesbudget-qa
pathrefOrLiteralYes$file:eval/budget-qa.jsonl

metrics values

faithfulness, answer_relevancy, hallucination, toxicity, context_precision, context_recall, bias, custom

yaml
spec:
  evaluation:
    framework: deepeval
    datasets:
      - name: budget-qa
        path: $file:eval/datasets/budget-qa.jsonl
    metrics:
      - faithfulness
      - answer_relevancy
      - hallucination
      - toxicity
    thresholds:
      faithfulness: 0.85
      hallucination: 0.05
    ciGate: true

spec.observability

Optional. Tracing, metrics, and structured logging.

spec.observability.tracing

FieldTypeRequiredDefaultConstraintsExample
backendenumYeslangfuse, langsmith, agentops, otel, honeycomb, datadoglangfuse
endpointrefOrLiteralNo$env:LANGFUSE_HOST
publicKeyrefOrLiteralNo$env:LANGFUSE_PUBLIC_KEY
secretKeyrefOrLiteralNo$secret:langfuse-secret-key
sampleRatenumberNo1.00..10.5

spec.observability.metrics

FieldTypeRequiredConstraintsExample
backendenumYesopentelemetry, prometheus, datadogopentelemetry
endpointrefOrLiteralNo$env:OTEL_EXPORTER_OTLP_ENDPOINT
serviceNamestringNogymcoach

spec.observability.logging

FieldTypeRequiredDefaultConstraintsExample
levelenumNoinfodebug, info, warn, errorinfo
structuredbooleanNotruetrue
redactFieldsstring[]No[api_key, password]
yaml
spec:
  observability:
    tracing:
      backend: langfuse
      endpoint: $env:LANGFUSE_HOST
      publicKey: $env:LANGFUSE_PUBLIC_KEY
      secretKey: $secret:langfuse-secret-key
      sampleRate: 1.0
    metrics:
      backend: opentelemetry
      endpoint: $env:OTEL_EXPORTER_OTLP_ENDPOINT
      serviceName: gymcoach
    logging:
      level: info
      structured: true
      redactFields: [api_key, password]

spec.compliance

Optional. Enables compliance pack scoring and suppression of known violations.

FieldTypeRequiredConstraintsExample
packsenum[]NoSee values below[owasp-llm-top10]
suppressionsobject[]NoSee below
auditScheduleenumNodaily, weekly, monthly, on-changeweekly

packs values

PackWhat it checks
owasp-llm-top10OWASP LLM Top 10 security rules
memory-hygienePII scrubbing, TTL, audit logging
model-resilienceFallback, version pinning, cost controls
evaluation-coverageEvaluation framework and metrics coverage
observabilityTracing, metrics, and logging presence

spec.compliance.suppressions[]

FieldTypeRequiredExample
rulestringYesSEC-LLM-08
reasonstringYes"Handled at the network layer"
approvedBystringNo"security-team"
expiresstringNo"2025-12-31" (ISO date)
yaml
spec:
  compliance:
    packs:
      - owasp-llm-top10
      - memory-hygiene
      - model-resilience
      - evaluation-coverage
    suppressions:
      - rule: SEC-LLM-08
        reason: "Handled at the network layer"
        approvedBy: "security-team"
        expires: "2025-12-31"
    auditSchedule: weekly

spec.requires

Optional. Declares runtime prerequisites so agentspec health can verify them before deployment.

FieldTypeRequiredConstraintsExample
envVarsstring[]No[OPENAI_API_KEY, DATABASE_URL]
servicesobject[]NoSee below
minimumMemoryMBintegerNoMin 128512
nodeVersionstringNo">=20"
pythonVersionstringNo">=3.11"

spec.requires.services[]

FieldTypeRequiredConstraintsExample
typeenumYespostgres, redis, mysql, mongodb, elasticsearchpostgres
connectionrefOrLiteralYes$env:DATABASE_URL
yaml
spec:
  requires:
    envVars:
      - OPENAI_API_KEY
      - DATABASE_URL
      - REDIS_URL
    services:
      - type: postgres
        connection: $env:DATABASE_URL
      - type: redis
        connection: $env:REDIS_URL
    minimumMemoryMB: 512
    nodeVersion: ">=20"
    pythonVersion: ">=3.11"

Full Manifest Example

The following is the complete GymCoach manifest, which exercises every major section:

yaml
apiVersion: agentspec.io/v1
kind: AgentSpec

metadata:
  name: gymcoach
  version: 1.0.0
  description: "AI fitness coaching assistant"
  tags: [fitness, coaching]
  author: "Acme Corp"
  license: MIT

spec:
  model:
    provider: groq
    id: llama-3.3-70b-versatile
    apiKey: $env:GROQ_API_KEY
    parameters:
      temperature: 0.3
      maxTokens: 500
    fallback:
      provider: azure
      id: gpt-4
      apiKey: $env:AZURE_OPENAI_API_KEY
      triggerOn: [rate_limit, timeout, error_5xx]
      maxRetries: 2
    costControls:
      maxMonthlyUSD: 200
      alertAtUSD: 150

  prompts:
    system: $file:prompts/system.md
    fallback: "I'm experiencing difficulties. Please try again."
    hotReload: true
    variables:
      - name: current_date
        value: "$func:now_iso"
      - name: unit_system
        value: $env:UNIT_SYSTEM

  tools:
    - name: delete-workout
      type: function
      description: "Delete a logged training session"
      module: $file:tools/impl.py
      function: delete_workout
      annotations:
        readOnlyHint: false
        destructiveHint: true

  mcp:
    servers:
      - name: postgres-db
        transport: stdio
        command: npx
        args: [-y, "@modelcontextprotocol/server-postgres"]
        env:
          DATABASE_URL: $env:DATABASE_URL
        healthCheck:
          timeoutSeconds: 5

  memory:
    shortTerm:
      backend: redis
      maxTurns: 20
      ttlSeconds: 3600
      connection: $env:REDIS_URL
    longTerm:
      backend: postgres
      connectionString: $env:DATABASE_URL
      table: agent_sessions
      ttlDays: 90
    hygiene:
      piiScrubFields: [ssn, credit_card]
      auditLog: true

  subagents:
    - name: observer
      ref:
        agentspec: ./agents/observer.yaml
      invocation: parallel
      passContext: true

  api:
    type: rest
    port: 8000
    pathPrefix: /api/v1
    auth:
      type: jwt
      jwksUri: $env:JWKS_URI
    rateLimit:
      requestsPerMinute: 60
    streaming: true
    healthEndpoint: /health
    metricsEndpoint: /metrics
    chatEndpoint:
      path: /v1/chat
      protocol: openai-compatible
      streaming: true
      sessionMode: stateful
      threadIdHeader: X-Thread-Id

  humanInTheLoop:
    enabled: true
    approvalRequired:
      - before-destructive-tool
      - on-high-cost
    timeoutSeconds: 300
    timeoutAction: reject
    notifyVia: [slack, webhook]
    webhookUrl: $env:APPROVAL_WEBHOOK_URL

  guardrails:
    input:
      - type: topic-filter
        blockedTopics: [illegal_activity, violence]
        action: reject
      - type: prompt-injection
        action: reject
        sensitivity: high
    output:
      - type: hallucination-detector
        threshold: 0.8
        action: retry
        maxRetries: 2
      - type: toxicity-filter
        threshold: 0.7
        action: reject

  evaluation:
    framework: deepeval
    metrics: [faithfulness, hallucination, toxicity]
    thresholds:
      faithfulness: 0.85
      hallucination: 0.05
    ciGate: true

  observability:
    tracing:
      backend: langfuse
      endpoint: $env:LANGFUSE_HOST
      publicKey: $env:LANGFUSE_PUBLIC_KEY
      secretKey: $secret:langfuse-secret-key
      sampleRate: 1.0
    metrics:
      backend: opentelemetry
      endpoint: $env:OTEL_EXPORTER_OTLP_ENDPOINT
      serviceName: gymcoach
    logging:
      level: info
      structured: true
      redactFields: [api_key, password]

  compliance:
    packs:
      - owasp-llm-top10
      - memory-hygiene
      - model-resilience
      - evaluation-coverage
    auditSchedule: weekly

  requires:
    envVars:
      - GROQ_API_KEY
      - DATABASE_URL
      - REDIS_URL
    services:
      - type: postgres
        connection: $env:DATABASE_URL
      - type: redis
        connection: $env:REDIS_URL
    minimumMemoryMB: 512

See also

Released under the Apache 2.0 License.