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.

ToolDoesNeeds an account
diagram_findLists the workspace’s diagramsYes
diagram_getReads a diagram as an outline, scene JSON or Mermaid, at any versionYes
diagram_validateChecks a scene or Mermaid text without saving itNo
diagram_createSaves a new diagramYes
diagram_editChanges a diagram, making the next revisionYes
diagram_renderReturns SVG and PNG links for a version: permanent once the diagram is publishedYes, except for an unsaved scene or mermaid
diagram_historyLists versions, or compares twoYes
diagram_deleteDeletes a diagram, or restores one deleted in the last 24 hoursYes
diagram_sharePublishes or unpublishes a diagram, makes (Pro or Team) or revokes share links, reports a version, or sends Zindex feedbackYes

Sign in with your Zindex account

Clients that support MCP sign-in need only the URL https://api.zindex.ai/mcp:

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.

VariableDefaultMeaning
ZINDEX_API_KEYnoneYour API key. Without one, only diagram_validate and unsaved previews work
ZINDEX_MCP_URLhttps://api.zindex.ai/mcpThe 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.

CodeMeans
AUTH_REQUIREDThe tool needs a signed-in account or an API key
EMAIL_NOT_VERIFIEDVerify the account’s email before saving, deleting, sharing, reporting or sending feedback
NOT_FOUNDNo such diagram or version in this workspace
NO_REVISION_AS_OFThe diagram had no version yet at that instant
INVALID_REQUESTAn argument is wrong; error says which
VALIDATION_FAILEDNothing was saved; errors lists each problem with a code, a one-line fix and, where it applies, the element
KEY_EXISTSThe key belongs to another diagram in the workspace, with different content or a teammate’s; id and revision name it
REVISION_CONFLICTThe diagram changed since baseRevision; see diagram_edit
REQUEST_ID_REUSEDThe requestId already made a different revision
PARSE_ERRORThe Mermaid has a syntax error; line and column say where
UNSUPPORTED_DIAGRAM_TYPEThe Mermaid isn’t an erDiagram or a flowchart
IMPORT_TIMEOUTReading the Mermaid took too long; send a smaller diagram
IMPORT_FAILEDThe Mermaid reader failed; error says how
MERMAID_FAMILY_MISMATCHA Mermaid edit doesn’t fit the diagram’s family; see diagram_edit
VIEW_UNAVAILABLEThe diagram can’t be read in that view (sequence diagrams have no Mermaid view)
INPUT_TOO_LARGEThe Mermaid text, or a feedback snippet, is over 64 KB
LIMIT_REACHEDThe workspace is at a plan limit; limit, maximum and current give the numbers
FEATURE_UNAVAILABLEThe workspace’s plan doesn’t include the feature (feature); diagram_share with link returns it on Free, before asking the person
READ_ONLYThe 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_DISABLEDThe workspace’s owners turned public sharing off: diagram_share with publish or link returns it before asking the person
RATE_LIMITEDThe 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_REQUIREDAsk the person first; see Confirmation
CANCELLEDThe person declined, so nothing changed
UNSUPPORTEDThis server doesn’t offer that action
DRAW_TIMEOUTDrawing 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
BUSYEvery drawing worker is busy; retryAfter is the seconds to wait
INTERNAL_ERRORZindex 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:

Undoing a delete, unpublishing and revoking share links never ask.

diagram_find

Lists the diagrams in this workspace, most recently changed first.

InputTypeNotes
querystring, up to 200 charactersMatches the title, key or brief, ignoring case
limit1 to 50Default 10
cursorstringnextCursor 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".

InputTypeNotes
idstringThe diagram’s ID or key
revision or asOfnumber or stringAn earlier version; default the latest
viewoutline, dsp or mermaidDefault outline. dsp returns the scene JSON; mermaid returns Mermaid you can edit and send back
knownRevisionnumberA revision you already have; returns only what changed since
elementsup to 50 element IDsOnly those elements, their direct neighbors and the edges among them
cursorstringThe 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"

diagram_validate

Checks a DSP scene document, or Mermaid text, without saving it. Works without a key.

InputTypeNotes
sceneobjectA scene document
mermaidstring, up to 64 KBMermaid 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.

InputTypeNotes
sceneobjectA DSP scene document
mermaidstring, up to 64 KBMermaid text, instead of scene: an erDiagram or a flowchart (graph)
keystring, up to 128 charactersYour stable name, such as payments-architecture: letters, digits, ., _ and -, starting with a letter or digit. Unique among the workspace’s live diagrams
briefstring, up to 1,000 charactersWhat the diagram shows, conventions to keep, decisions made
messagestring, up to 500 charactersOne line on why it was made
{ "id": "dgm_7Q2kD9a1B2c3", "key": "payments-architecture", "revision": 1, "hash": "sha256:be1cd7...", "chain": "sha256:9c68ef...", "warnings": [], "created": true }

diagram_edit

Changes a saved diagram. A change appends the next revision; nothing is overwritten, and every earlier revision stays readable.

InputTypeNotes
idstringThe diagram’s ID or key
baseRevisionnumberThe revision you last read; required
messagestring, 1 to 500 charactersOne line on what the edit does and why; required
opsup to 500 operationsTyped operations, checked against ops.schema.json
mermaidstring, up to 64 KBThe whole diagram as Mermaid, usually read with view: "mermaid" and edited
restoreRevisionnumber, or { "asOf": "..." }Makes the next revision equal to an earlier one
briefstring up to 1,000 characters, or nullReplaces the brief; null removes it
requestIdstring, 1 to 255 visible ASCII characters, no spacesYour 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": [] } }

diagram_render

Returns links to the SVG and PNG of one version, not the image itself.

InputTypeNotes
idstringThe diagram’s ID or key
revision or asOfnumber or stringAn earlier version; default the latest
previewbooleanAlso return the PNG, so you can look at it
sceneobjectAn unsaved DSP document, instead of id
mermaidstringUnsaved 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"
}

diagram_history

Lists versions newest first, or compares two versions.

InputTypeNotes
idstringThe diagram’s ID or key
limit1 to 50Default 10
cursorstringnextCursor 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).

InputTypeNotes
idstringThe diagram’s ID or key
undobooleanRestore a diagram deleted in the last 24 hours
confirmstringThe 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.

InputTypeNotes
idstringThe diagram’s ID or key; optional for feedback
actionpublish, unpublish, link, unlink, report or feedback
problemstring, up to 500 charactersFor report: what is wrong, in one line
revisionintegerFor report, or feedback with id; default the latest
anonymizebooleanFor report and feedback; default true
kindbug, docs, request or otherFor feedback; docs: docs and engine disagree
summarystring, up to 200 charactersFor feedback: one line
expected, observedstring, up to 2,000 characters eachFor feedback
confidenceseen, likely or unsureFor feedback
snippetscene object or Mermaid text, up to 64 KBFor feedback, in place of id: send one or the other, not both
confirmstringThe token from a CONFIRMATION_REQUIRED error