Overview
The 2Mind MCP server is a remote MCP server. It gives an assistant tools to search and read your notes, list your collections and tasks, and request changes to them. It works with the same account and the same data as the 2Mind apps.
Reading is immediate. Writing is never silent: every write tool files an approval request, and the change is applied only after you approve it, unless you have chosen to let that connection apply reversible changes on its own.
The server uses the Streamable HTTP transport in stateless mode. Each request is a single POST with an OAuth bearer token; there are no sessions and no server-sent event stream to keep open.
Connect
You need a 2Mind account and an assistant that can add a remote MCP server. Use this server URL:
https://api.use2mind.com/mcpClaude
Open the connector settings, choose to add a custom connector, give it a name such as 2Mind and paste the server URL. Organisation owners may need to add it for their members first.
ChatGPT
Turn on developer mode and create a new connector with the server URL and OAuth authentication. Developer mode depends on your ChatGPT plan and workspace settings.
Other clients
Point the client at the server URL. It discovers the authorization server by itself from the server's OAuth metadata, so there is nothing else to configure.
What happens when you connect
- Your assistant opens the 2Mind sign-in page in a browser.
- You sign in with Google, email and password, or Apple on Apple devices.
- You review what the app asks for and choose an access level.
- You are sent back to your assistant, and the 2Mind tools appear.
Access levels
When the assistant asks for write access, the consent screen lets you choose. The level you pick is checked on every single call, not just when you connect.
- Read only (default)
- Search, read and list. The write tools are not even listed for this connection.
- Read and make changes
- Adds the tools that request changes. Each change still goes through approval.
Authentication and scopes
The server accepts only OAuth 2.0 access tokens, sent in the Authorization header as a bearer token. There are no API keys, and no token is ever passed as a tool argument.
A request without a valid token receives 401 with a WWW-Authenticate header that points to the protected resource metadata. From there a client finds the authorization server and starts an authorization code flow with PKCE.
POST https://api.use2mind.com/mcpGET https://api.use2mind.com/.well-known/oauth-protected-resourceissuer https://auth.use2mind.com
| Scope | Allows | Tools |
|---|---|---|
notes:read | Search, list and read notes in full, and list tags. | searchfetchlist_entrieslist_tags |
collections:read | List and read collections, and list tags. | list_collectionsget_collectionlist_tags |
todos:read | List tasks with filters. | list_todos |
notes:write | Request creating, editing, tagging, moving and deleting notes. | create_entryupdate_entrymove_entrydelete_entryundo_command |
todos:write | Request creating, editing, reordering and deleting tasks. | create_todoupdate_tododelete_todoreorder_todosundo_command |
collections:write | Request creating, editing, reordering and archiving collections. | create_collectionupdate_collectionreorder_collectionsarchive_collectionunarchive_collectionundo_command |
Sign in with the same method you use in the app. Accounts are not merged across sign-in providers, so a different provider or an Apple private relay address can open a separate, empty 2Mind account.
How changes work
No write tool changes your data by itself. It checks the current version of what it targets, builds an exact plan and files an approval request. The response is an operation you can follow.
- The assistant files a requestIt calls a write tool with a requestId it generates. The server answers with an operation in pending_approval and a one-line summary of the change.
- You get a notificationA notification reaches your phone. You approve or decline the change there; the assistant never approves on your behalf.
- The change is appliedOn approval the change is applied and recorded, so it can be undone later. Requests you do not answer expire after 24 hours.
- The assistant checks the resultIt calls get_operation with the operationId to see whether the change was applied, declined, failed or expired.
Example
Tool call
{
"name": "create_todo",
"arguments": {
"requestId": "3f6c2a9e-8b1d-4c7a-9e2f-5a1b7d4c8e60",
"collectionId": "b2e4d6f8-1a3c-4e5f-8a7b-9c0d1e2f3a4b",
"content": "Book the dentist appointment",
"dueDate": "2026-10-02T09:00:00+03:00"
}
}Result
{
"operationId": "c81f0e2a-6d4b-4a9e-b3c7-1f2e3d4c5b6a",
"action": "create_todo",
"status": "pending_approval",
"summary": "Add task “Book the dentist appointment” to Errands",
"approvalUrl": "https://api.use2mind.com/connect/approvals/c81f0e2a-6d4b-4a9e-b3c7-1f2e3d4c5b6a",
"expiresAt": "2026-10-01T09:00:00.000Z"
}The operation object
operationId | Identifier to pass to get_operation. |
|---|---|
action | The tool that filed the request. |
status | Where the request is now; see the table below. |
summary | A one-line description of exactly what will change, written by the server. |
approvalUrl | A sign-in protected page where the request can also be reviewed. |
expiresAt | When an unanswered request expires. |
commandLogId | Set once applied. Use it with undo_command. |
result | The outcome of an applied change, such as the id of a new note. |
Status values
pending_approval | Waiting for you to approve or decline. |
|---|---|
applied | Approved and applied. |
failed | Approved, but could not be applied, for example because the item changed in the meantime. |
rejected | You declined it. |
expired | Not answered within 24 hours. Nothing changed. |
Apply changes without asking
In Connected apps, each connection has an Apply changes without asking switch. It is off by default. When it is on, reversible changes from that connection are applied straight away and returned as applied. delete_entry and delete_todo still wait for approval. Every change is still recorded and can be undone.
Undo
An applied change can be undone by the assistant with undo_command, using the commandLogId and version, or by you from Recent changes with one tap. An undo is refused if the item was edited after the change, so it never overwrites your newer work.
Tool reference
A connection only lists the tools its access level allows. Every write tool takes a requestId: retrying with the same requestId returns the same operation instead of creating a second change.
Read
search
Searches your notes for a keyword or topic and returns up to 20 matches with their id, title and link.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string | Yes | The keyword or topic to search for.1–2,000 characters |
fetch
Reads one note in full by id. A very long note arrives in parts; pass the returned nextId to read the next part.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | A note id from search, or a nextId from a previous fetch to continue a long note.up to 80 characters |
list_entries
Lists your notes newest first, optionally filtered by collection, tag, a text the title or body contains, or a creation-date range. Each row carries a snippet, every collection the note is in and its tags. Paginated.
| Parameter | Type | Required | Description |
|---|---|---|---|
collectionId | uuid | No | Only notes in this collection. |
tag | string | No | Only notes carrying this tag, matched without regard to case.1–100 characters |
contains | string | No | Only notes whose title or body contains this text, without regard to case.1–200 characters |
createdAfter | string (date-time) | No | Only notes created at or after this time. ISO 8601 with a time zone offset. |
createdBefore | string (date-time) | No | Only notes created at or before this time. ISO 8601 with a time zone offset. |
limit | integer | No | How many items to return per page.1–50 · default 20 |
cursor | string (date-time) | No | The nextCursor value from the previous page. |
list_collections
Lists your collections in your saved order, with type, parent, archive state and whether it holds tasks. Paginated.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | How many items to return per page.1–50 · default 20 |
cursor | string | No | The nextCursor value from the previous page.up to 100 characters |
includeArchived | boolean | No | Also return archived collections. Hidden by default. |
get_collection
Reads one collection by id: the same fields as list_collections, plus when it last changed, how many notes it holds and how many of its tasks are still open.
| Parameter | Type | Required | Description |
|---|---|---|---|
collectionId | uuid | Yes | The collection to read. |
list_todos
Lists your tasks, optionally filtered by collection, completion or a due-date range. Paginated.
| Parameter | Type | Required | Description |
|---|---|---|---|
collectionId | uuid | No | Only tasks in this collection. |
completed | boolean | No | Only completed (true) or open (false) tasks. |
dueAfter | string (date-time) | No | Only tasks due at or after this time. ISO 8601 with a time zone offset. |
dueBefore | string (date-time) | No | Only tasks due at or before this time. ISO 8601 with a time zone offset. |
limit | integer | No | How many items to return per page.1–50 · default 20 |
cursor | string | No | The nextCursor value from the previous page.up to 100 characters |
list_tags
Lists your tag vocabulary with how many notes and collections carry each tag, most used first. Notes and collections share one vocabulary.
| Parameter | Type | Required | Description |
|---|
Notes
create_entry
Requests a new note in an existing collection. The collection is always chosen explicitly.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | The collection to create the note in. Find it with list_collections. |
content | string | Yes | The note body.1–20,000 characters |
title | string or null | No | The note title. null removes it.up to 500 characters |
tags | string[] | No | Tags for the new note, without #. Reuse names from list_tags where you can.up to 10 items |
update_entry
Requests a change to the title, body or tags of one note.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
entryId | uuid | Yes | The note to change. |
title | string or null | No | The note title. null removes it.up to 500 characters |
content | string or null | No | The note body.up to 20,000 characters |
tags | string[] | No | The complete new tag set, without #. Anything left out is removed; [] removes all. Omit to leave the tags alone.up to 10 items |
move_entry
Requests a new set of collections for a note. The note leaves any collection not listed, along with tasks it created there.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
entryId | uuid | Yes | The note to change. |
collectionIds | uuid[] | Yes | The complete new set of collections for the note.1–5 items |
primaryCollectionId | uuid | No | The main collection. Must be one of collectionIds; defaults to the first. |
delete_entry
Requests deleting one note and the tasks linked to it. Always needs approval.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
entryId | uuid | Yes | The note to change. |
Tasks
create_todo
Requests a new task at the end of a task list.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | A collection where carriesTodos is true in list_collections. |
content | string | Yes | The task text.1–2,000 characters |
dueDate | string (date-time) or null | No | The due date, ISO 8601 with a time zone offset. null clears it. |
update_todo
Requests a change to a task's text, completion state or due date.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
todoId | uuid | Yes | The task to change. |
content | string or null | No | The task text.up to 20,000 characters |
isCompleted | boolean | No | Mark the task done (true) or open (false). |
dueDate | string (date-time) or null | No | The due date, ISO 8601 with a time zone offset. null clears it. |
delete_todo
Requests deleting one task. Always needs approval.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
todoId | uuid | Yes | The task to change. |
reorder_todos
Requests a new order for the tasks inside one collection, most important first. Naming only the tasks that move is enough; the rest keep their order after them.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | The collection whose tasks are reordered. Every id must belong to it. |
orderedIds | uuid[] | Yes | Task ids in the new order, from list_todos. Tasks not named keep their order after these.1–100 items |
Collections
create_collection
Requests a new, empty collection of a given type, optionally with tags. The type cannot be changed later, and names are unique under the same parent.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
name | string | Yes | The collection name, unique under the same parent.1–200 characters |
type | stringnotetodo_listplanidearesearcheventgeneric | Yes | The kind of collection. todo_list holds tasks; the others hold notes. |
description | string or null | No | A short description. null clears it.up to 2,000 characters |
parentId | uuid or null | No | Create it inside this collection. Omit or null for the top level. |
tags | string[] | No | Tags for the new collection, without #. Collections sharing a tag are shown as related.up to 5 items |
update_collection
Requests renaming a collection, changing its description or tags, or moving it under another collection. The type cannot be changed.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | The collection to change. |
name | string | No | The collection name, unique under the same parent.1–200 characters |
description | string or null | No | A short description. null clears it.up to 2,000 characters |
parentId | uuid or null | No | Move it inside this collection. null moves it to the top level. |
tags | string[] | No | The complete new tag set, without #. Anything left out is removed; [] removes all. Omit to leave the tags alone.up to 5 items |
reorder_collections
Requests a new order for your collections, most important first.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
orderedIds | uuid[] | Yes | Collection ids in the new order, from list_collections.1–50 items |
archive_collection
Requests archiving a collection. It stays intact and is hidden from the default list.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | The collection to change. |
unarchive_collection
Requests taking a collection out of the archive.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
collectionId | uuid | Yes | The collection to change. |
Operations
undo_command
Requests undoing a change that was already applied.
| Parameter | Type | Required | Description |
|---|---|---|---|
requestId | uuid | Yes | A UUID the assistant generates. Reusing it returns the existing operation. |
commandLogId | uuid | Yes | The commandLogId of the applied operation. |
version | integer | Yes | The version of that change to undo.1 or more |
get_operation
Reads the status and result of a request filed by a write tool. Returns only requests from the same connection.
| Parameter | Type | Required | Description |
|---|---|---|---|
operationId | uuid | Yes | The operationId returned by a write tool. |
list_operations
Lists the requests this connection filed, newest first, optionally filtered by status. Each row is the same operation get_operation returns. Paginated.
| Parameter | Type | Required | Description |
|---|---|---|---|
status | stringpending_approvalappliedfailedrejectedexpired | No | Only requests in this status. |
limit | integer | No | How many items to return per page.1–50 · default 20 |
cursor | string (date-time) | No | The nextCursor value from the previous page. |
Example prompts
You do not need to name tools. Ask in plain language and the assistant picks them:
- What did I save about the kitchen renovation last month?
- Summarise my notes in the Research collection.
- Which of my tasks are due this week?
- Add “renew passport” to my Errands list, due Friday.
- Create a Trip ideas collection and move my notes about Lisbon into it.
Limits and errors
Each connection can make up to 60 requests per minute. Protocol errors come back as HTTP responses; problems with a specific call come back as tool errors the assistant can read.
| Response | Meaning | What to do |
|---|---|---|
401 invalid_token | The token is missing, expired or the connection was revoked. | Reconnect 2Mind in your assistant and sign in again. |
403 invalid_origin | The request came from a browser page that is not allowed to call the server. | Use a supported assistant or client instead of a web page. |
429 rate_limited | The connection went over 60 requests in a minute. | Wait for the time in Retry-After, 60 seconds, and try again. |
isError: true | The call reached the server but could not be done, for example a missing scope, invalid input or an item that changed. | Read the error text. The assistant can usually fix the input or read the item again and retry. |
Size limits
- search: queries up to 2,000 characters, up to 20 results.
- list_collections and list_todos: 20 items per page by default, 50 at most.
- Notes: bodies up to 20,000 characters, titles up to 500.
- A note can be in up to 5 collections at once.
- Tags: up to 10 per note and 5 per collection, names up to 100 characters.
Plans
The MCP server is included in the Plus and Pro plans. Connecting an assistant does not change what your plan includes in the apps.
Troubleshooting
My assistant can read but cannot make changes.
The connection was set to Read only. Changing the level needs a new consent: revoke the connection in Connected apps, then connect again and choose Read and make changes.
The assistant said it made a change, but nothing happened.
The change is probably waiting for your approval. Check the notification on your phone. Requests you do not answer expire after 24 hours.
I see an empty account after connecting.
You probably signed in with a different method than in the app. Disconnect, then connect again using the same sign-in you use in 2Mind.
My assistant keeps asking me to sign in again.
The connection was revoked or its sign-in expired. Remove 2Mind from the assistant and add it again.
Can an assistant delete my notes without asking?
No. delete_entry and delete_todo always wait for your approval, even when Apply changes without asking is on.
How do I disconnect an assistant?
Revoke it in Connected apps. Access stops immediately. You can also remove the connector in the assistant's own settings.