Local CLI for syncing Toggl time entries into Jira worklogs. It keeps sync state in a local SQLite database, so repeated runs can skip already-synced entries and recover from interrupted runs.
This is an independent community tool. It is not an official Toggl, Jira, or Atlassian product, and it is not endorsed by those companies.
From crates.io:
cargo install toggl-jira-syncFrom GitHub:
cargo install --git https://github.com/gaboe/toggle-jira-syncUpdate an existing Cargo install:
cargo install toggl-jira-sync --forceFor local development from this repository:
cargo run -- config setupGitHub install works directly from the repository and is useful for testing unreleased changes. The crates.io install is the recommended stable path.
From this repository:
cargo run -- config setupIf you use the local alias:
tjs config setupconfig setup creates:
- config:
~/.config/toggl-jira-sync/config.toml - credentials:
~/.config/toggl-jira-sync/credentials.env - SQLite path in config:
toggl-jira-sync.sqlite - OS scheduler job for hourly sync, when scheduler installation is supported by the current OS
The setup prompt asks only for values that cannot be derived:
Toggl API token:
Toggl workspace id fallback, only if workspace discovery is skipped or fails
Jira site URL:
Jira email:
Jira API token:
Notes:
- In an interactive terminal, the Toggl API token is used to discover workspaces automatically.
- If one Toggl workspace is found, it is selected automatically.
- If multiple workspaces are found, the CLI shows a numbered list.
Jira site URLis enough; the internal site key is derived from the URL. Example:https://sabservis.atlassian.netbecomessabservis.- No Jira issue prefixes are configured. Jira site selection is resolved dynamically per issue and cached in SQLite.
- The SQLite file is created automatically on first command that opens the DB.
- Setup installs an hourly OS scheduler job by default. Use
tjs schedule status,tjs schedule set --disabled, ortjs schedule uninstallto inspect or disable it.
tjs config showSecrets are redacted by default. To inspect local secret values explicitly:
tjs config show --show-secretstjs config validate --config ~/.config/toggl-jira-sync/config.tomlLaunch the TUI:
tjsYou can also open it explicitly:
tjs tuiThe TUI shows recent local sync state from SQLite and lets you run common actions without leaving the terminal:
- search and filter entries
- open matching Jira or Toggl links
- press
dto run a dry-run sync - press
sto run a real sync - press
ato toggle the hourly OS scheduler
It is the main day-to-day view:
Toggl -> Jira Sync TUI normal
Issue search: - | Date/time filter: - | rows=3/3 | OS schedule: on every 60m
date start end duration issue site worklog status reason
2026-05-04 15:59 17:43 1h 44m PROJ-123 acme 26410 synced -
2026-05-04 18:00 18:30 30m PROJ-456 acme - skipped running entry
2026-05-05 09:15 10:00 45m PROJ-789 acme - error issue not found
Issue: PROJ-123 | Worklog: 26410 | Reason: -
Issue URL: https://acme.atlassian.net/browse/PROJ-123
Worklog URL: https://acme.atlassian.net/browse/PROJ-123?focusedWorklogId=26410
While the TUI is open, it also runs an hourly in-process sync. The OS scheduler is separate and keeps hourly sync running when the TUI is not open.
Run a safe preview first:
tjs sync --dry-runRun the real sync:
tjs syncInspect local sync state:
tjs statusRecover after an interrupted or uncertain sync:
tjs recoverManage the hourly OS scheduler:
tjs schedule status
tjs schedule set --interval-minutes 60 --enabled
tjs schedule set --disabled
tjs schedule uninstallFor each Toggl entry, the CLI extracts a Jira issue key from the description, for example PROJ-123.
Resolution flow:
- Check SQLite cache for
issue_key -> jira_site_key. - If cached, use it without Jira discovery.
- If not cached, query every enabled Jira site with
GET /rest/api/3/issue/{issueKey}. - If exactly one site has the issue, save that mapping to SQLite.
- If zero or multiple sites match, report an error instead of creating a worklog on the wrong site.
This means setup does not need issue prefixes.
~/.config/toggl-jira-sync/config.toml
~/.config/toggl-jira-sync/credentials.env
toggl-jira-sync.sqlite
credentials.env stores raw local credentials and is written with user-only permissions on Unix/macOS.