Skip to main content
Glama
figjam-context-mcp

figjam-context-mcp

figjam-context-mcp

A local MCP server that turns FigJam boards into source-cited context for LLMs. It reads a board through the Figma REST API, groups stickies, tables, images and arrows into clusters, and answers questions with links back to the original nodes.

Real run: ingest_board reads the demo board, answer_from_board cites two conflicting pilot dates, Figma's MCP server edits the board, ingest_board reports the change, diff_board names the edited sticky and table cell, answer_from_board gives the new date

Rendered from the tool calls and outputs of a real run against the public demo board with figjam-context-mcp 0.10.2 and openai/gpt-4.1-mini. Figma's MCP server (use_figma) made the edit.

Why

Workshop boards hold research notes, decisions and open questions, but an LLM cannot read a canvas. Screenshots and PDF exports lose tables, arrow direction and the link to the source. This server keeps the board's structure and cites every answer to the nodes it came from.

Related MCP server: Miro MCP Server

Compared with Figma's MCP server

Figma's official MCP server reads a FigJam board or node with its images (get_figjam) and edits boards (use_figma). This server turns a workshop board into context an assistant can cite and track:

  • large boards read section by section, with an overview, size-limited pages and search

  • source IDs in compact overviews, with Figma links in full excerpts and answer citations

  • tables read row by row

  • local snapshots, and diff_board to see what changed

  • explicit credentials redacted before they reach the cache, the output or a model

  • image descriptions from a vision model you configure

The two work together: in the demo above, Figma's server edits the board and this one reports the change.

Tools

Tool

What it does

LLM call

ingest_board

Reads a board, clusters it and saves a local snapshot. Re-ingests reuse unchanged clusters; focusNodeIds chooses which sections' images are interpreted first.

In balanced (default) and max_quality mode

get_board_context

Reads saved context, automatically using compact source-ID lines for large section reads; detail: "full" returns complete excerpts and Figma links. Also supports topic search and pagination.

No

answer_from_board

Answers one specific question (a number, status or decision) from the most relevant excerpts, with node-level citations or an insufficient-evidence result. Not meant for whole-board summaries.

Yes

diff_board

Compares snapshots with bounded lists and full totals: clusters, nodes, table cells (0-based), arrows with source IDs, section/frame renames and layout counts. Notes unchanged re-ingests.

No

diagnose_llm_config

Tests the configured models with small text and image JSON checks.

Yes

ingest_board also reads Figma design files (/design/, /file/ and /proto/ URLs), but clustering and reading order are made for FigJam boards.

Quick start

Five steps. Requires Node.js 22.12 or later. Step 4 sets the model provider that answer_from_board, diagnose_llm_config and image interpretation need; it is optional.

  1. Node.js. Check the installed version with node --version; install Node.js 22.12 or later if it is older.

  2. Figma token. Create a personal access token under Settings → Security → Personal access tokens with the scope file_content:read. The token's account must be able to open the board. Every ingest_board call is one Figma file download, a Tier 1 request. Figma allows View and Collab seats up to 20 Tier 1 requests a month on every plan, and says the actual limit may be lower (rate limits).

  3. Add the server with the example for your client below. The examples set only FIGMA_ACCESS_TOKEN, so the server starts and ingest_board works in ingestMode: "max_speed" without a model provider. @latest with --prefer-online makes npx check the registry for the latest release on every start, even when package metadata is cached (npm configuration).

  4. Optional: model provider. Add LLM_BASE_URL and LLM_API_KEY to the server's env block, then restart the client. Both are needed together; without them, balanced ingests run text-only and say that the model settings are missing. Example with OpenRouter (create a key):

    LLM_BASE_URL=https://openrouter.ai/api/v1
    LLM_API_KEY=your-openrouter-key

    In Claude Code, remove the entry with claude mcp remove figjam-context (with the same --scope as when you added it), then add it again with an --env flag for each variable (Claude Code). A local OpenAI-compatible server without sign-in still needs LLM_API_KEY set to any non-empty value. Set LLM_TEXT_MODELS, LLM_FAST_TEXT_MODELS and LLM_VISION_MODELS to its model names (configuration). Then run diagnose_llm_config in step 5.

  5. Check the setup. Ask your assistant to ingest one of your boards with ingestMode: "max_speed", for example "Ingest https://www.figma.com/board/FILE_KEY/Name with ingestMode max_speed." That makes one Figma request and no model call. A working setup answers with a line that starts Ingested board FILE_KEY (snapshot …): and counts the clusters. Clients that show their tools, such as Claude Code with /mcp, list the server there (Claude Code). With a provider from step 4, also run diagnose_llm_config; it checks the configured models with small synthetic inputs. For error messages, see common errors.

All settings: configuration.

Claude Code

claude mcp add --scope user --env FIGMA_ACCESS_TOKEN=your-figma-token --transport stdio figjam-context -- npx -y --prefer-online figjam-context-mcp@latest

--scope user makes the server available in all your projects. Without it, Claude Code stores the server for the current project only (scopes).

For longer ingests, set MCP_TOOL_TIMEOUT=300000 in the environment that launches Claude Code and INGEST_BOARD_VISION_BUDGET_MS=270000 in the server environment, leaving about 30 seconds for the rest of the ingest (Claude Code environment variables).

Claude Desktop

Open Settings → Developer → Edit Config in Claude Desktop. This opens claude_desktop_config.json; the file is at:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the server under mcpServers, keeping any other entries in the file:

{
  "mcpServers": {
    "figjam-context": {
      "command": "npx",
      "args": ["-y", "--prefer-online", "figjam-context-mcp@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "your-figma-token"
      }
    }
  }
}

Then quit Claude Desktop completely and start it again; the server starts with the app (MCP quickstart). The MCP documentation names no tool timeout setting for Claude Desktop, so keep the default image budget.

Codex CLI and ChatGPT desktop app

Add this to ~/.codex/config.toml; the app, CLI and IDE extension share this configuration (OpenAI MCP setup):

[mcp_servers.figjam-context-mcp]
enabled = true
command = "npx"
args = ["-y", "--prefer-online", "figjam-context-mcp@latest"]
startup_timeout_sec = 30
default_tools_approval_mode = "approve"

[mcp_servers.figjam-context-mcp.env]
FIGMA_ACCESS_TOKEN = "your-figma-token"

Without default_tools_approval_mode = "approve", ChatGPT may ask for approval or abort tools with external effects; with it, the client never asks before board content goes to the model provider, so use max_speed and avoid answer_from_board for confidential boards.

For longer ingests, set tool_timeout_sec = 300 under [mcp_servers.figjam-context-mcp] and INGEST_BOARD_VISION_BUDGET_MS = "270000" in its env table, leaving about 30 seconds for the rest of the ingest (OpenAI timeout options).

GitHub Copilot CLI

Add this to ~/.copilot/mcp-config.json (Copilot CLI MCP setup):

{
  "mcpServers": {
    "figjam-context": {
      "type": "local",
      "command": "npx",
      "args": ["-y", "--prefer-online", "figjam-context-mcp@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "your-figma-token"
      },
      "tools": ["*"]
    }
  }
}

For longer ingests, set "timeout": 300000 on the server in ~/.copilot/mcp-config.json and "INGEST_BOARD_VISION_BUDGET_MS": "270000" in its env, leaving about 30 seconds for the rest of the ingest (tested with a 600000 ms timeout).

VS Code

In the Copilot harness, add the server under Global → Copilot Global in Chat: Open Customizations (Command Palette), then MCP Servers. VS Code writes it to ~/.copilot/mcp-config.json, the same file as in the Copilot CLI section, in the portable mcpServers format (VS Code MCP servers, configuration reference):

{
  "mcpServers": {
    "figjam-context": {
      "type": "local",
      "command": "npx",
      "args": ["-y", "--prefer-online", "figjam-context-mcp@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "your-figma-token"
      },
      "tools": ["*"]
    }
  }
}

The portable format has no input variables, so the token is stored in this file. Keep that file in your user directory and out of any repository.

Local harness only: to keep the token out of the file, open MCP: Open User Configuration and use an input marked "password": true. VS Code does not forward servers that need inputs to Copilot harness sessions, so this works only in the Local harness (VS Code MCP configuration):

