Skip to main content
Glama
cotletdev

Milanote MCP Server

by cotletdev

Milanote API and MCP server, self-hosted

A Milanote API and a Milanote MCP server you run on your own computer, in Python, on the session of your own Google Chrome. 30 of the 31 Milanote tools we run in production at Cotlet: boards, notes, links, to-do lists with due dates, columns, labels, trash, comments, sharing and export.

Milanote has no public API and no official MCP server. This repo gives you both:

  • MCP server for Claude Code, Claude Desktop, Cursor, Codex and any MCP client, over stdio or HTTP. Setup

  • REST API on http://127.0.0.1:8787/api/v1/milanote, with OpenAPI docs at /docs. Setup

  • Python: call("get_board", board_id="1XiqwC1Mir4d4N"), plus 9 ready scripts in examples/.

It is for technical people who want to run it themselves, for personal use only (license). If you want it running 24/7 on a server, kept working when Milanote changes its app, for a team or a business, use the hosted version at cotlet.dev.

Milanote MCP server Python 3.11+ License: personal use

git clone https://github.com/cotletdev/milanote-api-mcp-server.git && cd milanote-api-mcp-server
python3 -m venv .venv && . .venv/bin/activate && pip install -e .
milanote-mcp connect                               # reads your Milanote session from Chrome
milanote-mcp call list_boards
claude mcp add milanote -- "$PWD/.venv/bin/milanote-mcp" mcp

Contents

Related MCP server: byob

How it works

AI agent (MCP) / script (REST, Python) ──▶ milanote-mcp on your computer ──your Milanote cookies──▶ milanote.com
                                                     ▲
                         milanote-mcp connect ───────┘ reads them once from your Chrome (DevTools Protocol)
  1. You sign in to Milanote in your own Chrome, the way you always do.

  2. milanote-mcp connect attaches to that Chrome through the Chrome DevTools Protocol, reads the milanote.com cookies and your browser's time zone, and saves them to ~/.config/milanote-api-mcp/session.json, readable by your user only. It never sees or stores your password.

  3. Reads are requests to the JSON endpoints of the Milanote web app on app.milanote.com/api. Changes go over the same socket.io channel the web app uses, sent as plain HTTP polling. Everything goes out with your cookies through curl_cffi, which copies Chrome's TLS fingerprint. No headless browser runs.

Milanote's session cookie lasts about a month. When Milanote signs you out, the server reads the cookies from Chrome again, if Chrome is open with remote debugging on.

Requirements

  • Python 3.11 or newer.

  • Google Chrome 144 or newer, signed in to Milanote. Any Chrome or Chromium works with a debugging port.

  • macOS, Linux or Windows.

  • Any Milanote plan. A free account stops at 100 cards, and the tools say so when Milanote refuses. Changing a board someone shared with you needs edit access to it.

Install

git clone https://github.com/cotletdev/milanote-api-mcp-server.git
cd milanote-api-mcp-server
python3 -m venv .venv
. .venv/bin/activate              # Windows: .venv\Scripts\activate
pip install -e .
milanote-mcp --version

With uv: uv venv && uv pip install -e ., then uv run milanote-mcp ....

Setting it up with an AI agent (Claude Code, Codex, Cursor)? Open it in this folder and ask it to set up the repo: AGENTS.md tells it every step, and it asks you only for the steps in Chrome.

To update: git pull && pip install -e .. We copy every change of the hosted Milanote tools into this repo.

Connect your Chrome

  1. Open chrome://inspect/#remote-debugging in Chrome and switch remote debugging on. Chrome then accepts DevTools connections from programs on this computer, and asks you before each one.

  2. Make sure you are signed in at app.milanote.com.

  3. Run:

    milanote-mcp connect
  4. Chrome asks whether to allow the connection. Click Allow.

Saved 8 Milanote cookies to /Users/you/.config/milanote-api-mcp/session.json
Signed in to Milanote as Ana Lopez

You can switch remote debugging off again afterwards. Leave it on if you want the server to pick up a new session by itself after Milanote signs you out.

connect looks for Chrome's DevToolsActivePort file in the default profile folder. For Chrome Beta, Canary or a custom profile folder, pass --profile-dir "<folder>".

Option B: a Chrome with a debugging port

Chrome does not open a debugging port on your default profile, so start a separate one, sign in to Milanote there once, and connect to it:

# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --remote-debugging-port=9222 --user-data-dir="$HOME/.chrome-milanote"
# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir="$HOME/.chrome-milanote"
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%USERPROFILE%\.chrome-milanote"

milanote-mcp connect --cdp http://127.0.0.1:9222

--cdp also takes a ws:// DevTools URL, for example of a Chrome on another machine reached over an SSH tunnel.

For a server with no Chrome: in Chrome open DevTools on app.milanote.com, Application > Cookies > https://app.milanote.com, copy the value of __Secure-milanote.session_token, then:

milanote-mcp connect --token       # paste it, input is hidden
# or, without a session file:
export MILANOTE_AUTH_TOKEN=...

A pasted token is not refreshed on its own. Paste a new one when Milanote signs you out. Times then come in this machine's time zone.

Check the session at any time:

milanote-mcp status

MCP server

The MCP server lists every tool with its input schema, a description written for agents, and hints: read tools are marked read-only, and tools that comment, invite, publish or trash are marked so your client asks before running them.

Claude Code

claude mcp add milanote -- /path/to/milanote-api-mcp-server/.venv/bin/milanote-mcp mcp
# read only:
claude mcp add milanote -- /path/to/milanote-api-mcp-server/.venv/bin/milanote-mcp mcp --read-only

Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "milanote": {
      "command": "/path/to/milanote-api-mcp-server/.venv/bin/milanote-mcp",
      "args": ["mcp"]
    }
  }
}

Cursor

~/.cursor/mcp.json, the same block as Claude Desktop. A ready copy is in mcp.json.

Codex

~/.codex/config.toml:

[mcp_servers.milanote]
command = "/path/to/milanote-api-mcp-server/.venv/bin/milanote-mcp"
args = ["mcp"]

Over HTTP

milanote-mcp serve also serves MCP over streamable HTTP at http://127.0.0.1:8787/mcp, for clients that take a URL:

milanote-mcp serve
claude mcp add --transport http milanote http://127.0.0.1:8787/mcp

Then ask your agent things like:

Put these 12 reference links on the Moodboard sub-board of Brand refresh and skip the ones already there.

Export my Novel outline board and each chapter sub-board as Markdown into ./outline.

Here are my call notes. Add the action items as a to-do list on Q1 campaign with the dates we agreed.

Where did I save that note about the color palette?

REST API

milanote-mcp serve                 # http://127.0.0.1:8787, MCP at /mcp, docs at /docs

Each tool has its own route under /api/v1/milanote, the same paths as the hosted API at cotlet.dev, so code written against one works with the other. Path parts and the query string are arguments, and a JSON body adds the rest.

curl 'http://127.0.0.1:8787/api/v1/milanote/boards'
curl 'http://127.0.0.1:8787/api/v1/milanote/boards/1XiqwC1Mir4d4N'
curl -X POST http://127.0.0.1:8787/api/v1/milanote/boards/1XiqwC1Mir4d4N/notes \
  -H 'Content-Type: application/json' \
  -d '{"text": "Kickoff moved to Tuesday."}'

Any tool by name, body as its arguments:

curl -X POST http://127.0.0.1:8787/api/v1/milanote/tools/export_board -d '{"board_id": "1XiqwC1Mir4d4N", "format": "markdown"}'
  • GET /api/v1/milanote/tools: every tool with its route, input schema and an example answer.

  • GET /docs: interactive OpenAPI docs, GET /openapi.json the schema, for n8n, Postman or a generated client.

  • Answers are JSON. Lists that stop early return has_more: true; raise limit to get the rest.

The server listens on 127.0.0.1 only. To reach it from another device of yours, set a token, and every request then needs Authorization: Bearer <token>:

MILANOTE_MCP_TOKEN=$(openssl rand -hex 24) milanote-mcp serve --host 0.0.0.0

Python and the example scripts

Straight from Python, no server needed:

from milanote_api_mcp import call

boards = call("list_boards")["boards"]
board = call("get_board", board_id=boards[0]["id"])
call(
    "add_todo_list",
    board_id=board["board_id"],
    title="This week",
    tasks=[{"text": "Send the brief", "due_date": "2026-10-28"}, {"text": "Book the photographer"}],
)

Or one tool from the shell: milanote-mcp call get_board board_id=1XiqwC1Mir4d4N, or with a JSON object.

Ready scripts in examples/. Each takes --help, and the ones that list things print JSON or save --out file.csv / --out file.json:

Script

What it does

list_boards.py

Your boards as a tree, from Home or any board, --depth levels down.

search_boards.py

Searches all your boards and prints each matching card with its board and path.

export_boards.py

A board and its sub-boards to Markdown, text, Word, PDF or PNG, one file per board, folders following the nesting.

board_card_counts.py

Cards on each board by type, biggest first, and your use of the free plan's limit.

open_tasks.py

Unticked tasks from every to-do list on a board and its sub-boards, soonest due first. --due-before.

save_links.py

