What it is
Three Days is a small Model Context Protocol server that stores one daily summary per person and hands it to the Three Days apps. An assistant such as Claude or ChatGPT connects to it as a custom connector, and a scheduled task in that assistant writes the summary each morning. The server never reads your mail or calendar; the assistant does, inside your own account, and sends only the finished document here.
| Endpoint | https://threedays.net/mcp |
|---|---|
| Transport | Streamable HTTP, MCP specification 2026-07-28 (stateless). Older clients that still send an initialize handshake are accepted. |
| Server name | three-days |
| Tools | get_instructions, publish_daily_summary, get_daily_summary, search, fetch |
| Scope | summary (the only scope; it covers every tool) |
Signing in
OAuth 2.1 (Claude, ChatGPT, any modern client)
Add the endpoint above as a custom connector and choose OAuth. The server supports PKCE, dynamic client registration (/register) and Client ID Metadata Documents, and publishes the usual discovery documents under /.well-known/. When the assistant connects, you are sent to a consent page showing a six-character code. Approve it in the Three Days app (tap Open Three Days on the page, or enter the code under Settings → Approve a connection), or sign in with Apple on the page itself. The assistant then receives a token tied to your account, and it appears under Connected apps in the app, where it can be disconnected at any time.
Personal no-sign-in URL
For connectors that cannot complete OAuth, the app can show a personal URL of the form https://threedays.net/mcp/<token>. It behaves like the main endpoint with the token supplied in the path. Anyone holding it can publish to your summary, so treat it as a secret; the app can replace it at any time, which invalidates the old one.
Tools
get_instructions
Read-only, no arguments. Returns the current publishing instructions as text: what to gather (calendar for today and tomorrow, mail from the last 36 hours, unanswered Slack messages), how to write each section, and how to confirm the publish. A scheduled task should call this first on every run and follow what it returns, so the task's own prompt can stay three lines long and never needs editing when the instructions change.
Prepare my Three Days summary. First call the Three Days connector's get_instructions tool and follow the instructions it returns exactly, using only the connectors attached to this task. Finish by confirming the publish as those instructions describe.
publish_daily_summary
Replaces the published summary with a complete document for one date. Every section must be present (empty arrays are fine). The server validates the document, stamps generatedAt, stores it as the latest summary and as that date's copy, sends a push to your devices, and returns the stored document plus the URL the apps read it from. Publishing again for the same date overwrites; the tool is idempotent.
| Argument | Meaning |
|---|---|
date | The local date the summary is for, YYYY-MM-DD. |
timezone | IANA zone the times are in, for example America/New_York. |
headline | Optional one sentence describing the shape of today. |
tomorrowHeadline | Optional one sentence describing the shape of tomorrow. |
sections.urgentToday | Items that must be handled today, highest priority first. |
sections.scheduleToday | Every event today, in time order, all-day items first. |
sections.importantYesterday | Decisions, results, or messages from yesterday worth remembering. |
sections.scheduleTomorrow | Every event tomorrow, in time order. |
sections.importantTomorrow | Preparation needed for tomorrow and anything notable that is not an event. |
get_daily_summary
Read-only. Returns the published document. Pass date as YYYY-MM-DD to read a specific day, or omit it (or pass latest) for the newest publish. The result is { found, summary }. Scheduled tasks use it to confirm a publish; a chat can use it to answer "what is on my summary today?".
search and fetch
Read-only. These exist because some ChatGPT connector modes require every connector to offer this pair. search takes a query (latest, today, a YYYY-MM-DD date, or free text) and returns document stubs (id, title, url). fetch takes one id (a date, or latest) and returns the full document as text with title, url, and metadata. They expose exactly what get_daily_summary exposes, in the shape those clients expect.
The summary document
One JSON document per day. The server adds schemaVersion and generatedAt; everything else comes from the assistant.
{
"schemaVersion": 1,
"generatedAt": "2026-09-22T10:05:12Z",
"date": "2026-09-22",
"timezone": "America/New_York",
"headline": "Two urgent items; light afternoon.",
"tomorrowHeadline": "Early flight; pack tonight.",
"sections": {
"urgentToday": [ { "title": "…", "detail": "…", "source": "gmail", "priority": "high", "link": "https://…" } ],
"scheduleToday": [ { "title": "…", "time": "09:00", "endTime": "09:30", "location": "…", "detail": "…" },
{ "title": "Holiday", "allDay": true } ],
"importantYesterday": [ { "title": "…", "detail": "…", "source": "slack" } ],
"scheduleTomorrow": [ { "title": "…", "time": "07:10", "endTime": "10:40", "location": "IAD → DEN" } ],
"importantTomorrow": [ { "title": "…", "detail": "…", "priority": "medium" } ]
}
}
| Item field | Notes |
|---|---|
title | Required, one line. |
detail | Optional second line: why it matters or what to do. |
source | Optional origin, for example gmail, calendar, slack. |
priority | Optional high, medium, or low; shown as a coloured dot. |
link | Optional deep link to the underlying message or event. |
| Schedule field | Notes |
time, endTime | Local 24-hour HH:MM. Omit time for all-day entries. |
allDay | Optional flag; all-day entries sort first. |
location, detail, link | Optional. |
Limits: up to 50 entries per section, short titles, and a longer free-text detail. Anything outside the schema is rejected with a validation error rather than stored.
Retention and delivery
- Latest is kept until the next publish replaces it. Dated copies expire after three days, which is what makes the Yesterday tab work.
- Push: every publish sends a silent push to each registered iPhone and Mac so the app and widget refresh, and a visible notification with the headline to devices that opted in.
- Welcome document: a new account receives a starter summary that walks through the setup, so the app has content before the first real run.
The app API
The iPhone and Mac apps read summaries over plain JSON with their own bearer token, never over MCP. Listed here for completeness; it is not something an assistant needs.
| Request | Returns |
|---|---|
GET /api/summary/latest | The current document, with an ETag; If-None-Match yields 304. |
GET /api/summary/previous | The archived document from the day before the latest one. |
GET /api/summary/YYYY-MM-DD | A specific day, while it is still retained. |
GET /api/connections | The assistants connected through OAuth, each tagged Claude, ChatGPT, or other. |
DELETE /api/me | Deletes the account and everything stored for it (Settings → Account → Delete account). |