Incremental XMind MCP server with atomic tools for reading and modifying mind maps
Strong tool design overall with clear naming conventions, complete parameter schemas, and descriptive docstrings. All 18 tools follow verb_noun naming and include proper input schemas with type definitions. Descriptions are well-written (100-300 chars typical), explaining WHAT the tool does and WHEN to use it. However, output schemas are only partially documented (returned as JSON strings without formal schema declarations), and error handling lacks recovery guidance. The server uses fastmcp framework which auto-registers tools, making schemas visible in code. No security concerns detected (no secrets in parameters). Tools are well-composed with clear single responsibilities. Per-tool scores range 65-80, averaging 72.
Add a boundary (visual box) around a range of sibling topics. *range* is a string like "(0,2)" meaning children 0 and 1 (2 is exclusive). Returns the boundary dict (including its generated ID).
Add a relationship (arrow/line) between two topics on the same sheet. Returns the relationship dict (including its generated ID).
Add a new sheet to the XMind file. Returns a dict with keys sheet_id and root_topic_id for use in subsequent operations on the new sheet.
Add a branch with nested children to an existing parent topic. *children* is a list of topic dicts, each with at minimum a "title" key and an optional "children" list for nesting. IDs are generated automatically. Example children: [{"title": "A", "children": [{"title": "A1"}, {"title": "A2"}]}, {"title": "B"}]
Add a summary (bracket annotation) to a range of sibling topics. *range* is a string like "(0,2)" meaning children 0 and 1 (2 is exclusive). Returns a dict with the summary info (including its generated ID).
Output schemas not formally documented. Tools return JSON strings (via json.dumps) but lack explicit response schema declarations. LLMs cannot reliably parse unstructured JSON responses or understand field types for downstream tool chaining.
Error handling lacks recovery guidance. Errors are raised as XMindFileError exceptions with basic messages (e.g. 'Topic not found: {topic_id}', 'File already exists') but do not suggest next steps or alternative actions for the LLM to take.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
Add a single child topic to an existing parent topic. Returns the new topic's JSON (including its generated ID). Use *index* to control position among siblings (default: append).
Create a new XMind mind-map file with a single sheet and root topic. Returns the tree view of the newly created map (including IDs).
Delete a boundary from a topic. Returns confirmation.
Delete a relationship (arrow/line) from a sheet. Returns confirmation.
Delete an entire sheet (and all its topics) from the XMind file. Cannot delete if it's the only sheet. Returns the title of the deleted sheet.
Delete a summary from a topic. Returns confirmation.
Delete a topic and all its descendants. Cannot delete a root topic (use xmind_delete_sheet instead). Returns the title of the deleted topic.
Get the full details of a specific topic and its subtree by ID. Returns the complete JSON representation including notes, labels, markers, boundaries, summaries, and all descendants.
Recursively list all .xmind files in a directory.
Move a topic (and its subtree) to a new parent. Cannot move a root topic. Use *index* to control position among new siblings (default: append).
Open an XMind file and return a compact tree view of its structure. Every node is annotated with its ID so you can reference it in subsequent add/update/delete/move calls. Use *max_depth* to limit how deep the tree is rendered (useful for large maps -- drill into specific branches with xmind_get_topic afterwards).
Search for topics matching a text query across the mind map. *search_in* controls which fields are searched. Defaults to ["title", "notes", "labels"]. Returns matching topics with their IDs, paths, and matched fields.
Update properties of an existing topic. Only supplied fields are changed. *notes* can be a plain string or {"plain": "...", "html": ""}. *task_status* should be "todo", "done", or null to clear.
Destructive operations (delete_topic, delete_sheet, delete_relationship, delete_boundary, delete_summary) lack confirmation or dry-run capability. Agents can irreversibly delete branches or entire sheets without verification, creating high risk of accidental data loss.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) declared. While risk levels are labeled in the evaluation metadata, the tools themselves do not expose these hints to clients for proper safety-aware scheduling and planning.
No pagination or result limits on potentially large returns. xmind_list_maps recursively lists all .xmind files without a limit parameter, and xmind_search_topics returns all matches without pagination. Large result sets could exhaust context windows.
Missing parameter validation descriptions. Some parameters (e.g. 'range' in xmind_add_boundary, xmind_add_summary) accept string format like '(0,2)' but lack explicit format validation hints or examples. LLMs may generate invalid range strings.