Skip to main content
FlowMCP enforces validation rules when loading schemas, shared lists, and groups. Each rule has a code, severity level, and description. Run validation with flowmcp validate <schema-path>.
This page covers all validation rules from the formal specification. Rules are enforced at load-time and during CLI validation.

Severity Levels

SeverityDescriptionEffect
errorMust fix before useSchema cannot be loaded
warningShould fixSchema loads with warnings
infoNice to haveInformational only

Validation Output

flowmcp validate etherscan/contracts.mjs
  VAL014 error   main.version: Must match ^2\.\d+\.\d+$ (found "1.2.0")
  VAL031 error   routes: Maximum 8 routes exceeded (found 10)
  VAL036 warning getContractAbi: output schema is recommended
  TST001 warning getContractAbi: No tests found

  2 errors, 2 warnings
  Schema cannot be loaded (has errors)

Rules by Category

CodeSeverityRule
VAL001errorSchema must export main as named export
VAL002errormain must be an object
VAL003errormain must not contain unknown fields
VAL004errorhandlers (if exported) must be a function
VAL005warninghandlers function must return an object with keys matching route names
CodeSeverityRule
VAL010errormain.namespace is required and must be a string
VAL011errormain.namespace must match ^[a-z]+$
VAL012errormain.name is required and must be a string
VAL013errormain.description is required and must be a string
VAL014errormain.version is required and must match ^2\.\d+\.\d+$
VAL015errormain.root is required and must be a valid URL
VAL016errormain.routes is required and must be a non-empty object
CodeSeverityRule
VAL020errormain.docs (if present) must be an array of strings
VAL021errormain.tags (if present) must be an array of strings
VAL022errormain.requiredServerParams (if present) must be an array of strings
VAL023errormain.headers (if present) must be a plain object
VAL024errormain.sharedLists (if present) must be an array of objects
VAL025errormain.requiredLibraries (if present) must be an array of strings
VAL026errorEach entry in requiredLibraries must be on the runtime allowlist
CodeSeverityRule
VAL030errorRoute name must match ^[a-z][a-zA-Z0-9]*$
VAL031errorMaximum 8 routes per schema
VAL032errorroute.method is required and must be GET, POST, PUT, or DELETE
VAL033errorroute.path is required and must be a string starting with /
VAL034errorroute.description is required and must be a string
VAL035errorroute.parameters is required and must be an array
VAL036warningroute.output is recommended for new schemas
VAL037inforoute.async is a reserved field (not executed in v2.0.0)
CodeSeverityRule
VAL040errorEach parameter must have position and z objects
VAL041errorposition.key is required and must be a string
VAL042errorposition.value is required and must be a string
VAL043errorposition.location must be insert, query, or body
VAL044errorz.primitive is required and must be a valid primitive type
VAL045errorz.options must be an array of strings
VAL046errorenum() values must not be empty
VAL047errorShared list interpolation {{listName:fieldName}} is only allowed in enum()
VAL048errorReferenced shared list must be declared in main.sharedLists
VAL049errorReferenced field must exist in the shared list’s meta.fields
VAL050errorinsert parameters must have a corresponding {{key}} in route.path
CodeSeverityRule
VAL060erroroutput.mimeType must be a supported MIME type
VAL061erroroutput.schema must be a valid schema definition
VAL062erroroutput.schema.type must match MIME type expectations
VAL063warningNested depth should not exceed 4 levels
VAL064errorproperties is only valid when type is object
VAL065erroritems is only valid when type is array
CodeSeverityRule
VAL070errorsharedLists[].ref is required and must be a string
VAL071errorsharedLists[].version is required and must be semver
VAL072errorReferenced list must exist in the list registry
VAL073errorReferenced list version must match or be compatible
VAL074errorfilter (if present) must have valid key field
VAL075warningUnused shared list reference (not used by any parameter or handler)
CodeSeverityRule
SEC001errorForbidden pattern found in schema file — no import statements allowed
SEC002errormain block contains non-serializable value (function, symbol, etc.)
SEC003errorShared list file contains forbidden pattern
SEC004errorShared list file contains executable code
SEC005errorrequiredLibraries contains unapproved package
See Security Model for the complete list of forbidden patterns and error codes.
CodeSeverityRule
LST001errorList must export list as named export
LST002errorlist.meta.name is required and must be unique
LST003errorlist.meta.version is required and must be semver
LST004errorlist.meta.fields is required and must be a non-empty array
LST005errorEach field must have key, type, and description
LST006errorlist.entries is required and must be a non-empty array
LST007errorEach entry must have all required fields
LST008errorEntry field types must match meta.fields type declarations
LST009errordependsOn references must resolve to existing lists
LST010errorCircular dependencies are forbidden
LST011errorMaximum dependency depth: 3 levels
CodeSeverityRule
GRP001errorGroup name must match ^[a-z][a-z0-9-]*$
GRP002errorMaximum 50 tools per group
GRP003errorTool reference must follow namespace/file::route format
GRP004errorAll referenced tools must be resolvable
GRP005errorDuplicate tool references are forbidden
GRP006errorGroup hash must match calculated hash
CodeSeverityRule
TST001errorEach route must have at least 1 test
TST002errorEach test must have a _description field of type string
TST003errorEach test must provide values for all required {{USER_PARAM}} parameters
TST004errorTest parameter values must pass the corresponding z validation
TST005errorTest objects must be JSON-serializable
TST006errorTest objects must only contain keys matching {{USER_PARAM}} parameter keys or _description
TST007warningRoutes with enum or chain parameters should test multiple enum values
TST008infoConsider adding tests that demonstrate optional parameter usage
See Route Tests for the complete test specification.
CodeSeverityRule
PRM001errorPrompt name must match ^[a-z][a-z0-9-]*$
PRM002errorFile must exist at declared path
PRM003errorFile must have # Title (first line)
PRM004errorFile must have ## Workflow section
PRM005warningTool references must resolve in group
PRM006errorGroup must have at least one tool
PRM007errorNo duplicate prompt names within a group
PRM008errorFilename must match prompt name
See Groups & Prompts for prompt format details.