{
  "inputs": [
    {
      "type": "promptString",
      "id": "figma-token",
      "description": "Figma personal access token (file_content:read)",
      "password": true
    }
  ],
  "servers": {
    "figjam-context": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "--prefer-online", "figjam-context-mcp@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "${input:figma-token}"
      }
    }
  }
}

Do not put tokens in a .vscode/mcp.json in a repository; VS Code's documentation says not to commit tokens or passwords.

In the Local harness, "envFile": "${workspaceFolder}/.env" on the server in mcp.json loads an environment file; the portable format does not support envFile, and the server does not load a working-directory .env itself.

For longer ingests, use the Local harness with a per-server "timeout": 300000 in mcp.json and "INGEST_BOARD_VISION_BUDGET_MS": "270000" in its env (about 30 seconds below the timeout); #343135 reports that remote HTTP tool calls in the Copilot harness, the default in 1.142, ignore that timeout and stop after about 180 seconds, while the Local harness honors it.

Other MCP clients

For clients that accept mcpServers, add this to their MCP configuration:

{
  "mcpServers": {
    "figjam-context": {
      "command": "npx",
      "args": ["-y", "--prefer-online", "figjam-context-mcp@latest"],
      "env": {
        "FIGMA_ACCESS_TOKEN": "your-figma-token"
      }
    }
  }
}

Where the client supports a configurable tool timeout, raise it to about 300 seconds using its documented setting and set INGEST_BOARD_VISION_BUDGET_MS=270000 in the server environment, about 30 seconds below it. Cursor has no configurable timeout: its IDE allows about 60 minutes, while ACP/CLI calls stop at 60 seconds even with progress, so keep the default image budget on that path (Cursor support).

Using the tools

Then ask your assistant to ingest a board URL, for example "Ingest https://www.figma.com/board/FILE_KEY/Name and list the open questions." The boardId of every later call is the file key from that URL, or the URL itself; a URL with a node-id and without nodeIds, topic and outsideSections makes get_board_context read that node. To summarize a board, the assistant calls ingest_board, then get_board_context without parameters, whose first page names the largest sections and includes a section overview with IDs within the page's size limit, and then reads the largest sections by passing their IDs as nodeIds. Several IDs in one call take turns in request order, up to 50 per call. For a whole-board summary, pass all top-level section IDs with maxChars: 24000, follow the cursor in the text with the same arguments, then read outsideSections: true. Large nodeIds reads automatically use short source-ID lines, grouped by section, when the first full page would leave unread excerpts. limit applies only with the full view; an overview ignores it even when supplied. Read complete text and its Figma link with the same boardId and snapshotId, the line's ID in nodeIds, and detail: "full". For a table row, use its table ID. Everything that lies in no section, such as loose notes and tables, comes with outsideSections: true. Compact overviews show the Figma link pattern for their node IDs (URL-encode the ID) and shorten each text to a shared 50–120-character prefix with …; the host writes the summary. Topic searches, outsideSections, single leaf, table or cell IDs and small containers always return the full view.

Inputs are read as hosts and users send them. A node ID in link form (5-87, 5%3A87, I5-87%3B1-2) or a Figma link of the same board with a node-id is read as the ID it stands for (5:87) in nodeIds and focusNodeIds, and the text says so once; an ID that exists in the snapshot is never changed, and a link of another board is an error. A key that differs from a parameter only in case, _ or - (ingest_mode, node_ids) ends the call with "did you mean …" before anything is done; any other unknown key is ignored and named, without its value, in the text and in ignoredArguments of structuredContent. File keys are case-sensitive: an unknown boardId lists the stored boards (at most 10, most recent first) and names a key that differs only in case.

How it works

Pipeline: a FigJam board is read through the Figma API, clustered by geometry, refined with vision and turned into LLM-ready context

  1. Read. ingest_board downloads the board through the Figma REST API on every call. get_board_context and answer_from_board read the saved snapshot without a new request.

  2. Normalize. Nodes become text, table cells, images and connectors, with their pages, sections and named enclosing frames and groups. Tables are read row by row: row and column come from the cell IDs, and each row becomes one excerpt.

  3. Cluster. Nearby nodes are grouped by rotation-aware distance. Arrows between groups become directed relations. Clusters without a model label are named after their section, and an arrow appears in the context once one of its ends, or a section, frame or group around one, is on the page.

  4. Interpret. In balanced mode, clusters with an image, or drawings without any text, get a vision-model summary within a 40-second budget; text clusters, however short, keep their extracted text. A cluster starts only when the time left fits it; unfinished clusters continue on the next ingest. With focusNodeIds, the images of the given sections, frames or nodes come first. In max_quality, one ingest interprets only a few dozen clusters within the 40-second image budget (20–35 on a board with about 300 clusters, measured with 3 parallel requests); the next ingest continues, each costs a Tier 1 file download, and focusNodeIds sets the order.

  5. Serve. The snapshot is saved to a private local cache. Search favors excerpts containing more of the question’s words. get_board_context searches it (BM25 over original text, table rows and names, arrow labels and table headings), answer_from_board answers with citations and diff_board compares snapshots. Topic and question searches match whole words ignoring case and accents (words of five or more letters also match compounds that begin with them), but not other word forms, synonyms or translations. Use the board's words and language; an empty search does not prove the board lacks the topic. Paging, overviews and the detail setting are described in Using the tools. Full-view excerpt text is quoted with > on every line, and model-generated cluster labels are marked as model labels. Text content is the readable page; structuredContent holds each excerpt once, in overview.text (with empty evidence and clusters) or in evidence for the full view. Full excerpts inherit snapshotId from the response; absent chunkIndex means 0 and absent truncated or modelDerived means false, with no inheritance of these flags from a cluster. Named frames and groups appear in frameNames on clusters and on excerpts whose location differs; their names also participate in search.

Models and cost

The default preset student-free uses free OpenRouter models: text and images go to openrouter/free, which picks a free model that supports structured outputs (and images, for images). The free default is best effort: free models change, hit rate limits and time out. A request to openrouter/free or openrouter/auto that fails with a provider error is sent once more, since the router may pick another model. Images go to the model with at most 1,024 px on the longest side; larger ones are scaled down locally.

  • OpenRouter allows free models 20 requests per minute and 50 requests per day, or 1,000 per day once you have bought at least 10 credits (limits).

  • Figma limits requests by seat and plan (rate limits). File downloads and image renders are Tier 1: Dev and Full seats on paid plans get 10–20 requests per minute, View and Collab seats and files in Starter plans at most 20 per month. Every ingest_board call is one file download, so a View or Collab seat allows about 20 ingests a month. Images come from the image fills instead, Tier 2 with at least 5 requests per minute, in one request per ingest. Renders are left for drawings without an image and as a fallback for images without a usable original; renders of several clusters share requests of up to 18 nodes, so 30 image clusters without image fills need 2 render requests. max_speed needs neither.

  • LLM_BASE_URL takes any OpenAI-compatible endpoint; for paid models, set LLM_TEXT_MODELS, LLM_FAST_TEXT_MODELS and LLM_VISION_MODELS, for example all three to openai/gpt-4.1-mini (provider charges apply).

  • Run diagnose_llm_config after every model change. It checks JSON replies and image understanding with synthetic inputs.

Privacy

  • The server reads from Figma and never changes a board.

  • Hidden elements and their descendants are skipped before extraction, image loading and provider requests.

  • balanced and max_quality ingests send board text and images (originals or renders) to the configured LLM provider. answer_from_board sends the question and selected excerpts. max_speed with get_board_context and diff_board sends nothing to an LLM provider.

  • Snapshots stay in a private per-user cache on your machine. Delete the cache directory to remove them.

  • Explicit credentials such as Passwort: … or API keys are redacted before they reach the cache, tool output or an LLM provider (FIGJAM_MCP_REDACT_CREDENTIALS). This is a safety net, not a guarantee: images are not redacted, so keep credentials off the board.

  • Keep tokens in the client's environment. A token passed as a tool argument can appear in client logs.

Limitations

  • Image interpretation gets 40 seconds per ingest by default; large boards need several ingests to interpret every image cluster.

  • A client that cancels an ingest, for example after a 60-second timeout, gets no partial result.

  • Free models are best effort. Citations show where an answer comes from, not that its conclusion is right.

  • Search is lexical; synonyms without shared words do not match.

  • Local stdio only; no hosted or multi-user mode.

