# Milanote by Cotlet (pypi · milanote-api-mcp)

Boards, notes and links in your Milanote workspace.

- Trust score: 65/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-24

## Components

- remote · `cotlet.dev`: 69/100, [markdown](https://verifymcp.io/servers/dev-cotlet-milanote/mcp-v1-milanote.md), [page](https://verifymcp.io/servers/dev-cotlet-milanote/mcp-v1-milanote)
- remote · `cotlet.dev`: 40/100, [markdown](https://verifymcp.io/servers/dev-cotlet-milanote/mcp-v1-milanote-connect.md), [page](https://verifymcp.io/servers/dev-cotlet-milanote/mcp-v1-milanote-connect)
- pypi · `milanote-api-mcp`: 65/100 (this document), [markdown](https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp.md), [page](https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp)

## Channel facts

- Registry: `pypi`
- Package: `milanote-api-mcp`
- Version: `1.0.3`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-24.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - 0 of 36 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 84/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to cotletdev/milanote-api-mcp-server).
  - License check failed: the license (PolyForm-Noncommercial-1.0.0) isn't a recognized OSI-approved license.
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 83/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3952 tokens (~123/item across 32 items; 30 tools + 2 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 3 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 32 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Milanote by Cotlet MCP server?

Milanote by Cotlet runs locally as a PyPI package, launched with uvx milanote-api-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add dev-cotlet-milanote -- uvx milanote-api-mcp
```

### Cursor

```json
{
  "mcpServers": {
    "dev-cotlet-milanote": {
      "command": "uvx",
      "args": [
        "milanote-api-mcp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "dev-cotlet-milanote": {
      "command": "uvx",
      "args": [
        "milanote-api-mcp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add dev-cotlet-milanote -- uvx milanote-api-mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "dev-cotlet-milanote": {
      "type": "local",
      "command": [
        "uvx",
        "milanote-api-mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add dev-cotlet-milanote --command uvx --arg milanote-api-mcp
```

### Hermes

```yaml
mcp_servers:
  dev-cotlet-milanote:
    command: "uvx"
    args: ["milanote-api-mcp"]
```

### Netclaw

```json
{
  "McpServers": {
    "dev-cotlet-milanote": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "milanote-api-mcp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add dev-cotlet-milanote -t stdio -c uvx -a milanote-api-mcp
```

### Other

```json
{
  "mcpServers": {
    "dev-cotlet-milanote": {
      "command": "uvx",
      "args": [
        "milanote-api-mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-24 (score 65)

First indexed and scored.

## MCP tools (30)

### `add_column` (~90 tokens)

Add column

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `title` (string, required): Column title.

### `add_comment` (~168 tokens)

Add comment

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `reply_to_id` (string): A comment thread ID or comment ID from get_board (include_comments) to reply in. Default: a new comment card.
- `text` (string, required): Comment text, plain.

### `add_label` (~119 tokens)

Add label

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `card_id` (string, required): Card ID from get_board.
- `label` (string, required): Label name; a name you have not used yet creates the label.

### `add_link` (~152 tokens)

Add link

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

Adds one link card on top of the board's Unsorted panel. Milanote fetches the page itself and fills in the title, description and preview image, as when you paste a link; the answer returns what it found (title is null when the page gave none). On the free plan a link counts toward the 100 cards limit. Nobody is notified; move the card to the trash in Milanote to undo it.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `url` (string, required): Web address to save, starting with http:// or https://.

### `add_note` (~128 tokens)

Add note

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `text` (string, required): Note text. Each line becomes a paragraph.

### `add_todo_list` (~169 tokens)

Add to-do list

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `tasks` (array, required): 1 to 50 tasks, in order.
- `title` (string): List title. Default: no title.

### `create_board` (~130 tokens)

Create board

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.

Input parameters:

- `parent_board_id` (string): Board to nest it in (ID or board URL). Default: your Home.
- `title` (string, required): Board title.

### `delete_comment` (~87 tokens)

Delete comment

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `comment_id` (string, required): comment_id from get_board (include_comments) or add_comment.

### `duplicate_board` (~173 tokens)

Duplicate board

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.

Input parameters:

- `board_id` (string, required): Board to copy: ID or board URL.
- `parent_board_id` (string): Board to put the copy in (ID or board URL). Default: where the original is.
- `title` (string): Title of the copy. Default: the same title.

### `edit_comment` (~103 tokens)

Edit comment

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `comment_id` (string, required): comment_id from get_board (include_comments) or add_comment.
- `text` (string, required): New comment text, plain.

### `edit_note` (~125 tokens)

Edit note

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `card_id` (string, required): Note ID from get_board.
- `text` (string, required): New note text. Each line becomes a paragraph.

### `export_board` (~141 tokens)

Export board

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `format` (string, required): markdown, plain_text, word, pdf or png.

### `get_board` (~211 tokens)

Get board

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `include_comments` (boolean): Also return comment threads with their comments. Default: false.

### `get_sharing` (~117 tokens)

Get sharing

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.

### `get_usage` (~99 tokens)

Get usage

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.

### `invite_editor` (~134 tokens)

Invite editor

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `email` (string, required): Their email address.

### `list_boards` (~152 tokens)

List boards

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.

Input parameters:

- `limit` (integer): 1 to 200. Default: 50.
- `parent_board_id` (string): Only boards inside this board (ID or board URL). Default: the boards on your Home.

### `list_labels` (~59 tokens)

List labels

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.

### `list_recent_boards` (~104 tokens)

List recent boards

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.

Input parameters:

- `limit` (integer): 1 to 50. Default 20.

### `list_trash` (~93 tokens)

List trash

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.

### `move_card` (~181 tokens)

Move card

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.

Input parameters:

- `board_id` (string, required): Board the card is on now: ID or board URL.
- `card_id` (string, required): Card ID from get_board; a sub-board's board_id works too.
- `to_board_id` (string): Board to move it to. Default: the same board.
- `to_column_id` (string): Column on the target board to put it in, at the top. Default: no column.

### `publish_board` (~148 tokens)

Publish board

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.

Input parameters:

- `allow_comments` (boolean): Let viewers of the link comment, react and draw. Default false.
- `allow_downloads` (boolean): Show download links on files to viewers. Default true.
- `board_id` (string, required): Board ID from list_boards, or the board URL.

### `remove_editor` (~134 tokens)

Remove editor

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `email` (string): Their email address, instead of user_id.
- `user_id` (string): Their user_id from get_sharing or invite_editor.

### `rename_board` (~80 tokens)

Rename board

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `title` (string, required): New title.

### `restore_card` (~104 tokens)

Restore card

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.

Input parameters:

- `card_id` (string, required): ID of a trashed card or board from list_trash.

### `search_boards` (~137 tokens)

Search boards

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.

Input parameters:

- `query` (string, required): Text to look for.
- `sort` (string): last_viewed or last_modified. Default: last_viewed.

### `set_card_color` (~129 tokens)

Set card color

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `card_id` (string, required): Card ID from get_board: a note, to-do list, link, file or column.
- `color` (string, required): Colour, or none to clear it.

### `set_task_done` (~150 tokens)

Set task done

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `card_id` (string, required): To-do list ID from get_board.
- `done` (boolean): true ticks it, false unticks it. Default true.
- `task` (string, required): The task's task_id from get_board, or its exact text.

### `trash_cards` (~124 tokens)

Trash cards

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.
- `card_ids` (array, required): 1 to 50 card IDs from get_board; a sub-board's board_id works too.

### `unpublish_board` (~97 tokens)

Unpublish board

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.

Input parameters:

- `board_id` (string, required): Board ID from list_boards, or the board URL.

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp#diagnostics

## Score history

- 2026-10-24: 65

## Common questions

### What is the Milanote by Cotlet MCP server?

Milanote by Cotlet is an MCP server listed in the public MCP registry as dev.cotlet/milanote. Boards, notes and links in your Milanote workspace. This page covers its PyPI package (milanote-api-mcp).

### Is the Milanote by Cotlet MCP server safe to use?

Milanote by Cotlet scores 65 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 24 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Milanote by Cotlet MCP server expose?

Milanote by Cotlet exposes 30 tools: add_column, add_comment, add_label, add_link, add_note, and 25 more. Their descriptions and schemas cost roughly 3,838 tokens of context every time the server is loaded.

### Is the Milanote by Cotlet MCP server still maintained?

Milanote by Cotlet is still listed as active in the MCP registry. We last reached this channel on 24 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Milanote by Cotlet MCP server under?

Milanote by Cotlet declares the PolyForm-Noncommercial-1.0.0 licence, which is not on the OSI-approved list. Read the terms before using it at work, and note this covers the source only, not the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/milanote-api-mcp/
- Socket report: https://socket.dev/pypi/package/milanote-api-mcp
- Repository: https://github.com/cotletdev/milanote-api-mcp-server
- Website: https://cotlet.dev/integrations/milanote-api-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp.xml
- Changelog JSON feed: https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp.json
- HTML version of this page: https://verifymcp.io/servers/dev-cotlet-milanote/milanote-api-mcp
