Todocko任务管理MCP服务器

Todocko MCP Server是一个模型上下文协议(MCP)服务器,让Claude等AI助手能够访问和管理Todocko的任务与项目数据,包括共享项目、工作日志、附件、标签和看板,适用于通过自然语言查看、创建、更新和同步项目数据。

  • by brnt-cz
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 brnt-cz/todocko-mcp

使用说明

Todocko MCP Server

English version below / Jump to English

MCP (Model Context Protocol) server pro práci s daty Todocko aplikace z AI asistentů.

Podpora

  • Claude Desktop - plná podpora
  • Claude Code (CLI) - plná podpora (stejná konfigurace)

Požadavky

  • Node.js 24.20+ — Evolu v8 to má v engines, a není to formalita: v8 stojí na navigator.locks, MessageChannel, BroadcastChannel a WebSocket, které má Node nativně teprve od 24
  • Todocko účet s daty synchronizovanými přes Evolu

Evolu v8 (TODO-88)

MCP běží na @evolu/common 8.23.2 a @evolu/nodejs 4.3.4. Upgrade z 8.22 (TODO-431) nevyžadoval změnu kódu; sync přes relay ověřen v obou směrech proti verzi 8.22.

Od Evolu 8.20.3 nese zápis do sdílené instance celého ownera, { owner: sharedOwner }, ne { ownerId }. Zapomenuté ownerId Evolu ignoruje a řádek zapíše pod jiného ownera, odkud se nenasynchronizuje. Hlídá to src/tools/sharedWrites.test.ts. Databázi, jejíž worker spadl, Evolu nově odmítne přes evoluError; td_sync_status ji ukáže v poli evoluError a nástroje na ni nečekají do timeoutu, hned řeknou, že je potřeba reconnect. (TODO-427)

v7 dodával createDbWorkerForPlatform, což bylo vše, co headless klient v Node potřeboval. v8 to zrušil: @evolu/nodejs v3 nabízí relay a pár primitiv, a jedinou kompletní klientskou platformu má upstream pro web. src/evoluPlatform.ts je protějšek pro Node, poskládaný ze stejných dílů.

Vyšel krátce, protože Node 24 má potřebná web API nativně. Oba workery běží in-process přes createWorker / createSharedWorker — to jsou vlastní fallbacky Evolu „pro platformy bez podpory workerů"; worker_threads by přinesly izolaci, kterou jednoprocesový CLI nepotřebuje.

Šest věcí, na kterých se to dá snadno rozbít:

  • Mutace má strop 640 000 bajtů (od 8.12). Větší zápis vyhodí výjimku ještě před uložením, takže se ani nenasynchronizuje. Přílohy se proto ukládají binárně a po kusech po 480 KiB (src/tools/attachmentChunks.ts), stejně jako v aplikaci; velikost kusu musí sedět s ní, jinak se příloha nahraná tady otevře jinde useknutá. Čtení umí i starý tvar, base64 v attachment.data, protože schéma je append-only.

  • installPolyfills() je povinné a musí proběhnout dřív než cokoli z @evolu/common. v8 volá Map.prototype.getOrInsert(Computed), které nemá žádný vydaný Node (ověřeno do 25.9.0). Bez toho to spadne na první zprávě.

  • Databáze patří jednomu mnemonicu. v7 při neshodě volal restoreAppOwner, který lokální databázi resetoval. v8 obnovu nemá, takže by v souboru zůstala data starého ownera zašifrovaná klíčem, který nový nemá. Server proto neshodu ohlásí a odmítne nastartovat — smaž ~/.todocko/todocko.db a nech ho stáhnout data znovu.

  • createNodeEvoluDeps() musí být singleton na proces. Shared worker drží jediný tabLeaderPortStore a initDbWorker každého tenanta předpokládá, že je už naplněný. Druhá sada deps znamená druhý shared worker, kterému nikdo leadera neohlásil, a vytvoření sdílené instance spadne na initDbWorker: Expected value to be non-nullable. Jeden worker obslouží obě instance jako dva tenanty podle appName, stejně jako @evolu/web na jedné stránce.

  • Mutace nevrací Result. v7 vracel z insert/update Result, takže se testovalo result.ok a čtlo result.value.id. v8 vrací přímo { id } a při neplatné změně vyhodí výjimku. Kontrola !result.ok proto uspěla vždy a nástroj ohlásil chybu u zápisu, který právě proběhl. U vkládání je to horší, protože uživatel to zkusí znovu a vznikne duplicita. Hlídá to src/tools/pure.test.ts.

  • Ownera filtrovat v SQL, ne až v JS. Sdílená instance drží data všech ownerů v jedné tabulce. limit provede SQLite dřív, než se v JS cokoli filtruje, takže nezúžený dotaz vrátí prvních N řádků přes všechny ownery a filtr je pak zahodí. Nástroj hlásil nula úkolů u projektu, který jich má 26. Stejná past číhá u orderBy position desc limit 1 při výpočtu další pozice.

Instalace

1. Stažení

Pomocí git:

git clone https://github.com/brnt-cz/todocko-mcp.git
cd todocko-mcp

Nebo stáhněte ZIP z Releases a rozbalte.

2. Spuštění instalátoru

Linux/macOS:

chmod +x install.sh
./install.sh

Windows (PowerShell):

.\install.ps1

Instalátor:

  1. Nainstaluje závislosti a sestaví projekt
  2. Zeptá se, zda chcete nakonfigurovat Claude Desktop, Claude Code nebo obojí
  3. Vytvoří konfigurační soubor s placeholderem
  4. Ručně doplňte svou 24slovnou zálohovací frázi do konfiguračního souboru
  5. Restartujte Claude

Manuální instalace

  1. Nainstalujte závislosti:

    npm install
    npm run build
    
  2. Přidejte do konfigurace:

Claude Desktop (~/.config/Claude/claude_desktop_config.json na Linuxu nebo ~/Library/Application Support/Claude/claude_desktop_config.json na macOS):

{
  "mcpServers": {
    "todocko": {
      "command": "node",
      "args": ["/cesta/k/mcp-server/dist/index.js"],
      "env": {
        "TODOCKO_MNEMONIC": "vaše 24slovná zálohovací fráze"
      }
    }
  }
}

Claude Code (CLI) - přidejte do ~/.claude/settings.json:

{
  "mcpServers": {
    "todocko": {
      "command": "node",
      "args": ["/cesta/k/mcp-server/dist/index.js"],
      "env": {
        "TODOCKO_MNEMONIC": "vaše 24slovná zálohovací fráze"
      }
    }
  }
}
  1. Restartujte Claude Desktop / Claude Code

Dostupné nástroje (157)

Projekty

Nástroj Popis
td_list_projects Seznam všech projektů
td_get_project Detail projektu podle ID nebo kódu
td_create_project Vytvoření nového projektu (kód jen A-Z a 0-9, jako v appce)
td_update_project Aktualizace projektu (name, code, color, isArchived, autoApproveMembers, isHiddenFromFilters; kód jen A-Z a 0-9)
td_delete_project Smazání projektu (soft delete)

Úkoly

Nástroj Popis
td_list_tasks Seznam úkolů s filtry (projekt, status, priorita, assignee)
td_get_task Detail úkolu podle ID nebo kódu (např. PROJ-123), včetně nastavení opakování
td_create_task Vytvoření nového úkolu (včetně recurrence, sprintNumber, parentTaskId)
td_update_task Aktualizace existujícího úkolu (včetně recurrence, sprintNumber, parentTaskId)
td_search_tasks Vyhledávání úkolů podle textu
td_bulk_update_tasks Hromadná aktualizace více úkolů (včetně sprintNumber)
td_bulk_delete_tasks Hromadné smazání více úkolů
td_delete_task Smazání jednoho úkolu (soft delete, kaskáda na worklogy a přílohy)
td_list_git_events Git aktivita pro úkol (commits, PR) z relay serveru

Uživatelé

Nástroj Popis
td_list_users Seznam všech uživatelů
td_get_user Detail uživatele
td_create_user Vytvoření nového uživatele
td_update_user Aktualizace uživatele
td_delete_user Smazání uživatele (soft delete)

Worklogy

