Purpose: make XRAI readable/writable by any MCP-compatible AI agent (Claude Desktop, Cursor, Cline, OpenAI agents, Gemini-with-MCP-shim).
Status: 8 of 11 tools shipped today (see ✅/⚠ markers below). Active impl at mcp-server/src/index.ts — @h3m/spatial-intelligence-mcp npm package. Remaining 3 tools ship Week 2.
All tools return JSON. All tools handle malformed input gracefully (Postel’s law).
Legend: ✅ = shipped today · ⚠ = spec only, Week 2
| Tool | Ship | Input | Output | Purpose |
|---|---|---|---|---|
compose_scene |
✅ | {description: string, clear_existing?: bool} |
scene + XRAI | NL → multi-object scene composition |
add_object |
✅ | {name, type, position?, scale?, rotation?, material?, color?, animation?} |
added object | Single-object precise spatial placement |
query_scene |
✅ | {filter?: string} |
objects + bounds | Inspect scene state + spatial relationships |
modify_object |
✅ | {name, position?, scale?, rotation?, material?, color?, animation?, vfx?} |
modified object | Change properties / attach VFX |
export_xrai |
✅ | {include_metadata?: bool} |
XRAI v1.0 JSON | Export scene as spatial interchange |
get_capabilities |
✅ | {} |
feature manifest | Enumerate primitives/materials/anims/VFX/brushes/creators |
paint_emit_stroke |
✅ | {brush_guid, points: {x,y,z}[], color?, width?, audio_reactive?, id?} |
XRAI object.paint-stroke fragment |
Free-form stroke, hand-drawn or generated, rendered as tube/quad-strip/hull |
paint_emit_parametric |
✅ | {creator: "spiral"\|"sphere"\|"lsystem"\|"tree", anchor, end_point?, params?, brush_guid?, seed?, id?} |
XRAI object.parametric-stroke fragment (sparse generator rule) |
Procedural stroke, sparse-seed DNA expanded by renderer |
xrai.parse |
⚠ | {doc: string} |
{valid, normalized, errors} |
Validate + normalize arbitrary JSON as XRAI v1.0 |
xrai.walk |
⚠ | {graph: XRAI, from: id, max_hops: int} |
subgraph | Traverse associative trails (memex-style) |
xrai.render |
⚠ | {graph: XRAI, target: "unity\|threejs\|unreal\|playcanvas\|webxr\|visionos"} |
bootstrap code | Emit runtime-specific loader + scene setup |
paint.emit_stroke// request
{
"brushGuid": "2d35bcf0-e4d8-452c-97b1-3311be063130", // optional; defaults to Flat
"brushName": "Flat", // alternative to brushGuid
"points": [[0,0.1,-1.5], [0.1,0.15,-1.5], [0.2,0.2,-1.5]],
"widths": [0.01, 0.012, 0.015], // optional; defaults to 0.01 per point
"color": "#00ffff", // optional; defaults to "#ffffff"
"audioReactive": true // optional; defaults to descriptor.m_AudioReactive
}
// response
{
"xrai_version": "1.1",
"scene": {
"entities": [{
"id": "stroke_<uuid>",
"type": "object.paint-stroke",
"params": {
"brushGuid": "2d35bcf0-e4d8-452c-97b1-3311be063130",
"brushName": "Flat",
"color": "#00ffff",
"audioReactive": true,
"points": [[0,0.1,-1.5], [0.1,0.15,-1.5], [0.2,0.2,-1.5]],
"widths": [0.01, 0.012, 0.015]
}
}]
}
}
paint.emit_parametricCreators (named, map 1:1 to Portals.Paint.Parametric classes in Unity runtime):
| creator | params schema | behavior |
|---|---|---|
sphere |
{ segments?: int = 48, spiralTurns?: float = 3 } |
Lat-lon spiral on sphere surface. Radius = distance(anchor, end). Center = midpoint. |
spiral |
{ turns?: float = 3, radiusRatio?: float = 0.3, pointsPerTurn?: int = 16 } |
3D spiral along axis anchor→end. |
lsystem |
{ axiom?: string = "F", rule?: string = "FF[+F][-F][&F][^F]", iterations?: int = 3, angleDeg?: float = 22.5 } |
Turtle grammar: F=forward, +/-=yaw, &/^=pitch, \// =roll, [/] =push/pop. |
// request (grow a spiral)
{
"creator": "spiral",
"params": { "turns": 5, "radiusRatio": 0.4 },
"anchor": [0, 0, -1.0],
"end": [0, 1.5, -1.0],
"brushName": "Neon",
"color": "#ff00ff"
}
// response
{
"xrai_version": "1.1",
"scene": {
"entities": [{
"id": "param_<uuid>",
"type": "object.parametric-stroke",
"params": {
"creator": "spiral",
"creatorParams": { "turns": 5, "radiusRatio": 0.4 },
"anchor": [0, 0, -1.0],
"end": [0, 1.5, -1.0],
"brushGuid": "<resolved from brushName>",
"color": "#ff00ff",
"seed": <int> // for reproducibility across runtimes
},
"baked": { // optional, for runtimes that don't have creator impl
"points": [[...], ...],
"widths": [...]
}
}]
},
"metadata": {
"XRAI_generators": [{ // voxel spec 023 cross-wire
"type": "parametric_stroke",
"entityId": "param_<uuid>",
"seed": <int>
}]
}
}
Sparse-seed principle (constitution §XRAI Philosophy): response embeds BOTH the generator rule (creator + params + seed) AND the baked point list. Runtimes with native creator impl (e.g. Portals Unity) expand from rule for perfect reproducibility. Runtimes without (e.g. Three.js v1 viewer) fall back to baked points. File size still tiny — ~200 bytes for a complex spiral vs. KB of raw points.
Voxel integration (spec 023 XRAI_generators): paint.emit_parametric outputs the metadata.XRAI_generators hint so voxel-world loaders can compose parametric strokes with voxel generators into one scene without rerouting through Unity. Single voice command "grow a spiral staircase" = one paint.emit_parametric(spiral) call + one xrai.emit call for the staircase voxel-world generator, merged via xrai.merge.
{valid: false, errors: []} insteadxrai.tool_info() returns the tool schema for discovery xrai-cloud plan)Conforms to Model Context Protocol spec (Anthropic, Nov 2024):
// server.ts (stub — full impl Week 2)
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
const server = new Server({ name: "xrai", version: "0.1.0" });
server.setRequestHandler("tools/list", async () => ({
tools: [
{ name: "xrai.validate", description: "...", inputSchema: {...} },
{ name: "xrai.merge", description: "...", inputSchema: {...} },
// ... all 9 xrai.* tools
{ name: "paint.emit_stroke", description: "...", inputSchema: {...} },
{ name: "paint.emit_parametric", description: "...", inputSchema: {...} },
// 11 tools total
]
}));
server.setRequestHandler("tools/call", async (req) => {
switch (req.params.name) {
case "xrai.validate": return validate(req.params.arguments);
case "xrai.merge": return merge(req.params.arguments);
// ...
case "paint.emit_stroke": return paintEmitStroke(req.params.arguments);
case "paint.emit_parametric": return paintEmitParametric(req.params.arguments);
}
});
npm i @xrai/mcp-server
# Or use npx without install:
npx @xrai/mcp-server
Add to Claude Desktop / Cursor / Cline config:
{
"mcpServers": {
"xrai": { "command": "npx", "args": ["-y", "@xrai/mcp-server"] }
}
}
Instantly, any MCP-compatible agent gains spatial cognition primitives.