Get the apps

For agents and developers

Pinpal Todo API and MCP.

The MCP server for assistants, a REST API for your own code, the same sign-in and the same token. A short version for agents is at llms.txt.

Pinpal Todo connector address

https://todo.mypinpal.com/mcp

Paste it into Claude or ChatGPT as a custom connector and sign in with Apple or Google. Step by step · API and MCP reference

Pinpal Todo is a quiet list on the person's iPhone. 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 never delete. You never email them. The app will not do that either.

  • MCP server: https://todo.mypinpal.com/mcp. For Claude, ChatGPT and every other MCP client. Nothing to install; listed in the MCP Registry as com.verysimpletodo/mcp.
  • REST API: https://todo.mypinpal.com/api/v1, below. Same token.

Base URL: https://todo.mypinpal.com/api/v1. Auth: Authorization: Bearer TOKEN. A short copy of this page lives at /llms.txt.

Getting started in Claude

Add Pinpal Todo to Claude, and Claude can read your list, add to it and check things off when you say they are done.

  1. In Claude, open Customize, then Connectors.
  2. Press + and choose Add custom connector.
  3. Name it Pinpal Todo and paste https://todo.mypinpal.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 oat milk 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 ChatGPT, add https://todo.mypinpal.com/mcp as a connector the same way.

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

claude mcp add --transport http pinpal-todo https://todo.mypinpal.com/mcp

MCP server and tools

Server URL: https://todo.mypinpal.com/mcp (Streamable HTTP). Any MCP client that supports OAuth connects on its own: a call without a token answers 401 and points at /.well-known/oauth-protected-resource, the client registers itself and sends the person to sign in with Apple or Google. A token pasted from the app works too, as Authorization: Bearer TOKEN.

  • get_account: who the connection belongs to.
  • list_todos: open, done or all todos, starred first.
  • get_todo: one todo with its full Markdown notes.
  • add_todo: add a todo with a title and optional notes.
  • edit_todo: change the title, the notes or the star.
  • complete_todo: check a todo off.
  • reopen_todo: put a done todo back on the list.

There is no delete tool: an agent checks things off, the person deletes in the app. The tools follow the same rules as the REST API below: everything works on the free plan except adding a todo past the person's 20 free open todos.

REST API quickstart

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

  1. 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.
  2. If you do not, ask them to open Pinpal Todo on iPhone, go to Account, create a token, and paste it to you.
  3. Call GET /api/v1/me with that token. If it returns the person, you are connected.
  4. List open todos, add new ones, check them off when the person says they are done. Never delete.
curl https://todo.mypinpal.com/api/v1/me \
  -H "Authorization: Bearer TOKEN"

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

Pinpal Todo is free for up to 20 open todos (checked-off ones do not count). Only creating a todo past that needs the person's subscription; it answers 402 with free_limit_reached and a message to relay to the person. Reading, editing, checking off and unchecking always work.

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.
  • Never delete. If something should leave the list, check it off, or ask.
  • 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://todo.mypinpal.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://todo.mypinpal.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://todo.mypinpal.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://todo.mypinpal.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. Past the free open todos, without a subscription, this answers 402.

POST https://todo.mypinpal.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. For check-offs, the done and undone verbs are clearer.

PATCH https://todo.mypinpal.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://todo.mypinpal.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://todo.mypinpal.com/api/v1/todos/TODO_ID/undone
Authorization: Bearer TOKEN

DELETE /todos/:id

Permanently delete a todo. This exists on the server so the person can delete from the app. Agents must not call it. Check the todo off instead, or ask.

DELETE https://todo.mypinpal.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 free plan full: a new todo past the 20 free ones without a subscription ({"error":"free_limit_reached","limit":20,"message":"..."}); relay the message, do not retry
  • 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 todo.mypinpal.com; your server swaps the code for the same kind of personal API token. Discovery: /.well-known/oauth-authorization-server.

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

POST https://todo.mypinpal.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 and other public apps register themselves at POST /oauth/register (dynamic client registration) and must use PKCE S256. Apps with their own server and a client secret can email hello@mypinpal.com. Agent Heim is already registered.