Nástroj Popis
td_list_worklogs Seznam worklogů pro úkol
td_add_worklog Přidání worklogu k úkolu
td_update_worklog Aktualizace worklogu
td_delete_worklog Smazání worklogu (soft delete)

Přílohy

Nástroj Popis
td_upload_attachment Nahrání přílohy k úkolu (ze souboru nebo base64)
td_list_attachments Seznam příloh úkolu
td_download_attachment Stažení přílohy
td_delete_attachment Smazání přílohy
td_upload_note_attachment Nahrání přílohy k lokální poznámce projektu
td_list_note_attachments Seznam příloh lokální poznámky
td_download_note_attachment Stažení přílohy poznámky
td_delete_note_attachment Smazání přílohy poznámky

Komentáře

Nástroj Popis
td_list_task_comments Seznam komentářů k úkolu
td_create_task_comment Přidání komentáře k úkolu
td_update_task_comment Úprava komentáře
td_delete_task_comment Smazání komentáře (soft delete)

Checklist

Nástroj Popis
td_list_checklist_items Seznam položek checklistu úkolu
td_create_checklist_item Přidání položky checklistu
td_update_checklist_item Aktualizace položky (zaškrtnutí, pozice)
td_delete_checklist_item Smazání položky (soft delete)

Zmínky (mentions)

Nástroj Popis
td_list_mentions Seznam zmínek uživatele
td_create_mention Vytvoření zmínky
td_mark_mention_read Označení zmínky jako přečtené
td_mark_all_mentions_read Označení všech zmínek jako přečtených
td_delete_mention Smazání zmínky (soft delete)

Linky mezi úkoly

Nástroj Popis
td_list_app_settings Nastavení účtu, která se přenášejí mezi zařízeními
td_set_app_setting Nastavení jedné hodnoty na účtu
td_list_task_links Seznam linků úkolu
td_create_task_link Vytvoření linku mezi úkoly (blocks, explicit, mention, relates, duplicate)
td_delete_task_link Smazání linku (soft delete)

Tagy

Nástroj Popis
td_list_tags Seznam štítků; vrací projectId, umí filtrovat podle projektu i na nezařazené
td_create_tag Vytvoření štítku — předej projectId, viz poznámku níž
td_update_tag Přejmenování, změna barvy, přiřazení projektu, nebo příznak výchozího štítku
td_delete_tag Smazání štítku (soft delete)
td_list_task_tags Seznam štítků přiřazených k úkolu
td_add_tag_to_task Přiřazení štítku k úkolu
td_remove_tag_from_task Odebrání štítku z úkolu

Sdílené projekty (TODO-235):

Nástroj Popis
td_list_shared_tags Štítky ve sdíleném projektu
td_create_shared_tag Vytvoření štítku ve sdíleném projektu
td_update_shared_tag Přejmenování / změna barvy / příznak výchozího štítku
td_delete_shared_tag Smazání (soft delete)
td_add_shared_tag_to_task Přiřazení k úkolu ve sdíleném projektu
td_remove_shared_tag_from_task Odebrání z úkolu

Štítek bez projektu appka nikde nenabídne. Od TODO-227 jsou štítky vázané na projekt; td_create_tag bez projectId vyrobí nezařazený štítek, který se v appce objeví jen v nastavení projektu v sekci „Nezařazené" s tlačítkem na přiřazení. Odpověď nástroje na to upozorní. Dodatečně to spraví td_update_tag s projectId.

Limity free tarifu (TODO-243). Tarifní limity patří do appky, ne sem. td_create_task a td_create_project proto do odpovědi přilepí varování s reálným počtem, když je owner na free tarifu a je nad limitem (1 projekt, 50 aktivních úkolů). Jde o to, aby se to člověk dozvěděl při zakládání, ne až zpětně v appce, a aby z textu bylo jasné, že o nic nepřišel. Nic to neblokuje a při neznámém tarifu (nedostupný relay) radši mlčí — falešný poplach je horší než žádný.

Výchozí štítky (TODO-239). isDefault u td_create_tag / td_update_tag (a sdílených variant) znamená, že štítek dostane každý nově zakládaný úkol projektu. td_create_task i td_create_shared_task je přidávají samy a vrátí je v appliedTags — appka je předzaškrtává v modalu, takže bez toho by výsledek závisel na tom, odkud úkol vznikne. Existujících úkolů se to nedotkne.

Ve sdílených projektech se zapisuje do jiné Evolu instance, proto samostatná sada nástrojů — td_add_tag_to_task na sdílený úkol nefunguje.

Šablony úkolů

Nástroj Popis
td_list_task_templates Seznam šablon úkolů
td_create_task_template Vytvoření šablony (volitelně checklistItems a tagIds)
td_update_task_template Aktualizace šablony (checklistItems, tagIds; prázdné pole maže)
td_delete_task_template Smazání šablony (soft delete)

Kanban sloupce

Nástroj Popis
td_list_kanban_columns Seznam kanban sloupců
td_create_kanban_column Vytvoření sloupce (volitelně wipLimit, max. úkolů na uživatele v In progress před varováním v hlavičce)
td_update_kanban_column Aktualizace sloupce (wipLimit: null limit zruší)
td_delete_kanban_column Smazání sloupce (soft delete)

Uložená zobrazení

Nástroj Popis
td_list_saved_views Seznam uložených zobrazení
td_create_saved_view Vytvoření zobrazení
td_update_saved_view Aktualizace zobrazení
td_delete_saved_view Smazání zobrazení (soft delete)

Aktivita

Nástroj Popis
td_list_activity_log Seznam zápisů aktivity s filtry (úkol, aktor, akce, typ entity, datum od/do) — read-only

Poznámky k projektu

Nástroj Popis
td_list_project_notes Seznam lokálních poznámek projektu
td_create_project_note Vytvoření lokální poznámky
td_update_project_note Aktualizace lokální poznámky
td_delete_project_note Smazání lokální poznámky (soft delete)

Dokumentace projektu

Dokumenty jsou poznámky s isDoc, takže mohou být zanořené pod jiný dokument (parentDocId).

Nástroj Popis
td_list_project_docs Seznam dokumentů projektu
td_create_project_doc Vytvoření dokumentu
td_update_project_doc Aktualizace dokumentu
td_delete_project_doc Smazání dokumentu (soft delete)

Systémová oznámení (relay)

Broadcast oznámení pro všechny uživatele. Zápis a výpis včetně expirovaných vyžaduje TODOCKO_RELAY_ADMIN_KEY; obráceným směrem jdou zprávy od uživatelů, viz níž.

Bez TODOCKO_RELAY_ADMIN_KEY se td_create_system_notification a td_delete_system_notification klientovi vůbec nenabízejí (nemohly by nic jiného než vrátit 401) a u výpisu zmizí přepínač admin. Klíč se navíc nikdy neposílá přes nešifrované http:// jinam než na localhost. (TODO-441)

Nástroj Popis
td_list_system_notifications Seznam aktivních oznámení (s admin: true i expirovaná)
td_create_system_notification Vytvoření oznámení pro všechny uživatele
td_delete_system_notification Smazání oznámení

Deployment stages

Nástroj Popis
td_list_deployment_stages Seznam deployment stages pro projekt
td_create_deployment_stage Vytvoření deployment stage
td_update_deployment_stage Aktualizace deployment stage
td_delete_deployment_stage Smazání deployment stage (soft delete)

Repository linky

Nástroj Popis
td_list_repository_links Seznam repozitářových linků
td_create_repository_link Vytvoření repozitářového linku
td_update_repository_link Aktualizace repozitářového linku
td_delete_repository_link Smazání repozitářového linku

Sdílené projekty

