MCP Tools

Zindex exposes the following tools via the Model Context Protocol. Agents discover these automatically when the MCP server is configured.

Building an agent integration? See How AI Agents Should Use Zindex for the recommended tool usage pattern, scene lifecycle, and conflict recovery behavior.

Tool input families

The tools fall into six input patterns:

Supported render formats: svg, png.

dsp_create_scene

Create a new diagram scene.

Input:

{
  "scene": {
    "schemaVersion": "0.1",
    "scene": {
      "id": "my-diagram",
      "title": "Architecture",
      "units": "px",
      "canvas": { "width": 1200, "height": 800, "background": "#ffffff" }
    },
    "elements": []
  }
}

Output:

{ "sceneId": "my-diagram", "revision": 1 }

Always declare scene-level diagramFamily (architecture, workflow, entityRelationship, sequence, network, orgchart, or uiflow) - it gates family-specific node and edge types, validation, and rendering behaviour, and omitting it triggers a MISSING_DIAGRAM_FAMILY info diagnostic. For automatic positioning, include layoutStrategy. To add icons to nodes, set "icon": "lucide:database" (or any key from the built-in icon registry).

dsp_apply_ops

Apply operations to an existing scene. Supports the full DSP operation set (createNode, createEdge, applyOps, etc.); the live enumeration is in ops.schema.json.

Input:

{
  "sceneId": "my-diagram",
  "baseRevision": 1,
  "transactionMode": "allOrNothing",
  "ops": [
    {
      "op": "createNode",
      "id": "api",
      "nodeType": "service",
      "shape": "roundedRect",
      "label": "API Gateway",
      "layout": { "mode": "absolute", "x": 100, "y": 100, "width": 200, "height": 80 }
    },
    {
      "op": "createNode",
      "id": "db",
      "nodeType": "database",
      "shape": "cylinder",
      "label": "PostgreSQL",
      "layout": { "mode": "absolute", "x": 400, "y": 100, "width": 160, "height": 90 }
    },
    {
      "op": "createEdge",
      "id": "e1",
      "from": { "elementId": "api" },
      "to": { "elementId": "db" },
      "router": "orthogonal",
      "label": "queries"
    }
  ]
}
FieldRequiredDescription
sceneIdYesTarget scene ID
baseRevisionYesExpected current revision (optimistic concurrency)
transactionModeNoallOrNothing (default) or bestEffort
opsYesArray of operations

Output:

{
  "applied": true,
  "revision": 2,
  "changedElementIds": ["api", "db", "e1"],
  "diagnostics": []
}

Returns 409 if baseRevision doesn’t match the current revision.

dsp_get_scene

Retrieve a scene by ID, optionally at a specific revision.

Input:

{ "sceneId": "my-diagram", "revision": 1 }
FieldRequiredDescription
sceneIdYesScene ID to retrieve
revisionNoSpecific revision number (defaults to latest)

Output:

{
  "sceneId": "my-diagram",
  "revision": 2,
  "scene": { "schemaVersion": "0.1", "scene": { ... }, "elements": [ ... ] }
}

dsp_validate_scene

Validate a scene document for structural and semantic correctness without persisting it.

Input:

{
  "scene": {
    "schemaVersion": "0.1",
    "scene": { "id": "test", "units": "px", "canvas": { "width": 800, "height": 600 } },
    "elements": [
      { "id": "n1", "kind": "node", "nodeType": "service", "shape": "rect", "label": "API" }
    ]
  }
}

Output (valid):

{ "ok": true, "diagnostics": [] }

Output (invalid):

{
  "ok": false,
  "diagnostics": [
    { "severity": "error", "code": "DUPLICATE_ID", "message": "Duplicate element ID: n1" }
  ]
}

dsp_normalize_scene

Normalize a scene - apply defaults, resolve layout, and compute element positions. Returns the fully normalized scene without persisting.

Input:

{
  "scene": {
    "schemaVersion": "0.1",
    "scene": { "id": "test", "units": "px", "canvas": { "width": 800, "height": 600 } },
    "elements": [
      { "id": "n1", "kind": "node", "nodeType": "service", "shape": "rect", "label": "API",
        "layout": { "mode": "absolute", "x": 50, "y": 50, "width": 200, "height": 80 } }
    ]
  }
}

Output: The full normalized scene with computed field containing resolved bounds and edge paths.

dsp_render_scene