Measured results: evaluation.

Development

git clone https://github.com/ecestnrkl/figjam-mcp.git
cd figjam-mcp
npm ci
cp .env.example .env    # optional: add tokens for local development
npm run check           # typecheck, tests, build, package validation
npm run package:smoke   # install the packed package and exercise all tools
npm run eval:retrieval  # offline retrieval and diff evaluation
npx --prefer-online @modelcontextprotocol/inspector --config inspector.config.json

npm run dev and inspector.config.json explicitly load the repository's .env with Node's --env-file-if-exists=.env; existing environment values win. For other launch commands, configure the MCP client's env or set FIGJAM_MCP_ENV_FILE to the absolute path of the file.

See CONTRIBUTING.md and the changelog.

License

MIT © 2026 ecestnrkl

Available Tools

5 tools
answer_from_boardAnswer From BoardA
Read-only

Answer one specific question, such as a number, a status or a decision, from the most relevant excerpts of an ingested board, with validated source citations or an insufficient-evidence result. It finds excerpts by the question's words (whole words, ignoring case and accents (words of five or more letters also match compounds that begin with them); no other word forms, synonyms or translations), so ask with the board's words and language. Keep its citations (node ID and Figma link) with the statements they support. It reads only a handful of excerpts: not for summaries, lists, risks or next steps across several sections; read those with get_board_context. Sends the question and the selected excerpts to the configured LLM provider; calls may incur charges.

NameRequiredDescriptionDefault
boardIdYesThe Figma file key returned by ingest_board, or the board URL
questionYes
snapshotIdNo

Output Schema