Nástroj Popis
td_list_shared_projects Seznam sdílených projektů s vaším oprávněním (ownerSecret už nevrací)
td_list_shared_tasks Seznam úkolů ze sdíleného projektu
td_create_shared_task Vytvoření úkolu ve sdíleném projektu (auto-generovaný kód)
td_update_shared_task Aktualizace úkolu ve sdíleném projektu (všechna pole včetně recurrence, estimate, blocking)
td_delete_shared_task Smazání úkolu ve sdíleném projektu (soft delete, kaskáda na checklist)
td_update_shared_project Aktualizace sdíleného projektu: název, kód, barva, archivace, skrytí z filtrů, automatické schvalování členů
td_list_shared_worklogs Seznam worklogů úkolu ve sdíleném projektu
td_add_shared_worklog Přidání worklogu k úkolu ve sdíleném projektu
td_delete_shared_worklog Smazání worklogu ve sdíleném projektu
td_list_shared_checklist_items Seznam položek checklistu úkolu ve sdíleném projektu
td_create_shared_checklist_item Přidání položky checklistu ve sdíleném projektu
td_update_shared_checklist_item Aktualizace položky checklistu ve sdíleném projektu
td_delete_shared_checklist_item Smazání položky checklistu ve sdíleném projektu
td_list_shared_task_links Seznam vazeb úkolu ve sdíleném projektu
td_create_shared_task_link Vytvoření vazby mezi úkoly ve sdíleném projektu
td_delete_shared_task_link Smazání vazby ve sdíleném projektu (soft delete)
td_list_shared_task_comments Seznam komentářů úkolu ve sdíleném projektu
td_create_shared_task_comment Přidání komentáře k úkolu ve sdíleném projektu
td_update_shared_task_comment Aktualizace komentáře ve sdíleném projektu
td_delete_shared_task_comment Smazání komentáře ve sdíleném projektu
td_upload_shared_attachment Nahrání přílohy k úkolu ve sdíleném projektu
td_list_shared_attachments Seznam příloh úkolu ve sdíleném projektu
td_download_shared_attachment Stažení přílohy úkolu sdíleného projektu
td_delete_shared_attachment Smazání přílohy úkolu sdíleného projektu
td_list_shared_deployment_stages Seznam deployment stages pro sdílený projekt
td_create_shared_deployment_stage Vytvoření deployment stage ve sdíleném projektu
td_update_shared_deployment_stage Aktualizace deployment stage ve sdíleném projektu
td_delete_shared_deployment_stage Smazání deployment stage ve sdíleném projektu
td_list_shared_repository_links Seznam repozitářových linků sdíleného projektu
td_create_shared_repository_link Vytvoření repozitářového linku ve sdíleném projektu
td_update_shared_repository_link Aktualizace repozitářového linku ve sdíleném projektu
td_delete_shared_repository_link Smazání repozitářového linku ve sdíleném projektu
td_list_shared_project_notes Seznam poznámek sdíleného projektu
td_create_shared_project_note Vytvoření poznámky ve sdíleném projektu
td_update_shared_project_note Aktualizace poznámky ve sdíleném projektu
td_delete_shared_project_note Smazání poznámky ve sdíleném projektu
td_list_shared_members Seznam členů sdíleného projektu (jméno, oprávnění, kicked/blocked stav, isPending = čeká na schválení)
td_update_shared_member Jen admin. Změna oprávnění mezi write a admin, schválení čekajícího nebo odblokování (jen dokud projekt nemá rotovaný klíč); block, kick, zamítnutí a snížení na read odmítne, ty patří do appky
td_upload_shared_note_attachment Nahrání přílohy k poznámce sdíleného projektu
td_list_shared_note_attachments Seznam příloh poznámky sdíleného projektu
td_download_shared_note_attachment Stažení přílohy poznámky sdíleného projektu
td_delete_shared_note_attachment Smazání přílohy poznámky sdíleného projektu
td_list_shared_project_docs Seznam dokumentů sdíleného projektu
td_create_shared_project_doc Vytvoření dokumentu ve sdíleném projektu
td_update_shared_project_doc Aktualizace dokumentu ve sdíleném projektu
td_delete_shared_project_doc Smazání dokumentu ve sdíleném projektu
td_get_shared_task Detail jednoho úkolu ve sdíleném projektu (podle ID nebo kódu, s odpracovaným časem a počty checklistu a komentářů)
td_list_shared_task_tags Tagy úkolu ve sdíleném projektu
td_bulk_update_shared_tasks Hromadná úprava úkolů ve sdíleném projektu
td_bulk_delete_shared_tasks Hromadné smazání úkolů ve sdíleném projektu (kaskáda na checklist a komentáře)
td_update_shared_worklog Úprava worklogu ve sdíleném projektu
td_list_shared_activity_log Aktivita ve sdíleném projektu (stejné filtry jako u osobní)

Oprávnění, ownerSecret a historie ve sdílených projektech (TODO-434).

  • ownerSecret je nepovinný a nemá se posílat. Každý sdílený nástroj si ho najde ve vašem projectRef podle sharedOwnerId a td_list_shared_projects ho už nevrací. Secret je klíč k celému projektu, takže dřív ležel v kontextu modelu i v každém přepisu konverzace. Kdo ho pošle, tomu to dál funguje (a kontroluje se proti sharedOwnerId).
  • Zápisy hlídají oprávnění stejně jako appka (src/permissions.ts, port appkového permissions.ts). Úkoly, worklogy, checklist, komentáře, přílohy, vazby, přiřazení štítků, poznámky a dokumenty chtějí write nebo admin. Nastavení projektu (td_update_shared_project včetně mazání a obnovy), deployment stages, repozitářové linky, správa štítků a členové chtějí vlastníka nebo admin. Bez projectRef se zápis odmítne, čtení jde dál. Odmítnutí přijde jako chyba a nic se nezapíše.
  • Členy MCP spravuje jen napůl. Appka po každé změně člena rotuje zapisovací klíč nebo předá ten současný, jinak zablokovaný člen zapisuje dál. MCP rotovat neumí, takže změny, po kterých člen nesmí zapisovat (block, kick, zamítnutí, snížení na read), odmítne s odkazem na appku. Schválení, odblokování a povýšení projdou, jen dokud projekt nemá rotovaný klíč.
  • Sdílené zápisy píšou historii do sdílené instance, stejné záznamy jako appka (úkol vytvořen/upraven po polích/smazán, worklog, checklist, komentář, příloha, štítek, stage, repozitář, projekt, člen), s actorId vašeho účtu a source: "mcp" v metadatech.
  • Mazání neexistujícího id vrací chybu místo success a hromadné mazání ho počítá mezi přeskočené. td_update_shared_project vybírá řádek projektu stejně jako appka (nejstarší živý) a umí ho obnovit z koše.
  • Kód projektu smí obsahovat jen A-Z a 0-9 a souběžná volání td_create_task / td_create_shared_task do jednoho projektu už nedostanou stejný kód.

Stavy úkolů a validace argumentů (TODO-296, TODO-297). Stav recurring je plnohodnotný, appka ho používá pro opakované úkoly a MCP ho teď nabízí ve všech devíti enumech. Zároveň se kontrolují hodnoty enumů a odmítají nedeklarované argumenty. Dřív byly enumy jen dokumentace a neznámý argument se tiše zahodil, což je přesně způsob, jak td_create_shared_checklist_item přijal isChecked, vrátil success a položku založil neodškrtnutou. Ten argument tam dnes je.

Při té příležitosti se srovnal i linkType: MCP nabízelo related, kterému appka nerozumí, a chyběly mu explicit a mention, které appka opravdu zapisuje. Platné hodnoty jsou blocks, explicit, mention.

Rodič se ověřuje, argumenty jsou dorovnané (TODO-300, TODO-302). td_create_task_comment a td_create_checklist_item šly dřív založit na neexistující úkol: řádek se zapsal proti ID, které nic nerozřeší, každý výpis jde přes taskId, takže ho nikdo nikdy nepřečte, a tool vrátil success. td_add_worklog to odmítal od TODO-90 M12, tyhle dva ne. Teď odmítají obě strany, osobní i sdílená, a sdílená scopuje i podle ownera.

Zároveň se dorovnalo devět argumentů, které sdílené tooly proti osobním neměly. Nejcitelnější byl td_update_shared_project: uměl jen archivaci, takže sdílený projekt nešlo přejmenovat.

Zprávy od uživatelů (relay)

Zprávy, které uživatelé posílají z aplikace (hlášení vad, návrhy, vzkazy). Výpis a mazání umí jen admin owner a relay od TODO-90 H2 nevěří samotnému ownerId — požadavek se podepisuje Ed25519 klíčem odvozeným z nastaveného mnemoniku. Odesílání relay nechává nepřihlášené, stejně jako formulář v appce.