Render a previously created scene to SVG or PNG.

Input:

{ "sceneId": "my-diagram", "format": "svg" }
FieldRequiredDescription
sceneIdYesScene ID to render
formatNosvg (default) or png

Output (SVG):

{ "mimeType": "image/svg+xml", "content": "<svg>...</svg>" }

Output (PNG):

{ "mimeType": "image/png", "content": "<base64-encoded>" }

Pass "theme" to control render aesthetics: "clean" (default), "dark", "blueprint", "sketch".

dsp_diff_scene

Compare two revisions of a scene. Returns categorized changes (added, removed, modified elements).

Input:

{
  "sceneId": "my-diagram",
  "from": 1,
  "to": 3
}

to is optional - defaults to the current revision.

Output:

{
  "sceneId": "my-diagram",
  "fromRevision": 1,
  "toRevision": 3,
  "summary": { "added": 2, "removed": 1, "modified": 1 },
  "added": ["node-x", "edge-y"],
  "removed": ["node-old"],
  "modified": ["node-a"],
  "changedConstraintIds": []
}

dsp_list_revisions

List all revisions of a scene with timestamps, messages, and change summaries.

Input:

{
  "sceneId": "my-diagram"
}

Output:

{
  "sceneId": "my-diagram",
  "currentRevision": 3,
  "revisions": [
    { "revision": 3, "createdAt": "2026-04-01T12:00:00Z", "message": "Added cache layer", "summary": { "added": 1, "removed": 0, "modified": 1 } },
    { "revision": 2, "createdAt": "2026-04-01T11:30:00Z", "message": "Initial structure", "summary": { "added": 5, "removed": 0, "modified": 0 } },
    { "revision": 1, "createdAt": "2026-04-01T11:00:00Z", "message": null, "summary": null }
  ]
}

dsp_delete_scene

Soft-delete a persisted scene. The scene is recoverable for 24 hours via dsp_undelete_scene; after that the scene is permanently removed by a scheduled cron and cannot be restored.

Confirm with the human before calling. Tell them which scene you’re about to delete (by id and title), and wait for their explicit confirmation. Never call this as part of a cleanup pass, batch operation, or “let me start over” reset without per-scene human confirmation. The server enforces confirm: true and rate-limits to 10 deletions per workspace per minute, but the human-in-the-loop confirmation is your responsibility.

Input:

{
  "sceneId": "my-diagram",
  "confirm": true
}

confirm must be exactly true. The tool returns an error result without calling the API when confirm is missing or false.

Output:

{
  "deleted": true,
  "sceneId": "my-diagram",
  "soft": true,
  "note": "Scene is soft-deleted. It is recoverable for 24 hours via dsp_undelete_scene. After that it is permanently removed."
}

Errors:

dsp_undelete_scene

Restore a soft-deleted scene during the 24-hour grace window. After the grace window the scene has been hard-deleted by a scheduled cron and cannot be restored.

Input:

{
  "sceneId": "my-diagram"
}

Output:

{
  "restored": true,
  "sceneId": "my-diagram",
  "revision": 3
}

Errors:

dsp_list_recently_deleted

Enumerate scenes in the caller’s workspace that were soft-deleted within the past 24 hours and are still recoverable. Use this when the human asks to restore a previously-deleted scene but does not remember the sceneId - read the returned titles back to them, then call dsp_undelete_scene on the one they confirm.

Input:

{}

The tool takes no arguments. The caller is identified by their API key.

Output:

{
  "items": [
    {
      "sceneId": "my-diagram",
      "title": "Architecture",
      "deletedAt": "2026-05-12T08:00:00Z",
      "expiresAt": "2026-05-13T08:00:00Z"
    }
  ]
}

title is null when the scene had no title set. expiresAt is the timestamp at which the hard-delete cron will permanently remove the row. Empty items array when nothing is recoverable.

Errors:

dsp_submit_to_support

Submit a persisted scene to Zindex support when you cannot resolve a rendering, validation, or layout issue alone. The scene’s privacy state transitions to support; Zindex admins can view the scene to diagnose the issue. The customer can withdraw at any time from the playground; every admin view is recorded in the customer’s audit log.

Confirm with the human before calling. This tool exposes the scene (raw or anonymized, see below) to Zindex support. Tell the human which scene you’re submitting (by id and title) and what anonymize value you’re going to send, then wait for their explicit confirmation. The customer-facing chrome at https://zindex.ai/playground?id=<sceneId> reflects the shared state and offers a one-click withdraw; share that link with the human after the tool returns so they can monitor the submission.