Saves a list of URLs as link cards, skipping the ones already on the board. --dry-run first.

add_todo_list.py

A to-do list from a text file, one task per line, with optional YYYY-MM-DD HH:MM due dates.

add_note.py

A note card from --text, a file or standard input.

publish_board.py

Turns a board's read-only link on and prints it, or --off.

python examples/export_boards.py --board 1XiqwC1Mir4d4N --dir ./outline
python examples/save_links.py --board 1XiqwC1Mir4d4N --file links.txt --dry-run

On a schedule, cron on your own computer works while it is on: 0 18 * * 5 cd ~/milanote-api-mcp-server && .venv/bin/python examples/export_boards.py --board 1XiqwC1Mir4d4N --dir ~/backups/milanote.

All 30 tools

board_id is the ID from list_boards, or the board's URL (https://app.milanote.com/1XiqwC1Mir4d4N/...). Cards the tools add land in the board's Unsorted panel, the same place Milanote puts uploads, so they never cover cards on the canvas. milanote-mcp tools prints this list, milanote-mcp tools --json adds the input schemas.

Boards

Tool

Access

REST route

What it does

list_boards

read

GET /boards

Boards inside one board, by default the boards on your Home, with title, ID and link.

list_recent_boards

read

GET /boards/recent

Boards you opened lately, newest first, wherever they sit in your board tree.

search_boards

read

GET /boards/search

Find boards and cards by text across your boards, like the Search icon in Milanote.

get_board

read

GET /boards/{board_id}

Every card on a board: notes, links, images, files, to-do lists, columns and sub-boards.

create_board

write

POST /boards

New board on your Home or nested inside another board.

rename_board

write

PATCH /boards/{board_id}

Change a board's title.

duplicate_board

write

POST /boards/{board_id}/duplicate

Copy a board with everything on it, sub-boards included, as a template.

export_board

read

GET /boards/{board_id}/export

Export a board as Markdown, plain text, Word, PDF or PNG, as the Export menu does.

Cards

Tool

Access

REST route

What it does

add_note

write

POST /boards/{board_id}/notes

Note card with plain text, added to a board's Unsorted panel.

edit_note

write

PATCH /boards/{board_id}/notes/{card_id}

Replace the text of a note card.

add_link

write

POST /boards/{board_id}/links

Link card for a web address, with the page's title and preview, added to Unsorted.

add_todo_list

write

POST /boards/{board_id}/todo-lists

To-do list card with tasks, each with an optional due date and time, added to Unsorted.

set_task_done

write

PUT /boards/{board_id}/cards/{card_id}/tasks/{task}/done

Tick or untick one task in a to-do list.

add_column

write

POST /boards/{board_id}/columns

Empty column on a board, to group cards in a stack.

Arrange cards

Tool

Access

REST route

What it does

move_card

write

POST /boards/{board_id}/cards/{card_id}/move

Move a card or a sub-board to another board, or into or out of a column.

set_card_color

write

PUT /boards/{board_id}/cards/{card_id}/color

Colour the bar on top of a note, to-do list, link, file or column, or clear it.

add_label

write

POST /boards/{board_id}/cards/{card_id}/labels

Put a label on a card, creating the label when the name is new.

list_labels

read

GET /labels

The labels you can put on cards, with name and colour.

Trash

Tool

Access

REST route

What it does

trash_cards

write

POST /boards/{board_id}/cards/trash

Move cards or sub-boards to the trash, as the Delete key does.

list_trash

read

GET /trash

Cards and boards you moved to the trash, with the board each one came from.

restore_card

write

POST /trash/{card_id}/restore

Take a card or board out of the trash and put it back where it was.

Comments

Tool

Access

REST route

What it does

add_comment

write

POST /boards/{board_id}/comments

Comment card on a board, or a reply in a comment thread, posted under your name.

edit_comment

write

PATCH /boards/{board_id}/comments/{comment_id}

Replace the text of a comment you wrote.

delete_comment

write

DELETE /boards/{board_id}/comments/{comment_id}

Delete a comment you wrote, for everyone.

Sharing

Tool

Access

REST route

What it does

get_sharing

read

GET /boards/{board_id}/sharing

Who can open a board: owner, editors and the read-only link with its settings.

invite_editor

write

POST /boards/{board_id}/editors

Invite someone by email to edit a board and the boards inside it.

remove_editor

write

DELETE /boards/{board_id}/editors

Take away someone's access to a board, or cancel an invite they have not accepted.

publish_board

write

POST /boards/{board_id}/publish

Turn on a board's read-only link, which anyone can open without signing up.

unpublish_board

write

DELETE /boards/{board_id}/publish

Turn off a board's read-only link; people who had it can no longer open the board.

Account

Tool

Access

REST route

What it does

get_usage

read

GET /usage

How many cards your account uses against the free plan's limit, by card type.

Not in this version

Tool

Why

upload_image

On the hosted version it takes the image as a link, an upload or base64 through Cotlet's file handling, which this repo does not have yet. Upload images in Milanote, or use the hosted tool.

Never built, on purpose: your Milanote sign-in, email, password and profile settings, and plans and billing.

Configuration

Variable

Default

What it does

MILANOTE_MCP_HOME

~/.config/milanote-api-mcp

Folder of session.json.

MILANOTE_AUTH_TOKEN

Milanote __Secure-milanote.session_token cookie, instead of milanote-mcp connect.

MILANOTE_PROXY

Proxy for every request to Milanote, e.g. http://user:pass@host:port.

MILANOTE_MCP_READ_ONLY

1 hides and refuses every tool that changes Milanote (same as --read-only).

MILANOTE_MCP_TOKEN

Bearer token required by serve; needed to listen beyond 127.0.0.1.

MILANOTE_MCP_HOST, MILANOTE_MCP_PORT

127.0.0.1, 8787

Address of serve.

Security and your Milanote account

  • Your password never reaches this code. Only cookies are read, and only those of milanote.com.

  • The session file is yours. session.json is created with mode 0600. Anyone who has it can act as you on Milanote, so keep it out of git and shared folders.

  • Local by default. serve binds to 127.0.0.1 and refuses another address without MILANOTE_MCP_TOKEN.

  • milanote.com only. Requests and redirects outside milanote.com are refused.

  • Read-only mode. --read-only or MILANOTE_MCP_READ_ONLY=1 exposes the 9 read tools only.

  • Some actions reach other people. Comments carry your name, invite_editor emails the person you invite, and publish_board makes a board readable by anyone with the link. MCP clients ask before running them; a script does not.

  • Trash is reversible, comments are not. trash_cards moves cards to the board's trash, and restore_card brings them back. delete_comment deletes for everyone.

Errors

The REST API answers {"error": "<code>", "message": "..."}. The MCP server returns the same code and message as a tool error.

Status

Code

What to do

401

auth_required, auth_expired

No session, or Milanote signed you out. Sign in to Milanote in Chrome and run milanote-mcp connect.

403

scope_denied

The server runs read-only.

403

target_blocked

Milanote refused the request or showed a bot check. Open app.milanote.com in Chrome once, then retry.

422

invalid_input

An argument is missing or wrong; the message names it.

429

rate_limited

Milanote is limiting the account. Wait a few minutes.

502

target_error

Milanote answered with an error, for example the free plan's card limit, or changed its app. git pull for the latest tools, or open an issue.

504

timeout

Milanote did not confirm a change in time. Check the board before you retry, the change may have landed.

Self-hosted or hosted

This repo

Cotlet, hosted

Tools

30

31, upload_image included

Runs

on your computer, while it is on

in the cloud, 24/7

Milanote session

your Chrome, cookies in a local file

your own Cloud Browser in the EU, profile encrypted with AES-256-GCM

When Milanote changes its app

git pull once we have fixed it

fixed for you, every tool tested daily

Approvals

your MCP client asks per call

comments, invites, publishing and trash wait for your OK, switchable per tool

Works with

MCP clients on your machine, local scripts

Claude.ai and ChatGPT connectors, n8n, Make, Zapier, any HTTP client

Who may use it

you, for personal use

teams, businesses, agencies

Price

free

free 7-day trial with 2,000 credits, no card; then one-time packs from $29 for 5,000 credits

On the hosted version a successful call uses 20 to 30 credits (25 for most tools), failed calls are free, and the Cloud Browser uses 50 credits a day while it has an app enabled for agents. Full pricing.

FAQ

Does Milanote have an official API? No. Milanote has no public API, no webhooks and no official MCP server (checked October 2026). A public API and an MCP server are open requests on its public roadmap, and the only way to get content out is the Export button, one board at a time. Details: cotlet.dev/integrations/milanote-api-mcp-server.

Is there a Milanote MCP server for Claude, ChatGPT or Cursor? Yes, this one runs on your machine: milanote-mcp mcp for Claude Code, Claude Desktop, Cursor and Codex. ChatGPT and Claude.ai connectors need a public HTTPS URL, which the hosted Milanote MCP server gives you.

Can I export Milanote boards to Markdown? Yes, with sub-boards: python examples/export_boards.py --board <board URL> --dir ./outline writes one Markdown file per board, in folders that follow the nesting. Word, PDF, PNG and plain text work the same way with --format.