Nástroj Popis
td_list_user_messages Výpis zpráv od uživatelů (jen admin owner)
td_submit_user_message Odeslání zprávy adminům (hlášení vady, návrh, vzkaz)
td_delete_user_message Smazání zprávy na relayi (jen admin owner, tvrdé smazání)

Analytika a přehledy

Nástroj Popis
td_get_dashboard_summary Přehled: úkoly dnes, po termínu, odpracováno tento týden, nadcházející deadline
td_get_team_workload Vytížení týmu: odpracováno vs odhad vs kapacita per uživatel za období
td_list_recurring_tasks Seznam opakujících se úkolů s konfigurací opakování
td_list_overdue_tasks Úkoly po termínu (seřazené od nejstaršího)

Do v1.6.0 tyhle tři nástroje vracely vždy prázdno. td_list_recurring_tasks, td_list_overdue_tasks a td_list_tasks_by_date_range čtly result.rows, zatímco evolu.loadQuery vrací pole samo — takže count: 0 na jakýkoli vstup, bez chyby, které by šlo si všimnout. Opraveno v TODO-242 přes společný queryRows. Recurrence pole navíc vrací i td_get_task, takže nastavení opakování jde přečíst tou nejpřímější cestou. | td_list_tasks_by_date_range | Úkoly filtrované podle scheduledDate nebo deadline v daném rozmezí | | td_analyze_dependencies | Analýza závislostí: blokované úkoly, blokující řetězce, kritická cesta |

Sdílené projekty se do analytiky počítají (TODO-112). Do MCP IX čtlo všech pět přehledů jen osobní instanci, takže úkol ve sdíleném projektu neviděl dashboard, rozdělení vytížení, seznam opakujících se ani po termínu, ani dotaz na rozmezí dat. U vytížení to nebylo jen chybějící číslo: počítá se z odpracovaného času, takže vynechané sdílené minuty podhodnocovaly každého, kdo ve sdíleném projektu pracuje. Každý nástroj bere includeShared (výchozí true) a vrací sharedIncluded, ať je vidět, jestli se sdílená polovina opravdu načetla. td_analyze_dependencies zůstává záměrně jen osobní: appka sdílené taskLink řádky čte, ale žádné nezapisuje.

td_search_tasks hledá ve sdílených projektech taky, se stejným přepínačem.

Diagnostika

Nástroj Popis
td_sync_status Stav synchronizace
td_force_sync Vynutí sync round-trip s relayem (užitečné, když chceš mít jistotu, že vidíš nejnovější data z jiného zařízení)

Příklady použití

Seznam projektů

Zobraz mi seznam všech projektů v Todocko

Seznam úkolů

Jaké mám úkoly ve stavu "todo"?
Zobraz úkoly projektu TODO

Detail úkolu

Jaké jsou detaily úkolu TODO-15?

Vytvoření úkolu

Vytvoř nový úkol v projektu PROJ s názvem "Opravit bug v přihlášení" a prioritou high
Vytvoř úkol s deadline na 2026-03-15 a scheduledDate na 2026-03-10

Aktualizace úkolu

Označ úkol PROJ-5 jako dokončený
Přiřaď úkol TODO-10 uživateli s ID xyz
Nastav scheduledDate úkolu TODO-10 na zítra

Logování času

Zaloguj 2 hodiny práce na úkol TODO-15 s popisem "Implementace feature"

Práce s přílohami

Nahraj soubor /home/user/report.pdf jako přílohu k úkolu TODO-15
Jaké přílohy má úkol TODO-15?
Smaž přílohu s ID xyz

Sdílené projekty

Zobraz sdílené projekty
Jaké úkoly jsou ve sdíleném projektu?
Označ úkol jako nasazený na produkci

Deployment stages

Jaké deployment stages má projekt?
Vytvoř novou deployment stage "Staging" pro sdílený projekt

Sub-úkoly

Vytvoř sub-úkol k úkolu TODO-15 v projektu TODO
Odpoj úkol TODO-20 od rodičovského úkolu (parentTaskId: null)

Přehledy a analytika

Jaký mám dnes přehled? (dashboard summary)
Jak je vytížený tým tento týden?
Jaké úkoly jsou po termínu?
Zobraz úkoly naplánované na příští týden
Analyzuj závislosti v projektu TODO
Jaké mám opakující se úkoly?

Linux CLI (todo) (TODO-160)

Vedle MCP serveru je v balíčku i CLI todo pro rychlé osobní ovládání z terminálu — sdílí stejnou databázi i TODOCKO_MNEMONIC jako MCP. Po npm link (nebo globální instalaci) je dostupné jako todo.

📖 Podrobný návod: CLI.md

# Přidání úkolu (bez -p použije první projekt)
todo add "Opravit login"
todo add "Opravit login" -p TODO --priority high --scheduled today

# Změna stavu (identifikace kódem úkolu)
todo done TODO-160          # status=done
todo start TODO-160         # status=in_progress
todo mv TODO-160 review     # backlog|todo|in_progress|review|done|recurring

# Worklog
todo log TODO-160 1h30m "ladění OAuth"
todo worklogs TODO-160      # tabulka worklogů

# Strojový výstup na všech příkazech
todo add "X" --json
  • Architektura: src/cli.ts (commander) → mapuje argumenty na existující tool handlery (handleToolCall), žádná duplicitní business logika. Kód úkolu se překládá na ID přes td_get_task.
  • Sync: po mutaci čeká ~3 s na relay; když je offline, vypíše ⚠ uloženo lokálně a skončí s kódem 0 (data jsou lokálně bezpečně).
  • Exit kódy: 0 úspěch, 1 user/business chyba (neznámý kód, špatný stav/čas), 2 config (chybí mnemonic).
  • Barvy jen v TTY a při nenastaveném NO_COLOR.
  • Pozn.: běží jako samostatný proces nad stejnou SQLite DB jako MCP; při souběžném zápisu s MCP může (vzácně) nastat SQLITE_BUSY — v takovém případě příkaz zopakuj. Mimo rozsah v1: list/today, editace popisu, projekty/tagy/checklist, sdílené projekty.

Bezpečnost

Důležité: Vaše zálohovací fráze (mnemonic) je citlivý údaj!

  • Nikdy ji nesdílejte v přímé konverzaci s AI
  • MCP server frázi nevystavuje přes žádný nástroj: nejde ji z Todočka přečíst ani vypsat
  • To ale neznamená, že k ní AI nemá přístup. Agent, který umí spouštět příkazy nebo číst soubory (Claude Code a podobní), si ~/.claude.json nebo ~/.claude/settings.json přečte stejně jako kterýkoli jiný soubor. Konfigurace chrání frázi před nástroji MCP, ne před shellem. (TODO-441)
  • Kdokoli s vaší frází má plný přístup k vašim datům

Kontrola argumentů a cest (TODO-441)

  • Hodnoty argumentů se kontrolují proti typu, který nástroj deklaruje. isBlocked: "false" se dřív ukládalo jako true (neprázdný řetězec je pravdivý), teď je to chyba.
  • Datová pole (deadline, scheduledDate, loggedAt, recurrenceEndDate, startDate, endDate, …) musí být YYYY-MM-DD; kde schéma mluví o datetime (completedAt, expiresAt, from/to v activity logu), projde i ISO datetime. deadline: "zítra" se dřív uložilo doslova a nikdo se to nedozvěděl.
  • Přílohy: cesty se vyhodnocují až po rozpadnutí symlinků, takže odkaz uvnitř povoleného adresáře už nevede ven. Stahování nově odmítá tečkové soubory (stejně jako nahrávání) a nepřepíše existující soubor, dokud nepošleš overwrite: true.

WebSocket Origin (TODO-169)

MCP server při WebSocket připojení k relay posílá hlavičku Origin: https://todocko-mcp. Sdílený relay (relay.todocko.cz) má tuto hodnotu povolenou ve whitelistu Access Control. Pokud používáš vlastní relay, musíš ji přidat do tiers.json.allowedDomains, jinak relay odmítne připojení s 403 Forbidden na WS upgrade.