Input:

{
  "sceneId": "my-diagram",
  "problem": "Labels overlap on the orders graph; the layout engine fans them out cleanly until ~30 elements then collisions appear.",
  "anonymize": true
}

problem is a 1-500 character description of what you tried + what you’re seeing. anonymize defaults to false. When acting without explicit human confirmation, default to anonymize: true - the platform replaces labels and IDs with same-width random characters before admins see the scene, so support can still diagnose layout / routing / clipping issues without seeing the customer’s actual content. The customer can re-submit with anonymize off if they decide raw labels are fine.

Output:

{
  "sceneId": "my-diagram",
  "privacyStatus": "support",
  "supportSubmittedAt": "2026-05-19T10:00:00.000Z",
  "supportAnonymized": true,
  "auditUrl": "https://zindex.ai/playground?id=my-diagram"
}

auditUrl is the deep link the customer uses to monitor the submission state, see the audit trail of admin views, and withdraw.

Errors:

Scope: The tool requires a persisted sceneId. There is no inline-scene form - if you need to share a stateless render with support, persist it first via dsp_create_scene, then submit.

dsp_publish_scene

Make a persisted scene publicly addressable at https://zindex.ai/s/<sceneId>. Anyone with the URL - including search engines and AI crawlers - can view the rendered scene and its source JSON via the unauthenticated GET /v1/public/scenes/:id endpoint.

Confirm with the human before calling. This is the only MCP tool that exposes customer content to the public Internet. Repeat back which scene (by id and any known title) you’re about to publish AND that the source JSON will be fetchable without authentication. Wait for explicit confirmation.

Input:

{
  "sceneId": "my-diagram"
}

Output:

{
  "sceneId": "my-diagram",
  "privacyStatus": "public",
  "madePublicAt": "2026-05-20T09:00:00.000Z",
  "publicUrl": "https://zindex.ai/s/my-diagram"
}

madePublicAt is preserved across re-publish cycles. Share publicUrl with the human so they can verify what visitors see.

Errors:

Hosted-content policy: Public scenes are subject to Zindex’s hosted-content policy. Visitors see an in-page “Report this scene” link; reports go to the Zindex moderation queue. If a scene violates the policy, Zindex can disable the public URL and email the owner the reason verbatim. The scene document itself stays in the workspace and can be re-published if the issue is addressed. Full policy: Terms of service §5 Publicly-hosted scenes.

dsp_make_scene_private

Revert a scene to private. The public URL stops resolving immediately - the public read endpoint sets Cache-Control: no-store so revocation propagates without a TTL wait. The scene document itself is unchanged; the owner can re-publish later via dsp_publish_scene.

This is also the canonical “undo” for dsp_submit_to_support - calling it on a scene currently shared with support withdraws the submission.

No confirmation gate. Making a scene private strictly reduces exposure.

Input:

{
  "sceneId": "my-diagram"
}

Output:

{
  "sceneId": "my-diagram",
  "privacyStatus": "private"
}

Errors:

Configuration

The MCP server is a thin HTTP client to the Zindex API. With ZINDEX_API_KEY configured the server runs in authenticated mode and exposes the full MCP tool set above (persisted scenes, revisions, diff, soft-delete recovery, support submission). Without the key it runs in anonymous mode and exposes only the public-endpoint tools (dsp_validate_scene, dsp_normalize_scene, dsp_render_scene with inline-scene mode only). See MCP Setup > Two modes for the full mode comparison.

{
  "mcpServers": {
    "zindex": {
      "command": "npx",
      "args": ["@zindex-ai/mcp"],
      "env": {
        "ZINDEX_API_KEY": "dsp_sk_..."
      }
    }
  }
}

Omit the env block entirely to install in anonymous mode.

Environment variables

VariableRequiredDefaultDescription
ZINDEX_API_KEYno-API key. Without one the server runs in anonymous mode (public-endpoint tools only); with one it runs in authenticated mode (full MCP tool set). Get a free key at zindex.ai/signup.
ZINDEX_API_URLnohttps://api.zindex.aiAPI base URL. Override only for staging or self-hosted.

The startup banner on stderr names the active mode and tool count. npx @zindex-ai/mcp --help and --version work without a key in either mode.