Can I back up all my boards? Run export_boards.py on each board of your Home, from cron. Images and files on a board stay in Milanote. Milanote's own Generate ZIP in the Export menu downloads the originals.

Can it add to boards someone shared with me? Yes, if your account can edit that board. Read-only boards can be read and exported, not changed.

Does it work on the free plan? Yes. The free plan's 100-card limit still applies: get_usage shows where you stand, and adding a card past it fails with Milanote's own message.

Why does it need my Chrome? To read your Milanote session without your password, and your time zone for due dates. Chrome is used once per sign-in, not for each call.

What happens when Milanote signs me out? Calls fail with auth_expired. With Chrome remote debugging on, the server reads the new cookies on the next call (click Allow when Chrome asks); otherwise run milanote-mcp connect again.

Can it run on a VPS or in Docker? Technically yes, with MILANOTE_AUTH_TOKEN. Milanote then sees your session from a datacenter IP, which looks less like you, and the license allows it only on a server you alone use. For an always-on setup the hosted version keeps your session in your own Cloud Browser on a fixed IP.

Will my Milanote account get banned? Requests carry Chrome's fingerprint and go out one at a time, as you would click. Nobody can promise a platform never acts. Keep to your normal use.

Can I use it at work or for my clients? No, the license is for personal use by one person. For a team, a company or client work, use Cotlet or write to contact@cotlet.dev.

Is it open source? The source is public, the license is not an open source license: personal use only, no business use, no hosting for others.

A tool broke or I need another one. Open an issue with the tool name and the error message.

License

Cotlet Personal Use License 1.0. In short:

  • Allowed: one person, on their own computers, with their own Milanote accounts, for their own purposes. Changing the code for yourself, and a GitHub fork under the same license.

  • Not allowed: any use in or for a company or organization, your own business included; letting other people use your instance (shared server, team machine, cloud service); selling or offering it or a service built on it.


Maintained by Cotlet (@cotletdev). Milanote is a trademark of its owner. This project is unofficial and not affiliated with, endorsed or sponsored by Milanote.

Available Tools

30 tools
add_columnAdd columnA

Empty column on a board, to group cards in a stack.

Adds a titled column on top of the board's Unsorted panel and returns its column_id; move_card with to_column_id puts cards into it. Editors of the board see it, nobody is notified.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesColumn title.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare non-read-only, non-idempotent, non-destructive, open-world. The description adds context the annotations don't carry: it returns a column_id, where the column is placed, that editors see it, and that no one is notified. It does not address duplicate-title behavior, which matters for a non-idempotent mutation.

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?

Three tight sentences with the core action and placement front-loaded. The opening fragment ('Empty column on a board, to group cards in a stack') is slightly telegraphic but earns its place by defining the artifact.

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 no output schema, the description usefully states the returned column_id and the notification/visibility side effects. Only error handling and duplicate-title semantics are unaddressed for a two-parameter mutation.

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%, with board_id and title already documented in the schema. The description only implies these fields ('titled column', 'on a board') without adding format or constraint detail, so baseline 3 applies.

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+resource ('Adds a titled column') plus its function (grouping cards in a stack) and where it lands (top of the Unsorted panel). This clearly differentiates it from siblings like create_board or move_card.

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?

Explains the downstream step explicitly: use move_card with to_column_id to populate the new column, and notes placement on top of Unsorted. No explicit 'when not to use' or alternative, but the workflow context is clear enough to select it correctly.

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

add_commentAdd commentA
Destructive

Comment card on a board, or a reply in a comment thread, posted under your name.

Without reply_to_id it adds a new comment card on top of the board's Unsorted panel; with it the comment joins that thread. Everyone who can open the board sees it under your name, and Milanote notifies people already in the thread. The text is plain: an @name stays text and tags nobody. Only you can edit or delete it afterwards, in Milanote.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesComment text, plain.
board_idYesBoard ID from list_boards, or the board URL.
reply_to_idNoA comment thread ID or comment ID from get_board (include_comments) to reply in. Default: a new comment card.

TDQS

A4.2/5.0
Behavior4/5

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

Adds substantial context beyond annotations: placement in the Unsorted panel, board-wide visibility under the caller's name, notifications to thread participants, plain-text semantics where @name tags nobody, and creator-only editing. It does not address non-idempotency (duplicate comments on repeated calls) or explain why destructiveHint=true for an additive action.

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?

Four tight sentences, front-loaded with the two modes, then placement, then audience/notification behavior, then the plain-text and ownership caveats. 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?

For a 3-parameter write tool with no output schema, the description covers placement, visibility, notifications, and permission scope. It never says what is returned (e.g., the new comment ID needed for later edit/delete), which is the one practical gap.

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 coverage is 100%, so the schema already documents all three parameters; baseline is 3. The description does add real meaning for reply_to_id by spelling out the default behavior and resulting placement, but text and board_id are only restated.

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: posting a comment card on a board or a reply in a comment thread, attributed to the caller. The two modes (new card vs. thread reply) make it clearly distinguishable from siblings like add_note, edit_comment, and delete_comment.

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?

Explicitly gives the branch condition: omit reply_to_id to create a new comment card, include it to join an existing thread. It hints at follow-up tools ('Only you can edit or delete it afterwards') without naming edit_comment/delete_comment, so no formal alternative routing.

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

add_labelAdd labelA

Put a label on a card, creating the label when the name is new.

Matches the name against your labels (list_labels) without regard to case; created is true when it made a new one. The card keeps its other labels. Editors of the board see the label on the card.

ParametersJSON Schema
NameRequiredDescriptionDefault
labelYesLabel name; a name you have not used yet creates the label.
card_idYesCard ID from get_board.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.7/5.0
Behavior5/5

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

Beyond annotations, the description discloses that label matching is case-insensitive, that a new label may be created, that the card retains its other labels, and that editors see the label. These details add meaningful behavioral context for a non-readonly, open-world mutation.

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?

The description is front-loaded with the core action and then adds only relevant details in short sentences. Every sentence contributes useful information without repetition or padding.

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 no output schema, the description helpfully mentions the created indicator and explains label-creation behavior. Together with the annotations and fully documented schema, it gives an agent enough context to invoke the tool correctly.

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 schema already documents all three parameters. The description still adds value by explaining that label-name matching is case-insensitive and that an unused name creates a new label, which goes beyond the schema text.

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 description states a specific verb and resource: putting a label on a card. It also clarifies the important nuance that a new label is created when the name is new, which distinguishes this action from merely listing or reusing labels.

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 gives clear context for use by explaining that it adds a label to a card and creates the label if needed. It references list_labels for matching but does not explicitly state when not to use this tool or name alternative sibling tools for other labeling actions.

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

add_noteAdd noteA

Note card with plain text, added to a board's Unsorted panel.

Adds one note card on top of the board's Unsorted panel and returns its card_id. The text is plain: line breaks become paragraphs, Markdown is not converted. On the free plan a note counts toward the 100 cards limit. Editors of the board see it, nobody is notified; move it to the trash in Milanote to undo it.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesNote text. Each line becomes a paragraph.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, idempotentHint=false, destructiveHint=false and openWorldHint=true, and the description goes well beyond them: it names the return value (card_id), specifies plain-text handling (line breaks become paragraphs, Markdown is not converted), notes the free-plan 100-card quota consumption, and states that no notifications fire. It stops short of disclosing failure modes or permission requirements (e.g., whether the caller must be an editor).

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?