Rotace zapisovacího klíče sdílených projektů (TODO-268)

Když vlastník sdíleného projektu někoho vyhodí, aplikace vymění zapisovací klíč projektu na relayi. Klíč odvozený z ownerSecret tím přestane platit a relay s ním odmítne každý zápis.

MCP server si nový klíč načte ze sloupce projectRef.writeKey, který do jeho databáze přiteče běžným syncem AppOwnera. Kontrola běží při startu a pak každou minutu, takže po rotaci může být zhruba minuta, kdy zápisy do toho jednoho projektu relay odmítá a řádky čekají lokálně. Čtení rotace neovlivňuje.

Umístění dat

Databáze jsou uloženy v adresáři ~/.todocko/:

Platforma Cesta
Linux ~/.todocko/
macOS ~/.todocko/
Windows C:\Users\<user>\.todocko\

Soubory:

  • todocko.db - vaše osobní data (úkoly, projekty)
  • todocko-shared.db - sdílené projekty

Změna konfigurace

Claude Code (CLI)

Po změně konfigurace v ~/.claude/settings.json (např. změna mnemonicu) spusťte příkaz:

/mcp

Tím se MCP server restartuje s novou konfigurací.

Přepnutí na jiný účet

Při změně mnemonicu na jiný Todocko účet je potřeba smazat lokální databázi:

# Linux/macOS
rm ~/.todocko/todocko.db

# Windows
del %USERPROFILE%\.todocko\todocko.db

Databáze obsahuje ID vlastníka z předchozího mnemonicu. Po smazání se při dalším spuštění vytvoří nová databáze a stáhnou se data nového účtu.

Troubleshooting

Server se nespustí

  • Zkontrolujte, že máte Node.js 24.20+
  • Zkontrolujte, že jste spustili npm run build
  • Zkontrolujte logy v Claude Desktop

Data se nesynchronizují

  • Ověřte, že je zálohovací fráze správná (24 slov)
  • Zkontrolujte internetové připojení
  • Počkejte pár sekund na synchronizaci
  • Zkuste smazat ~/.todocko/todocko.db a restartovat

Nástroje nejsou viditelné

  • Restartujte Claude Desktop
  • V Claude Code použijte /mcp pro reload
  • Zkontrolujte konfigurační soubor
  • Zkontrolujte cestu k dist/index.js

project ... is a shared project při zápisu

Sdílený projekt má svá data ve sdílené instanci. Osobní nástroje (td_create_task, td_update_task, td_bulk_update_tasks) proto zápis do takového projektu odmítnou a pošlou tě na td_*_shared_* protějšek.

Dřív se zápis tiše uložil do osobní instance vedle skutečného řádku. Vznikly tím dvě kopie téhož úkolu v různých instancích, které se rozcházely: aplikace čte sdílenou stranu, MCP td_list_tasks osobní, takže každý ukazoval něco jiného a nic to nehlásilo. (TODO-318)

Mazání zůstává povolené i pro sdílený projekt, jinak by staré osobní kopie nešlo uklidit. td_search_tasks s includeShared ukáže obě kopie vedle sebe a je proto nejrychlejší způsob, jak zjistit, že je úkol rozdvojený.

Kód úkolu se teď přidělit nedá (TODO-373)

td_create_task odvozuje kód z nejvyššího, který v téhle kopii vidí. Když část účtu ještě nedorazila, je maximum nižší než skutečné a vznikne kód, který na relayi už existuje. Stalo se to 2026-09-23: v 07:01 kopie neměla TODO-360 až 367 a server vyrobil TODO-353 a dál, v 09:33 už je nad stejným souborem měla a navázal správně na 368. Nic se nerozbilo jen proto, že 353 až 359 byla shodou okolností volná.

Před přidělením kódu se proto porovná počet zpráv: Evolu jich drží po jedné v evolu_timestamp, relay hlásí stejné číslo pro ownera. Naměřeno 81 130 na obou stranách. Když je kopie pozadu, zápis se odmítne a řekne, kolik zpráv chybí; až se sync dotáhne, projde. Když se relay zeptat nedá, zápis projde: odmítat i tam by z lokálně prvního nástroje udělalo nástroj závislý na síti.

Aktuální stav ukáže td_sync_status v poli copy.

Sdílené projekty tenhle strážce nemají. Jejich úkoly patří jinému ownerovi s vlastním počtem zpráv a zeptat se na něj chce jeho klíč, ne ten odvozený z mnemoniky. Měřit tam app ownera by vypadalo jako pokrytí a nebylo by.

Todocko MCP už nad touto databází běží (TODO-341)

Druhá instance nad stejnou zálohovací frází se odmítne nastartovat. Není to opatrnost navíc: klientská databáze jede v režimu journal_mode=delete s nulovým busy_timeout, takže druhý proces dostane SQLITE_BUSY okamžitě, Evolu z toho udělá PanicAbortReason: database is locked a prvnímu procesu umře dbWorker. Do TODO-341 tak nové okno tiše shodilo to, ve kterém jsi pracoval (projevilo se jako status: worker-dead, viz níž).

Zámek je soubor ~/.todocko/todocko-<owner>.lock vedle databáze. Drží pid, který ho vzal; po pádu procesu se pozná jako neaktuální a další start si ho vezme.

Samotné process.kill(pid, 0) na to nestačí (TODO-372). Zombie procesem ten test projde: proces, který skončil, ale rodič ho nesklidil, je pořád v tabulce procesů a signál 0 na něm uspěje. Zámek pak vypadá jako věčně držený a žádná nová instance se nespustí. Stalo se to 2026-09-22, kdy byl držitel ve stavu Z a jeho rodič zastavený claude ve stavu Tl, takže neměl kdo sklízet. Na Linuxu se proto čte stav z /proc/<pid>/stat a Z se bere jako mrtvý. Kde /proc není, zůstává původní chování.

Když potřebuješ druhou instanci doopravdy (třeba CLI todo vedle MCP), spusť ji s vlastním jménem databáze:

TODOCKO_INSTANCE=cli todo ...

Dostane ~/.todocko/todocko-cli-<owner>.db, tedy vlastní lokální kopii, která se s tou první srovná přes relay. Povolené znaky jsou a-z0-9-, zbytek se zahodí; prázdná hodnota znamená výchozí databázi.

Worker umřel za běhu (status: worker-dead)

Proces normálně naběhl a po nějaké době přestal odpovídat. td_sync_status vrátí status: "worker-dead" a v workerDefects je panika i s časem. Dotazy v tomhle stavu selžou hned, ne až po 15 s. Řešení je /mcp reconnect. Nejčastější příčina je druhý MCP proces nad stejnou databází; od TODO-341 se druhá instance nenastartuje, takže tuhle cestu k mrtvému workeru už nemá jak způsobit.

Každý loadQuery skončí timeoutem (loadQuery timed out after 15000ms)

Příčiny jsou dvě, poznáte je podle toho, co server řekne.

1. Mrtvý dbWorker po závodu dvou procesů (TODO-316). Dva MCP procesy, které současně zakládají schéma téže databáze, se porvou. Poražený dostane SqliteError: table evolu_version already exists a jeho dbWorker zůstane mrtvý do konce života procesu. Typicky při prvních startech po upgradu MCP, který přidá tabulku.

Od TODO-316 to server pozná při startu a odmítne se nastartovat: každé volání nástroje hned vrátí Evolu dbWorker never answered. Od TODO-317 se navíc zapíše i proč worker umřel, do workerDefects v td_sync_status a do stderr jako FATAL: Evolu dbWorker defect: .... Dřív se tvářil zdravě a každý dotaz visel, dokud to klient po 1800 s nevzdal. Řešení je /mcp reconnect v Claude Code.

2. Nesedící native binding. better-sqlite3 native binding byl zkompilován proti jiné Node.js ABI verzi, než pod kterou MCP server běží. new Database() selže s ERR_DLOPEN_FAILED, Evolu dbWorker init nikdy nedoběhne a všechny loadQuery volání visí navždy. Mutace (insert/update) reportují success, ale ve skutečnosti se nezapíšou.

Symptom v praxi: td_sync_status hlásí ok, errorCount: 0, ale td_get_task, td_list_* apod. timeoutují.

