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:
- Scene document tools -
dsp_create_scene,dsp_validate_scene,dsp_normalize_scenetake a full scene document withschemaVersion,scene, andelements. - Scene ID tools -
dsp_get_scene,dsp_render_scene,dsp_undelete_scenetake asceneIdto reference a persisted scene. - Operations tool -
dsp_apply_opstakes asceneId,baseRevision,opsarray, and optionalmessage. - Revision tools -
dsp_diff_scene,dsp_list_revisionstake asceneIdand revision numbers. - Destructive tool -
dsp_delete_scenetakes asceneIdand a requiredconfirm: trueboundary parameter to prevent accidental deletion. - No-argument enumeration -
dsp_list_recently_deletedtakes no arguments and returns the caller’s recently-deleted scenes.
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, oruiflow) - it gates family-specific node and edge types, validation, and rendering behaviour, and omitting it triggers aMISSING_DIAGRAM_FAMILYinfo diagnostic. For automatic positioning, includelayoutStrategy. 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"
}
]
}
| Field | Required | Description |
|---|---|---|
sceneId | Yes | Target scene ID |
baseRevision | Yes | Expected current revision (optimistic concurrency) |
transactionMode | No | allOrNothing (default) or bestEffort |
ops | Yes | Array 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 }
| Field | Required | Description |
|---|---|---|
sceneId | Yes | Scene ID to retrieve |
revision | No | Specific 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" }
| Field | Required | Description |
|---|---|---|
sceneId | Yes | Scene ID to render |
format | No | svg (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:
- Scene not found (already deleted, cross-workspace, or never existed):
isError: true. confirm: falseor missing:isError: truewith no API call made.
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:
- Scene never existed, or its 24-hour grace window has expired:
isError: true.
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:
- Authentication failure:
isError: true.
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:
- Scene not found (wrong sceneId, or scene owned by a different workspace):
isError: truewith a hint to verify the sceneId + ownership. problemis empty or longer than 500 characters: rejected at the Zod validation layer before any HTTP call.
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:
- Scene not found (wrong sceneId, or scene owned by a different workspace):
isError: truewith a hint to verify the sceneId + ownership. - Scene is currently shared with support (
support->publiccross-state move):isError: truewith a hint to withdraw the support submission viadsp_make_scene_privatefirst, then re-publish.
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:
- Scene not found (wrong sceneId, or scene owned by a different workspace):
isError: truewith a hint to verify the sceneId + ownership.
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
| Variable | Required | Default | Description |
|---|---|---|---|
ZINDEX_API_KEY | no | - | 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_URL | no | https://api.zindex.ai | API 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.