Developers
Developer API
Four ways to work with Docket from code, from highest to lowest level:
| Interface | Best for | Auth |
|---|---|---|
| REST tools + OpenAPI | GPT actions, automations (n8n, Zapier, Make), quick scripts | Connector key (Bearer) |
| MCP | AI agents and MCP clients | Connector key or OAuth |
docket CLI with --json | Shell scripts on Windows | Docket settings |
| Vikunja REST API | Anything the tools don't cover | Vikunja API token |
The first two are served by docket-mcp --http (the Docker server runs it). They share one
implementation, so they always offer the same 26 tools with the same behaviour as the Docket apps: My Day, steps,
repeats and quick-add words work the same way everywhere. None of them delete.
#REST tools and OpenAPI
POST /api/tools/{tool}
Authorization: Bearer <connector key>
Content-Type: application/json
{ ...arguments }Replies:
| Status | Body | Meaning |
|---|---|---|
| 200 | {"result": "text"} | Done. The text is human-readable, with task ids as #123 |
| 400 | {"error": "..."} | Missing or wrongly typed argument |
| 401 | {"error": "unauthorized"} | Missing or wrong key |
| 404 | {"error": "..."} | No such tool |
| 422 | {"error": "..."} | Docket couldn't do it, e.g. "No task #99" |
GET /openapi.json (no auth) describes every tool, its arguments, types, defaults and which ones change data
(x-openai-isConsequential). It's generated from the code, so it's always current.
Examples:
KEY=your-connector-key; BASE=https://tasks.example.com
curl -s $BASE/api/tools/list_tasks -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"view":"today"}'
curl -s $BASE/api/tools/add_task -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"title":"Renew passport friday !3","project":"Home","labels":["Admin"]}'
curl -s $BASE/api/tools/complete_task -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"ids":[42]}'
curl -s $BASE/api/tools/set_reminder -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-d '{"id":42,"times":["tomorrow 9:00"]}'import requests
s = requests.Session()
s.headers["Authorization"] = "Bearer your-connector-key"
r = s.post("https://tasks.example.com/api/tools/my_day", json={"suggestions": True})
print(r.json()["result"])#Tool reference
Every tool, with its arguments and whether it changes data, is in the tool reference. It's generated
from the connector's source, so it matches /openapi.json. The tool name is the {tool} in the URL and the
arguments are the JSON body.
Dates accept 2026-11-20, 2026-11-20T15:00, today, tomorrow, weekdays (fri), in 3 days, 20/11
(day/month) or none to clear. Lists (projects) can be given by name or id. Quick-add words in titles (today,
tomorrow, a weekday, in 3 days, 20/11, !1 to !5) set the due date and priority and are removed from the title.
#MCP
Endpoint: POST /mcp, Streamable HTTP,
stateless (no session id needed). Or run docket-mcp with no arguments for stdio.
curl -s https://tasks.example.com/mcp -H "Authorization: Bearer $KEY" \
-H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_tasks","arguments":{"view":"overdue"}}}'Tool annotations follow the MCP spec: read tools are readOnlyHint: true; nothing is destructiveHint: true.
Errors come back as tool results with isError: true and a readable message.
#OAuth
For clients that need it, the connector is its own OAuth 2.1 authorization server:
| Endpoint | |
|---|---|
GET /.well-known/oauth-protected-resource | Resource metadata (RFC 9728); also linked from the 401 WWW-Authenticate header |
GET /.well-known/oauth-authorization-server | Server metadata (RFC 8414) |
POST /oauth/register | Dynamic client registration (RFC 7591). Redirects: localhost, or https on a DOCKET_OAUTH_REDIRECT_HOSTS host; up to 5 per client; 200 clients kept |
GET/POST /oauth/authorize | Sign-in page: the user types the connector key once. PKCE S256 required |
POST /oauth/token | authorization_code and refresh_token grants. Access tokens last 12 hours, refresh tokens 90 days and rotate on use |
Only SHA-256 hashes of tokens are stored (oauth.json in the data folder), and a new connector key revokes them all.
Ten wrong keys from one address (or 100 overall) in 15 minutes pause sign-in. Token responses are Cache-Control: no-store,
and the sign-in page can't be framed.
#CLI
The Windows docket command prints JSON with --json on any listing:
docket today --json | ConvertFrom-Json | Where-Object priority -ge 3
docket planned --json # [{ group: "Today", task: {...} }, ...]
docket show 42 --jsonTask objects look like:
{
"id": 42, "title": "Send invoice", "done": false, "project": "Work", "projectId": 3,
"due": "2026-11-20T17:00:00+00:00", "dueText": "Fri 20 Nov", "priority": 3, "column": "To-Do",
"important": true, "myDay": true,
"steps": [{ "Title": "Price it", "Done": true }], "repeat": "every week",
"nextReminder": "2026-11-20T09:00:00+00:00", "categories": ["Admin"]
}Run docket --help for every command. Exit code is 0 on success, 1 on errors, 2 on wrong usage.
#Vikunja API
Docket stores everything in plain Vikunja, so the Vikunja API (/api/v1, Swagger at
/api/v1/docs on your server) sees the same data. Make a token under Settings > API Tokens with only the
permissions you need. How Docket maps its features onto Vikunja:
| Docket | In Vikunja |
|---|---|
| Lists and groups | Projects; a group is a parent project |
| Important | is_favorite |
| My Day | The label "My Day"; its description holds the day it was last reset (Docket My Day yyyy-MM-dd) |
| Categories | Other labels |
| Steps | A task list (<ul data-type="taskList">) at the start of the description |
| Daily, weekly, every N days/weeks, monthly repeats | Vikunja's own repeat_after / repeat_mode |
| Weekdays, yearly, every N months/years repeats | A label starting with "↻" (handled when completed through Docket) |
| Reminders | reminders |
| Board columns | Kanban buckets of the project's Kanban view |
Changing tasks from another tool is fine; avoid renaming the "My Day" label or the "↻" labels.
#Building on Docket.Core
src/Docket.Core (.NET 10, no UI or platform code) holds the Vikunja client and all of Docket's behaviour
(DocketService, QuickAdd, RepeatRule, TaskNotes, TaskFormat). The apps, CLI and connector are thin layers on
it; reference it from your own .NET tool to get identical behaviour.