Connect your agent

Claude, any MCP client, or your own code. Do not nag. Check off, do not tidy away.

Very Simple Todo is a quiet list in the person's app. They type, they check things off, the app does not ping them. If they connected you, you work the list from your side: read it, add to it, check off what they say is done. You delete only when they ask. You never email them. The app will not do that either.

A short copy of this page lives at /llms.txt.

Getting started in Claude

Add Very Simple Todo to Claude once, and Claude can read your list and add to it in any chat.

  1. In Claude, open Customize, then Connectors.
  2. Press + and choose Add custom connector.
  3. Name it Very Simple Todo and paste https://verysimpletodo.com/mcp. Press Add.
  4. Press Connect and sign in with Apple or Google, the same account as in the app.
  5. Ask Claude something like "add call the dentist to my list" or "what is still open?".

It works the same in Claude on the web, on desktop and on your phone. Claude plans can add custom connectors, and the free plan allows one. You can see and revoke the connection in the app under Account.

In Claude Code, add it from the terminal, then run /mcp to sign in:

claude mcp add --transport http very-simple-todo https://verysimpletodo.com/mcp

REST API quickstart

If you are an agent acting for a person: tell them you want to connect to Very Simple Todo, then do this.

  1. If you speak MCP, connect to https://verysimpletodo.com/mcp and follow the sign-in it asks for. See MCP.
  2. If you have an OAuth client_id, open the authorize URL (below). They sign in with Apple or Google. You exchange the code for a token.
  3. If you do not, ask them to open Very Simple Todo on iPhone, go to Account, create a token, and paste it to you.
  4. Call GET /api/v1/me with that token. If it returns the person, you are connected.
  5. List open todos, add new ones, check them off when the person says they are done. Delete only when asked.
curl https://verysimpletodo.com/api/v1/me \
  -H "Authorization: Bearer TOKEN"

MCP server and tools

Very Simple Todo is also an MCP server, for Claude and any other client that speaks the Model Context Protocol. Same person, same todos, same rules as the API below.

https://verysimpletodo.com/mcp

Add it to Claude:

  1. Open Customize, then Connectors.
  2. Press the + button and choose Add custom connector.
  3. Paste https://verysimpletodo.com/mcp and press Add.
  4. Sign in with Apple or Google, with the account you use in the app.

Free Claude plans can add one custom connector.

Other MCP clients find the sign-in on their own. /mcp answers 401 with a pointer to /.well-known/oauth-protected-resource; the client registers itself at /oauth/register, uses PKCE, and sends the person to sign in. The token it gets shows up in the app under Account, where it can be revoked.

Tools:

  • list_todos: open, done or all todos.
  • read_todo: one todo with its Markdown body.
  • create_todo: add a todo (title required).
  • edit_todo: title, body, done or star.
  • set_done: check off or reopen.
  • delete_todo: delete for good, only when the person asks.

Authentication

Every call to /api/v1 needs a personal API token as a Bearer token. The token is scoped to one person. They can revoke it in the app under Account. Tokens do not expire on their own.

Authorization: Bearer TOKEN

Reading never needs a subscription. Creating a todo and PATCH need an active subscription; without one those answer 402 with subscription_required. Checking off and unchecking always work, even if the plan has lapsed.

How to behave

  • One todo per thing. "Buy milk and call mum" is two todos.
  • Keep titles short. A title is one line the person reads at a glance.
  • Put details in the body as Markdown.
  • Check off only what the person says is done. Never guess.
  • Delete only when the person asks, for example a duplicate. If something is finished, check it off.
  • Read the open list before adding, so you do not create duplicates.
  • Star (important: true) only when the person calls it urgent.

GET /me

Connect check. Who this token belongs to.

GET https://verysimpletodo.com/api/v1/me
Authorization: Bearer TOKEN
{
  "id": "…",
  "email": "…",
  "name": "…"
}

DELETE /me

