MAP Docs

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

ChangeAction
Adding an optional fieldSame major version (v1.0.x)
Removing an unused fieldSame major version (v1.0.x)
Renaming a field with a serde aliasSame major version
Changing a field typeMajor version bump (v2.0.0)
Removing a required fieldMajor version bump
Renaming an operationMajor 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

On this page