Fix — přebuildit native binding proti aktuálnímu Node:

cd ~/.todocko-mcp # případně cesta, kde máš nainstalované todocko-mcp
cd node_modules/better-sqlite3
npx node-gyp rebuild --release

Pak /mcp reconnect v Claude Code.

Mismatch je typický, pokud upgradneš Node.js (např. z v22 na v25) nebo přepneš mezi nvm a linuxbrew/brew Node. Při instalaci installer použije node z PATH — pokud claude později spouští MCP přes jiný node binary, binding nesedí.

Vývoj

# Instalace závislostí
npm install

# Build
npm run build

# Watch mode pro vývoj
npm run dev

# Ruční spuštění
TODOCKO_MNEMONIC="vaše fráze" npm start

English

MCP (Model Context Protocol) server for working with Todocko app data from AI assistants.

Support

  • Claude Desktop - full support
  • Claude Code (CLI) - full support (same configuration)

Requirements

  • Node.js 24.20+ — required by Evolu v8's engines, and not merely formally: v8 relies on navigator.locks, MessageChannel, BroadcastChannel and WebSocket, which Node only has natively from 24 on
  • Todocko account with data synchronized via Evolu

Installation

1. Download

Using git:

git clone https://github.com/brnt-cz/todocko-mcp.git
cd todocko-mcp

Or download ZIP from Releases and extract.

2. Run the installer

Linux/macOS:

chmod +x install.sh
./install.sh

Windows (PowerShell):

.\install.ps1

The installer will:

  1. Install dependencies and build the project
  2. Ask whether to configure Claude Desktop, Claude Code, or both
  3. Create a configuration file with a placeholder
  4. Manually add your 24-word backup phrase to the configuration file
  5. Restart Claude

Manual installation

  1. Install dependencies:

    npm install
    npm run build
    
  2. Add to configuration:

Claude Desktop (~/.config/Claude/claude_desktop_config.json on Linux or ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "todocko": {
      "command": "node",
      "args": ["/path/to/mcp-server/dist/index.js"],
      "env": {
        "TODOCKO_MNEMONIC": "your 24 word backup phrase"
      }
    }
  }
}

Claude Code (CLI) - add to ~/.claude/settings.json:

{
  "mcpServers": {
    "todocko": {
      "command": "node",
      "args": ["/path/to/mcp-server/dist/index.js"],
      "env": {
        "TODOCKO_MNEMONIC": "your 24 word backup phrase"
      }
    }
  }
}
  1. Restart Claude Desktop / Claude Code

Available Tools (157)

Projects

Tool Description
td_list_projects List all projects
td_get_project Get project details by ID or code
td_create_project Create a new project (code: A-Z and 0-9 only, as in the app)
td_update_project Update a project (name, code, color, isArchived, autoApproveMembers, isHiddenFromFilters; code A-Z and 0-9 only)
td_delete_project Delete a project (soft delete)

Tasks

Tool Description
td_list_tasks List tasks with filters (project, status, priority, assignee)
td_get_task Get task details by ID or code (e.g., PROJ-123), recurrence settings included
td_create_task Create a new task (with recurrence, sprint, parentTaskId support)
td_update_task Update an existing task (with recurrence, sprint, parentTaskId support)
td_search_tasks Search tasks by text
td_bulk_update_tasks Bulk update multiple tasks
td_bulk_delete_tasks Bulk delete multiple tasks
td_delete_task Soft-delete a single personal task (cascades to its worklogs and attachments).
td_list_git_events List git events (push, PR opened/merged/closed) for a task by its code.

Users

Tool Description
td_list_users List all users
td_get_user Get user details
td_create_user Create a new user
td_update_user Update a user
td_delete_user Delete a user (soft delete)

Worklogs

Tool Description
td_list_worklogs List worklogs for a task
td_add_worklog Add a worklog to a task
td_update_worklog Update a worklog
td_delete_worklog Delete a worklog (soft delete)

Attachments

Tool Description
td_upload_attachment Upload an attachment to a task (from file or base64)
td_list_attachments List attachments for a task
td_download_attachment Download an attachment
td_delete_attachment Delete an attachment
td_upload_note_attachment Upload an attachment to a local project note
td_list_note_attachments List attachments of a local note
td_download_note_attachment Download a note attachment
td_delete_note_attachment Delete a note attachment

Comments

Tool Description
td_list_task_comments List comments for a task
td_create_task_comment Add a comment to a task
td_update_task_comment Update a comment
td_delete_task_comment Delete a comment (soft delete)

Checklist

Tool Description
td_list_checklist_items List checklist items for a task
td_create_checklist_item Add a checklist item
td_update_checklist_item Update a checklist item (check, reposition)
td_delete_checklist_item Delete a checklist item (soft delete)

Mentions

Tool Description
td_list_mentions List mentions for a user
td_create_mention Create a mention
td_mark_mention_read Mark a mention as read
td_mark_all_mentions_read Mark all mentions as read
td_delete_mention Delete a mention (soft delete)

Task Links

Tool Description
td_list_app_settings Account settings that follow the user across devices
td_set_app_setting Set one account setting
td_list_task_links List links for a task
td_create_task_link Create a link between tasks (blocks, explicit, mention, relates, duplicate)
td_delete_task_link Delete a task link (soft delete)

Tags

Tool Description
td_list_tags List tags; returns projectId, filters by project or unassigned
td_create_tag Create a tag — pass projectId, see the note below
td_update_tag Rename, recolour, assign to a project, or mark default
td_delete_tag Delete a tag (soft delete)
td_list_task_tags List tags assigned to a task
td_add_tag_to_task Assign a tag to a task
td_remove_tag_from_task Remove a tag from a task

Shared projects (TODO-235):

Tool Description
td_list_shared_tags Tags in a shared project
td_create_shared_tag Create a tag in a shared project
td_update_shared_tag Rename / recolour
td_delete_shared_tag Delete (soft delete)
td_add_shared_tag_to_task Assign to a task in a shared project
td_remove_shared_tag_from_task Remove from a task

A tag without a project is never offered by the app. Since TODO-227 tags belong to a project; td_create_tag without projectId makes an unassigned tag, which shows up only under "Nezařazené" in project settings with a button to adopt it. The tool response says so. Fix it afterwards with td_update_tag and a projectId.

Free-tier limits (TODO-243). Tier caps belong to the app, not here. td_create_task and td_create_project append a warning with the real count when the owner is on the free tier and above its cap (1 project, 50 active tasks), so that it is learned at creation time rather than later in the app, and so that the text makes clear nothing was lost. Nothing is blocked, and with an unknown tier (unreachable relay) it stays silent — a false alarm is worse than none.

Default tags (TODO-239). isDefault on td_create_tag / td_update_tag (and the shared variants) means every task newly created in the project gets the tag. Both td_create_task and td_create_shared_task apply them and report them back in appliedTags — the app pre-ticks them in its form, so without this the result would depend on where the task was created. Existing tasks are untouched.

Shared projects write to a different Evolu instance, hence the separate set — td_add_tag_to_task does not work on a shared task.

Task Templates

Tool Description
td_list_task_templates List task templates
td_create_task_template Create a task template (optional checklistItems and tagIds)
td_update_task_template Update a task template (checklistItems, tagIds; empty array clears)
td_delete_task_template Delete a task template (soft delete)

Kanban Columns

Tool Description
td_list_kanban_columns List kanban columns
td_create_kanban_column Create a kanban column (optional wipLimit, max tasks per user in In progress before the header warns)
td_update_kanban_column Update a kanban column (wipLimit: null clears the limit)
td_delete_kanban_column Delete a kanban column (soft delete)

Saved Views

Tool Description
td_list_saved_views List saved views
td_create_saved_view Create a saved view
td_update_saved_view Update a saved view
td_delete_saved_view Delete a saved view (soft delete)

Activity Log

Tool Description
td_list_activity_log List activity log entries with filters (task, actor, action, entityType, date from/to) — read-only

Project Notes

Tool Description
td_list_project_notes List local project notes
td_create_project_note Create a local project note
td_update_project_note Update a local project note
td_delete_project_note Delete a local project note (soft delete)

Deployment Stages

