Service API
The WackyTracky backend exposes a Connect RPC API. The web app uses this API for all operations (lists, tasks, search, metadata, and more). You can call it from scripts, other applications, or a CLI using HTTP and JSON.
Base URL
When the server is running (e.g. on port 8080), the API base URL is:
http://<host>:<port>/api
Example: http://localhost:8080/api
Each RPC has a procedure path under this base. The full URL for a procedure is:
<base>/wackytracky.clientapi.v1.WackyTrackyClientService/<MethodName>
Example: http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/GetLists
Protocol
The service uses the Connect protocol (HTTP/JSON):
- Method:
POST - Request:
Content-Type: application/json, body is a JSON object with the request message fields (empty{}for empty requests). - Response:
Content-Type: application/json, body is a JSON object with the response message fields. - Errors: On failure, the server returns an appropriate HTTP status (e.g. 4xx/5xx) and a Connect error payload in JSON.
If your deployment uses HTTP authentication (e.g. the optional httpauthshim integration), include credentials in your requests (e.g. Authorization: Basic ... for Basic auth).
Quick start
Version (no arguments)
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/Version' \
-H "Content-Type: application/json" \
-d '{}'
Example response:
{"version":"1.9.0","commit":"abc123","date":"2025-01-15T12:00:00Z"}
Get lists
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/GetLists' \
-H "Content-Type: application/json" \
-d '{}'
Example response:
{"lists":[{"id":"list-id-1","title":"Inbox","countItems":5}]}
Create a task
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/CreateTask' \
-H "Content-Type: application/json" \
-d '{"content":"Buy milk #errands @home","parentListId":"<list-id>"}'
Use the list ID from GetLists. Omit parentListId to use the default list (implementation-dependent). Use parentTaskId to create a subtask.
Search tasks
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/SearchTasks' \
-H "Content-Type: application/json" \
-d '{"query":"#work -#done"}'
Query syntax is backend-dependent; the todo.txt backend supports plain terms, #tag, @context, and -term to exclude. See Search (SearchTasks) for details.
Mark a task done
curl -s -X POST 'http://localhost:8080/api/wackytracky.clientapi.v1.WackyTrackyClientService/DoneTask' \
-H "Content-Type: application/json" \
-d '{"id":"<task-id>"}'
Task IDs come from ListTasks or SearchTasks responses.
Reference
The full list of RPCs and request/response message types is in the API reference.
Machine-readable spec (OpenAPI)
A generated OpenAPI 3.1 description of every procedure and message is available at openapi.yaml. When the server is running, the same spec is also served at GET /openapi on your instance (e.g. http://localhost:8080/openapi). It is produced from the Protocol Buffers definition, so it always matches the running API. Use it to:
- Feed the API to tools like Swagger UI, Redoc, or Postman.
- Let an LLM or code generator discover endpoints, request/response shapes, and field types without reading prose.
Regenerate it with make in the protocol/ directory.
LLM discovery (llms.txt)
Running servers expose GET /llms.txt (e.g. http://localhost:8080/llms.txt) with a short guide for LLMs and automation: where to find the OpenAPI spec, how to call the HTTP API, and how to use the MCP server.
MCP server (for LLM assistants)
To let an LLM assistant (Claude Desktop, Cursor, etc.) read and manage your tasks directly, WackyTracky exposes an MCP server. When the HTTP server is running, connect at /mcp (Streamable HTTP). For local subprocess clients, use wt mcp over stdio.
Code generation
The API is defined with Protocol Buffers in protocol/wacky-tracky/clientapi/v1/wt.proto. You can generate client code using:
- Connect: connectrpc.com (Go, TypeScript/JavaScript, etc.)
- buf: buf.build with the Connect plugins
The web frontend uses the generated Connect-Web client; the Go server implements the same service.