{"id":44998799,"url":"https://github.com/c00llin/thingstodo","last_synced_at":"2026-04-02T17:52:48.101Z","repository":{"id":338761066,"uuid":"1158697644","full_name":"c00llin/thingstodo","owner":"c00llin","description":"Self-hosted Things 3 / Todoist inspired task manager","archived":false,"fork":false,"pushed_at":"2026-03-25T20:12:58.000Z","size":1487,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-26T19:59:18.296Z","etag":null,"topics":["self-host","self-hosted","selfhosted","task-list","task-management","tasks-manager","things3","todoist"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/c00llin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-15T19:28:35.000Z","updated_at":"2026-03-25T20:13:03.000Z","dependencies_parsed_at":"2026-03-11T20:01:23.277Z","dependency_job_id":null,"html_url":"https://github.com/c00llin/thingstodo","commit_stats":null,"previous_names":["c00llin/thingstodo"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/c00llin/thingstodo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c00llin%2Fthingstodo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c00llin%2Fthingstodo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c00llin%2Fthingstodo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c00llin%2Fthingstodo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/c00llin","download_url":"https://codeload.github.com/c00llin/thingstodo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/c00llin%2Fthingstodo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31312744,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-02T12:59:32.332Z","status":"ssl_error","status_checked_at":"2026-04-02T12:54:48.875Z","response_time":89,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["self-host","self-hosted","selfhosted","task-list","task-management","tasks-manager","things3","todoist"],"created_at":"2026-02-18T22:03:43.021Z","updated_at":"2026-04-02T17:52:48.094Z","avatar_url":"https://github.com/c00llin.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ThingsToDo\n\nA self-hosted, Things 3 / Todoist inspired task manager.\n\n![ThingsToDo screenshot](docs/screenshots/screenshot-light.png)\n\n## Features\n\n- **Offline-First** — all data stored locally in IndexedDB; create, edit, and complete tasks offline with automatic sync when online\n- **Projects \u0026 Areas** — organize tasks into projects (completable) and areas (ongoing)\n- **Tags** — flexible labeling with inline `#tag` syntax and customizable colors\n- **Review Tasks** — tasks not edited for a configurable number of days surface in a Review section in Inbox, so nothing falls through the cracks\n- **Checklists** — subtasks within any task\n- **File Attachments \u0026 Links** — attach files or URLs to tasks\n- **Multi-Date Scheduling** — schedule tasks across multiple dates with optional start/end times (up to 12 entries per task)\n- **Repeating Tasks** — daily, weekly, monthly, and custom schedules\n- **Natural Language Dates** — type \"tomorrow\", \"next friday\", etc.\n- **Keyboard-Driven** — full keyboard navigation and shortcuts\n- **Filters** — filter any view by area, project, tag, priority, date, and deadline with saved filter presets\n- **Search** — full-text search across tasks and notes\n- **Privacy Mode** — blur task titles, notes, and project/area/tag names to prevent over-the-shoulder reading\n- **Dark Mode** — automatic or manual theme switching\n- **Reminders** — per-task reminders with relative (e.g. 15 min before) and exact time options, plus configurable defaults\n- **Push Notifications** — reminders via Browser Push (VAPID) or [ntfy](https://ntfy.sh), configurable in Settings\n- **PWA** — installable on mobile and desktop with offline support\n- **Single Binary** — Go backend with embedded SPA frontend, SQLite database\n- **Sync** — bidirectional push/pull sync with last-write-wins conflict resolution; works across multiple devices\n\n### Offline Limitations\n\nMost features work fully offline. The following require an internet connection:\n\n- **Recurring task rules** — creating, editing, or deleting repeat rules (the recurrence engine runs server-side)\n- **File uploads** — uploading new file attachments (requires server-side multipart processing)\n- **Search** — full-text search uses server-side FTS5; offline search falls back to basic string matching\n- **Settings changes** — user settings are not stored locally and will be lost if changed offline\n- **Saved filters** — creating or deleting saved filter presets\n- **Reminder scheduling** — the reminder scheduler runs server-side; reminders set offline will fire after sync\n- **Logbook/Trash pagination** — local views load all entries (no pagination); may be slow with very large histories\n\n## Quick Start\n\n```yaml\n# docker-compose.yml\nservices:\n  app:\n    image: ghcr.io/c00llin/thingstodo:latest\n    container_name: thingstodo\n    volumes:\n      - ./data:/data\n    ports:\n      - \"2999:2999\"\n    environment:\n      - AUTH_MODE=builtin\n      - JWT_SECRET=change-me-to-a-random-string\n      - LOGIN_PASSWORD=your-password-here\n    restart: unless-stopped\n```\n\n```sh\ndocker compose up -d\n```\n\nOpen [http://localhost:2999](http://localhost:2999) and log in with the password you set.\n\n## Configuration\n\n| Variable | Default | Description |\n|---|---|---|\n| `PORT` | `2999` | Server port (must match container port) |\n| `LOG_LEVEL` | `info` | Log level |\n| `MAX_UPLOAD_SIZE` | `26214400` | Max file upload size in bytes (25 MB) |\n| `AUTH_MODE` | `builtin` | Auth mode: `builtin`, `proxy`, or `oidc` |\n| `TZ` | `UTC` | Timezone for reminder scheduling (e.g. `Europe/Amsterdam`) |\n\n### Builtin Auth\n\n| Variable | Default | Description |\n|---|---|---|\n| `JWT_SECRET` | — | Secret for signing JWT tokens (required) |\n| `LOGIN_PASSWORD` | — | Seeds an \"admin\" user on first start |\n\n### Proxy Auth\n\nFor use behind an authenticating reverse proxy (Authelia, Authentik, etc.).\n\n| Variable | Default | Description |\n|---|---|---|\n| `AUTH_PROXY_HEADER` | `Remote-User` | Header containing the authenticated username |\n\n### OIDC Auth\n\nLog in via any OpenID Connect provider (Google, Keycloak, Authelia, etc.). On first login the existing user is automatically linked to your OIDC identity. Only a single user is allowed — other OIDC accounts are rejected.\n\n| Variable | Default | Description |\n|---|---|---|\n| `JWT_SECRET` | — | Secret for signing JWT tokens (required) |\n| `OIDC_ISSUER` | — | OIDC provider URL (e.g. `https://auth.example.com`) |\n| `OIDC_CLIENT_ID` | — | OAuth2 client ID |\n| `OIDC_CLIENT_SECRET` | — | OAuth2 client secret |\n| `OIDC_REDIRECT_URI` | — | Callback URL: `https://your-domain/api/auth/oidc/callback` |\n\n### API Key\n\nEnable external access (e.g. iOS Shortcuts) with a static API key alongside any auth mode.\n\n| Variable | Default | Description |\n|---|---|---|\n| `API_KEY` | — | Static bearer token for `Authorization: Bearer \u003ckey\u003e` |\n\n### Notifications\n\nPush notifications for task reminders can be delivered via **Browser Push** (default) or **[ntfy](https://ntfy.sh)**. Configure the provider in **Settings \u003e Notifications \u003e Delivery**.\n\n\u003e **Important:** Set the `TZ` environment variable (e.g. `TZ=America/Chicago`) so reminders fire at the correct local time. The Docker scratch image defaults to UTC.\n\n#### Browser Push (VAPID)\n\nVAPID keys are auto-generated on first start and stored in the database. You can also set them explicitly:\n\n| Variable | Default | Description |\n|---|---|---|\n| `VAPID_PRIVATE_KEY` | auto-generated | VAPID private key |\n| `VAPID_PUBLIC_KEY` | auto-generated | VAPID public key |\n| `VAPID_CONTACT` | — | Contact email for VAPID (e.g. `mailto:you@example.com`) |\n\n#### ntfy\n\nNo env vars required — ntfy is configured entirely from the Settings UI:\n\n- **Server URL** — defaults to `https://ntfy.sh` (or your self-hosted instance)\n- **Topic** — defaults to `thingstodo`; subscribe to this topic in the ntfy app on your phone/desktop\n- **Access Token** — only needed if your ntfy server requires authentication\n- **Base URL** — your app's public URL (e.g. `https://tasks.example.com`) for click-through links in notifications\n\nUse the **Send Test** button to verify your setup.\n\n## MCP Server (Claude Code Integration)\n\nThingsToDo includes an MCP (Model Context Protocol) server that lets you manage tasks directly from Claude Code or any MCP-compatible client. The server exposes 40+ tools covering views, tasks, projects, areas, tags, headings, checklists, attachments, and schedules.\n\n### Setup\n\n1. Set an `API_KEY` in your ThingsToDo environment\n2. Build the MCP server:\n   ```sh\n   cd mcp \u0026\u0026 npm install \u0026\u0026 npm run build\n   ```\n3. Add to your Claude Code MCP config (e.g. `~/.claude/settings.json`):\n   ```json\n   {\n     \"mcpServers\": {\n       \"thingstodo\": {\n         \"command\": \"node\",\n         \"args\": [\"/path/to/thingstodo/mcp/dist/index.js\"],\n         \"env\": {\n           \"THINGSTODO_URL\": \"http://localhost:2999\",\n           \"THINGSTODO_API_KEY\": \"your-api-key\"\n         }\n       }\n     }\n   }\n   ```\n\n### Available Tools\n\n| Domain | Tools | Description |\n|---|---|---|\n| Views | `get_today`, `get_upcoming`, `get_inbox`, `get_anytime`, `get_someday`, `get_logbook` | Read task views |\n| Tasks | `search_tasks`, `get_task`, `create_task`, `update_task`, `complete_task`, `cancel_task`, `wontdo_task`, `reopen_task`, `delete_task`, `purge_task`, `restore_task` | Full task CRUD |\n| Bulk | `bulk_action` | Apply actions to multiple tasks |\n| Projects | `list_projects`, `get_project`, `create_project`, `update_project`, `delete_project` | Manage projects |\n| Areas | `list_areas`, `get_area`, `create_area`, `update_area`, `delete_area` | Manage areas |\n| Tags | `list_tags`, `create_tag`, `update_tag`, `delete_tag` | Manage tags |\n| Headings | `list_headings`, `create_heading`, `update_heading`, `delete_heading` | Project sub-sections |\n| Checklists | `add_checklist_item`, `update_checklist_item`, `delete_checklist_item` | Task sub-items |\n| Attachments | `add_link`, `delete_attachment` | Link management |\n| Schedules | `add_schedule`, `update_schedule`, `delete_schedule` | Multi-date scheduling |\n\n## Development\n\n```sh\n# Clone and configure\ncp .env.example .env   # edit JWT_SECRET and LOGIN_PASSWORD\n\n# Run backend (port 2999) + frontend dev server (port 5173)\nmake dev\n```\n\nThe Vite dev server on port 5173 proxies API requests to the Go backend and provides hot reload.\n\n## License\n\nAGPL-3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc00llin%2Fthingstodo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fc00llin%2Fthingstodo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fc00llin%2Fthingstodo/lists"}