MCP tools
The Zindex MCP server is at https://api.zindex.ai/mcp. There is nothing to install. Your client connects over HTTPS (Streamable HTTP), and signs you in with your Zindex account (OAuth) or sends an API key. The tools run the same code as the REST API, so a diagram saved here is the same diagram over REST and in every other client.
Without signing in, diagram_validate and unsaved previews from diagram_render work. The first time a tool needs your account, the client opens a Zindex page where you sign in and choose Allow.
No tool exports a diagram’s whole history or the whole workspace, because a tool’s result goes into the model’s context and a whole history can run to megabytes. A diagram’s history downloads from its page on the dashboard, and every diagram at once from Settings → Account; the REST API has both, as GET /v1/diagrams/{id}/export and GET /v1/workspace/export.
| Tool | Does | Needs an account |
|---|---|---|
diagram_find | Lists the workspace’s diagrams | Yes |
diagram_get | Reads a diagram as an outline, scene JSON or Mermaid, at any version | Yes |
diagram_validate | Checks a scene or Mermaid text without saving it | No |
diagram_create | Saves a new diagram | Yes |
diagram_edit | Changes a diagram, making the next revision | Yes |
diagram_render | Returns SVG and PNG links for a version: permanent once the diagram is published | Yes, except for an unsaved scene or mermaid |
diagram_history | Lists versions, or compares two | Yes |
diagram_delete | Deletes a diagram, or restores one deleted in the last 24 hours | Yes |
diagram_share | Publishes or unpublishes a diagram, makes (Pro or Team) or revokes share links, reports a version, or sends Zindex feedback | Yes |
Sign in with your Zindex account
Clients that support MCP sign-in need only the URL https://api.zindex.ai/mcp:
- claude.ai and the Claude apps: add a custom connector with that URL. On Claude’s Team and Enterprise plans, an Owner adds the connector first. Claude opens the Zindex page when you connect, or the first time a tool needs your account, depending on what you choose when adding it.
- ChatGPT: on the web, turn on developer mode, then add a connector with that URL and OAuth sign-in. ChatGPT opens the Zindex page the first time a tool needs your account.
- Claude Code:
claude mcp add --transport http zindex https://api.zindex.ai/mcp, then run/mcpand choose to authenticate. - Cursor: add Zindex to Cursor, then sign in when Cursor asks.
- VS Code: add Zindex to VS Code, then sign in when VS Code asks.
The Zindex plugin installs this server together with the Zindex skill, the guide agents follow when they use the tools, in Claude Code, Claude, VS Code, Cursor and Gemini CLI. Its README has the steps for each.
On that page you choose the workspace the app works in, when you belong to a team workspace, and its access. With Read and write, the app can find, read, save, change, render and delete the workspace’s diagrams, make them public, make share links to them, report a problem with one to Zindex support, and send Zindex feedback, acting as you. With Read only, it can find, read, render and compare them, and every change answers READ_ONLY; a viewer in the workspace, or a client that asks for the OAuth scope diagrams:read alone, gets read only. An app works in one workspace: to work in two, connect it once for each (Workspaces). Every app you allow is listed under Dashboard → API keys → Connected apps for its workspace, where you can disconnect it. Disconnecting it, resetting your password, deleting your account or leaving its workspace signs it out, and the workspace’s owners can disconnect it too. claude.ai, the Claude apps and ChatGPT can’t send a key, so they connect only by signing in. If another client can’t complete sign-in, connect it with an API key, and tell us through the contact page.
Connect with an API key
Clients that can send a header, such as Claude Code, Cursor and VS Code, can use an API key instead of signing in. Sign up at zindex.ai/signup and create a key under Dashboard → API keys. Keys start with dsp_sk_. A key works in the workspace selected when it is made, with Read and write or Read only access, as a connected app does.
Claude Code:
claude mcp add --transport http zindex https://api.zindex.ai/mcp \
--header "Authorization: Bearer dsp_sk_your_key"
Cursor, in ~/.cursor/mcp.json (or .cursor/mcp.json in a project):
{
"mcpServers": {
"zindex": {
"url": "https://api.zindex.ai/mcp",
"headers": { "Authorization": "Bearer dsp_sk_your_key" }
}
}
}
VS Code, in .vscode/mcp.json. VS Code asks for the key once and stores it:
{
"servers": {
"zindex": {
"type": "http",
"url": "https://api.zindex.ai/mcp",
"headers": { "Authorization": "Bearer ${input:zindex-key}" }
}
},
"inputs": [
{ "id": "zindex-key", "type": "promptString", "description": "Zindex API key", "password": true }
]
}
Other clients: point any client that supports Streamable HTTP at https://api.zindex.ai/mcp and send Authorization: Bearer <your key>. The server keeps no session state, so it works behind any proxy. It speaks both the 2026-07-28 protocol and the earlier 2025 revisions.
Run it locally with npm
For hosts that start MCP servers as local commands over stdio, such as Claude Desktop, the npm package @zindexai/mcp forwards every call to this server, so it offers the same tools and instructions, and they stay current without updating the package. It needs Node.js 18 or later and takes an API key from ZINDEX_API_KEY; sign-in is only for clients that connect over HTTPS. Without a key it still starts: diagram_validate, and diagram_render with an unsaved scene or mermaid, work, and the other tools return AUTH_REQUIRED, naming ZINDEX_API_KEY.
In Claude Desktop’s claude_desktop_config.json (Cursor’s mcp.json takes the same entry), then restart the app:
{
"mcpServers": {
"zindex": {
"command": "npx",
"args": ["-y", "@zindexai/mcp"],
"env": {
"ZINDEX_API_KEY": "dsp_sk_..."
}
}
}
}
In Claude Code:
claude mcp add zindex -e ZINDEX_API_KEY=dsp_sk_... -- npx -y @zindexai/mcp
Any other host: run npx -y @zindexai/mcp with ZINDEX_API_KEY in its environment.
| Variable | Default | Meaning |
|---|---|---|
ZINDEX_API_KEY | none | Your API key. Without one, only diagram_validate and unsaved previews work |
ZINDEX_MCP_URL | https://api.zindex.ai/mcp | The server the package forwards to |
ZINDEX_API_URL, the setting before 1.0, still works and means <url>/mcp.
Through the package, every confirmation comes back as CONFIRMATION_REQUIRED with a confirm token (Confirmation). A tool call the server refuses over HTTP comes back as a tool error with the refusal’s code and, when it has one, retryAfter in seconds: RATE_LIMITED for a 429, BUSY for a 503 and DRAW_TIMEOUT for a 422 when the answer names no code. Other HTTP errors reach the app as an error whose message carries the server’s answer.
Check it. npx -y @zindexai/mcp --version and --help don’t contact Zindex or need a key. When the server starts, it writes one line to stderr, which your host’s MCP log shows: Zindex MCP server vX.Y.Z running on stdio, connected to https://api.zindex.ai/mcp. Without a key, the line goes on to say that only diagram_validate and unsaved previews work.
If it fails. “could not connect” at start, followed by “The API key was rejected”, means ZINDEX_API_KEY is wrong, revoked or expired: create a new key at zindex.ai/dashboard/api-keys. Followed by “Rate limit exceeded” or “Zindex is busy”, it means the server answered 429 or 503. Wait the time it gives, or a minute, and restart the host. Otherwise check the network, and ZINDEX_MCP_URL if you set it. AUTH_REQUIRED from the tools means the server started without a key, or Zindex stopped accepting it: put a valid key in the env block for this server and restart the host. If npx isn’t found, install Node.js 18 or later.
Upgrading from 0.x
Version 1.0 replaced the dsp_* tools with the diagram_* tools. The old names are gone, not aliased, so prompts and code that call a dsp_* tool by name need the new tool. Diagrams saved with 0.x keep their IDs and work with the new tools. A config pinned to a 0.x version, such as @zindexai/[email protected], still lists the old tools, but every call fails: 0.x calls /v1/scenes, which answers 410 MOVED. Remove the pin so the config runs @zindexai/mcp, and restart the host.
How every tool behaves
Signing in. A client either signs the person in with their Zindex account (OAuth 2.1; Sign in with your Zindex account) or sends an API key as Authorization: Bearer dsp_sk_... (or in X-API-Key). Without either, diagram_validate and diagram_render with an unsaved scene or mermaid work. Any other tool call gets an HTTP 401 with WWW-Authenticate: Bearer resource_metadata="https://api.zindex.ai/.well-known/oauth-protected-resource/mcp", scope="diagrams", so the client can sign the person in and retry; ChatGPT gets the AUTH_REQUIRED tool error instead, with the same challenge in _meta["mcp/www_authenticate"]. A token or key that is sent but invalid, revoked or expired gets an HTTP 401 with error="invalid_token" before any tool runs; code is OAUTH_TOKEN_INVALID for a sign-in token and API_KEY_INVALID, API_KEY_REVOKED or API_KEY_EXPIRED for a key. A sign-in token or key whose person is no longer in its workspace gets OAUTH_TOKEN_INVALID or API_KEY_REVOKED. Sign-in tokens work only on /mcp; the REST API takes API keys.
Workspaces. Every sign-in and key works in one workspace, and every tool acts on that workspace’s diagrams; no tool takes a workspace. With read-only access, or as a viewer in the workspace, every tool that changes or shares a diagram, or reports a problem with one, returns READ_ONLY, diagram_delete and diagram_share before asking the person. Don’t retry: with reason: "credential" the person connects again with read and write, or uses a key with write access; with reason: "role" they are a viewer, and a workspace owner can make them a member. diagram_history shows who saved each version (by) and how (credential), never which key (Workspaces).
IDs and keys. Wherever a tool takes id, you can pass the diagram’s ID (dgm_ plus 12 characters) or the key you gave it. A diagram in another workspace answers exactly like a missing one: NOT_FOUND.
Versions. revision picks a version by number. asOf picks the version that was current at an instant: a date such as 2026-09-26 (the end of that day in UTC) or an ISO 8601 timestamp with an offset, such as 2026-09-26T14:00:00Z. Give one or the other, not both.
Results. diagram_create, diagram_edit and diagram_render return JSON as text and as structuredContent, except a diagram_render preview of an unsaved scene or mermaid, which returns only the image. Every other tool returns text only.
Errors. A failed call is a tool result with isError: true. Its text is JSON with code, error (one sentence) and any details. Arguments that don’t match a tool’s input schema are refused before the tool runs, with plain text starting Input validation error: instead of JSON.
| Code | Means |
|---|---|
AUTH_REQUIRED | The tool needs a signed-in account or an API key |
EMAIL_NOT_VERIFIED | Verify the account’s email before saving, deleting, sharing, reporting or sending feedback |
NOT_FOUND | No such diagram or version in this workspace |
NO_REVISION_AS_OF | The diagram had no version yet at that instant |
INVALID_REQUEST | An argument is wrong; error says which |
VALIDATION_FAILED | Nothing was saved; errors lists each problem with a code, a one-line fix and, where it applies, the element |
KEY_EXISTS | The key belongs to another diagram in the workspace, with different content or a teammate’s; id and revision name it |
REVISION_CONFLICT | The diagram changed since baseRevision; see diagram_edit |
REQUEST_ID_REUSED | The requestId already made a different revision |
PARSE_ERROR | The Mermaid has a syntax error; line and column say where |
UNSUPPORTED_DIAGRAM_TYPE | The Mermaid isn’t an erDiagram or a flowchart |
IMPORT_TIMEOUT | Reading the Mermaid took too long; send a smaller diagram |
IMPORT_FAILED | The Mermaid reader failed; error says how |
MERMAID_FAMILY_MISMATCH | A Mermaid edit doesn’t fit the diagram’s family; see diagram_edit |
VIEW_UNAVAILABLE | The diagram can’t be read in that view (sequence diagrams have no Mermaid view) |
INPUT_TOO_LARGE | The Mermaid text, or a feedback snippet, is over 64 KB |
LIMIT_REACHED | The workspace is at a plan limit; limit, maximum and current give the numbers |
FEATURE_UNAVAILABLE | The workspace’s plan doesn’t include the feature (feature); diagram_share with link returns it on Free, before asking the person |
READ_ONLY | The sign-in or key can read diagrams but not change or share them or report a problem with them; reason is credential or role; Workspaces above says what to do |
SHARING_DISABLED | The workspace’s owners turned public sharing off: diagram_share with publish or link returns it before asking the person |
RATE_LIMITED | The account sent 20 feedback items in the last 24 hours, or a request through @zindexai/mcp went over a rate limit; retryAfter is the seconds to wait |
CONFIRMATION_REQUIRED | Ask the person first; see Confirmation |
CANCELLED | The person declined, so nothing changed |
UNSUPPORTED | This server doesn’t offer that action |
DRAW_TIMEOUT | Drawing the scene took longer than the drawing budget (5 s for diagram_validate and previews before sign-in, 20 s after it and for every save, edit and render), or needed more memory than it allows. A save or edit saved nothing. Split the diagram, or draw fewer edges into one node |
BUSY | Every drawing worker is busy; retryAfter is the seconds to wait |
INTERNAL_ERROR | Zindex hit an internal error; try again |
Over a request rate limit, the server refuses the request itself rather than returning a tool result: HTTP 429 with a Retry-After header, and a JSON-RPC error whose data is { "code": "RATE_LIMITED", "retryAfter": 12 }.
Confirmation
diagram_delete, and diagram_share with publish, link, report or feedback, need the person’s agreement. The server enforces it:
- A client on the 2026-07-28 protocol that supports elicitation shows the person a yes or no form. If they decline, the call returns
CANCELLED. - Every other client, including every client on a 2025 protocol revision, gets
CONFIRMATION_REQUIRED. The error says what will happen and carries aconfirmtoken. Tell the person, and only if they agree, call again with the same arguments plusconfirm. The token is valid for 10 minutes and only for that account, action and diagram (forfeedback, that item); it can be sent again until it expires.
Undoing a delete, unpublishing and revoking share links never ask.
diagram_find
Lists the diagrams in this workspace, most recently changed first.
| Input | Type | Notes |
|---|---|---|
query | string, up to 200 characters | Matches the title, key or brief, ignoring case |
limit | 1 to 50 | Default 10 |
cursor | string | nextCursor from the previous page |
{
"diagrams": [
{ "id": "dgm_7Q2kD9a1B2c3", "key": "payments-architecture", "title": "Payments", "revision": 12, "updatedAt": "2026-10-01T14:02:11.204Z" }
],
"nextCursor": "..."
}
key is left out when a diagram has none, or when it equals the ID. nextCursor appears only when there are more.
diagram_get
Reads a saved diagram. By default it returns an outline: a header line (ID, title, revision, time in UTC, the first 12 hex characters of the content hash), the key, the brief, the last three changes, then one element per line in document order, with a container’s children indented under it. Edges follow as id: from -> to "label".
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key |
revision or asOf | number or string | An earlier version; default the latest |
view | outline, dsp or mermaid | Default outline. dsp returns the scene JSON; mermaid returns Mermaid you can edit and send back |
knownRevision | number | A revision you already have; returns only what changed since |
elements | up to 50 element IDs | Only those elements, their direct neighbors and the edges among them |
cursor | string | The next page of a long outline |
dgm_7Q2kD9a1B2c3 "Payments" r2 2026-10-01T14:02Z sha256:182e406914b7
key: payments-architecture
brief: Checkout payment services, left to right.
recent: r2 Claude Code/2.1 "Add the job queue" | r1 Cursor/1.4 "First version"
outline: 3 nodes, 2 edges
api service "API"
db database "Ledger"
queue queue "Jobs"
e1: api -> db "writes"
e2: api -> queue "enqueues"
recent:lists the last three versions with their client and message. In a team workspace it names the person too:r7 Ana Lima via Claude Code/2.1 "Add the queue".- Long outlines. Past 150 element lines the outline stops and its last line is
nextCursor: <cursor>. Pass that ascursorfor the next page. knownRevisionapplies when you read the latest version. If it equals the latest revision, the answer is{ "unchanged": true, "id", "revision", "hash", "chain" }. If it is older, you get the header, the versions since, and one line per changed element:+added,~changed,-removed (ID only).view: "dsp"returns{ "id", "key", "revision", "hash", "chain", "createdAt", "visibility", "scene" }, wherevisibilityispublicorprivateandsceneis the DSP document withoutcomputed, the engine’s drawing output (element boxes, edge routes, label positions). It holds what was written: what the engine infers while drawing, such as an ER edge end’s cardinality from its column, isn’t in it. It is valid input: send it to diagram_create to save a copy. Each node’slayoutholds the position the engine placed it at, which is part of the content and itshash. Later edits keep it, with three exceptions, andchangedlists the nodes each one moves: a node that grows pushes the nodes in its way; a frame added or deleted round placed nodes places them again when keeping them would leave frames overlapping or a frame holding a node that isn’t its member; and anorderconstraint you add places its two nodes again when they stand the wrong way round. To have the engine place nodes again, send anautoLayoutop with diagram_edit. The engine lays sequence diagrams out from their messages, so their nodes stay atx: 0, y: 0, which means not placed. While the diagram is public,madePublicAtsays when it was published.view: "mermaid"returns a header line (ID, revision, content hash), anote:line for anything Mermaid can’t show, then the diagram in a fencedmermaidcode block: anerDiagramfor entity-relationship diagrams, aflowchartfor every other family except sequence. Node IDs are the Mermaid IDs; an ID Mermaid can’t hold is written as an alias such aszid1, with a%% zindex-idcomment that maps it back, so keep those comments. Frames and groups appear as subgraphs. Edit it and send it back asmermaidto diagram_edit. Mermaid scope has what the text leaves out.
diagram_validate
Checks a DSP scene document, or Mermaid text, without saving it. Works without a key.
| Input | Type | Notes |
|---|---|---|
scene | object | A scene document |
mermaid | string, up to 64 KB | Mermaid text, instead of scene: an erDiagram or a flowchart (graph) |
{
"ok": false,
"errors": [{ "code": "SCHEMA_VALIDATION_ERROR", "element": "cache", "fix": "/elements/1/kind: 'nod' is not allowed; use one of 'node', 'edge', 'group', 'text', 'guide', 'frame', 'image'." }],
"warnings": []
}
ok is false when there is at least one error. Warnings don’t block a save. Mermaid that can’t be read (PARSE_ERROR, UNSUPPORTED_DIAGRAM_TYPE, IMPORT_TIMEOUT, IMPORT_FAILED, INPUT_TOO_LARGE), a scene without an elements array (INVALID_REQUEST), and a check when every drawing worker is busy (BUSY), come back as a tool error instead. element appears when a problem belongs to one element, and each list holds at most 10 entries, Mermaid’s notes included. The codes are in Validation rules.
A valid scene is also laid out and drawn, so warnings include what drawing notices: TEXT_OVERFLOW when text doesn’t fit its element, ICON_NOT_FOUND when a node’s icon key isn’t a built-in icon, NODE_OVERLAP_DETECTED when two nodes sit on top of each other, NODE_OUTSIDE_FRAME when a node sits outside a frame that doesn’t grow to fit it, FRAME_OVERLAP_DETECTED when two frames overlap, NODE_IN_WRONG_FRAME when a node lies inside a frame it isn’t a member of, LABEL_DUPLICATION_DETECTED when edges that meet at one element share a label, and DRAW_TIMEOUT when drawing took longer than its budget, so the other drawing warnings weren’t checked. diagram_create and diagram_edit return the same warnings for the version they save, including the diagram family’s rules.
diagram_create
Saves a new diagram and returns revision 1.
| Input | Type | Notes |
|---|---|---|
scene | object | A DSP scene document |
mermaid | string, up to 64 KB | Mermaid text, instead of scene: an erDiagram or a flowchart (graph) |
key | string, up to 128 characters | Your stable name, such as payments-architecture: letters, digits, ., _ and -, starting with a letter or digit. Unique among the workspace’s live diagrams |
brief | string, up to 1,000 characters | What the diagram shows, conventions to keep, decisions made |
message | string, up to 500 characters | One line on why it was made |
{ "id": "dgm_7Q2kD9a1B2c3", "key": "payments-architecture", "revision": 1, "hash": "sha256:be1cd7...", "chain": "sha256:9c68ef...", "warnings": [], "created": true }
- Zindex mints the ID. Any
scene.scene.idyou send is ignored. hashis the content hash.chainis the chain hash, which covers this version and every one before it. Verifying explains both.chainisnulluntil Zindex has computed it, normally when the version is saved; a render, an export or the next edit computes a missing one. Reads and the history never compute it.- From Mermaid, element IDs are the Mermaid IDs and the same text always gives the same diagram; no model is involved. Subgraphs, edges to them and styles are left out for now and listed in
warnings. - Repeating a create with the same
keyand the same content returns the existing diagram withcreated: false, so a retry never makes a copy. The same key with different content isKEY_EXISTS, and so is a teammate’s create with a key the team workspace already has. Without akey, every call makes a new diagram. - The scene is validated first. Errors return
VALIDATION_FAILEDand nothing is saved.
diagram_edit
Changes a saved diagram. A change appends the next revision; nothing is overwritten, and every earlier revision stays readable.
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key |
baseRevision | number | The revision you last read; required |
message | string, 1 to 500 characters | One line on what the edit does and why; required |
ops | up to 500 operations | Typed operations, checked against ops.schema.json |
mermaid | string, up to 64 KB | The whole diagram as Mermaid, usually read with view: "mermaid" and edited |
restoreRevision | number, or { "asOf": "..." } | Makes the next revision equal to an earlier one |
brief | string up to 1,000 characters, or null | Replaces the brief; null removes it |
requestId | string, 1 to 255 visible ASCII characters, no spaces | Your ID for this edit, such as a UUID |
Send ops, mermaid, restoreRevision, or brief on its own. brief may also go with ops or mermaid. restoreRevision can’t be combined with any of them.
{ "id": "dgm_7Q2kD9a1B2c3", "revision": 3, "hash": "sha256:9b1c...", "chain": "sha256:e665...", "warnings": [], "changed": { "added": ["queue"], "updated": ["api"], "removed": [] } }
- No change, no revision. An edit that leaves the diagram as it was returns
noop: truewith the current revision and nochanged. - Retries. A call with a
requestIdthat already made a revision returns that revision’s result withreplayed: true. The samerequestIdwith a different edit isREQUEST_ID_REUSED. Without arequestId, a retried edit whose result is already the current content returnsnoop: true. - Conflicts. If the diagram moved past
baseRevision, the call returnsREVISION_CONFLICTwith the currentrevisionandchanges, the lines that changed since your base in the same form asknownRevision. AbaseRevisionpast the latest gets nochanges. Re-plan against the new revision and call again. changedlists every element the edit changed, including nodes a grown node pushed, members a moved frame carried, and nodes the engine placed again because of a frame the edit added or deleted: at most 20 IDs;morecounts the rest.- Every edit is all or nothing. Operations run in order, but only the element an operation changes must exist by then: an edge, group, frame, style, placement or constraint can name an element a later operation creates. An operation that can’t apply (such as
moveElementon an edge), a name nothing creates, or a version with an error its base didn’t have returnsVALIDATION_FAILEDand saves nothing. An error the diagram already had doesn’t block an edit that leaves it alone. - A saved edit’s
warningsalso note what adeleteElementchanged besides the element it named:CONSTRAINT_REMOVEDfor each constraint it removed,RELATIVE_LAYOUT_FIXEDfor each element that was placed relative to the deleted one. A response lists at most 10 warnings. - Mermaid edits. Zindex compares the Mermaid with the
baseRevisionversion and applies only the differences, as operations. Nodes are matched by ID, and edges by ID or by their ends, so everything you didn’t change keeps its ID and history, and a node keeps its type unless you change its Mermaid shape. Nodes and edges missing from the Mermaid are deleted. Frames, groups, text, images and guides are never changed this way: a changed subgraph comes back as aFRAMES_NOT_CHANGEDwarning, so change frames withops. An edge to a subgraph that shows a frame or group is an edge to that frame or group, changed like any other edge; an edge to any other subgraph is left out, with aCONSTRUCT_DROPPEDnote. Mermaid edits work on architecture and entity-relationship diagrams; another family, anerDiagramsent for an architecture diagram or a flowchart sent for an entity-relationship one returnsMERMAID_FAMILY_MISMATCH. Text sent back as read returnsnoop: truewhen everything in the diagram has a Mermaid form (Mermaid scope: Edits). AnerDiagramrelationship’s cardinality, as read, is the one drawn (inferred from the columns where none was set): left as read, it keeps following the columns; changed, it is saved as you wrote it.
diagram_render
Returns links to the SVG and PNG of one version, not the image itself.
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key |
revision or asOf | number or string | An earlier version; default the latest |
preview | boolean | Also return the PNG, so you can look at it |
scene | object | An unsaved DSP document, instead of id |
mermaid | string | Unsaved Mermaid text, instead of id |
{
"id": "dgm_7Q2kD9a1B2c3",
"revision": 3,
"hash": "sha256:9b1c...",
"chain": "sha256:e665...",
"engine": "6.0.0+build.1690",
"svg": "https://api.zindex.ai/v1/images/[email protected]?e=1791756000&s=...",
"png": "https://api.zindex.ai/v1/images/[email protected]?e=1791756000&s=...",
"expires": "2026-10-11T22:00:00.000Z"
}
- For a private diagram, as above, the links are signed and work without a key until
expires, 7 days after the call. Anyone holding a link can open that one version until then, so share them only with people who may see the diagram. - For a published diagram, the links are its permanent version links instead, and there is no
expires:urlis the version’s page,https://zindex.ai/d/<id>@<revision>, andsvgandpngare that page with.svgor.png. They work until the diagram is made private or deleted. For a private diagram that should stay private,diagram_sharewithlinkmakes a share link that shows only its images. hashandchainare the version’s content and chain hashes, as diagram_create returns them.engineis the API build that drew the image. Each version’s image is drawn once, when it is saved (or the first time it is needed, for older versions), and kept, so a link always shows the same picture even after an engine update.- With
sceneormermaidinstead ofid, the tool renders the document as a PNG, as a saved version is drawn (the default style, ordarkfor a dark canvas), and returns only the image. Nothing is saved, and it works without a key. Giveid,sceneormermaid, only one.
diagram_history
Lists versions newest first, or compares two versions.
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key |
limit | 1 to 50 | Default 10 |
cursor | string | nextCursor from the previous page |
compare | { "from": ..., "to": ... } | Revision numbers or dates; to defaults to the latest |
{
"id": "dgm_7Q2kD9a1B2c3",
"currentRevision": 2,
"versions": [
{ "revision": 2, "at": "2026-10-01T14:02:11.204Z", "by": "Ana Lima", "credential": "oauth", "client": "Claude Code/2.1", "message": "Add the job queue", "chain": "sha256:d6d68b...", "added": 2, "changed": 0, "removed": 0 },
{ "revision": 1, "at": "2026-09-30T09:12:40.517Z", "by": "Ana Lima", "credential": "api_key", "client": "Cursor/1.4", "message": "First version", "chain": "sha256:9c68ef..." }
]
}
by is who saved the version: their name, else their email, "former member" once their account is closed, or null when it isn’t known. credential is how: session, api_key or oauth, never which key. client is the MCP client’s name and version, or the first product token of the REST caller’s User-Agent. chain is the version’s chain hash. Revision 1 has no counts. With compare, the result is { "id", "from", "to", "added", "changed", "removed", "scene", "authors" }: element IDs in each list, in scene the names of the scene-level fields that changed, such as title or brief, and in authors each distinct { "by", "client" } that saved a version after from, up to to.
diagram_delete
Deletes a diagram with all its versions. Asks the person first (see Confirmation).
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key |
undo | boolean | Restore a diagram deleted in the last 24 hours |
confirm | string | The token from a CONFIRMATION_REQUIRED error |
{ "id": "dgm_7Q2kD9a1B2c3", "deleted": true, "undoWithinHours": 24 }
For 24 hours, undo: true restores it with every version: { "id", "restored": true, "revision", "key" }. If another diagram took its key in the meantime, it comes back without one and the result says so in note. After 24 hours the diagram and its history are gone for good, and undo returns NOT_FOUND.
diagram_share
Changes who can see a diagram, reports a problem with one version to Zindex support, or sends Zindex feedback. Sharing compares what publishing and a share link each let people see: publishing also lets anyone read the scene JSON.
| Input | Type | Notes |
|---|---|---|
id | string | The diagram’s ID or key; optional for feedback |
action | publish, unpublish, link, unlink, report or feedback | |
problem | string, up to 500 characters | For report: what is wrong, in one line |
revision | integer | For report, or feedback with id; default the latest |
anonymize | boolean | For report and feedback; default true |
kind | bug, docs, request or other | For feedback; docs: docs and engine disagree |
summary | string, up to 200 characters | For feedback: one line |
expected, observed | string, up to 2,000 characters each | For feedback |
confidence | seen, likely or unsure | For feedback |
snippet | scene object or Mermaid text, up to 64 KB | For feedback, in place of id: send one or the other, not both |
confirm | string | The token from a CONFIRMATION_REQUIRED error |
publishasks first, then makes the diagram readable by anyone with its link, and returns{ "id", "visibility": "public", "url", "madePublicAt" }. Anyone with the link tohttps://zindex.ai/d/<id>can see every version and fetch its scene JSON without a key;https://zindex.ai/d/<id>@<revision>is one version, which never changes (version links).robots.txtasks crawlers to skip/d/pages, but treat a published diagram as public. Public diagrams fall under the hosted-content policy.unpublishmakes the diagram private again and returns{ "id", "visibility": "private" }. Its links by ID stop working at once; its share links don’t.linkneeds Pro or Team; on Free it returnsFEATURE_UNAVAILABLEwithout asking. On Pro and Team it asks first, then makes a share link and returns{ "id", "linkId", "url", "svg", "png", "createdAt" }.urlishttps://zindex.ai/d/<token>, where the token is 22 random characters: anyone who has it can see the diagram’s images and the dates of its versions, never its scene, until the link is revoked. It follows the latest version; add@<revision>for one version. The diagram stays private. Anyone who has the link can report the diagram, and a link whose diagram breaks the hosted-content policy is revoked. Each call makes a new link.unlinkrevokes every share link on the diagram and returns{ "id", "revoked" }, the number revoked. They stop working at once. To revoke one link and keep the others, use the dashboard orDELETE /v1/diagrams/{id}/links/{linkId}.- Each of these takes effect at once for new fetches through Zindex: unpublishing stops the links by ID, revoking stops share links, and deleting the diagram stops both. Copies people already fetched stay with them, as with any image once shared: a browser may keep an exact version’s image for up to a year.
reportasks first, then sends one version to Zindex support with your one-lineproblemand returns{ "reportId", "id", "revision", "reported": true, "anonymized" }. A report is its own record: the diagram stays as private or public as it was, and later versions aren’t part of it. Withanonymizeleft attrue, Zindex keeps an anonymized copy and staff see only that: the diagram’s text (labels, titles, the brief, column names and comments) and IDs with their letters and digits swapped for random ones of similar width, which is usually enough to diagnose a layout or rendering problem; metadata, which isn’t drawn, is left out. Punctuation, spacing and non-ASCII characters stay as they are. Withanonymize: false, staff see that version as it is. Each time staff open a report, an internal audit log records it with the staff member who viewed it. That log is for Zindex’s own use; you can’t see it. The person sees exactly what staff see on the diagram’s page in the dashboard, under Report a problem, and can withdraw a report there (or withDELETE /v1/diagrams/{id}/reports/{reportId}). Deleting the diagram hides its reports from staff at once, and they are removed for good with the diagram 24 hours later.feedbackasks first, then sends Zindex staff one item and returns{ "feedbackId", "sent": true, "status": "new" }. Send it when the docs and the engine disagree, or something you needed is missing.kindandsummaryare required;expected,observedandconfidencehelp staff reproduce it. It needs no diagram:idattaches a version of one, orsnippeta scene or Mermaid text, anonymized unlessanonymizeisfalse. The question names the item, what it carries, the engine version and your client, andCONFIRMATION_REQUIREDalso carriespreview, the item as staff will see it, the anonymized copy included. Aconfirmtoken covers that item only, so call again with the same arguments. An account can send 20 items in any 24 hours. The person sees each item as staff see it, with its status, under Your feedback on the dashboard (GET /v1/feedback).