Skip to main content

Backend contract schemas

The SDK publishes language-neutral JSON Schemas so backend teams can design payloads without reverse-engineering TypeScript or frontend normalizers.

Use contracts/implement-command-center-contract to implement any existing manifest entry in another language. More focused workflows live under contracts/ for resource collections and bulk actions. These installed skills consume the published bundle and never redefine or modify it.

Package layout​

command-center-sdk/
contracts/
README.md
manifest.json
schemas/
*.schema.json
fixtures/
valid/
invalid/

The directory ships in the npm tarball. manifest.json is the canonical machine-readable contract documentation: it records each stable contract ID, schema $id, public npm path, role, matching TypeScript type, and fixture list. The referenced schemas define the bytes. This guide explains usage and intentionally does not maintain another contract catalog.

The manifest also indexes command-center.static_site_iframe@v1 with role iframe-protocol. That schema lets non-TypeScript hosts and static sites validate the additive version-one iframe messages, including delegated FastAPI request/response/error bytes. It does not define how the host obtains credentials from its backend. The host backend remains authoritative for issuing credentials, source/target access, organization policy, origin policy, expiry, CORS, and FastAPI authorization; the host adapter maps the backend's response into the public SDK resolver shape. A backend-confirmed, retryable runtime start maps to runtime_starting; permission and origin denials must not use that code. HTTP 401, 403, 404, 502, 503, and 504 from the target runtime remain HTTP responses classified by the SDK child transport and are not credential-error messages.

The same v1 schema additively includes FastAPI WebSocket ticket request, cancellation, response, and sanitized error messages. The request carries only a correlation ID, canonical release UID, and normalized absolute path. The response carries the correlated binding, WebSocket URL, canonical reserved ticket subprotocol, and expiry; it never carries a separate raw ticket, user, Origin, session, or application protocol list. Runtime checks additionally enforce exact request/response correlation, child Origin binding, secure scheme, future expiry, protocol-list limits, and one native constructor attempt. The host adapter maps its backend's ticket response into the SDK resolver result.

The v1 schema also includes the platform request messages of SDK ADR 013: platform-request, platform-response, platform-error, and platform-cancel. They cross only between the host and the iframe. The host sends each request to the platform itself, with its own credential, so no backend implements or validates these messages and no platform route changes. The request carries the public uid of the person the child believes is signed in, a method, an absolute path and query, accept and content-type, and a text body; the response carries a status, content-type, and a text or base64 body. Runtime checks additionally refuse a request whose userUid is not the host's current person, count the 1 MiB request and 8 MiB response caps in bytes, correlate answers, cancel, time out, and limit a child to 16 requests in flight.

The normalized collection is not automatically a requirement for every raw product endpoint. An existing {count, results} API can keep that envelope when its frontend adapter maps it to ResourceListResult<T>. An endpoint claiming a schema contract must validate directly against it.

MCP platform skill catalog ownership​

The authenticated MCP platform-skill catalog is intentionally not another entry in this package's contract manifest. The backend already owns its version-2 resource manifest, mainsequence://platform/ontology, and the ontology's skill_resources membership. The packaged CLI consumes that existing protocol through resources/list and resources/read; it does not publish a competing command-center.* catalog shape.

Each catalog revision has one manifest hash; its skills are listed in ontology.skill_resources under the manifest schema version, and list and read metadata match that revision. Compatible installed SDKs accept additive skills dynamically without a new npm contract or hard-coded skill list. Breaking metadata semantics require a new backend manifest version and an SDK compatibility update. Run command-center-sdk skills sync --path . --json to validate the complete live revision before it is written under .agents/skills/ms-command-center/. The Python Main Sequence SDK owns .agents/skills/mainsequence/; the Command Center SDK installs nothing there.

Resource-list discovery and bulk-action lifecycle​