Two tight paragraphs, front-loaded with placement and followed by consequences in a logical order. The opening sentence ('Note card with plain text, added to a board's Unsorted panel') partially duplicates the first clause of the next sentence, a small redundancy in an otherwise dense block.

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 only two well-documented parameters and no output schema, the description covers everything an agent needs: return value (card_id), text formatting behavior, quota impact, visibility/notification behavior, and the undo path. Nothing material is missing for correct invocation.

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 genuine meaning by clarifying the text format contract — Markdown is not converted — which the schema's 'Each line becomes a paragraph' does not make explicit. No extra detail is given about the board_id/URL acceptance already covered in the schema, so it is not a 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?

States a specific verb and resource ('Adds one note card') and pins down both placement ('on top of the board's Unsorted panel') and return value ('returns its card_id'). The 'plain text' framing plus the Unsorted-panel destination is enough to separate it from add_todo_list, add_link, and edit_note without opening a schema.

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

Usage Guidelines3/5

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

Usage context is implied but never explicit: nothing says when to choose this over add_todo_list/add_link or, once the card exists, edit_note. What it does offer — free-plan card limit, editors see it, nobody is notified, undo by trashing in Milanote — informs the decision to call it but does not function as when/when-not routing.

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

add_todo_listAdd to-do listA

To-do list card with tasks, each with an optional due date and time, added to Unsorted.

Creates one to-do list on top of the board's Unsorted panel with all its tasks, unchecked, and returns each task_id. A due date without a time is due at 5 PM; Milanote reminds you at 9 AM the day it's due, by the channels in your notification settings. Times are in the Cloud Browser's time zone. Nobody else is notified; move the list to the trash in Milanote to undo it.

ParametersJSON Schema
NameRequiredDescriptionDefault
tasksYes1 to 50 tasks, in order.
titleNoList title. Default: no title.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.6/5.0
Behavior5/5

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

Goes well past the annotations (non-read-only, non-idempotent, non-destructive, open-world) by disclosing that each task_id is returned, that a date without a time is due at 5 PM, the 9 AM reminder behavior driven by notification settings, that times follow the Cloud Browser time zone, that nobody else is notified, and how to undo. This is exactly the context annotations cannot carry.

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?

Two short paragraphs, front-loaded with the core action before defaults and side effects. The opening phrase 'To-do list card with tasks...' partially restates the following sentence, a small redundancy that keeps it from a 5.

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?

Despite having no output schema, the description states the return value (each task_id) and covers scheduling defaults, notification side effects, timezone, and undo. Combined with a fully documented schema, an agent has everything needed to call it correctly.

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, but the description adds semantics the schema lacks: the 5 PM default when due_time is omitted and the Cloud Browser time zone governing times. The unchecked-initial-state detail also clarifies what the tasks payload becomes.

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 — creates one to-do list card with all its tasks — and pins the destination to the board's Unsorted panel. This clearly separates it from sibling mutations like add_column, add_note, and add_link, which target different card types.

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?

Explains the operative context: the list always lands in Unsorted rather than a chosen column, tasks arrive unchecked, and the undo path is moving the list to the trash in Milanote. It stops short of naming an explicit alternative tool or a when-not-to-use condition, but the placement and reversibility guidance is concrete.

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

create_boardCreate boardA

New board on your Home or nested inside another board.

Creates an empty board and returns its board_id for the tools that add cards. It appears in the Unsorted panel of the parent board (your Home by default), where you can drag it onto the canvas. It is private unless the parent board is shared, in which case the parent's editors can open it; nobody is notified. Move it to the trash in Milanote to undo it.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesBoard title.
parent_board_idNoBoard to nest it in (ID or board URL). Default: your Home.

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the annotations (readOnly=false, idempotent=false, destructive=false), the description discloses the visibility model — private unless the parent is shared, in which case the parent's editors can open it — plus that nobody is notified and that undo is done by trashing the board in Milanote. This is exactly the mutation context annotations cannot carry, and it is consistent with destructiveHint=false.

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?

Four compact sentences that front-load scope, then return value, placement, visibility, and undo. The opening sentence is a sentence fragment, and the 'drag it onto the canvas' detail is arguably UI trivia, but nothing is padded.

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 two-parameter creation tool with no output schema, the description covers the return value (board_id), placement/default parent, visibility inheritance, notification behavior, and reversibility. An agent has everything needed to call it and to warn a user about side effects.

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 already 100%, so the baseline is 3; the description adds meaning on top by explaining that parent_board_id defaults to Home and that the chosen parent also governs inheritance of sharing visibility. Title semantics are left entirely to the schema, which is acceptable.

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 ('Creates an empty board') and immediately distinguishes it from duplicate_board by emphasizing 'empty'. It also tells the agent what the call yields — a board_id used by the card-adding tools — so the tool's role in the workflow is unambiguous.

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 clear selection context: create at Home by default or nest under an existing board via parent_board_id, and notes the board lands in the Unsorted panel where it must be dragged onto the canvas. It never explicitly names an alternative (e.g. duplicate_board for an existing layout), so the routing guidance is strong but not complete.

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

delete_commentDelete commentA
Destructive

Delete a comment you wrote, for everyone.

Removes your own comment from its thread; the thread and other people's comments stay. There is no trash for comments, so it cannot be brought back.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.
comment_idYescomment_id from get_board (include_comments) or add_comment.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true and non-idempotent, so permanence is partly given. The description adds specifics the annotations cannot: the containing thread and other comments survive, and there is no trash/undo path for comments. It does not mention permission requirements or the response, but the important behavioral traits are covered.

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?

Three short sentences, front-loaded with the action and audience, then the blast radius, then the irreversibility. No filler or restated name.

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 2-required-param destructive tool with full schema coverage and annotations carrying the safety profile, 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.

Parameters3/5

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

Both parameters are fully documented in the schema (100% coverage) with provenance hints (list_boards, get_board with include_comments, add_comment). The description adds no parameter-level meaning, so the baseline 3 applies.

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 (delete a comment) plus the two scoping facts an agent needs: it must be your own comment, and the removal is visible to everyone. That distinguishes it from edit_comment and add_comment without naming them.

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?

'Delete a comment you wrote' implicitly states the precondition and excludes deleting other people's comments, which is a genuine when-not constraint. It does not explicitly route to edit_comment when the user actually wants to change rather than remove text, so it falls short of full alternative guidance.

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

duplicate_boardDuplicate boardA

Copy a board with everything on it, sub-boards included, as a template.

Does what Duplicate in a board's menu does: Milanote copies every card, column, comment and sub-board into a new board and returns its board_id. The copy lands in the parent board's Unsorted panel, private to you unless that board is shared; the read-only link and editors are not copied. Every copied card counts toward the free plan's card limit (get_usage). card_count is what Milanote reports it copied.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleNoTitle of the copy. Default: the same title.
board_idYesBoard to copy: ID or board URL.
parent_board_idNoBoard to put the copy in (ID or board URL). Default: where the original is.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations: the copy lands in the parent board's Unsorted panel, is private unless the board is shared, the read-only link and editors are not copied, and every copied card counts against the free-plan limit. It also discloses the return payload (board_id, card_count), which no output schema provides.

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?

Three sentences, each carrying distinct information: what is copied, where it lands and what is excluded, then the billing/return consequences. No filler, and the core action is front-loaded.

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 no output schema, the description still covers return values, placement, privacy, exclusions, and cost implications — everything needed to call a copying mutation correctly. Nothing material 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 titles and defaults are already documented; the description adds the missing placement semantics for parent_board_id by explaining the copy lands in that board's Unsorted panel, and clarifies what the call returns. Baseline 3 is exceeded because that placement detail is not in 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 ('Copy a board with everything on it, sub-boards included'), and names the scope of what is copied (cards, columns, comments, sub-boards). This clearly separates it from siblings like create_board, rename_board and export_board.

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?

Grounds usage with a familiar analogue ('Does what Duplicate in a board's menu does') and points to get_usage for the plan-limit consequence. It does not explicitly say when to prefer this over create_board plus manual copying, but the intended context is unambiguous.

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

edit_commentEdit commentA

Replace the text of a comment you wrote.

Overwrites your own comment with plain text, as Edit then Save does in the thread. Others' comments cannot be changed. People who already read it get no new notification.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesNew comment text, plain.
board_idYesBoard ID from list_boards, or the board URL.
comment_idYescomment_id from get_board (include_comments) or add_comment.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already declare this as a non-read-only, non-idempotent, non-destructive mutation, and the description adds real value on top: it states that the operation overwrites existing text, that ownership restricts who can call it, and that no new notification fires for prior readers. That last point is a side effect an agent could not infer from any structured field.

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?

Three short sentences, front-loaded with the action and ownership scope, then side effects. Every sentence carries information an agent needs and none restates the tool name.

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?

For a simple three-parameter mutation with full schema coverage and no output schema, the description covers action, permission, and notification behavior adequately. Minor gaps remain around failure modes (e.g., what happens with a stale comment_id) and whether mentions or formatting survive, but nothing essential is missing.

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 all three parameters are already documented in the schema, including where board_id and comment_id come from. The description only reinforces "plain text" for the text parameter and adds no new format or constraint detail beyond that. Baseline 3 applies when the schema carries the parameter burden.

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 description opens with a specific verb+resource pair ("Replace the text of a comment") and immediately scopes it with "you wrote." That cleanly separates it from add_comment and delete_comment in the sibling list without the agent needing to open 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?

"Others' comments cannot be changed" gives an explicit precondition that tells the agent when the call will be rejected, and "as Edit then Save does in the thread" frames the intended workflow. It stops short of naming the sibling alternatives (delete_comment for removal, add_comment for new text), so it is clear but not fully routable.

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

edit_noteEdit noteA

Replace the text of a note card.

Overwrites the whole note with plain text: line breaks become paragraphs, and bold, links or lists the note had are lost. Only note cards; to-do lists change with set_task_done. Editors of the board see the change at once; Milanote's undo in the app does not reach it.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYesNew note text. Each line becomes a paragraph.
card_idYesNote ID from get_board.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.6/5.0
Behavior5/5

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

The description goes well beyond the annotations: it discloses that the whole note is overwritten, that bold/links/lists are destroyed, that line breaks become paragraphs, that editors see the change immediately, and that in-app undo does not cover it. This is precisely the kind of consequence detail annotations cannot convey; the destructiveHint=false annotation refers to the card surviving, and the description clarifies the nuance rather than contradicting it.

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?

The core action is stated in a single front-loaded sentence, followed by two dense sentences covering side effects and visibility. No filler, and each sentence carries a distinct behavioral fact.

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?

For a mutation tool with no output schema, it covers effects, irreversibility, collaboration visibility and scope. Minor gap: it doesn't say what happens on invalid input (e.g., card_id pointing at a non-note card) or whether failure leaves the note untouched.

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 coverage is 100%, so text, card_id and board_id are already documented in the schema, including where IDs come from. The description reinforces the paragraph-per-line behavior but adds no syntax, length limits or formatting rules beyond what the schema states, so it sits at the baseline.

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?

"Replace the text of a note card" gives a specific verb (replace) plus resource (note card text), which is immediately distinguishable from add_note. It also states the scope boundary (only note cards, not to-do lists), so an agent can separate it from set_task_done without inspecting schemas.

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?

It supplies an explicit when-not clause ("Only note cards; to-do lists change with set_task_done") and names the alternative tool that handles the excluded case. That is exactly the routing information an agent needs when the two siblings look similar.

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

export_boardExport boardA
Read-onlyIdempotent

Export a board as Markdown, plain text, Word, PDF or PNG, as the Export menu does.

Runs Milanote's own export of one board. markdown and plain_text return the text in content; word, pdf and png return only file_url. Text formats follow the board's reading order and leave out comments and sub-board contents; pdf and png are a picture of the canvas. Anyone with file_url can download the file, and Milanote deletes it after about a day.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatYesmarkdown, plain_text, word, pdf or png.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations by disclosing content scope (text formats follow reading order and omit comments and sub-board contents; pdf/png are a snapshot of the canvas) and, critically, that anyone holding file_url can download the file and that Milanote deletes it after about a day. That expiry and public-link behavior is exactly the kind of operational fact an agent cannot infer from readOnlyHint/idempotentHint.

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?

Three sentences, front-loaded with the verb and format list, then return-shape, then the caveats about content scope and link expiry. No sentence is filler; each carries a distinct operational fact.

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 no output schema present, the description takes on the return-value burden and does so: it says which field carries the payload for which format group. Combined with the scope and expiry notes, an agent has everything needed to call this and handle the result.

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 description coverage is 100%, so the baseline is 3, and the description earns more by explaining the semantic consequence of each enum value rather than just naming it — text formats populate `content`, binary formats populate `file_url`. It adds no extra detail on `board_id` beyond the schema's own 'Board ID or board URL' note.

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 ('Export a board') and enumerates the exact output formats, plus names the equivalent UI affordance ('as the Export menu does'). No sibling tool performs exports, so the tool's identity is unambiguous without opening the 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?

There is no competing sibling to route away from, and the description instead gives selection guidance between formats by stating what each returns ('markdown and plain_text return the text in content; word, pdf and png return only file_url'). It does not state prerequisites (e.g. access level needed on the board), which keeps it from a 5.

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

get_boardGet boardA
Read-onlyIdempotent

Every card on a board: notes, links, images, files, to-do lists, columns and sub-boards.

Returns one entry per card with its type, ID and content, so other tools can point at it. Order is the board's: the canvas top to bottom, then the Unsorted panel (section says which). Notes come back as plain text. To-do lists list each task with its done state and due date (due_time only when one was set). Cards inside a column carry column_id; color and labels (by name) appear when a card has them. Sub-boards appear as cards with their own board_id; call get_board again to open one. Drawings, lines and tables come back with their type and ID only. include_comments adds comment threads with author, text and time.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.
include_commentsNoAlso return comment threads with their comments. Default: false.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the remaining burden is return behavior, and the description delivers it: order is canvas top-to-bottom then Unsorted panel, notes arrive as plain text, drawings/lines/tables return type and ID only. That last detail is exactly the kind of surprise (missing content for certain card types) an agent needs disclosed.

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?

One dense but ordered paragraph: contents first, ordering second, per-type return semantics third, recursion fourth, optional flag last. No sentence is filler and nothing is buried.

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 no output schema, the description must carry the return contract, and it does: entry-per-card shape (type, ID, content), ordering, plain-text notes, to-do done state and due date, column_id, labels, sub-board board_id. For a read tool whose readOnly behavior is already annotated, an agent has everything needed to call it and interpret results.

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 baseline is 3; the description earns a step above by explaining that include_comments yields 'comment threads with author, text and time' and that due_time is only present when set. It doesn't clarify board_id vs URL handling beyond the schema, but it meaningfully deepens what the flags produce.

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 with scope: 'Every card on a board' with notes, links, images, files, to-do lists, columns and sub-boards. This is clearly distinguishable from list_boards (board enumeration) and the add_/edit_ siblings by the fact it returns a readout of an entire board's contents.

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 operational guidance for the recursive case ('Sub-boards appear as cards with their own board_id; call get_board again to open one') and explains that entries carry type/ID so 'other tools can point at it'. It does not name an alternative for locating a single card (e.g. search_boards) or say when a caller should skip this tool, so it stops short of full when-not guidance.

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

get_sharingGet sharingA
Read-onlyIdempotent

Who can open a board: owner, editors and the read-only link with its settings.

Lists the board's owner and the editors invited to it; status is invited for someone who has not made a Milanote account yet. Editors of a parent board can open it too and are not listed here. read_only_link is null until publish_board turns the link on; comments_on_link and downloads_on_link say what viewers of that link may do.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A3.8/5.0
Behavior4/5

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

Beyond the readOnly/idempotent annotations, the description discloses meaningful behavioral caveats: pending invitees carry status 'invited', editors of a parent board are NOT listed here (a partial-result warning), and read_only_link is null until published. This is genuinely useful context an agent could otherwise get wrong; only return format/pagination detail is absent.

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 headline scoping sentence is front-loaded and the caveats are packed into a short second sentence with no filler. It is dense to the point of being slightly run-on (several clauses chained by semicolons), but every clause carries information.

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?

No output schema exists, so the description carries the return-value burden, and it does: it enumerates owner, editors, status values, read_only_link, comments_on_link, and downloads_on_link, plus the parent-editor exclusion. For a one-parameter read tool this is complete enough to call correctly.

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?

There is a single parameter with 100% schema description coverage ('Board ID from list_boards, or the board URL'), so the schema already carries the meaning. The description adds nothing about the parameter, which is acceptable given the high coverage but earns only the baseline.

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

Purpose4/5

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

The opening line 'Who can open a board: owner, editors and the read-only link with its settings' clearly identifies the resource (sharing/permissions for a board) and what is returned. It is distinguishable from mutating siblings like invite_editor or publish_board by referencing them, though it never uses a direct verb like 'retrieve' or 'list'.

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

Usage Guidelines3/5

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

The reference to publish_board ('read_only_link is null until publish_board turns the link on') implies when this returns a populated link, but there is no explicit 'use this when' guidance or comparison to get_board or the editor-management tools. Usage is inferable rather than stated.

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

get_usageGet usageA
Read-onlyIdempotent

How many cards your account uses against the free plan's limit, by card type.

used is what Milanote counts toward the free plan's limit (100 cards, more with referral bonuses); once exceeded is true Milanote refuses new cards until you delete some or upgrade. On a paid plan unlimited is true and limit is null. by_type counts each kind of element you made, comments and lines included; Milanote decides which of them count toward used.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior4/5

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

Annotations already declare readOnly, idempotent, non-destructive, so safety is covered; the description adds what annotations cannot — that exceeding the limit blocks card creation until deletion or upgrade, and that paid plans return unlimited=true and limit=null. These are genuinely useful state facts beyond the annotations.

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?

Front-loaded with the core purpose and organized by field meaning. Slightly dense in the middle sentence about referral bonuses, but every sentence carries information an agent needs to interpret the output.

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?

No output schema exists, so the description must explain return values — and it does, field by field, including the subtle point that by_type includes comments and lines whose counting toward 'used' is decided by Milanote. An agent can interpret the response without any further source.

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?

Zero parameters, so the baseline is 4. The description instead documents the response fields (used, exceeded, unlimited, limit, by_type), which is where all the agent-facing semantics live for this tool.

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

Purpose4/5

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

Opens with a specific statement: reports how many cards the account uses against the free plan limit, broken down by card type. An agent can tell exactly what the tool returns. It doesn't differentiate from siblings, but none of the listed siblings overlap with usage reporting, so that absence is harmless.

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

Usage Guidelines3/5

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

Usage is implied (check quota before adding cards, since exceeding the limit blocks new cards), but the description never says explicitly when to call it or that there is no alternative. The statement that Milanote refuses new cards once exceeded gives implicit context, not routing guidance.

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

invite_editorInvite editorA
Destructive

Invite someone by email to edit a board and the boards inside it.

Adds the address as an editor, as Share, Invite editors via email does, and Milanote emails them a link. status is invited when they have no Milanote account yet (a free one is enough to edit), active when they do. Milanote allows inviting only once your account's email is verified; the free plan limits how many boards you can share. Remove them in the Share dialog to undo it.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesTheir email address.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.5/5.0
Behavior5/5

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

Adds substantial behavior beyond annotations: Milanote emails an invite link, status becomes invited or active depending on whether the recipient has an account, account email verification is required, and plan limits apply. It also explains that removal in the Share dialog undoes the invite, complementing the destructiveHint annotation without contradicting it.

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?

Front-loads the core action and then adds only useful operational context: email/status behavior, prerequisites, plan limits, and undo path. Every sentence contributes to correct selection or invocation.

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?

Complete for a two-parameter mutation with no output schema. It explains side effects, recipient statuses, prerequisites, and how to undo, which is enough for an agent to call it correctly.

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 coverage is 100%, so both parameters are already documented in the schema. The description adds that board access includes boards inside it, but does not add syntax or format details beyond the schema baseline.

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: invite someone by email to edit a board and its nested boards. This clearly distinguishes it from sibling operations like remove_editor and get_sharing.

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?

Provides clear usage context: it mirrors Share > Invite editors via email, requires a verified account email, and notes free-plan sharing limits. It also mentions undoing via the Share dialog, though it does not explicitly route to the sibling remove_editor tool.

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

list_boardsList boardsA
Read-onlyIdempotent

Boards inside one board, by default the boards on your Home, with title, ID and link.

Lists the boards one level down: on your Home, or inside parent_board_id. Boards nest like folders, so pass a board's id as parent_board_id to walk down. Order is the board's own: the canvas top to bottom, then Unsorted. parent_board_id in the answer is the Home board's id when you left it out. Boards in the trash are left out.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo1 to 200. Default: 50.
parent_board_idNoOnly boards inside this board (ID or board URL). Default: the boards on your Home.

TDQS

A4.3/5.0
Behavior4/5

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

The annotations already establish that this is a read-only, idempotent, non-destructive operation. The description adds useful behavior beyond the annotations: it explains the ordering, the exclusion of trashed boards, and the meaning of parent_board_id in the response when no parent is supplied.

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 description is front-loaded with the core purpose and every sentence adds useful information about hierarchy, ordering, or exclusions. It is slightly repetitive between the opening phrase and the second sentence, but remains efficient overall.

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 only two optional parameters, full schema coverage, and annotations covering safety, the description is largely complete for correct invocation. Since there is no output schema, it helpfully names returned fields and ordering, but it could say more about pagination or the exact response shape.

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 still adds semantic value by explaining the nesting behavior of parent_board_id and what that field means in the answer, although it does not elaborate on the limit parameter beyond what the schema already states.

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 description states a specific verb and resource: it lists boards one level down, by default from Home, and returns title, ID, and link. The hierarchical scope distinguishes it from sibling tools such as get_board, search_boards, and list_recent_boards.

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 tells the agent how to walk down the board hierarchy by passing a board id as parent_board_id and clarifies the default when omitted. However, it does not explicitly compare this tool with alternatives such as search_boards, list_recent_boards, or list_trash.

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

list_labelsList labelsA
Read-onlyIdempotent

The labels you can put on cards, with name and colour.

Labels are yours, not a board's: the same label can sit on cards across all your boards. add_label puts one on a card by name and creates it when it is new.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so safety is covered; the description adds the non-obvious domain fact that labels are user-scoped rather than board-scoped, which materially affects how an agent interprets results across boards. It adds the side-effect note that add_label creates a label when the name is new, though it says nothing about ordering or what an empty result means.

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?

Three short sentences, front-loaded with what is returned, then the scoping fact, then the pointer to the write-side sibling. Every sentence carries distinct information and nothing is repeated from the annotations.

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?

For a parameterless read tool with no output schema, the description covers what is returned, the scope of the data, and the relationship to add_label. Only minor gaps remain, such as ordering of results or behavior when no labels exist.

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 zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless schema applies. No misleading parameter hints are given.

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

Purpose4/5

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

The description states the resource (labels) and what each item contains (name and colour), and the account-wide scope makes clear this is not a board-scoped list like list_boards or list_trash. The listing verb itself is only implied by the title rather than stated, so it falls just short of a fully self-contained verb+resource statement.

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 establishes the context in which this is the right call (you need the set of labels available to apply to cards) and routes the write side of the workflow to add_label by name. It does not state exclusions, but no sibling competes for this exact job, so the routing is unambiguous in practice.

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

list_recent_boardsList recent boardsA
Read-onlyIdempotent

Boards you opened lately, newest first, wherever they sit in your board tree.

The list behind Milanote's search box before you type: every board you viewed, shared ones too, with when you last opened it and how many times. Home and Quick notes appear like any other board. Boards you have not opened since they were made are missing; list_boards walks the tree instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo1 to 50. Default 20.

TDQS

A4.3/5.0
Behavior5/5

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

Annotations already cover the safety profile, yet the description adds substantial new behavior: newest-first ordering, tree-wide scope, inclusion of shared boards, Home/Quick notes appearing like any other board, and the specific contents returned (last-opened time, open count). The exclusion rule for never-opened boards is the kind of caveat an agent can only get here.

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?

Three sentences, front-loaded with the core definition and ending on the sibling contrast, so the important routing information is not buried. The search-box analogy is slightly decorative but does real work in conveying the list's nature.

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 no output schema, the description usefully enumerates what each entry carries (last-opened timestamp, open count) and what is excluded. Only the truncation/pagination behavior implied by 'limit' is left unexplained, a minor gap for a read-only listing tool.

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 coverage is 100% and the single 'limit' parameter (1-50, default 20) is fully documented in the schema. The description says nothing about limiting or result size, so it adds no meaning beyond the schema — baseline 3.

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 ('Boards you opened lately') with scope ('wherever they sit in your board tree') and ordering ('newest first'). It is immediately distinguishable from list_boards, which is named and characterized as the tree-walking alternative.

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?

Explicitly frames itself as 'the list behind Milanote's search box before you type' and carves out the exclusion ('Boards you have not opened since they were made are missing'), then routes to list_boards. No guidance on choosing it over search_boards, which is the closest sibling, so it stops short of 5.

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

list_trashList trashA
Read-onlyIdempotent

Cards and boards you moved to the trash, with the board each one came from.

Lists your own trash, newest first: one entry per trashed card or board with its ID, content and board_id of the board it was on. restore_card puts one back where it was. Milanote keeps trashed items until you empty the trash in the app; has_more is true when it holds more than one page.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already cover safety (readOnly, idempotent, non-destructive), and the description adds genuinely new behavior: newest-first ordering, per-entry fields (ID, content, board_id), and the retention rule that Milanote keeps trash until the user empties it in the app. The one real gap is pagination mechanics — it says has_more can be true but there are zero parameters, so it never explains how a caller retrieves the next page.

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?

Three sentences, front-loaded with the resource and scope, then return contents, then lifecycle/pagination caveats. The slight restatement between the opening clause and 'Lists your own trash' earns its place by adding the ownership constraint and sort order.

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 no output schema, the description correctly supplies the return shape and ordering, plus the retention rule that an agent otherwise could not guess. It is nearly complete for a zero-parameter read tool; only the has_more retrieval path is left unexplained.

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 to disambiguate and the baseline of 4 applies. The description does not need to explain inputs, and it instead spends its words on output shape, which is the right trade.

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 resource (trashed cards and boards) with explicit scope ('your own trash') and ordering ('newest first'), and distinguishes it from active board listing by naming the trash as the domain and restore_card as the recovery path. An agent can tell immediately this is not list_boards.

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?

Usage context is clear — this is the view of items the user discarded and has not yet emptied — and it points to restore_card as the follow-up action. It never explicitly says when not to use it (e.g., use list_boards for live content), so it stops short of a full routing rule.

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

move_cardMove cardA

Move a card or a sub-board to another board, or into or out of a column.

Moves it the way drag and drop does, keeping its ID, comments and content. With to_column_id it goes to the top of that column; without it, to the top of the target board's Unsorted panel. Moving a board moves everything inside it. Moving to a board shared with other people shows it to them.

ParametersJSON Schema
NameRequiredDescriptionDefault
card_idYesCard ID from get_board; a sub-board's board_id works too.
board_idYesBoard the card is on now: ID or board URL.
to_board_idNoBoard to move it to. Default: the same board.
to_column_idNoColumn on the target board to put it in, at the top. Default: no column.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the annotations (readOnly=false, idempotent=false, destructive=false), the description discloses real side effects an agent must know: the card keeps its ID, comments and content; moving a board cascades to everything inside it; and moving to a shared board makes the card visible to other people. These are non-obvious behavioral consequences that annotations cannot convey.

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?

Two short paragraphs, front-loaded with the core action and followed by the parameter-driven behavioral detail. Every sentence carries information; the only slack is the slightly redundant 'Moves it the way drag and drop does' framing.

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?

For a 4-parameter mutation tool with no output schema, the description covers placement rules, cascade behavior and visibility side effects. The main remaining gap is what the call returns or what happens on failure (e.g., invalid column on target board), which the agent must infer.

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, and the description adds genuine meaning: to_column_id places the card at the top of the column, and its absence routes the card to the Unsorted panel rather than leaving placement undefined. It also confirms to_board_id defaults to the same board. No format examples for IDs/URLs are given, so it stops short of a 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 first sentence names a specific verb (move) and the exact resources handled: a card or a sub-board, to another board or into/out of a column. No sibling tool in the list performs relocation, so the tool is unambiguously distinguishable from create/duplicate/trash operations.

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 states the two usage modes clearly: with to_column_id the card lands at the top of that column, without it the card lands in the target board's Unsorted panel. That is an explicit when-to-use-each-parameter rule. It does not name alternative tools or exclusions, which keeps it below a 5.

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

publish_boardPublish boardA
Destructive

Turn on a board's read-only link, which anyone can open without signing up.

Does what Share, Enable read-only link does and returns the link. Anyone who has it sees the board and the boards inside it, without a Milanote account. A board keeps one link: publishing again, even after unpublish_board, brings back the same link with these settings. unpublish_board turns it off.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.
allow_commentsNoLet viewers of the link comment, react and draw. Default false.
allow_downloadsNoShow download links on files to viewers. Default true.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations declare this a destructive, open-world, non-read-only write, and the description earns its keep by explaining exactly what the exposure means: anyone with the link sees the board and the boards nested inside it, without an account. It also discloses link persistence (one link per board, the same link returns even after unpublish). What it does not disclose is the permission level required or whether re-publishing with different settings mutates the live link for existing viewers.

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?

Front-loaded with the core action and its audience consequence, then the link-persistence rule and the inverse tool. Four sentences, all doing work, with only mild redundancy between the opening clause and the 'without a Milanote account' restatement.

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?

Even without an output schema, the description states that the tool returns the link, describes what viewers of that link can see, and covers lifecycle behavior on re-publish. Missing only authorization requirements and whether the two optional flags can be changed later without republishing, which matters for a destructive public-exposure operation.

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 optional flags (allow_comments, allow_downloads) are already fully documented in the schema. The description only alludes to them as 'these settings' and adds no syntax, defaults, or interaction detail beyond that, so it hits the baseline for high-coverage schemas.

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+resource (turn on a board's read-only link) and immediately distinguishes it from the inverse operation by naming unpublish_board and describing what it does. An agent can tell this apart from get_sharing, export_board, and invite_editor 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 clear context for use (share a board publicly, no signup required) and explicitly routes to unpublish_board for turning it off. It does not cover preconditions such as who is allowed to publish, nor when to prefer invite_editor over a public link, so it stops short of a full when/when-not matrix.

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

remove_editorRemove editorA
Destructive

Take away someone's access to a board, or cancel an invite they have not accepted.

Removes one editor, by user_id or email, as the Share dialog's Remove does. They lose the board and the boards inside it unless a parent board is shared with them too; Milanote does not tell them. The owner cannot be removed. invite_editor adds them back.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailNoTheir email address, instead of user_id.
user_idNoTheir user_id from get_sharing or invite_editor.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare destructiveHint=true, idempotentHint=false, openWorldHint=true, so the safety profile is covered. The description goes further by disclosing cascade behavior (they lose the board and nested boards unless a parent is shared), that the removed person is not notified, and the owner exception — real behavioral value beyond structured fields. It stops short of saying what a failed removal returns or what permissions the caller needs.

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?

Four short sentences, front-loaded with the core action and followed by consequences and the owner exception; nothing is wasted. Minor awkwardness in 'the boards inside it unless a parent board is shared with them too', but each clause carries information.

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?

For a destructive, single-target mutation with fully described parameters and no output schema, the description covers scope, side effects, exclusions and the inverse operation. Only caller-permission requirements and the result of a no-op/failed removal are left unstated.

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 board_id, user_id and email are already documented in the schema. The description adds only that the target is identified 'by user_id or email' and that exactly one editor is affected, which is marginal beyond the schema baseline.

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+resource ('take away someone's access to a board') plus the secondary case ('cancel an invite they have not accepted'). It is clearly distinguishable from siblings like invite_editor and get_sharing 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 Guidelines5/5

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

Gives the operative conditions (removing one editor, cancelling a pending invite), names the inverse tool ('invite_editor adds them back'), and states an explicit exclusion ('The owner cannot be removed'). An agent has everything needed to choose this tool or not.

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

rename_boardRename boardA

Change a board's title.

Renames the board everywhere it shows: its card on the parent board, the breadcrumb and search. The board_id and the links to it stay the same. Your Home cannot be renamed.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesNew title.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false and idempotentHint=false, so safety is covered. The description adds real behavioral context beyond that: the rename propagates to the parent-board card, breadcrumb and search, IDs and links are preserved, and Home is excluded.

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?

Four short, front-loaded sentences: the action first, then propagation effects, then what stays stable, then the Home exclusion. Nothing is redundant with the title or schema.

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?

For a simple two-parameter mutation with full schema coverage and annotations present, the description covers effect scope, invariants and the main restriction. Only an explicit note on return/confirmation behavior is absent, which is minor with no output schema needed.

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 coverage is 100%, with both title and board_id documented (including that board_id may come from list_boards or a board URL). The description adds no parameter-level syntax or format details, so the baseline of 3 is appropriate.

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?

Starts with a specific verb+resource ('Change a board's title' / 'Renames the board') and elaborates the exact scope of the change. No sibling tool performs renaming, so it is unambiguously distinguishable from create_board, duplicate_board, etc.

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

Usage Guidelines3/5

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

Usage is strongly implied by the name and purpose, and the 'Your Home cannot be renamed' line supplies one important exclusion. However, it never explicitly states when to rename versus, say, move_card or create a new board, so guidance is inferred rather than stated.

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

restore_cardRestore cardA

Take a card or board out of the trash and put it back where it was.

Puts it back on the board, and in the column, it was trashed from, at its old place; a restored board comes back with its contents. column_id is set when it went back into a column. Only items in your own trash, as list_trash shows them.

ParametersJSON Schema
NameRequiredDescriptionDefault
card_idYesID of a trashed card or board from list_trash.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=false, destructiveHint=false, idempotentHint=false, so the description's job is to add placement semantics — and it does: the item returns to its original column and position, and a restored board brings its contents back. It does not address what happens if the target is no longer trashed or the parent column was deleted, a minor gap given the annotations.

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 core action is front-loaded and nothing is truly wasted, including the useful board-contents caveat. The second sentence is comma-cluttered ('in the column, it was trashed from, at its old place'), which slightly hurts readability but not clarity.

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 one required parameter, full schema coverage and no output schema, the description supplies the missing return-value hint (column_id set when restored into a column) and the restore-location behavior. It is nearly complete; only error/edge-case behavior is left unstated.

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 coverage is 100% and the schema already says card_id is 'ID of a trashed card or board from list_trash.' The description repeats that scope rather than adding syntax or edge-case detail. The mention of column_id is a return-value note, not parameter guidance, so baseline 3 applies.

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 description opens with a specific verb+resource: 'Take a card or board out of the trash and put it back where it was.' It also clarifies the scope beyond the tool name (cards AND boards), which no sibling tool does, clearly separating it from trash_cards and list_trash.

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 points the agent at list_trash as the source of valid IDs and restricts use to 'items in your own trash, as list_trash shows them,' which is clear context. It does not explicitly state when not to use it (e.g., restoring an item that isn't trashed), so it falls short of naming exclusions.

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

search_boardsSearch boardsA
Read-onlyIdempotent

Find boards and cards by text across your boards, like the Search icon in Milanote.

Runs Milanote's own search over every board you can open. Each result is a board, with the cards on it that matched (matches) and the boards above it (path). A board whose title matched has no matches. Sorted by when you last viewed the board, or last modified. Returns Milanote's first page of boards; use get_board on a result to read all its cards.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNolast_viewed or last_modified. Default: last_viewed.
queryYesText to look for.

TDQS

A4.4/5.0
Behavior5/5

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

Goes well beyond the readOnly/idempotent annotations by describing the result shape (a board with matched cards under 'matches' and ancestor boards under 'path'), the edge case where a title match yields no matches, the default ordering, and the hard limit of only the first page of 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?

Front-loads the purpose, then layers result shape, ordering, and the follow-up tool in a logical sequence of four sentences. The parenthetical '(matches)'/'(path)' clarifications are worth their space; the Milanote analogy is slightly decorative but aids intuition.

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 no output schema and a simple two-parameter input, the description supplies everything needed: what matching means, what each result contains, how results are ordered, and the first-page limitation that would otherwise cause an agent to assume completeness.

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 coverage is 100%, so the enum already documents sort and query. The description adds only modest meaning—clarifying that ordering follows last-viewed or last-modified and that matching spans board titles as well as card text—but supplies no syntax or matching-rule details beyond that.

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 ('Find boards and cards by text'), plus scope: Milanote's own search over every board the caller can open. It also implicitly separates itself from full-board reads by telling the agent to use get_board on a result to see all cards.

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 concrete usage context through the 'Search icon in Milanote' analogy and an explicit follow-up path via get_board. It lacks explicit when-not guidance (e.g., use list_recent_boards for browsing rather than searching), so it stops short of full routing.

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

set_card_colorSet card colorA
Idempotent

Colour the bar on top of a note, to-do list, link, file or column, or clear it.

Sets one of Milanote's eleven card colours, as the Color tool does; none removes it. Boards and images take no colour here. Editors of the board see the change at once.

ParametersJSON Schema
NameRequiredDescriptionDefault
colorYesColour, or none to clear it.
card_idYesCard ID from get_board: a note, to-do list, link, file or column.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.3/5.0
Behavior4/5

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

Annotations already declare mutation, idempotence, non-destructiveness, and open-world behavior. The description adds useful behavioral detail: `none` removes the color, unsupported card types are excluded, and editors see the change immediately, though it does not discuss permissions or error behavior.

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?

The description is three compact sentences and front-loads the main operation. Every sentence contributes useful scoping, clearing behavior, or collaboration context.

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 3-required-parameter mutation tool with full schema coverage, annotations, and no output schema, the description supplies enough context to call it correctly. Supported types, exclusions, clearing behavior, and immediate visibility are all covered.

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 coverage is 100%, and the enum plus parameter descriptions already document `color`, `card_id`, and `board_id` well. The description adds only light reinforcement about the color applying to the top bar and `none` clearing it, so it does not materially exceed 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?

The description states a specific verb and resource: coloring the bar on top of supported card types, or clearing it. It also names exclusions (boards and images) and clarifies the effect of `none`, so an agent can distinguish this from unrelated board-editing siblings.

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 clearly indicates supported card types and when clearing applies, which is strong context for usage. It does not explicitly name alternatives or compare to operations like labels, so it falls short of full when/when-not guidance.

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

set_task_doneSet task doneA
Idempotent

Tick or untick one task in a to-do list.

Finds the task by task_id or by its exact text and sets it done or not done, as clicking its checkbox does; the rest of the list stays as it was. Returns the whole list after the change. When two tasks share the text, pass the task_id instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
doneNotrue ticks it, false unticks it. Default true.
taskYesThe task's task_id from get_board, or its exact text.
card_idYesTo-do list ID from get_board.
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.7/5.0
Behavior5/5

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

Goes beyond the annotations (readOnlyHint=false, idempotentHint=true, destructiveHint=false) by stating the blast radius: only the one task changes and 'the rest of the list stays as it was,' plus the return shape ('the whole list after the change'). That is exactly the mutation-scope context an agent needs.

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?

Three sentences, front-loaded with the action, then the targeting/return semantics, then the edge-case caveat. Every sentence adds information; nothing is restated from the title.

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?

There is no output schema, and the description compensates by saying it returns the whole list after the change. Mutation scope, idempotence implications, and parameter disambiguation are all covered for a 4-parameter 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 100%, so the baseline is 3; the description earns extra by clarifying the polymorphic 'task' parameter (id or exact text) and giving a tie-breaking rule for duplicate text that the schema does not state.

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?

Specific verb + resource: 'Tick or untick one task in a to-do list', with the scope (one task, rest unchanged) made explicit. No sibling tool does this, and the definition makes that unambiguous without requiring comparison of schemas.

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?

Provides clear operational guidance on how to target the task ('by task_id or by its exact text') and a disambiguation rule: 'When two tasks share the text, pass the task_id instead.' It doesn't name alternative tools, but no genuine sibling alternative exists for this operation.

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

trash_cardsTrash cardsA
Destructive

Move cards or sub-boards to the trash, as the Delete key does.

The cards leave the board for everyone who can see it, and a trashed sub-board takes its contents with it. Nothing is gone for good: list_trash shows them and restore_card puts one back where it was, until the trash is emptied in Milanote.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.
card_idsYes1 to 50 card IDs from get_board; a sub-board's board_id works too.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and openWorldHint, but the description adds real behavioral context beyond them: the removal is visible to all board viewers, a sub-board takes its contents with it, and the action is reversible until the trash is emptied outside the API. That is exactly the extra information an agent needs before a destructive call.

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, second sentence carrying the collaboration impact, recoverability path, and the limits of that recovery. No wasted text.

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?

No output schema exists, and the description covers outcome, visibility, cascading effects, and the recovery route. An agent has everything required to call this correctly or route to restore_card/list_trash instead.

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 both parameters are already documented, but the description corroborates that sub-boards are acceptable targets and explains the consequence of passing a sub-board ID (its contents move too). That is meaning beyond the schema's type description.

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?

A specific verb plus resource ('Move cards or sub-boards to the trash') with the scope of the action made explicit, including the sub-board cascade case. It is immediately distinguishable from siblings like move_card, restore_card, and list_trash.

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 states the effect and points to list_trash for viewing and restore_card for undo, which tells the agent how this fits into a recoverable workflow. It stops short of explicit when-not-to-use guidance (e.g., permanent removal is only possible in the Milanote app), but the context is clear.

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

unpublish_boardUnpublish boardA
Destructive

Turn off a board's read-only link; people who had it can no longer open the board.

Does what switching off Share, Enable read-only link does. Editors keep their access. publish_board turns the same link back on, so anyone who kept it can open the board again. was_published is false when the board had no link.

ParametersJSON Schema
NameRequiredDescriptionDefault
board_idYesBoard ID from list_boards, or the board URL.

TDQS

A4.4/5.0
Behavior5/5

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

Annotations already flag this as a destructive, non-read-only, non-idempotent write; the description adds exactly the context they can't: the blast radius (anyone holding the link loses access), the important nuance that editors retain access, reversibility (publish_board restores the same link so former holders can reopen it), and the return signal was_published=false when no link existed. This also explains the playIdempotent=false consequence of a second call.

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?

Front-loaded with the core action and consequence in the first sentence, then supporting details. The UI-equivalence sentence ('switching off Share, Enable read-only link') is slightly product-specific phrasing but earns its place by grounding the action; otherwise tight with no filler.

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?

No output schema exists, and the description compensates by documenting the was_published return flag as well as the access impact and reversibility path. For a single-parameter destructive toggle, an agent has everything needed to call and interpret it correctly.

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 coverage is 100% and the single board_id parameter is documented in the schema (including that a board URL is acceptable). The description adds nothing about the identifier itself, so baseline 3 applies.

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 ('Turn off a board's read-only link') with the user-visible consequence, and explicitly contrasts with the sibling publish_board, which does the inverse. An agent can distinguish this from publish_board and from editor/permission tools like remove_editor without opening a 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 a concrete anchor for when to use it ('Does what switching off Share, Enable read-only link does') and names the alternative for the opposite operation (publish_board). It does not spell out exclusions, e.g. that this does not revoke editor access or delete the board, but it does state editors keep their access, which implicitly rules out a permissions-revocation interpretation.

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. 30 tool updatesv1.0.1
    • First observedadd_column
    • First observedadd_comment
    • First observedadd_label
    • First observedadd_link
    • First observedadd_note
    • First observedadd_todo_list
    • First observedcreate_board
    • First observeddelete_comment
    • First observedduplicate_board
    • First observededit_comment
    • First observededit_note
    • First observedexport_board
    • First observedget_board
    • First observedget_sharing
    • First observedget_usage
    • First observedinvite_editor
    • First observedlist_boards
    • First observedlist_labels
    • First observedlist_recent_boards
    • First observedlist_trash
    • First observedmove_card
    • First observedpublish_board
    • First observedremove_editor
    • First observedrename_board
    • First observedrestore_card
    • First observedsearch_boards
    • First observedset_card_color
    • First observedset_task_done
    • First observedtrash_cards
    • First observedunpublish_board

TDQS

A4.1/5.0

Scored across 30 tools

Disambiguation5/5

Each tool has a distinct resource and action; card-creation tools are separated by card type (note, link, todo list, comment, column), while board navigation, search, trash, sharing, and usage are clearly scoped. There is no meaningful overlap that would cause misselection.

Naming Consistency5/5

All tool names use snake_case and follow a predictable verb_noun pattern (list_boards, add_note, create_board, delete_comment, get_sharing, set_task_done). Minor compound names like set_card_color remain readable and consistent.

Tool Count2/5

At 30 tools, the surface is heavy and exceeds the typical well-scoped range; many granular operations are exposed separately. While the domain is broad, the count feels excessive and could be consolidated.

Completeness3/5

Core board, comment, note, sharing, trash, and export workflows are covered, but notable gaps remain: no tools to add image/file cards, no way to add tasks to an existing to-do list or edit task due dates, and no label removal. These gaps could cause agent dead ends for common board-management requests.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Open-source MCP server that gives AI agents access to 100+ web applications through the user's authenticated browser session. No API keys, no screenshots, no DOM scraping — talks directly to web app internal APIs via a Chrome extension. Supports Slack, Discord, GitHub, Jira, Notion, Reddit, X, and 100+ more services with ~2,000 tools. Works with Claude Code, Cursor, Windsurf, and any MCP client.
    42
    988
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server that lets AI coding tools drive the user's own already-logged-in Chrome — clicking, typing, reading pages, taking screenshots, and inspecting cookies, network, and console through the extension rather than a debug port. All communication stays on the machine, with agent-opened tabs grouped and kept out of focus.
    1 npm
    ISC
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server that lets AI assistants drive your real, already-logged-in Chrome through a browser extension, so agents can read, click, type, navigate, screenshot, inspect network traffic, and manage cookies or storage on pages that require existing sessions. It works without opening a remote-debugging port and keeps all communication on your machine.
    1 npm
    ISC
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local MCP server that lets AI coding tools drive the user's actual, already-logged-in Chrome browser — snapshotting pages, clicking, typing, navigating, reading content, taking screenshots, and inspecting cookies, network traffic, and console output. Browser automation happens through a Chrome extension using Native Messaging, so no remote-debugging port is exposed and all communication stays on the local machine.
    1 npm
    ISC