NameRequiredDescription
answerYes
citationsYes
snapshotIdYes
citedClustersYes
ignoredArgumentsNoUnknown input keys that were ignored; their values are not echoed. Absent when none

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations it discloses real operational traits: it reads only a handful of excerpts, sends the question and excerpts to a configured LLM provider, and calls may incur charges. It also states the possible failure outcome (insufficient evidence) and the obligation to keep citations attached to the statements they support.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence and each subsequent sentence covers a distinct concern (matching behavior, citation handling, scope limits, cost). The heavy parenthetical nesting in the matching sentence slightly hurts scannability but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be fully explained, and the description still flags citations and the insufficient-evidence outcome. The remaining gap is snapshotId and any indication of which snapshot is used by default, which matters for reproducibility of an idempotentHint=false tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is only 33% (only boardId is described), so the description must compensate, and it does for the key parameter: exact whole-word, case- and accent-insensitive matching, five-letter compounds, and no synonyms or translations. The snapshotId parameter is never mentioned, which leaves one of three parameters entirely undocumented outside the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: answer one question (number, status, decision) from the most relevant excerpts of an ingested board, returning validated citations or an insufficient-evidence result. This is clearly distinguishable from get_board_context, which is named explicitly for the broader reading case.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives both when-to-use and when-not-to-use: not for summaries, lists, risks or next steps across several sections, and routes those to get_board_context. It also tells the agent how to phrase the input (use the board's words and language), which is actionable guidance rather than inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diagnose_llm_configDiagnose LLM ConfigA
Read-only

Test the configured text and vision models with three small synthetic JSON challenges. Sends synthetic text and an image to the configured provider, may incur charges, and reports semantic/schema failures. Does not read board contents. Use after changing model/provider settings.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
okYes
checksYes
presetYes
summaryYes
textModelsYes
visionModelsYes
fastTextModelsYes
ignoredArgumentsNoUnknown input keys that were ignored; their values are not echoed. Absent when none
providerRequireParametersYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations by warning that it sends synthetic text and an image to the configured provider and may incur charges — cost exposure is exactly the kind of thing readOnlyHint/openWorldHint do not convey. Reports failures rather than throwing, which is useful to know. It does not state whether provider credentials must already be configured or how long the test takes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the action, then cost/scope caveats, then the usage trigger. Every clause carries information an agent needs and nothing is repeated from the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With zero parameters and an output schema present, the description only needs to cover what it does, what it touches, and when to call it — all three are present. The cost warning and the board-exclusion note close the remaining gaps an agent would otherwise have to guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so there is nothing for the description to disambiguate; baseline 4 applies. The description correctly refrains from inventing arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and target (test the configured text and vision models) and pins down the mechanism (three small synthetic JSON challenges) plus what it reports (semantic/schema failures). An agent can distinguish it from the board-oriented siblings at a glance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear trigger condition: 'Use after changing model/provider settings.' Also adds an explicit exclusion, 'Does not read board contents,' which separates it from ingest_board and get_board_context. No alternative-tool routing is stated, but the exclusions do most of the work.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diff_boardDiff Board SnapshotsA
Read-onlyIdempotent

Compare retained local snapshots of the same board, reporting cluster, node and connector changes. Names each changed node with its section and its old and new text, and each changed table cell with its row and column. Needs two ingests; when the board did not change in between, it reports no changes since the first. compareTo=1 selects the previous snapshot, 2 selects two states back. No network or LLM calls; ingest_board must capture the current Figma state first.

NameRequiredDescriptionDefault
boardIdYesThe Figma file key, as returned by ingest_board, or the board URL
compareToNoHow many snapshots back to use as the baseline (1 = the ingest before the latest)

Output Schema

NameRequiredDescription
statsYes
boardIdYes
newClustersYes
nodeChangesNoEdited, added, then removed nodes in reading order; read whole texts with get_board_context and nodeIds
summaryTextYesPaste-ready human/LLM-readable change report
removedClustersYes
addedConnectionsYes
currentCreatedAtYesISO timestamp of the latest ingest
ignoredArgumentsNoUnknown input keys that were ignored; their values are not echoed. Absent when none
modifiedClustersYes
tableCellChangesNo
baselineCreatedAtYesISO timestamp of the baseline ingest
currentSnapshotIdNo
baselineSnapshotIdNo
newClustersOmittedNoNew clusters beyond the first 20
nodeChangesOmittedNoChanged nodes beyond the first 100
removedConnectionsYes
removedClustersOmittedNoRemoved clusters beyond the first 20
addedConnectionsOmittedNoAdded connections beyond the first 50
modifiedClustersOmittedNoModified clusters beyond the first 20
tableCellChangesOmittedNoTable cell changes beyond the first 50
removedConnectionsOmittedNoRemoved connections beyond the first 50

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, non-destructive, non-open-world behavior, and the description reinforces this with 'No network or LLM calls' while adding genuinely new facts: the two-ingest requirement and the no-change result ('reports no changes since the first'). It also sketches what changed content gets reported, though it says nothing about retention limits or result size for large boards.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with the core purpose and wastes little space, packing prerequisites and parameter behavior into a few sentences. The node/table-cell reporting sentence partially duplicates the existing output schema and could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full annotation coverage, the description only needs to carry preconditions and scope, which it does. The remaining gap is minor: no indication of how many snapshots are retained or what happens if fewer than compareTo snapshots exist.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented, including compareTo's baseline meaning. The description only restates it with an example ('compareTo=1 selects the previous snapshot, 2 selects two states back') and adds nothing about boardId beyond what the schema says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource ('Compare retained local snapshots of the same board') plus the outputs covered (cluster, node, connector changes). This clearly separates it from siblings like ingest_board, which capture state rather than compare it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear precondition ('Needs two ingests') and an ordering constraint ('ingest_board must capture the current Figma state first'), so an agent knows exactly when the tool is callable. It stops short of naming an explicit alternative or a when-not-to-use case, but no sibling competes for the same diff job.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_board_contextGet Board ContextA
Read-onlyIdempotent

Read source-cited context from an ingested board snapshot. Start overviews, summaries and documentation with a call without topic, nodeIds, limit and maxChars: its first page names the largest sections and lists sections with IDs. Then pass section, page, frame or group IDs as nodeIds; several IDs share each page in request order. For a whole-board summary, pass all top-level section IDs (at most 50 per call) with maxChars 24000, follow nextCursor, then read outsideSections: true. Default detail: "auto" switches reads of multiple distinct IDs or one page, section, frame or group to a compact overview only when the first full page would leave unread excerpts. Overview lines contain node IDs and deterministically shortened text (50–120 characters); structuredContent puts the excerpts once in overview.text, with empty evidence and clusters. limit applies only to the full view and is ignored in an overview, even when explicit. Read the complete source and Figma link with the same boardId and snapshotId, nodeIds: [""] and detail: "full"; table IDs read every row. Without overview, excerpts are in evidence. Read outsideSections: true, search with topic, or continue with cursor. Cite the node ID or Figma link behind each statement. Synthesize the answer yourself. No network or LLM calls; use ingest_board to refresh Figma content.

NameRequiredDescriptionDefault
limitNoMaximum evidence excerpts per full page (default 20, at most 100); ignored in an automatic overview, even when explicit. Use detail: full for an excerpt limit
topicNoWords to search for. An excerpt matches when at least one of them is in its text, its section or node name, the label of an arrow attached to it or, for a table row, its column headings, as a whole word ignoring case and accents (words of five or more letters also match compounds that begin with them); excerpts with more of the words come first. Other word forms, synonyms and translations do not match: include them yourself, for example "payment payments pay Bezahlung". Cannot be combined with nodeIds or outsideSections.
cursorNonextCursor of the previous page, unchanged; send it with the same topic, nodeIds, outsideSections, detail, limit and maxChars
detailNoauto uses a compact, source-marked overview when a requested container or several nodeIds need multiple full pages; full returns linked evidence objects. Overview lines may be shortened; use full to read all textauto
boardIdYesThe Figma file key returned by ingest_board, or the board URL. A URL with a node-id, without nodeIds, topic and outsideSections, reads that node
nodeIdsNoRead exact source nodes, all rows of a table or the row of a table cell, or every excerpt inside a page, section, frame or group by its ID (nested sections included, in reading order); several IDs in one call share every page in request order; cannot be combined with topic
maxCharsNoCharacter budget for each representation: the readable text content and the JSON of structuredContent (default 12000, minimum 2000)
snapshotIdNoRead a specific retained snapshot instead of the latest board
outsideSectionsNoRead every excerpt that lies in no section, cluster by cluster in reading order, tables row by row; on a board without sections, all excerpts. Cannot be combined with topic or nodeIds

Output Schema

NameRequiredDescription
clustersYes
evidenceYesFull linked excerpts; empty in overview mode, where excerpts are in overview.text instead
overviewNoPresent only for automatic compact overview pages; evidence and clusters are empty, not a claim of no matches. Read a line's full text and Figma link with the same boardId and snapshotId, its nodeId, and detail: full
relationsNoCluster-to-cluster relations derived from connector arrows
truncatedYes
nextCursorNo
snapshotIdYes
truncationYesExplicit omissions from structured results and the readable text
connectionsYesArrows with at least one end, or a section, frame or group around one, among this page's excerpts; never arrows to a page. The label is the text on the arrow
contextTextYesOrientation and reading instructions. Excerpts are in overview.text when overview is present (evidence and clusters are then empty), otherwise in evidence; text content carries the same readable excerpts
totalMatchedYes
unknownNodeIdsNoRequested nodeIds that are not in this snapshot; the others are read
ignoredArgumentsNoUnknown input keys that were ignored; their values are not echoed. Absent when none

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/idempotent/non-destructive/closed-world behavior, and the description adds substantial context beyond them: no network or LLM calls, overview shortening to 50–120 characters, excerpts placed in structuredContent overview.text with empty evidence and clusters, limit being ignored in overview, and table IDs reading every row.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is valuable but delivered as a dense run-on paragraph with repeated overview explanations and nested clauses, making it hard to scan. The purpose is front-loaded, but the middle-to-end could be restructured into bullets for faster parsing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 9-parameter read tool with full schema coverage, annotations, and an output schema, the description covers the key workflows: overview, full read, topic search, cursor pagination, outsideSections, and citations. Return values and safety are handled by structured fields, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds cross-parameter workflow semantics: omitting topic/nodeIds/limit/maxChars yields an overview, multiple nodeIds share pages in request order, whole-board summaries use top-level section IDs with maxChars 24000, and cursor must be reused with the same parameters. Much individual parameter documentation is already in the schema, so it is not a full 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific verb and resource ('Read source-cited context from an ingested board snapshot') and distinguishes the tool from ingest_board by directing refresh calls there. The closing 'Synthesize the answer yourself' also implicitly separates it from answer_from_board, even though that sibling is not named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It prescribes a detailed sequence: start without topic/nodeIds/limit/maxChars to get an overview, then pass container IDs, use all top-level section IDs with maxChars 24000 for a whole-board summary, follow nextCursor, then read outsideSections. It also covers topic search and cursor continuation. It stops short of explicitly stating when to choose answer_from_board instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ingest_boardIngest FigJam BoardA

Read a FigJam/Figma URL with the configured Figma token and persist a local snapshot for get_board_context, answer_from_board and diff_board; the summary names the largest sections to read next and how many excerpts lie outside sections. Leaves the Figma file unchanged. Every call downloads the board from Figma (one Tier 1 request); get_board_context and answer_from_board read the saved snapshot without a new request. Balanced/quality modes may send board text and images to the configured LLM provider and incur charges; max_speed skips vision. Re-ingest to refresh stale content and continue pending image interpretation; focusNodeIds with section IDs from the summary or the first page of get_board_context interprets their images first. Local history is bounded. Supports framework phases or customPhases.

NameRequiredDescriptionDefault
ingestModeNoHow aggressively to use vision LLM calls during ingestbalanced
customPhasesNoFree-form phase names to map clusters onto (e.g. ["Ideen", "Feedback", "Offene Fragen"]); overrides docStructureHint
figmaFileUrlYesURL of the FigJam/Figma file to ingest
focusNodeIdsNoIDs of pages, sections, frames, groups or single nodes whose image clusters are interpreted first, in list order; the rest of the board follows in the usual order. Section IDs come from the ingest_board summary or the first page of get_board_context. Only the order of image interpretation changes: the whole board is still read and cached, and later ingests without focusNodeIds reuse the interpretations. No effect in max_speed
forceFullIngestNoBuild the snapshot from the downloaded board again instead of the cached result for unchanged content, e.g. after turning credential redaction off. Image interpretations of unchanged clusters are kept, as without forceFullIngest; clusters still pending are interpreted as on any ingest. Model and prompt changes are detected automatically, so forceFullIngest is not needed for them. An unchanged board gives no new snapshot for diff_board. Default: false
docStructureHintNoBuilt-in framework used to map clusters to phasesfreeform
figmaAccessTokenNoFigma personal access token; falls back to FIGMA_ACCESS_TOKEN env var if omitted

Output Schema

NameRequiredDescription
boardIdYes
summaryYes
ingestModeNo
snapshotIdNo
clusterCountYes
figmaVersionNo
qualityReportNo
relationCountNoDirected cluster-to-cluster relations derived from connector arrows
ignoredArgumentsNoUnknown input keys that were ignored; their values are not echoed. Absent when none
freshnessCheckedAtNo
persistenceWarningNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the annotations: the Figma file is left unchanged, every call costs exactly one Tier 1 Figma request, balanced/quality modes may incur LLM charges while max_speed skips vision, and local history is bounded. These are exactly the cost, side-effect and safety facts an agent needs before invoking an open-world, non-idempotent tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first clause, but the body is a single dense run-on block mixing cost, caching, vision ordering and phase mapping. It also restates focusNodeIds semantics already fully documented in the schema, so several clauses do not earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter ingest tool with an output schema, the description covers cost model, caching/idempotency behavior, staleness, refresh path and downstream consumers. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining the cost/vision tradeoff behind ingestMode and the resolution path for focusNodeIds section IDs. It adds little on figmaAccessToken and docStructureHint beyond what the schema already says.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb+resource (read a FigJam/Figma URL, persist a local snapshot) and immediately ties the result to the three sibling tools that consume it. An agent can distinguish this ingest step from get_board_context/answer_from_board/diff_board without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit refresh guidance ("Re-ingest to refresh stale content and continue pending image interpretation") and clarifies that siblings read the saved snapshot with no new request, which implicitly tells the agent when not to call this tool. It stops short of an explicit "use X instead when the snapshot is fresh" routing rule, so 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 5 tool updatesv0.12.0
    • Changedanswer_from_board5 fields changed
      • changedInput schema / properties / boardId / description
        Previous value: -"The Figma file key returned by ingest_board"New value: +"The Figma file key returned by ingest_board, or the board URL"
      • changedInput schema / properties / boardId / maxLength
        Previous value: -128New value: +2048
      • removedInput schema / properties / boardId / pattern
        Removed value: -"^[A-Za-z0-9]+$"
      • addedOutput schema / properties / citations / items / properties / frameNames
        Added value: +{
        +  "description": "Names of enclosing frames and groups, outermost first",
        +  "items": {
        +    "maxLength": 80,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
      • addedOutput schema / properties / ignoredArguments
        Added value: +{
        +  "description": "Unknown input keys that were ignored; their values are not echoed. Absent when none",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changeddiagnose_llm_config1 field changed
      • addedOutput schema / properties / ignoredArguments
        Added value: +{
        +  "description": "Unknown input keys that were ignored; their values are not echoed. Absent when none",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changeddiff_board14 fields changed
      • changedInput schema / properties / boardId / description
        Previous value: -"The Figma file key, as returned by ingest_board"New value: +"The Figma file key, as returned by ingest_board, or the board URL"
      • changedInput schema / properties / boardId / maxLength
        Previous value: -128New value: +2048
      • removedInput schema / properties / boardId / pattern
        Removed value: -"^[A-Za-z0-9]+$"
      • addedOutput schema / properties / addedConnectionsOmitted
        Added value: +{
        +  "description": "Added connections beyond the first 50",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / ignoredArguments
        Added value: +{
        +  "description": "Unknown input keys that were ignored; their values are not echoed. Absent when none",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / modifiedClustersOmitted
        Added value: +{
        +  "description": "Modified clusters beyond the first 20",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / newClustersOmitted
        Added value: +{
        +  "description": "New clusters beyond the first 20",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / removedClustersOmitted
        Added value: +{
        +  "description": "Removed clusters beyond the first 20",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / removedConnectionsOmitted
        Added value: +{
        +  "description": "Removed connections beyond the first 50",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / tableCellChanges / items / properties / currentColumn / description
        Added value: +"0-based, as in get_board_context"
      • addedOutput schema / properties / tableCellChanges / items / properties / currentRow / description
        Added value: +"0-based, as in get_board_context"
      • addedOutput schema / properties / tableCellChanges / items / properties / previousColumn / description
        Added value: +"0-based, as in get_board_context"
      • addedOutput schema / properties / tableCellChanges / items / properties / previousRow / description
        Added value: +"0-based, as in get_board_context"
      • addedOutput schema / properties / tableCellChangesOmitted
        Added value: +{
        +  "description": "Table cell changes beyond the first 50",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
    • Changedget_board_context7 fields changed
      • changedInput schema / properties / boardId / description
        Previous value: -"The Figma file key returned by ingest_board"New value: +"The Figma file key returned by ingest_board, or the board URL. A URL with a node-id, without nodeIds, topic and outsideSections, reads that node"
      • changedInput schema / properties / boardId / maxLength
        Previous value: -128New value: +2048
      • removedInput schema / properties / boardId / pattern
        Removed value: -"^[A-Za-z0-9]+$"
      • changedInput schema / properties / topic / description
        Previous value: -"Optional topic to focus the context on"New value: +"Words to search for. An excerpt matches when at least one of them is in its text, its section or node name, the label of an arrow attached to it or, for a table row, its column headings, as a whole word ignoring case and accents (words of five or more letters also match compounds that begin with them); excerpts with more of the words come first. Other word forms, synonyms and translations do not match: include them yourself, for example \"payment payments pay Bezahlung\". Cannot be combined with nodeIds or outsideSections."
      • addedOutput schema / properties / clusters / items / properties / frameNames
        Added value: +{
        +  "description": "Named enclosing frames and groups, outermost first; excerpts repeat them only where they differ",
        +  "items": {
        +    "maxLength": 80,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
      • addedOutput schema / properties / evidence / items / properties / frameNames
        Added value: +{
        +  "description": "Named enclosing frames and groups, outermost first; included only when nonempty and different from the cluster",
        +  "items": {
        +    "maxLength": 80,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
      • addedOutput schema / properties / ignoredArguments
        Added value: +{
        +  "description": "Unknown input keys that were ignored; their values are not echoed. Absent when none",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Changedingest_board1 field changed
      • addedOutput schema / properties / ignoredArguments
        Added value: +{
        +  "description": "Unknown input keys that were ignored; their values are not echoed. Absent when none",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
  2. 2 tool updatesv0.10.3
    • Changeddiff_board3 fields changed
      • addedOutput schema / properties / modifiedClusters / items / properties / section
        Added value: +{
        +  "description": "Name of the innermost section around the cluster; absent outside sections",
        +  "type": "string"
        +}
      • addedOutput schema / properties / newClusters / items / properties / section
        Added value: +{
        +  "description": "Name of the innermost section around the cluster; absent outside sections",
        +  "type": "string"
        +}
      • addedOutput schema / properties / removedClusters / items / properties / section
        Added value: +{
        +  "description": "Name of the innermost section around the cluster; absent outside sections",
        +  "type": "string"
        +}
    • Changedget_board_context16 fields changed
      • changedInput schema / properties / cursor / description
        Previous value: -"nextCursor of the previous page, unchanged; send it with the same topic, nodeIds, outsideSections, limit and maxChars"New value: +"nextCursor of the previous page, unchanged; send it with the same topic, nodeIds, outsideSections, detail, limit and maxChars"
      • addedInput schema / properties / detail
        Added value: +{
        +  "default": "auto",
        +  "description": "auto uses a compact, source-marked overview when a requested container or several nodeIds need multiple full pages; full returns linked evidence objects. Overview lines may be shortened; use full to read all text",
        +  "enum": [
        +    "auto",
        +    "full"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum evidence excerpts per page (default 20)"New value: +"Maximum evidence excerpts per full page (default 20, at most 100); ignored in an automatic overview, even when explicit. Use detail: full for an excerpt limit"
      • changedInput schema / properties / maxChars / description
        Previous value: -"Character budget for each representation: the readable text content and the JSON of structuredContent (default 12000)"New value: +"Character budget for each representation: the readable text content and the JSON of structuredContent (default 12000, minimum 2000)"
      • changedInput schema / properties / maxChars / minimum
        Previous value: -512New value: +2000
      • changedOutput schema / properties / clusters / items / properties / summary / description
        Previous value: -"Model summary of the cluster; empty for deterministic clusters, whose excerpts carry the text"New value: +"Model summary of the cluster; empty for deterministic clusters, whose excerpts carry the text, and where maxChars leaves no room for it"
      • changedOutput schema / properties / contextText / description
        Previous value: -"Orientation: board header, page position, board overview or subsections. The excerpts are in evidence; the text content carries the readable version"New value: +"Orientation and reading instructions. Excerpts are in overview.text when overview is present (evidence and clusters are then empty), otherwise in evidence; text content carries the same readable excerpts"
      • addedOutput schema / properties / evidence / description
        Added value: +"Full linked excerpts; empty in overview mode, where excerpts are in overview.text instead"
      • addedOutput schema / properties / evidence / items / properties / chunkIndex / description
        Added value: +"Absent means 0"
      • addedOutput schema / properties / evidence / items / properties / modelDerived / description
        Added value: +"Absent means false, independent of the cluster's modelDerived"
      • addedOutput schema / properties / evidence / items / properties / snapshotId / description
        Added value: +"Omitted when inherited from the response snapshotId; only snapshotId is inherited"
      • addedOutput schema / properties / evidence / items / properties / truncated / description
        Added value: +"Absent means false, independent of the cluster"
      • changedOutput schema / properties / evidence / items / required
        Previous value: -[
        -  "evidenceId",
        -  "snapshotId",
        -  "nodeId",
        -  "text",
        -  "sourceType",
        -  "modelDerived",
        -  "chunkIndex",
        -  "url",
        -  "truncated"
        -]New value: +[
        +  "evidenceId",
        +  "nodeId",
        +  "text",
        +  "sourceType",
        +  "url"
        +]
      • addedOutput schema / properties / overview
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Present only for automatic compact overview pages; evidence and clusters are empty, not a claim of no matches. Read a line's full text and Figma link with the same boardId and snapshotId, its nodeId, and detail: full",
        +  "properties": {
        +    "shortenedEvidence": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "shownEvidence": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "text": {
        +      "description": "Source-marked excerpt lines grouped by innermost section; the excerpt texts occur only here in structuredContent",
        +      "type": "string"
        +    },
        +    "textLimit": {
        +      "maximum": 120,
        +      "minimum": 50,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "text",
        +    "shownEvidence",
        +    "shortenedEvidence",
        +    "textLimit"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / truncation / properties / omittedSummaries
        Added value: +{
        +  "description": "Clusters on this page whose model summary is left empty to fit maxChars",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / unknownNodeIds
        Added value: +{
        +  "description": "Requested nodeIds that are not in this snapshot; the others are read",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
  3. 4 tool updatesv0.10.2
    • Changeddiagnose_llm_config1 field changed
      • addedOutput schema / properties / checks / items / properties / attempts
        Added value: +{
        +  "description": "The model candidates tried, in order; error is the provider's message or the error",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "error": {
        +        "type": "string"
        +      },
        +      "model": {
        +        "type": "string"
        +      },
        +      "ok": {
        +        "type": "boolean"
        +      }
        +    },
        +    "required": [
        +      "model",
        +      "ok"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
    • Changeddiff_board5 fields changed
      • addedOutput schema / properties / nodeChanges
        Added value: +{
        +  "description": "Edited, added, then removed nodes in reading order; read whole texts with get_board_context and nodeIds",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "changeType": {
        +        "enum": [
        +          "added",
        +          "removed",
        +          "edited"
        +        ],
        +        "type": "string"
        +      },
        +      "changes": {
        +        "items": {
        +          "enum": [
        +            "text",
        +            "name",
        +            "image",
        +            "rotation",
        +            "type",
        +            "appearance"
        +          ],
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "currentText": {
        +        "description": "Whitespace-collapsed; only the changed part of a long text",
        +        "type": "string"
        +      },
        +      "name": {
        +        "type": "string"
        +      },
        +      "nodeId": {
        +        "type": "string"
        +      },
        +      "nodeType": {
        +        "type": "string"
        +      },
        +      "previousName": {
        +        "type": "string"
        +      },
        +      "previousText": {
        +        "description": "Whitespace-collapsed; only the changed part of a long text",
        +        "type": "string"
        +      },
        +      "section": {
        +        "type": "string"
        +      },
        +      "sectionId": {
        +        "description": "Innermost section; absent outside sections",
        +        "type": "string"
        +      },
        +      "url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "nodeId",
        +      "changeType",
        +      "nodeType",
        +      "url"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / nodeChangesOmitted
        Added value: +{
        +  "description": "Changed nodes beyond the first 100",
        +  "exclusiveMinimum": 0,
        +  "maximum": 9007199254740991,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / tableCellChanges / items / properties / columnLabel
        Added value: +{
        +  "description": "Text of the cell in the first row of the column",
        +  "type": "string"
        +}
      • addedOutput schema / properties / tableCellChanges / items / properties / rowLabel
        Added value: +{
        +  "description": "Text of the first cell in the row",
        +  "type": "string"
        +}
      • addedOutput schema / properties / tableCellChanges / items / properties / tableName
        Added value: +{
        +  "type": "string"
        +}
    • Changedget_board_context4 fields changed
      • changedInput schema / properties / cursor / description
        Previous value: -"Continue a page using the same query, snapshot, limit and maxChars"New value: +"nextCursor of the previous page, unchanged; send it with the same topic, nodeIds, outsideSections, limit and maxChars"
      • addedOutput schema / properties / connections / description
        Added value: +"Arrows with at least one end, or a section, frame or group around one, among this page's excerpts; never arrows to a page. The label is the text on the arrow"
      • addedOutput schema / properties / connections / items / properties / fromText
        Added value: +{
        +  "description": "Short text or name of the start node when it is not among this page's excerpts, redacted like excerpts",
        +  "maxLength": 80,
        +  "type": "string"
        +}
      • addedOutput schema / properties / connections / items / properties / toText
        Added value: +{
        +  "description": "Short text or name of the end node when it is not among this page's excerpts, redacted like excerpts",
        +  "maxLength": 80,
        +  "type": "string"
        +}
    • Changedingest_board3 fields changed
      • addedInput schema / properties / focusNodeIds
        Added value: +{
        +  "description": "IDs of pages, sections, frames, groups or single nodes whose image clusters are interpreted first, in list order; the rest of the board follows in the usual order. Section IDs come from the ingest_board summary or the first page of get_board_context. Only the order of image interpretation changes: the whole board is still read and cached, and later ingests without focusNodeIds reuse the interpretations. No effect in max_speed",
        +  "items": {
        +    "maxLength": 200,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 50,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / forceFullIngest / description
        Previous value: -"Download and extract the board again, skipping the unchanged-board check and cache, and redo the image interpretation of the chosen ingestMode. Interpretations this mode does not redo (all in max_speed; in balanced those of clusters without image or drawing) are kept while a cluster's content is unchanged. The vision time budget still applies, so balanced and max_quality may need several ingests until every image is interpreted again. An unchanged board gives no new snapshot for diff_board, even with forceFullIngest. Model/configuration changes are detected automatically. Default: false"New value: +"Build the snapshot from the downloaded board again instead of the cached result for unchanged content, e.g. after turning credential redaction off. Image interpretations of unchanged clusters are kept, as without forceFullIngest; clusters still pending are interpreted as on any ingest. Model and prompt changes are detected automatically, so forceFullIngest is not needed for them. An unchanged board gives no new snapshot for diff_board. Default: false"
      • addedOutput schema / properties / qualityReport / properties / focus
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Only with focusNodeIds: the IDs found on the board and the clusters in focus this ingestMode interprets, of them interpreted and pending",
        +  "properties": {
        +    "foundIds": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "imageClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "interpreted": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "pending": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "requestedIds": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "requestedIds",
        +    "foundIds",
        +    "imageClusters",
        +    "interpreted",
        +    "pending"
        +  ],
        +  "type": "object"
        +}
  4. 2 tool updatesv0.8.0
    • Changedget_board_context2 fields changed
      • changedInput schema / properties / nodeIds / description
        Previous value: -"Read exact source nodes, all rows of a table or the row of a table cell, or every excerpt inside a page, section, frame or group by its ID (nested sections included, in reading order); cannot be combined with topic"New value: +"Read exact source nodes, all rows of a table or the row of a table cell, or every excerpt inside a page, section, frame or group by its ID (nested sections included, in reading order); several IDs in one call share every page in request order; cannot be combined with topic"
      • addedInput schema / properties / outsideSections
        Added value: +{
        +  "description": "Read every excerpt that lies in no section, cluster by cluster in reading order, tables row by row; on a board without sections, all excerpts. Cannot be combined with topic or nodeIds",
        +  "type": "boolean"
        +}
    • Changedingest_board2 fields changed
      • changedInput schema / properties / forceFullIngest / description
        Previous value: -"Deliberately skip all caching and incremental reuse, including successful interpretations. The vision time budget still applies. Model/configuration changes are detected automatically. Default: false"New value: +"Download and extract the board again, skipping the unchanged-board check and cache, and redo the image interpretation of the chosen ingestMode. Interpretations this mode does not redo (all in max_speed; in balanced those of clusters without image or drawing) are kept while a cluster's content is unchanged. The vision time budget still applies, so balanced and max_quality may need several ingests until every image is interpreted again. An unchanged board gives no new snapshot for diff_board, even with forceFullIngest. Model/configuration changes are detected automatically. Default: false"
      • addedOutput schema / properties / qualityReport / properties / figmaRequests
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Figma requests of this ingest for images: image fills (Tier 2) and renders (Tier 1)",
        +  "properties": {
        +    "imageFills": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "renders": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "imageFills",
        +    "renders"
        +  ],
        +  "type": "object"
        +}
  5. 2 tool updatesv0.7.0
    • Changedanswer_from_board1 field changed
      • changedOutput schema / properties / citations / items / properties / sourceType / enum
        Previous value: -[
        -  "board_text",
        -  "table_cell",
        -  "board_metadata",
        -  "model_interpretation",
        -  "cluster_summary"
        -]New value: +[
        +  "board_text",
        +  "table_cell",
        +  "table_row",
        +  "board_metadata",
        +  "model_interpretation",
        +  "cluster_summary"
        +]
    • Changedget_board_context9 fields changed
      • changedInput schema / properties / maxChars / description
        Previous value: -"Character budget for the whole structured result (JSON of structuredContent, including contextText; default 12000)"New value: +"Character budget for each representation: the readable text content and the JSON of structuredContent (default 12000)"
      • changedInput schema / properties / nodeIds / description
        Previous value: -"Read exact source nodes or table cells; cannot be combined with topic"New value: +"Read exact source nodes, all rows of a table or the row of a table cell, or every excerpt inside a page, section, frame or group by its ID (nested sections included, in reading order); cannot be combined with topic"
      • addedOutput schema / properties / clusters / items / properties / pageName
        Added value: +{
        +  "description": "Page of this cluster's excerpts on this page of results; excerpts repeat it only where they differ",
        +  "maxLength": 160,
        +  "type": "string"
        +}
      • addedOutput schema / properties / clusters / items / properties / sectionNames
        Added value: +{
        +  "description": "Enclosing sections, outermost first, of this cluster's excerpts; excerpts repeat them only where they differ",
        +  "items": {
        +    "maxLength": 80,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
      • addedOutput schema / properties / clusters / items / properties / summary / description
        Added value: +"Model summary of the cluster; empty for deterministic clusters, whose excerpts carry the text"
      • addedOutput schema / properties / contextText / description
        Added value: +"Orientation: board header, page position, board overview or subsections. The excerpts are in evidence; the text content carries the readable version"
      • addedOutput schema / properties / evidence / items / properties / pageName / description
        Added value: +"Only for an excerpt outside the listed clusters or whose location differs from its cluster's"
      • addedOutput schema / properties / evidence / items / properties / sectionNames / description
        Added value: +"Same rule as pageName; an empty list means outside sections"
      • changedOutput schema / properties / evidence / items / properties / sourceType / enum
        Previous value: -[
        -  "board_text",
        -  "table_cell",
        -  "board_metadata",
        -  "model_interpretation",
        -  "cluster_summary"
        -]New value: +[
        +  "board_text",
        +  "table_cell",
        +  "table_row",
        +  "board_metadata",
        +  "model_interpretation",
        +  "cluster_summary"
        +]
  6. 1 tool updatev0.6.0
    • Changedget_board_context1 field changed
      • changedInput schema / properties / maxChars / description
        Previous value: -"Character budget for the readable context (default 12000)"New value: +"Character budget for the whole structured result (JSON of structuredContent, including contextText; default 12000)"
  7. 5 tool updatesv0.4.0
    • Changedanswer_from_board13 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / boardId / description
        Added value: +"The Figma file key returned by ingest_board"
      • addedInput schema / properties / boardId / maxLength
        Added value: +128
      • addedInput schema / properties / boardId / minLength
        Added value: +6
      • addedInput schema / properties / boardId / pattern
        Added value: +"^[A-Za-z0-9]+$"
      • addedInput schema / properties / question / maxLength
        Added value: +2000
      • addedInput schema / properties / question / minLength
        Added value: +1
      • addedInput schema / properties / snapshotId
        Added value: +{
        +  "maxLength": 128,
        +  "minLength": 1,
        +  "pattern": "^[A-Za-z0-9_-]+$",
        +  "type": "string"
        +}
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / citations
        Added value: +{
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "clusterId": {
        +        "type": "string"
        +      },
        +      "clusterLabel": {
        +        "type": "string"
        +      },
        +      "column": {
        +        "type": "number"
        +      },
        +      "evidenceId": {
        +        "type": "string"
        +      },
        +      "modelDerived": {
        +        "type": "boolean"
        +      },
        +      "nodeId": {
        +        "type": "string"
        +      },
        +      "nodeName": {
        +        "maxLength": 160,
        +        "type": "string"
        +      },
        +      "pageId": {
        +        "type": "string"
        +      },
        +      "pageName": {
        +        "maxLength": 160,
        +        "type": "string"
        +      },
        +      "quote": {
        +        "type": "string"
        +      },
        +      "row": {
        +        "type": "number"
        +      },
        +      "sectionIds": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "sectionNames": {
        +        "items": {
        +          "maxLength": 80,
        +          "type": "string"
        +        },
        +        "maxItems": 16,
        +        "type": "array"
        +      },
        +      "snapshotId": {
        +        "type": "string"
        +      },
        +      "sourceType": {
        +        "enum": [
        +          "board_text",
        +          "table_cell",
        +          "board_metadata",
        +          "model_interpretation",
        +          "cluster_summary"
        +        ],
        +        "type": "string"
        +      },
        +      "url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "evidenceId",
        +      "snapshotId",
        +      "nodeId",
        +      "quote",
        +      "url",
        +      "sourceType",
        +      "modelDerived"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / snapshotId
        Added value: +{
        +  "type": "string"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "answer",
        -  "citedClusters"
        -]New value: +[
        +  "answer",
        +  "citedClusters",
        +  "snapshotId",
        +  "citations"
        +]
    • Addeddiagnose_llm_config
    • Addeddiff_board
    • Changedget_board_context27 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / boardId / description
        Added value: +"The Figma file key returned by ingest_board"
      • addedInput schema / properties / boardId / maxLength
        Added value: +128
      • addedInput schema / properties / boardId / minLength
        Added value: +6
      • addedInput schema / properties / boardId / pattern
        Added value: +"^[A-Za-z0-9]+$"
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "Continue a page using the same query, snapshot, limit and maxChars",
        +  "maxLength": 2048,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 20,
        +  "description": "Maximum evidence excerpts per page (default 20)",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / maxChars
        Added value: +{
        +  "default": 12000,
        +  "description": "Character budget for the readable context (default 12000)",
        +  "maximum": 24000,
        +  "minimum": 512,
        +  "type": "integer"
        +}
      • addedInput schema / properties / nodeIds
        Added value: +{
        +  "description": "Read exact source nodes or table cells; cannot be combined with topic",
        +  "items": {
        +    "maxLength": 200,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 50,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • addedInput schema / properties / snapshotId
        Added value: +{
        +  "description": "Read a specific retained snapshot instead of the latest board",
        +  "maxLength": 128,
        +  "minLength": 1,
        +  "pattern": "^[A-Za-z0-9_-]+$",
        +  "type": "string"
        +}
      • addedInput schema / properties / topic / maxLength
        Added value: +200
      • addedInput schema / properties / topic / minLength
        Added value: +1
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / clusters / items / properties / modelDerived
        Added value: +{
        +  "description": "True for model summaries and summaries whose non-model origin cannot be established",
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / clusters / items / properties / sourceNodeIds / description
        Added value: +"Source nodes displayed on this page, not citations validating the cluster summary"
      • addedOutput schema / properties / clusters / items / properties / summarySource
        Added value: +{
        +  "description": "Origin of the derived cluster summary; the summary is not verbatim source evidence",
        +  "enum": [
        +    "vision_llm",
        +    "text_llm",
        +    "deterministic",
        +    "cache",
        +    "unknown"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / properties / clusters / items / required
        Previous value: -[
        -  "label",
        -  "summary",
        -  "sourceNodeIds"
        -]New value: +[
        +  "label",
        +  "summary",
        +  "summarySource",
        +  "modelDerived",
        +  "sourceNodeIds"
        +]
      • addedOutput schema / properties / connections
        Added value: +{
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "connectorId": {
        +        "type": "string"
        +      },
        +      "direction": {
        +        "enum": [
        +          "forward",
        +          "reverse",
        +          "bidirectional",
        +          "undirected"
        +        ],
        +        "type": "string"
        +      },
        +      "fromNodeId": {
        +        "type": "string"
        +      },
        +      "label": {
        +        "type": "string"
        +      },
        +      "toNodeId": {
        +        "type": "string"
        +      },
        +      "url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "connectorId",
        +      "fromNodeId",
        +      "toNodeId",
        +      "direction",
        +      "url"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / evidence
        Added value: +{
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "chunkIndex": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "clusterId": {
        +        "type": "string"
        +      },
        +      "clusterLabel": {
        +        "type": "string"
        +      },
        +      "column": {
        +        "type": "number"
        +      },
        +      "evidenceId": {
        +        "type": "string"
        +      },
        +      "modelDerived": {
        +        "type": "boolean"
        +      },
        +      "nodeId": {
        +        "type": "string"
        +      },
        +      "nodeName": {
        +        "maxLength": 160,
        +        "type": "string"
        +      },
        +      "pageId": {
        +        "type": "string"
        +      },
        +      "pageName": {
        +        "maxLength": 160,
        +        "type": "string"
        +      },
        +      "renderNodeId": {
        +        "type": "string"
        +      },
        +      "row": {
        +        "type": "number"
        +      },
        +      "sectionIds": {
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "sectionNames": {
        +        "items": {
        +          "maxLength": 80,
        +          "type": "string"
        +        },
        +        "maxItems": 16,
        +        "type": "array"
        +      },
        +      "snapshotId": {
        +        "type": "string"
        +      },
        +      "sourceType": {
        +        "enum": [
        +          "board_text",
        +          "table_cell",
        +          "board_metadata",
        +          "model_interpretation",
        +          "cluster_summary"
        +        ],
        +        "type": "string"
        +      },
        +      "text": {
        +        "type": "string"
        +      },
        +      "truncated": {
        +        "type": "boolean"
        +      },
        +      "url": {
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "evidenceId",
        +      "snapshotId",
        +      "nodeId",
        +      "text",
        +      "sourceType",
        +      "modelDerived",
        +      "chunkIndex",
        +      "url",
        +      "truncated"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / nextCursor
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / relations
        Added value: +{
        +  "description": "Cluster-to-cluster relations derived from connector arrows",
        +  "items": {
        +    "additionalProperties": false,
        +    "properties": {
        +      "edgeCount": {
        +        "exclusiveMinimum": 0,
        +        "maximum": 9007199254740991,
        +        "type": "integer"
        +      },
        +      "from": {
        +        "description": "Label of the source cluster",
        +        "type": "string"
        +      },
        +      "label": {
        +        "description": "Connector label(s), when the arrows are annotated",
        +        "type": "string"
        +      },
        +      "to": {
        +        "description": "Label of the target cluster",
        +        "type": "string"
        +      }
        +    },
        +    "required": [
        +      "from",
        +      "to",
        +      "edgeCount"
        +    ],
        +    "type": "object"
        +  },
        +  "type": "array"
        +}
      • addedOutput schema / properties / snapshotId
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / totalMatched
        Added value: +{
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "type": "boolean"
        +}
      • addedOutput schema / properties / truncation
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "Explicit omissions from structured results and the readable text",
        +  "properties": {
        +    "omittedConnections": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "omittedRelations": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "omittedTextConnections": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "omittedTextRelations": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "remainingEvidence": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "remainingEvidence",
        +    "omittedConnections",
        +    "omittedRelations",
        +    "omittedTextConnections",
        +    "omittedTextRelations"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / required
        Previous value: -[
        -  "contextText",
        -  "clusters"
        -]New value: +[
        +  "contextText",
        +  "clusters",
        +  "snapshotId",
        +  "evidence",
        +  "connections",
        +  "totalMatched",
        +  "truncated",
        +  "truncation"
        +]
    • Changedingest_board22 fields changed
      • changedInput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / customPhases
        Added value: +{
        +  "description": "Free-form phase names to map clusters onto (e.g. [\"Ideen\", \"Feedback\", \"Offene Fragen\"]); overrides docStructureHint",
        +  "items": {
        +    "maxLength": 80,
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 12,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • changedInput schema / properties / docStructureHint / description
        Previous value: -"How to interpret the board's structure when mapping clusters to phases"New value: +"Built-in framework used to map clusters to phases"
      • changedInput schema / properties / docStructureHint / enum
        Previous value: -[
        -  "double_diamond",
        -  "freeform"
        -]New value: +[
        +  "freeform",
        +  "double_diamond",
        +  "lean_canvas",
        +  "retro",
        +  "user_journey"
        +]
      • addedInput schema / properties / figmaAccessToken / maxLength
        Added value: +512
      • addedInput schema / properties / figmaAccessToken / minLength
        Added value: +1
      • addedInput schema / properties / figmaFileUrl / maxLength
        Added value: +2048
      • addedInput schema / properties / forceFullIngest
        Added value: +{
        +  "description": "Deliberately skip all caching and incremental reuse, including successful interpretations. The vision time budget still applies. Model/configuration changes are detected automatically. Default: false",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / ingestMode
        Added value: +{
        +  "default": "balanced",
        +  "description": "How aggressively to use vision LLM calls during ingest",
        +  "enum": [
        +    "balanced",
        +    "max_quality",
        +    "max_speed"
        +  ],
        +  "type": "string"
        +}
      • changedOutput schema / $schema
        Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
      • addedOutput schema / properties / boardId / maxLength
        Added value: +128
      • addedOutput schema / properties / boardId / minLength
        Added value: +6
      • addedOutput schema / properties / boardId / pattern
        Added value: +"^[A-Za-z0-9]+$"
      • addedOutput schema / properties / clusterCount / maximum
        Added value: +9007199254740991
      • addedOutput schema / properties / figmaVersion
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / freshnessCheckedAt
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / ingestMode
        Added value: +{
        +  "enum": [
        +    "balanced",
        +    "max_quality",
        +    "max_speed"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / properties / persistenceWarning
        Added value: +{
        +  "type": "string"
        +}
      • addedOutput schema / properties / qualityReport
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "cachedClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "deterministicClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "fallbackCount": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "fallbackReasons": {
        +      "additionalProperties": {
        +        "maximum": 9007199254740991,
        +        "minimum": 0,
        +        "type": "integer"
        +      },
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "incompleteClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "modelsUsed": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "nextRetryAt": {
        +      "type": "number"
        +    },
        +    "reusedClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    },
        +    "visionClusters": {
        +      "maximum": 9007199254740991,
        +      "minimum": 0,
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "modelsUsed",
        +    "cachedClusters",
        +    "deterministicClusters",
        +    "visionClusters",
        +    "fallbackCount"
        +  ],
        +  "type": "object"
        +}
      • addedOutput schema / properties / relationCount
        Added value: +{
        +  "description": "Directed cluster-to-cluster relations derived from connector arrows",
        +  "maximum": 9007199254740991,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / snapshotId
        Added value: +{
        +  "type": "string"
        +}
  8. 3 tool updatesv0.1.0
    • First observedanswer_from_board
    • First observedget_board_context
    • First observedingest_board

TDQS

A4.3/5.0

Scored across 5 tools

Disambiguation4/5

Each tool maps to a distinct role: ingest (fetch snapshot), read/summarize (get_board_context), specific Q&A (answer_from_board), compare snapshots (diff_board), and config self-test (diagnose_llm_config). The main risk area is get_board_context vs answer_from_board, which both read from the same snapshot; the descriptions spend a lot of text partitioning them (summaries vs single factual questions), which mostly resolves the overlap but shows the boundary is not self-evident.

Naming Consistency4/5

All names are snake_case and verb-first (ingest_board, get_board_context, answer_from_board, diff_board, diagnose_llm_config). The verbs vary in form (plain verb, verb_prepositional, verb_object_object), but the pattern remains readable and predictable.

Tool Count5/5

Five tools is well-scoped for a board-snapshot context server: one write path, two read paths, one comparison, one diagnostics. No tool appears redundant or bolted on.

Completeness4/5

The lifecycle is covered: ingest, summarized/structured reading with cursors and search, targeted Q&A, snapshot diffing, and model diagnostics. Minor gaps exist around snapshot management (no explicit list/delete/prune of the bounded local history or snapshot inventory), but compareTo and re-ingest let agents work around these.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables MCP-compatible LLMs to interact with Miro whiteboards to manage boards, create and manipulate shapes, and organize content through grouping tools.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to programmatically interact with a Miro board through the Miro API, supporting operations like creating items, updating positions, and managing connectors.
    16
    ISC
  • F
    license
    B
    quality
    D
    maintenance
    Enables AI agents to read, inspect, and export Figma designs programmatically. Provides tools for listing components, styles, and exporting assets in various formats.
    5
    1
    -