Tool Description
td_list_deployment_stages List deployment stages for a project
td_create_deployment_stage Create a deployment stage for a personal project.
td_update_deployment_stage Update a deployment stage in a personal project.
td_delete_deployment_stage Soft-delete a deployment stage in a personal project.

Repository Links

Tool Description
td_list_repository_links List repository links
td_create_repository_link Create a repository link
td_delete_repository_link Delete a repository link
td_update_repository_link Update a repository link for a project.

Shared Projects

Tool Description
td_list_shared_projects List shared projects with your permission (no longer returns ownerSecret)
td_list_shared_tasks List tasks from a shared project
td_update_shared_task Update a task in a shared project
td_list_shared_deployment_stages List deployment stages for a shared project
td_create_shared_deployment_stage Create a deployment stage in a shared project
td_list_shared_repository_links List repository links for a shared project
td_create_shared_repository_link Create a repository link in a shared project
td_list_shared_project_notes List notes for a shared project
td_create_shared_project_note Create a note in a shared project
td_update_shared_project_note Update a note in a shared project
td_delete_shared_project_note Delete a note in a shared project
td_list_shared_members List members of a shared project (name, permission, kicked/blocked state, isPending = waiting for approval)
td_update_shared_member Admin only. Change permission between write and admin, approve a pending join or unblock (only while the project has no rotated write key); refuses block, kick, reject and downgrade to read, which belong in the app
td_upload_shared_note_attachment Upload an attachment to a shared project note
td_list_shared_note_attachments List attachments of a shared project note
td_download_shared_note_attachment Download a shared note attachment
td_delete_shared_note_attachment Delete a shared note attachment
td_list_shared_project_docs List document pages from a shared project
td_create_shared_project_doc Create a document page in a shared project
td_update_shared_project_doc Update a document page in a shared project
td_delete_shared_project_doc Delete a document page in a shared project (soft delete)
td_create_shared_task Create a task in a shared project.
td_delete_shared_task Soft-delete a task in a shared project (cascades to its checklist items and comments).
td_list_shared_worklogs List worklogs for a task in a shared project.
td_add_shared_worklog Add a worklog to a task in a shared project.
td_delete_shared_worklog Soft-delete a worklog in a shared project.
td_list_shared_checklist_items List checklist items for a task in a shared project.
td_create_shared_checklist_item Create a checklist item on a task in a shared project.
td_update_shared_checklist_item Update a checklist item in a shared project (toggle done, rename, reorder).
td_delete_shared_checklist_item Soft-delete a checklist item in a shared project.
td_list_shared_task_links List dependency links for a task in a shared project.
td_create_shared_task_link Create a dependency link between tasks in a shared project.
td_delete_shared_task_link Delete a dependency link in a shared project (soft delete).
td_list_shared_task_comments List comments for a task in a shared project.
td_create_shared_task_comment Add a comment to a task in a shared project.
td_update_shared_task_comment Update a comment in a shared project.
td_delete_shared_task_comment Soft-delete a comment in a shared project.
td_update_shared_repository_link Update a repository link in a shared project.
td_delete_shared_repository_link Soft-delete a repository link in a shared project.
td_update_shared_deployment_stage Update a deployment stage in a shared project.
td_delete_shared_deployment_stage Soft-delete a deployment stage in a shared project.
td_update_shared_project Update shared-project metadata (archive / hide from filters).
td_upload_shared_attachment Upload a file attachment to a task in a shared project.
td_list_shared_attachments List file attachments of a task in a shared project (metadata only, no data).
td_download_shared_attachment Download a task attachment from a shared project.
td_delete_shared_attachment Soft-delete a task attachment in a shared project.
td_get_shared_task Get one task in a shared project by ID or code, with its worklog total, checklist and comment counts.
td_list_shared_task_tags List the tags on a task in a shared project.
td_bulk_update_shared_tasks Update several tasks in a shared project at once.
td_bulk_delete_shared_tasks Soft-delete several tasks in a shared project at once, cascading their checklist items and comments.
td_update_shared_worklog Update a worklog in a shared project.
td_list_shared_activity_log List activity log entries for a shared project.

