Schemas
Every protocol operation has a JSON Schema for request and response. Versioned, generated from Rust types via schemars.
Every protocol operation has a published JSON Schema for its request and response. These are the OCIP contracts — Open Cross-Inter-Protocol — and they live in /Volumes/L1feAI/l1feosx/map/schemas/.
Layout
schemas/
├── macs/v1/
│ ├── index.json # protocol metadata + operation list
│ ├── operations.auth_negotiation.request.json
│ ├── operations.auth_negotiation.response.json
│ ├── operations.generate_challenge.request.json
│ ├── operations.generate_challenge.response.json
│ └── ...
├── mind/v1/
│ ├── index.json
│ ├── operations.store_memory.request.json
│ ├── operations.store_memory.response.json
│ └── ...
├── marc/v1/
│ ├── index.json
│ └── ...
└── ... (30+ total)Each protocol has a directory; each version is a subdirectory.
index.json
{
"protocol": "MARC",
"version": "v1.0.0",
"kind": "agent",
"plane": "II",
"operations": [
"reasoning_task",
"publish_model",
"share_model",
"causal_analysis"
],
"stability": "stable",
"last_changed": "2026-05-20"
}Operation schemas
Each operation has two files — request and response. Both are standard JSON Schema with extensions:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://schemas.multiagentic.dev/marc/v1/reasoning_task.request.json",
"title": "MARC::reasoning_task request",
"type": "object",
"required": ["intent", "budget"],
"properties": {
"intent": {
"type": "string",
"description": "Natural-language statement of the reasoning intent."
},
"premises": {
"type": "array",
"items": { "type": "string", "format": "uri" },
"description": "MARS-addressable premises."
},
"world_model_snapshot": {
"type": "string",
"format": "uri",
"pattern": "^mind://snapshot/"
},
"budget": {
"type": "object",
"required": ["tokens", "deadline_ms"],
"properties": {
"tokens": { "type": "integer", "minimum": 1, "maximum": 1000000 },
"deadline_ms": { "type": "integer", "minimum": 100, "maximum": 600000 }
}
}
},
"$comment": "Generated from schemars::JsonSchema on MarcReasoningRequest"
}Generation
Schemas are not hand-written. They are generated from the Rust request/response types using schemars:
use schemars::JsonSchema;
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
pub struct ReasoningTaskRequest {
pub intent: String,
pub premises: Vec<String>,
#[serde(default)]
pub world_model_snapshot: Option<String>,
pub budget: Budget,
}A workspace script (scripts/regenerate-schemas.sh) walks every protocols/*-lib crate and emits the JSON Schemas. The CI pipeline asserts the committed schemas match the generated ones — drift is a build failure.
Versioning
Versions are directory-level:
schemas/
├── mind/
│ ├── v1/
│ └── v2/A new version is a copy of the previous one with the type changes applied. The engine routes by the requested version field. Multiple versions can be served concurrently during a migration.
Compatibility levels
| Change | Action |
|---|---|
| Adding an optional field | Same major version (v1.0.x) |
| Removing an unused field | Same major version (v1.0.x) |
| Renaming a field with a serde alias | Same major version |
| Changing a field type | Major version bump (v2.0.0) |
| Removing a required field | Major version bump |
| Renaming an operation | Major version bump |
The engine refuses to register two protocols at the same name:version — versioning is mandatory for breaking changes.
Consuming schemas
In Rust
use schemars::schema::RootSchema;
let raw = std::fs::read_to_string("schemas/marc/v1/operations.reasoning_task.request.json")?;
let schema: RootSchema = serde_json::from_str(&raw)?;In TypeScript (Zod)
import { z } from 'zod';
// Auto-generated from the JSON Schema
export const ReasoningTaskRequestSchema = z.object({
intent: z.string(),
premises: z.array(z.string()).optional(),
world_model_snapshot: z.string().regex(/^mind:\/\/snapshot\//).optional(),
budget: z.object({
tokens: z.number().int().min(1).max(1_000_000),
deadline_ms: z.number().int().min(100).max(600_000)
})
});
export type ReasoningTaskRequest = z.infer<typeof ReasoningTaskRequestSchema>;The TypeScript SDK ships these Zod schemas under @l1fe/mind-wm/schemas/.
Externally (any language)
Schemas are published at https://schemas.multiagentic.dev/<protocol>/<version>/.... Any JSON Schema validator works. The CLI also ships a local cache:
map mcp list --json | jq '.tools[] | select(.name=="map.marc.reasoning_task") | .inputSchema'Schema-bound validation
The engine validates inbound payloads against the JSON Schema before reaching the protocol module's invoke. Validation failures return ProtocolError::InvalidPayload(reason) with the schema path that failed.
422 Unprocessable Entity
{
"error": {
"code": "invalid_payload",
"message": "/budget/tokens: expected integer, got string",
"context": { "schema": "marc/v1/operations.reasoning_task.request.json" }
}
}This means the protocol module never sees malformed input. The schema is the canonical contract; the implementation is downstream.
Extension fields
Schemas allow free-form extension under a top-level extended property:
{
"extended": {
"vendor_specific_field": { ... }
}
}Protocols use this for forward-compatibility — new optional fields can be added under extended without bumping the major version.
For tooling and codegen, the canonical source is the published schema URLs. The Rust types are an implementation detail. Other implementations (in any language) are expected to consume the published JSON Schemas directly.
See also
- Engine handle_request
- Wire protocol
- MCP — schemas are reused for MCP
inputSchema