command-center.resource_discovery@v1 is the backend response that lets a backend engineer extend a resource list without reading React. It owns ordered UI identity fields, visible search/filter/ ordering controls, ordered columns, and actions available to the current caller and semantic scope. Collection endpoints remain authoritative for rows and pagination.

The backend returns trusted local renderer IDs without value_path; a new generic column provides both a safe dot-delimited value_path and one of the schema's supported data_type values. The backend never returns JSX, component names, CSS, callbacks, or executable expressions.

Example:

{
"contract": "command-center.resource_discovery@v1",
"resource": {
"id": "records",
"label": "Records",
"item_label": "record",
"identity": { "fields": ["uid"] }
},
"list": {
"controls": {
"search": { "placeholder": "Search records", "fields": ["name", "uid"] },
"filters": [],
"ordering": ["name"]
},
"columns": [
{
"id": "name",
"header": "Record",
"default_visible": true,
"hideable": false,
"sortable_key": "name"
}
]
},
"bulk_actions": [
{
"id": "archive",
"label": "Archive records",
"endpoint": "/records/actions/archive/",
"preflight_endpoint": "/records/actions/archive/preflight/",
"method": "POST",
"tone": "danger",
"selection_modes": ["explicit", "all_matching"],
"confirmation": {
"title": "Archive records",
"word": "ARCHIVE",
"button_label": "Archive",
"warning": "Archived records are unavailable."
},
"options": []
}
]
}

A column's optional importance (primary, secondary, or tertiary) is the responsive signal the SDK uses on small screens: the primary column is the row's identity and the title of a stacked row, secondary columns stay visible from 640px, and tertiary columns from 768px. Annotate columns deliberately; exactly one should be primary. A backend that omits the field gets the SDK's default (the first visible column is primary, the rest secondary).

Discovery query parameters contain semantic search, visible filters, and explicitly declared hidden host scope only. Pagination and current sort presentation are rejected. User-specific responses use private revalidation with ETag; browser transports can honor the backend's Cache-Control: private, max-age=0, must-revalidate and Vary headers normally.

The SDK sends the same request body to the advertised preflight and execution endpoints:

{
"selection": {
"mode": "all_matching",
"query": {
"search": "risk",
"filters": {
"status": "active"
}
}
},
"options": {}
}

Preflight returns the execution decision:

{
"allowed": false,
"detail": "One record is protected.",
"matched_count": 2,
"blockers": ["Protected records cannot be archived."],
"warnings": []
}

Domain-specific preflight properties are allowed and preserved in the raw result. The base fields above retain their documented meaning.

Resolve the bundle​

After installing a pinned SDK version, resolve the manifest through the package export:

import { createRequire } from "node:module";
import { readFile } from "node:fs/promises";

const require = createRequire(import.meta.url);
const manifestPath = require.resolve(
"@dev-mainsequence/command-center-sdk/contracts/manifest.json",
);
const manifest = JSON.parse(await readFile(manifestPath, "utf8"));

Register all manifest schemas with a draft-2020-12 validator before validating fixtures or payloads. The resource-collection schema references the bulk-action action definition by its stable URN, so registering only one file is insufficient.

Non-Node backends can unpack the pinned npm tarball or vendor contracts/ from an exact repository release tag. Production validation must not depend on a moving main branch.

The package-level schema README includes a Python validator example.

Compatibility rules​

  • Released contract IDs, filenames, and $id URNs are immutable.
  • Additive compatible changes require updated positive and negative fixtures.
  • Breaking semantics require a new vN schema and contract ID.
  • TypeScript types, runtime parsers, schemas, manifest entries, and fixtures change together.
  • Backend handoffs must state rollout order, defaults, mixed-version behavior, and rollback.

Portable JSON Schema cannot enforce uniqueness by one object property. Runtime parsers additionally require unique action IDs, option keys, filter keys, and ordering values. Schemas mark those rules with $comment where applicable.

Adding the SDK schema bundle documents SDK-owned contracts and does not itself migrate stored data. A backend changes only when an endpoint opts into or evolves one of these contracts.