MCP server
Applies to monthlet 0.13.1 and later
monthlet can act as an MCP server, so an agent outside the app — Claude Code, for example — can read and write the notes in your vault through monthlet itself rather than touching the files behind its back. This page lists what is published and what each tool guarantees. For the steps inside the app, see Help in the app.
What it is
When you turn it on, monthlet listens for MCP connections and offers a fixed set of tools: searching and listing notes, reading a note as Markdown, reading spreadsheet cells and chart values, and — separately opt-in — creating and rewriting notes.
The app has to be running. Agents connect only while monthlet is open, and the vault they see is the one you have open. Switching vaults switches what is published.
Everything goes through monthlet, which stays the single writer of your files. That is what keeps the note history, the search index, and the open editor in step with what an agent does.
Setting it up
- In monthlet, open Settings → Connectors → Publish to external agents and turn on Publish.
- Under Setup, press Copy command and run what you copied in a terminal. It registers monthlet with Claude Code.
- To let agents write as well, turn on Allow writing in the same place. It is off by default.
The command looks like this. Copy the real one from the settings screen — the path depends on where the app is installed.
claude mcp add --scope user monthlet -- \
/Applications/monthlet.app/Contents/Resources/bin/monthlet-mcpThis is the newer of two ways to connect, and it needs monthlet 0.13.3 or later, which is where the command started being bundled. You can also tell from the settings screen: if Setup offers both Copy command and Direct HTTP (with token), you have it. If there is only one button, use the HTTP method below instead.
- Running this command requires Node.js on your machine. monthlet bundles the script, not a runtime to execute it with.
- What gets registered is only the path to that command. Your token is not written into the agent’s config — the command reads the token and the port from monthlet each time it runs.
- Because of that, regenerating the token does not require registering again, and neither does the port changing when the default one is taken.
--scope userregisters monthlet once for your user, rather than inside a single project’s config file.
Connecting over HTTP instead
Clients that cannot launch a command, or that only speak streamable HTTP, can connect to the endpoint directly. Copy this one from Direct HTTP (with token) on the same screen — it carries your token, and the port differs when the default one is taken.
claude mcp add --scope user --transport http monthlet \
http://127.0.0.1:27180/mcp --header "Authorization: Bearer <token>"- Here
--scope usermatters for a second reason: the token is saved in your user settings, not in a project file that could be committed. - The token is written into the client’s config, so regenerating it from the settings screen means registering again. The previous token stops working immediately.
- Any MCP client that speaks streamable HTTP can connect with the same endpoint and header.
Tools
Reading
| Tool | What it does | Main arguments | Returns |
|---|---|---|---|
search_notes | Full-text search over notes and spreadsheets: titles, bodies, and tags. | query (required), tags, includeArchived, limit (20) | Matches by relevance, each with path, title, kind, updated date, tags, and a short snippet. |
list_notes | Lists notes and spreadsheets, most recently updated first. | folder, includeExcerpt, includeArchived, limit (200) | Path, folder, title, kind (note or sheet), updated date, tags, pinned, archived, and the first 160 characters when asked for. |
read_note | Reads a note body as Markdown. Spreadsheets are not covered — use read_sheet_range. | path (required) | Path, title, tags, updated date, and the body as Markdown. |
read_sheet_range | Reads cells from a spreadsheet in the vault. | path (required over this connection), range (A1 notation), sheet_id | The cell values. Without a range, an overview of the used area. |
read_chart_data | Reads the numbers behind a chart in a note. | path (required), id | Labels and series values per chart. For charts bound to a sheet, the source path and range as well. |
Writing
These appear only while Allow writing is on. Paths are relative to the vault, the same ones the reading tools return.
| Tool | What it does | Main arguments | Returns |
|---|---|---|---|
create_note | Creates a note from Markdown. Missing folders are created along the way. | title (required), markdown (required), folder | The path and title of the new note. A number is appended when the title is already taken. |
update_note | Replaces the body of a note with Markdown. | path (required), markdown (required) | The path, the title, the placeholders that survived, and any that were dropped. |
create_folder | Creates an empty folder, intermediate levels included. | path (required) | The folder that was created. |
create_sheet | Creates a spreadsheet from rows of text. Formulas and formatting are not set at creation. | title (required), rows (required), folder | The path and title of the new spreadsheet. |
What the tools guarantee
- Markdown is the contract.
read_notehands you Markdown andupdate_notetakes Markdown back. Nothing else about the file format is part of the interface. - Elements that Markdown cannot express are kept as placeholders. Charts, embeds, and calculation blocks come through as fenced
monthlet-blockcode blocks carrying an id. Leave the line in place and the element survives the round trip; remove the line and the element goes with it. Anything removed that way is reported back asdroppedBlockswith its id and a label, so a rewrite never drops a chart silently. When you need the numbers rather than the placeholder, callread_chart_data. update_notereplaces the whole body. Send the full text, not a patch. The title is not part of it and does not change.- A write is refused in two cases: the note is open in monthlet with unsaved changes, or it has changed since you read it with
read_note. The second one clears as soon as you read the note again and rebuild your edit on that. - The previous version is kept. Every write goes into the note’s change history in the app, so a person can look at what an agent did and restore the earlier version.
- Turning writing off takes effect immediately. A client that is already connected may keep showing the old tool list until it reconnects, but every call is checked against the current setting, so anything you have not allowed will not run.
- Paths can change. Opening a note whose filename disagrees with its title renames the file to match the title. Treat paths as current, not permanent: list or search again rather than reusing a path you cached a while ago.
Not exposed, on purpose
These exist in the app but are not offered over the connection.
- Deleting, moving, renaming, and merging notes or foldersThese are the operations the app confirms with you before running, and a connection has nobody at the screen to ask.
- Editing cells in an existing spreadsheetSheet edits are applied against the sheet you have open, in the part of the app that draws it. Creating a new spreadsheet is available; changing one in place is not.
- Anything that moves the app’s interfaceOpening a note or a search panel has no meaning for an agent working outside the window.
- Fetching URLs, saving skills, and looking up in-app helpThese serve the chat inside monthlet. An outside agent already has its own.
Security
- Off by default. Nothing listens until you turn it on, and reading and writing are separate switches — turning it on does not let anything write.
- Local only. The server binds to 127.0.0.1, so it is not reachable from your network.
- Every request carries a token. A
Authorization: Bearerheader is required even locally, and requests that arrive with anOriginheader are refused outright, which keeps web pages in a browser from connecting. - One vault, while the app runs. What is published is the vault you have open, and only for as long as monthlet is running.
- Note contents are untrusted input for the agent that reads them. A note can contain text that reads like an instruction, and an agent that acts on it is acting on whatever happened to be written down. Handling that is the connecting agent’s responsibility — monthlet hands over the content as it is.
Compatibility
- Tool names and their inputs and outputs are kept backward compatible. Fields may be added; existing ones keep their meaning.
- When something has to change in a way that breaks callers, it arrives as a new tool name rather than a quiet change to an existing one.
- The
monthlet-blocksJSON inside a note file is not part of the published interface. It changes as the app changes, so go through the tools rather than reading it.