Anybox MCP Server
Anybox for Mac includes a Model Context Protocol (MCP) server, so AI agents such as Claude Desktop, Claude Code and Cursor can work with your library. An agent can:
- search your saved links, notes, images and files
- read the saved text of articles
- save new links
- change titles, descriptions, comments, keywords, stars, tags and folders
- move items to the Trash
Nothing is ever deleted permanently through the server, and nothing leaves your Mac. The server listens only on this computer and only while Anybox is open.
Requirements
- Anybox for Mac 2.15 or later
- The server turned on in Anybox › Settings › MCP
- Your API key, shown in Anybox › Settings › General
The server is off until you turn it on. While it is off, every request is refused.
Connecting
The endpoint is http://localhost:6391/mcp. Every request must carry your API key, either as an x-api-key header or as a Bearer token. The copy buttons in Settings › MCP produce each of the snippets below with your key filled in.
Claude Code
claude mcp add --transport http anybox http://localhost:6391/mcp --header "x-api-key: YOUR_API_KEY"
Add --scope local to keep the key in your own Claude Code configuration for the current project rather than in a shared .mcp.json.
Claude Desktop
Claude Desktop launches a command rather than connecting to a URL, so Anybox ships a small helper at Anybox.app/Contents/Helpers/anybox-mcp. Add this to claude_desktop_config.json (Claude › Settings › Developer › Edit Config), then quit and reopen Claude Desktop:
{
"mcpServers": {
"anybox": {
"command": "/Applications/Anybox.app/Contents/Helpers/anybox-mcp",
"args": ["--api-key", "YOUR_API_KEY"]
}
}
}
The helper forwards each message to the endpoint and launches Anybox if it is not running. The path points at where Anybox is installed; update it if you move the app. The key can also be supplied through the ANYBOX_API_KEY environment variable instead of --api-key.
Cursor and other HTTP clients
Clients that support HTTP MCP servers take the URL and the header. For Cursor, put this in .cursor/mcp.json in a project or in ~/.cursor/mcp.json for all projects. Most other clients use the same shape.
{
"mcpServers": {
"anybox": {
"url": "http://localhost:6391/mcp",
"headers": { "x-api-key": "YOUR_API_KEY" }
}
}
}
Restart the client after editing its configuration; most clients only read it at launch.
Overview page
Open http://localhost:6391/mcp in a browser to see whether the server is running, the same setup snippets, and a reference of every tool with its parameters. The page is generated from the server's own tool definitions, so it always matches what the server reports.
Things to try
- "Find the links I saved about Swift concurrency last month."
- "Save this page to Anybox with the tag Reading and download the article."
- "Read the article I saved from MacRumors yesterday and summarise it."
- "Star everything tagged Work that I opened this week."
Tools
Ids are the values returned by search_links. Tags, folders and smart lists can be given by name or by id; nested tags and folders use path names such as Work/Reading.
search_links
Search the library. Matches the keyword against titles, URLs, descriptions, comments and keywords, and returns compact records. Results are paged.
| Parameter | Type | Description |
|---|---|---|
query | string | Keyword to search for. Omit to list items matching the other filters, most recently opened first. |
tag | string | Only items with this tag, by name or id. |
folder | string | Only items in this folder, by name or id. |
smartList | string | Only items matching this smart list, by name or id. |
starred | boolean | true for starred items only, false for unstarred only. |
type | string | all, link, note, image or file. Defaults to all. |
sort | string | dateLastOpened, dateAdded, dateUpdated or name. Defaults to dateLastOpened. |
order | string | desc or asc. Defaults to desc. |
limit | integer | Maximum number of results, 1 to 100. Defaults to 20. |
offset | integer | Number of results to skip, for paging. Defaults to 0. |
Returns count, offset, items and, when more results may exist, nextOffset. Each item has id, type, title, starred, tags, folder, dates, hasArticle, hasArchive and an anyboxURL deep link; links also have url and description, notes an excerpt, files a fileName and kind.
get_link
Full details of one item.
| Parameter | Type | Description |
|---|---|---|
id | string | The item's id. Required. |
Returns everything search_links returns plus keyword, the note text for notes, articleCharacters and articleAuthor when an article is saved, the web archive's title, size and date, preferredBrowser, source, and inTrash with dateMovedToTrash.
get_article
The saved article text of a link as Markdown, in chunks.
| Parameter | Type | Description |
|---|---|---|
id | string | The link's id. Required. |
offset | integer | Character offset to start from. Defaults to 0. |
maxCharacters | integer | Maximum characters to return, up to 100000. Defaults to 20000. |
Returns text with totalCharacters, offset, returnedCharacters, hasMore and, when more remains, nextOffset to pass to the next call. Fails with a message when the link has no saved article.
save_link
Save a URL. If the URL is already saved, the existing item is returned with alreadyExisted: true, restored from the Trash if it was there, and any given tags, folder and star are applied to it. Tags and folders that do not exist are created.
| Parameter | Type | Description |
|---|---|---|
url | string | The URL to save. Required. |
title | string | A title to use instead of the page's own title. |
description | string | A description to use instead of the page's own description. |
comment | string | The user's comment on the link. |
tags | array of strings | Tag names or ids to assign. |
folder | string | Folder name or id to file the link in. |
starred | boolean | Star the link. |
downloadArticle | boolean | Also download the page's article text for get_article. Defaults to false. |
The page title, description and image are fetched in the background after saving, so the returned record may still show the URL as the title. Call get_link a moment later if the final title matters.
update_link
Change an item. Only the fields given are changed.
| Parameter | Type | Description |
|---|---|---|
id | string | The item's id. Required. |
title | string | New title. For links this overrides the page title. |
description | string | New description. Links only. |
comment | string | New comment. An empty string clears it. |
keyword | string | New keyword for keyword expansion. An empty string clears it. |
starred | boolean | Star or unstar the item. |
addTags | array of strings | Tag names or ids to add. Missing tags are created. |
removeTags | array of strings | Tag names or ids to remove. Nothing is created. |
folder | string | Folder name or id to move the item into. A missing folder is created. |
removeFromFolder | boolean | true to take the item out of its folder. |
Returns the updated record with a changed flag. Starring goes through the same action as the app's UI, so it can be undone in Anybox.
move_to_trash
Move items to the Trash, where they can be put back for 30 days. This tool never deletes permanently.
| Parameter | Type | Description |
|---|---|---|
ids | array of strings | Ids of the items to move. Required. |
Returns trashed and notFound.
Tool annotations
The three read tools are annotated readOnlyHint: true. The write tools are annotated as writes, and move_to_trash as destructiveHint: true, so clients that follow the protocol ask before running them.
Security
- The API key allows changes to your library, so treat it like a password. Reset it any time in Settings › General; clients then need the new key.
- The server binds to the local machine only and refuses requests that carry a browser
Originheader from anywhere butlocalhost, so a web page you visit cannot reach it. - Turning the server off in Settings › MCP makes it refuse every request until it is turned on again.
- The existing browser and Raycast extension routes on the same port are unchanged; the key and origin checks apply to
/mcponly.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
401 Unauthorized | The key is missing or wrong. Copy it again from Settings › General, or use the copy buttons in Settings › MCP. |
403 Forbidden | The server is turned off in Settings › MCP, or the request came from a web page. |
| "Anybox is not running" | The app must be open. Claude Desktop's helper launches it; other clients need you to open Anybox first. |
| The agent sees no tools | Restart the client after adding the server. |
| The saved link shows its URL as the title | Metadata is fetched after saving. Ask for the item again a moment later. |
Protocol details
For anyone integrating directly rather than through a client:
- Transport is MCP's Streamable HTTP, stateless: one JSON-RPC 2.0 request per POST, answered with
application/json. Notifications receive202 Acceptedwith no body. There is no session id and no server-to-client stream, andGETreturns the overview page. - Supported protocol versions are
2024-11-05,2025-03-26and2025-06-18.initializeanswers with the client's version when it is one of these, otherwise with the latest. - Methods:
initialize,ping,tools/list,tools/call,resources/listandprompts/list(both empty). Anything else returns JSON-RPC error-32601. Batched requests are rejected with-32600. - Tool results carry a
contenttext part and astructuredContentobject with the same data. A tool failure such as an unknown id is returned as a result withisError: true; protocol problems are JSON-RPC errors.
A first request from the command line:
curl -s http://localhost:6391/mcp \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_links","arguments":{"query":"swift","limit":5}}}'
The stdio helper
anybox-mcp lives inside the app bundle and is a plain bridge: it reads newline-delimited JSON-RPC messages from standard input, forwards each one to http://127.0.0.1:6391/mcp with the key, and writes the reply to standard output. Notifications produce no output. If the app is not running it launches the bundle it lives in, waits up to 20 seconds for the server, and retries once. A 401 and an unreachable server are turned into JSON-RPC errors so the client can show the reason.
anybox-mcp --api-key KEY [--no-launch]
--no-launch is for testing; it reports an error instead of launching Anybox.