Permissions, ownerSecret and history in shared projects (TODO-434).

  • ownerSecret is optional; leave it out. Every shared tool looks it up from your projectRef by sharedOwnerId, and td_list_shared_projects no longer returns it. The secret is the key to the whole project, so it used to sit in the model's context and every transcript. Passing it still works and is checked against sharedOwnerId.
  • Writes are gated by permission, as in the app (src/permissions.ts, a port of the app's permissions.ts). Tasks, worklogs, checklist items, comments, attachments, links, tag assignment, notes and documents need write or admin. Project settings (td_update_shared_project, delete and restore included), deployment stages, repository links, tag management and members need the owner or admin. Without a projectRef writes are refused, reads still work. A refusal is an error and nothing is written.
  • Member management is partial. After every member change the app rotates the write key or hands the current one over, otherwise a blocked member keeps writing. The MCP cannot rotate, so changes that leave the member unable to write (block, kick, reject, downgrade to read) are refused with a pointer to the app. Approving, unblocking and upgrading pass only while the project has no rotated write key.
  • Shared writes record history in the shared instance, the same entries the app writes (task created / updated per field / deleted, worklog, checklist, comment, attachment, tag, stage, repository link, project, member), with your account as actorId and source: "mcp" in metadata.
  • Deleting an unknown id is an error instead of success, and bulk delete counts it as skipped. td_update_shared_project picks the project row the way the app does (oldest live row) and can restore it from the Trash.
  • Project codes may contain only A-Z and 0-9, and concurrent td_create_task / td_create_shared_task calls for one project no longer get the same code.

Project Documentation

Documents are notes with isDoc, so they can nest under another document via parentDocId.

Tool Description
td_list_project_docs List local project document pages (not synced to shared projects)
td_create_project_doc Create a local project document page
td_update_project_doc Update a local project document page
td_delete_project_doc Delete a local project document page (soft delete)

System Notifications (relay)

Broadcast notices for every user. Writing, and listing expired ones, needs TODOCKO_RELAY_ADMIN_KEY.

Without TODOCKO_RELAY_ADMIN_KEY, td_create_system_notification and td_delete_system_notification are not offered to the client at all (a 401 is the only answer they could give) and the listing drops its admin flag. The key is never sent over plain http:// to anything but localhost. (TODO-441)

Tool Description
td_list_system_notifications List active system/broadcast notifications from the relay server.
td_create_system_notification Create a broadcast notification visible to all Todocko users.
td_delete_system_notification Delete a system notification by ID.

User Messages (relay)

What users send from the app: bug reports, feature requests, notes. Listing and deleting are admin-owner only and the request is signed with the configured mnemonic; submitting needs no admin rights.

Tool Description
td_list_user_messages List messages users have sent from the app (bug reports, feature requests, notes).
td_submit_user_message Send a message to the Todocko admins (bug report, feature request or note), the same way the app's feedback form does.
td_delete_user_message Delete one user message from the relay.

Analytics & Reports

Tool Description
td_get_dashboard_summary Overview: tasks today, overdue, this week's worklog, upcoming deadlines
td_get_team_workload Team workload: logged vs estimate vs capacity per user for a period
td_list_recurring_tasks List recurring tasks with recurrence configuration
td_list_overdue_tasks Overdue tasks (sorted oldest first)

Before v1.6.0 these three tools always returned nothing. td_list_recurring_tasks, td_list_overdue_tasks and td_list_tasks_by_date_range read result.rows, while evolu.loadQuery resolves to the array itself — so count: 0 for every input, with no error to notice. Fixed in TODO-242 behind a shared queryRows. td_get_task now returns the recurrence settings too, so a schedule can be read the obvious way. | td_list_tasks_by_date_range | Tasks filtered by scheduledDate or deadline within a date range | | td_analyze_dependencies | Dependency analysis: blocked tasks, blocking chains, critical path |

Diagnostics

Tool Description
td_sync_status Sync status
td_force_sync Force a sync round-trip with the relay (useful when you want to make sure you're reading the latest data from another device)

Usage Examples

List projects

Show me all projects in Todocko

List tasks

What tasks do I have with status "todo"?
Show tasks for project TODO

Task details

What are the details of task TODO-15?

Create task

Create a new task in project PROJ with title "Fix login bug" and priority high
Create a task with deadline 2026-03-15 and scheduledDate 2026-03-10

Update task

Mark task PROJ-5 as completed
Assign task TODO-10 to user with ID xyz
Set scheduledDate of task TODO-10 to tomorrow

Log time

Log 2 hours of work on task TODO-15 with description "Feature implementation"

Working with attachments

Upload file /home/user/report.pdf as attachment to task TODO-15
What attachments does task TODO-15 have?
Delete attachment with ID xyz

Shared projects

Show shared projects
What tasks are in the shared project?
Mark task as deployed to production

Deployment stages

What deployment stages does the project have?
Create a new deployment stage "Staging" for the shared project

Sub-tasks

Create a sub-task for task TODO-15 in project TODO
Detach task TODO-20 from its parent (parentTaskId: null)

Analytics & Reports

What's my dashboard summary for today?
How is the team's workload this week?
What tasks are overdue?
Show tasks scheduled for next week
Analyze dependencies in project TODO
What recurring tasks do I have?

Security

Important: Your backup phrase (mnemonic) is sensitive data!

  • Never share it directly in conversation with AI
  • The MCP server never exposes the phrase through a tool: nothing in Todocko can read or print it
  • That is not the same as the AI having no access to it. An agent that can run commands or read files (Claude Code and the like) reads ~/.claude.json or ~/.claude/settings.json like any other file. The configuration keeps the phrase away from MCP tools, not from a shell. (TODO-441)
  • Anyone with your phrase has full access to your data

Argument and path checks (TODO-441)

  • Argument values are checked against the type the tool declares. isBlocked: "false" used to be stored as true (a non-empty string is truthy); it is an error now.
  • Date arguments (deadline, scheduledDate, loggedAt, recurrenceEndDate, startDate, endDate, ...) must be YYYY-MM-DD; where the schema says datetime (completedAt, expiresAt, activity-log from/to) an ISO datetime is accepted too. deadline: "zitra" used to be stored verbatim with nothing reporting it.
  • Attachments: paths are judged after symlinks are resolved, so a link inside the allowed directory no longer leads out of it. Downloads now refuse dotfiles (as uploads already did) and never replace an existing file unless overwrite: true is passed.

Shared project write key rotation (TODO-268)

When the owner of a shared project removes a member, the app swaps the project's write key on the relay. The key derived from ownerSecret stops being valid and the relay refuses every write made with it.

This server picks the new key up from the projectRef.writeKey column, which reaches its database through the ordinary AppOwner sync. It checks at start and then once a minute, so a rotation can leave about a minute in which writes to that one project are refused and the rows wait locally. Reading is unaffected.

Data Location

Databases are stored in the ~/.todocko/ directory:

Platform Path
Linux ~/.todocko/
macOS ~/.todocko/
Windows C:\Users\<user>\.todocko\

Files:

  • todocko.db - your personal data (tasks, projects)
  • todocko-shared.db - shared projects

Configuration Changes

Claude Code (CLI)

After changing configuration in ~/.claude/settings.json (e.g., changing mnemonic), run the command:

/mcp

This will restart the MCP server with the new configuration.

Switching to a Different Account

When changing the mnemonic to a different Todocko account, you need to delete the local database:

# Linux/macOS
rm ~/.todocko/todocko.db

# Windows
del %USERPROFILE%\.todocko\todocko.db

The database contains the owner ID from the previous mnemonic. After deletion, a new database will be created on the next startup and data from the new account will be downloaded.

Troubleshooting

Server won't start

  • Check that you have Node.js 24.20 or newer (Evolu v8 requires it)
  • Check that you ran npm run build
  • Check logs in Claude Desktop

Data not syncing

  • Verify the backup phrase is correct (24 words)
  • Check internet connection
  • Wait a few seconds for synchronization
  • Try deleting ~/.todocko/todocko.db and restart

Tools not visible

  • Restart Claude Desktop
  • In Claude Code, use /mcp for reload
  • Check the configuration file
  • Check the path to dist/index.js

project ... is a shared project on a write

A shared project keeps its data in the shared instance, so the personal tools (td_create_task, td_update_task, td_bulk_update_tasks) refuse a write aimed at one and point at the td_*_shared_* counterpart.

Such a write used to be stored quietly in the personal instance beside the real row, leaving the same task in two instances, free to drift: the app reads the shared side and td_list_tasks reads the personal one, so the two disagreed with nothing reporting it. (TODO-318)

Deletes are still allowed on a shared project, because otherwise old personal copies could never be cleaned up. td_search_tasks with includeShared shows both copies side by side and is the quickest way to spot a split task.

Todocko MCP už nad touto databází běží (TODO-341)

A second instance over the same backup phrase refuses to start. The client database runs with journal_mode=delete and a zero busy_timeout, so the second process gets SQLITE_BUSY immediately, Evolu turns it into PanicAbortReason: database is locked, and the first process loses its dbWorker. Until TODO-341 a new window silently killed the one you were working in.

The lock is ~/.todocko/todocko-<owner>.lock next to the database. It holds the owning pid; after a crash the next start detects it as stale (process.kill(pid, 0)) and takes it over.

If you really need a second instance (the todo CLI next to the MCP, say), give it its own database name:

TODOCKO_INSTANCE=cli todo ...

It gets ~/.todocko/todocko-cli-<owner>.db, a separate local copy that reconciles with the first one through the relay. Allowed characters are a-z0-9-; anything else is dropped and an empty value means the default database.

Every loadQuery ends with a timeout (loadQuery timed out after 15000ms)

There are two causes, told apart by what the server says.

1. A dead dbWorker after two processes raced (TODO-316). Two MCP processes creating the schema of the same database at the same time race each other. The loser gets SqliteError: table evolu_version already exists and its dbWorker stays dead for the life of the process. Typically on the first starts after an MCP upgrade that adds a table.

Since TODO-316 the server detects this at startup and refuses to start: every tool call returns Evolu dbWorker never answered immediately. Since TODO-317 the reason the worker died is recorded too, in workerDefects from td_sync_status and on stderr as FATAL: Evolu dbWorker defect: .... It used to look healthy while every query hung until the client gave up 1800s later. The fix is a /mcp reconnect in Claude Code.

2. A mismatched native binding. The better-sqlite3 native binding was compiled against a different Node.js ABI than the one running the MCP server. new Database() fails with ERR_DLOPEN_FAILED, the Evolu dbWorker init never completes, and every loadQuery hangs forever. Mutations (insert/update) report success but are silently lost.

Typical symptoms: td_sync_status reports ok with errorCount: 0, but td_get_task, td_list_*, etc. all time out.

Fix — rebuild the native binding against the current Node:

cd ~/.todocko-mcp # or wherever todocko-mcp is installed
cd node_modules/better-sqlite3
npx node-gyp rebuild --release

Then /mcp reconnect in Claude Code.

This mismatch typically appears after upgrading Node.js (e.g. v22 → v25) or switching between nvm and linuxbrew/brew Node, because the installer builds the binding against the node from PATH, but claude may later spawn the MCP with a different node binary.

Development

# Install dependencies
npm install

# Build
npm run build

# Watch mode for development
npm run dev

# Tests
npm test

# Manual run
TODOCKO_MNEMONIC="your phrase" npm start

Testy

Vitest, 164 testů ve dvanácti souborech. Běží v CI (ci.yml, push i PR na main) od TODO-229 — do té doby CI spouštěla jen build, takže se nikdo nedozvěděl, že helpers.test.ts na Node 18/20 ani neprojde importem: přes helpers.ts tahal ../evolu.js, jehož inicializace při načtení modulu spadne na crypto.getRandomValues must be defined.

Proto jsou funkce bez závislosti na Evolu v src/tools/pure.ts a testují se odtud. helpers.ts je re-exportuje, takže volající se nemění. Když píšeš helper, který Evolu nepotřebuje, patří do pure.ts — jinak ho nejde testovat bez nastartované databáze.

Závazná verze je Node 24.20 nebo novější — je v engines a Evolu v8 na starším neběží. Na té jede ci.yml i release.yml.