Skip to main content
FlowMCP enforces validation rules when loading schemas, shared lists, groups, resources, and skills. 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 ^3\.\d+\.\d+$ (found "2.0.0")
  VAL031 error   tools: Maximum 8 tools 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 tool 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 ^3\.\d+\.\d+$
VAL015errormain.root is required and must be a valid URL
VAL016errormain.tools 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
VAL030errorTool name must match ^[a-z][a-zA-Z0-9]*$
VAL031errorMaximum 8 tools per schema
VAL032errortool.method is required and must be GET, POST, PUT, or DELETE
VAL033errortool.path is required and must be a string starting with /
VAL034errortool.description is required and must be a string
VAL035errortool.parameters is required and must be an array
VAL036warningtool.output is recommended for new schemas
VAL037infotool.async is a reserved field (not executed in v3.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 tool.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::type::name format
GRP004errorAll referenced tools must be resolvable
GRP005errorDuplicate tool references are forbidden
GRP006errorGroup hash must match calculated hash
CodeSeverityRule
TST001errorEach tool 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
TST007warningTools with enum or chain parameters should test multiple enum values
TST008infoConsider adding tests that demonstrate optional parameter usage
See Tests for the complete test specification.
CodeSeverityRule
PRM001errorSkill 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 skill names within a group
PRM008errorFilename must match skill name
See Groups & Skills for skill format details.
CodeSeverityRule
RES001errorresources (if present) must be an object
RES002errorResource name must match ^[a-z][a-zA-Z0-9]*$
RES003errorMaximum 2 resources per schema
RES004errorresource.description is required and must be a string
RES005errorresource.source must be 'sqlite'
RES006errorresource.database is required and must be a string ending in .db
RES007errorresource.queries is required and must be a non-empty object
RES008errorMaximum 4 queries per resource
RES009errorQuery name must match ^[a-z][a-zA-Z0-9]*$
RES010errorquery.description is required and must be a string
RES011errorquery.sql is required and must be a string
RES012errorSQL must start with SELECT (read-only enforcement)
RES013errorSQL must not contain blocked patterns (ATTACH DATABASE, LOAD_EXTENSION, PRAGMA, etc.)
RES014errorSQL must use ? placeholders (no string interpolation)
RES015errorNumber of ? placeholders must match number of parameters
RES016errorquery.parameters (if present) must be an array
RES017errorEach query parameter must have key, type, and description
RES018errorQuery parameter type must be string, number, or boolean
RES019errorQuery parameter key must match ^[a-z][a-zA-Z0-9]*$
RES020errorNo duplicate parameter keys within a query
RES021errorDatabase file must exist at schema-relative path (runtime check)
RES022warningConsider adding tests to resource queries
RES023errorSQL must not contain subqueries with write operations
CodeSeverityRule
SKL001errorskills (if present) must be an array
SKL002errorMaximum 4 skills per schema
SKL003errorEach skill entry must have name, file, and description
SKL004errorSkill name must match ^[a-z][a-z0-9-]*$
SKL005errorSkill file must end in .mjs
SKL006errorSkill file must exist at schema-relative path
SKL007errorSkill file must export skill as named export
SKL008errorskill.name must match the name in main.skills entry
SKL009errorskill.version must be 'flowmcp-skill/1.0.0'
SKL010errorskill.description is required and must be a string
SKL011errorskill.content is required and must be a non-empty string
SKL012errorskill.requires must be an object with tools, resources, and external arrays
SKL013errorEach requires.tools entry must match a tool name in the schema
SKL014errorEach requires.resources entry must match a resource name in the schema
SKL015errorskill.input (if present) must be an array
SKL016errorEach input must have key, type, description, and required fields
SKL017errorInput key must match ^[a-z][a-zA-Z0-9]*$
SKL018errorInput type must be string, number, or boolean
SKL019errorNo duplicate input keys within a skill
SKL020errorskill.output (if present) must be a string
SKL021warning{{tool:x}} placeholders should reference tools in requires.tools
SKL022warning{{resource:x}} placeholders should reference resources in requires.resources
SKL023warning{{input:x}} placeholders should reference input keys
SKL024error{{skill:x}} placeholders must reference other skills in the schema
SKL025errorNo circular skill references via {{skill:x}} placeholders
CodeSeverityRule
DEP001warningmain.routes is deprecated — use main.tools instead (v3.0.0: alias, v3.1.0: loud warning, v3.2.0: error)
DEP002infoLegacy ::routeName format in groups — use ::tool::routeName discriminator
DEP003warningprompts key in groups.json — renamed to skills
DEP004infoversion: '2.x.x' detected — run flowmcp migrate to upgrade