Revoke this token. Call it before you store a new one on reconnect, so Account does not fill with dead rows. A token that is already gone answers 401, which is the same end state.

DELETE https://verysimpletodo.com/api/v1/me
Authorization: Bearer TOKEN
{ "ok": true }

GET /todos

List todos. Query filter=open|done|all (default open). Starred first, then most recently updated. preview is the first plain line of the body, not the full Markdown.

GET https://verysimpletodo.com/api/v1/todos?filter=open
Authorization: Bearer TOKEN
{
  "todos": [
    {
      "id": "…",
      "title": "Buy milk",
      "preview": "oat",
      "done": false,
      "doneAt": null,
      "important": false,
      "updatedAt": "2026-09-11T12:00:00.000Z"
    }
  ]
}

GET /todos/:id

One todo, including the Markdown body.

GET https://verysimpletodo.com/api/v1/todos/TODO_ID
Authorization: Bearer TOKEN
{
  "id": "…",
  "title": "Buy milk",
  "body": "- [ ] oat\n- [ ] whole",
  "done": false,
  "doneAt": null,
  "important": false,
  "createdAt": "2026-09-01T09:00:00.000Z",
  "updatedAt": "2026-09-11T12:00:00.000Z"
}

POST /todos

Create a todo. Body { title, body? }. title is required. Needs an active subscription.

POST https://verysimpletodo.com/api/v1/todos
Authorization: Bearer TOKEN
Content-Type: application/json

{ "title": "Book dentist", "body": "Call Dr Lind before Friday." }

Returns the full todo, 201.

PATCH /todos/:id

Update a todo. Send only the fields you want to change: title, body, done, important. Needs an active subscription, even if you only send done. For check-offs, use the done and undone verbs instead; those work without a subscription.

PATCH https://verysimpletodo.com/api/v1/todos/TODO_ID
Authorization: Bearer TOKEN
Content-Type: application/json

{ "important": true }

Returns the full todo.

POST /todos/:id/done

Check a todo off. It leaves the open list. Always allowed.

POST https://verysimpletodo.com/api/v1/todos/TODO_ID/done
Authorization: Bearer TOKEN

POST /todos/:id/undone

Put a done todo back on the open list. Always allowed.

POST https://verysimpletodo.com/api/v1/todos/TODO_ID/undone
Authorization: Bearer TOKEN

DELETE /todos/:id

Permanently delete a todo, only when the person asks for it: a duplicate you just added, or something they want gone. A finished todo is checked off, not deleted.

DELETE https://verysimpletodo.com/api/v1/todos/TODO_ID
Authorization: Bearer TOKEN
{ "ok": true }

Markdown

body is Markdown. The person never sees the syntax; the app renders it. When you write, use:

  • **bold** and *italic*
  • - bullets and 1. numbered
  • - [ ] unchecked and - [x] checked checklist items

Errors

  • 401 missing or bad token ({"error":"Unauthorized"})
  • 402 write without a subscription ({"error":"subscription_required"})
  • 400 bad body ({"error":"title required"} or {"error":"Invalid body"})
  • 404 no such todo

OAuth 2.0

An app can obtain a token without a paste. The person signs in on verysimpletodo.com; your server swaps the code for the same kind of personal API token. Discovery: /.well-known/oauth-authorization-server.

GET https://verysimpletodo.com/oauth/authorize
  ?client_id=…
  &redirect_uri=…
  &response_type=code
  &state=…
  &code_challenge=…
  &code_challenge_method=S256

POST https://verysimpletodo.com/oauth/token
  grant_type=authorization_code
  code=…
  redirect_uri=…
  client_id=…
  client_secret=…
  code_verifier=…

→ { "access_token": "…", "token_type": "Bearer", "scope": "todos" }

PKCE S256 is supported. Optional label on authorize names the token in Account (for example Agent Heim · Freja). MCP clients register themselves at /oauth/register and must use PKCE. Other apps can still ask us for a client_id: email verysimple@portfoliobox.net. Agent Heim is already registered.