# VAPORA Validation Schemas Nickel schemas for runtime validation of MCP tools and agent tasks. ## Directory Structure ``` schemas/ ├── tools/ # MCP tool parameter validation │ ├── kanban_create_task.ncl │ ├── kanban_update_task.ncl │ ├── assign_task_to_agent.ncl │ ├── get_project_summary.ncl │ └── get_agent_capabilities.ncl │ └── agents/ # Agent task assignment validation └── task_assignment.ncl ``` ## Schema Format Nickel schemas define: - **Field types** (String, Number, Bool, Array, Object) - **Required/optional fields** (via `default` values) - **Validation contracts** (NonEmpty, Email, UUID, Range, Pattern, etc.) - **Documentation** (via `doc` annotations) ### Example ```nickel { tool_name = "example_tool", parameters = { # Required field with contracts user_id | String | doc "User UUID" | std.string.NonEmpty | std.string.match "^[0-9a-f]{8}-[0-9a-f]{4}-...$", # Optional field with default priority | Number | doc "Priority score (0-100)" | std.number.between 0 100 | default = 50, }, } ``` ## Supported Contracts | Contract | Description | Example | |----------|-------------|---------| | `std.string.NonEmpty` | String cannot be empty | Required text fields | | `std.string.length.min N` | Minimum length | `min 3` for titles | | `std.string.length.max N` | Maximum length | `max 200` for titles | | `std.string.match PATTERN` | Regex validation | UUID format | | `std.number.between A B` | Numeric range | `between 0 100` | | `std.number.greater_than N` | Minimum value (exclusive) | `> -1` | | `std.number.less_than N` | Maximum value (exclusive) | `< 1000` | | `std.string.Email` | Email format | user@example.com | | `std.string.Url` | URL format | https://... | | `std.string.Uuid` | UUID format | xxxxxxxx-xxxx-... | | `std.enum.TaggedUnion` | Enum validation | `[| 'low, 'high |]` | ## Usage Schemas are loaded by `ValidationPipeline` at runtime: ```rust use vapora_shared::validation::{SchemaRegistry, ValidationPipeline}; let registry = Arc::new(SchemaRegistry::new(PathBuf::from("schemas"))); let pipeline = ValidationPipeline::new(registry); // Validate MCP tool input let result = pipeline.validate("tools/kanban_create_task", &input).await?; if !result.valid { return (StatusCode::BAD_REQUEST, Json(result.errors)); } ``` ## Testing Schemas Validate schema syntax: ```bash nickel typecheck schemas/tools/kanban_create_task.ncl ``` Export schema as JSON: ```bash nickel export schemas/tools/kanban_create_task.ncl ``` Query specific field: ```bash nickel query --field parameters.title schemas/tools/kanban_create_task.ncl ``` ## Adding New Schemas 1. Create `.ncl` file in appropriate directory 2. Define `tool_name` or `schema_name` 3. Define `parameters` or `fields` with types and contracts 4. Add `doc` annotations for documentation 5. Test with `nickel typecheck` 6. Restart services to reload schemas (or use hot-reload) ## Hot Reload Invalidate cached schema without restart: ```rust registry.invalidate("tools/kanban_create_task").await; ``` Invalidate all schemas: ```rust registry.invalidate_all().await; ```