@togglhq/cli
v1.11.128
Published
Toggl CLI for Toggl 2.0 API operations.
Readme
@toggl/cli
Command-line interface for Toggl 2.0.
Installation
npm install -g @togglhq/cliOr run without installing:
npx @togglhq/cliAuthentication
toggl authOpens a browser for OAuth sign-in. On success, credentials are saved to ~/.toggl/focus-tools.json. When --profile is omitted, the CLI saves the account under a name based on your account, such as user-12345, and makes it active.
Options:
| Flag | Description |
| --------------------- | --------------------------------------------------------------------- |
| --workspace-id <id> | Select a specific workspace (required when your account has multiple) |
| --profile <name> | Save credentials under an explicit profile name |
Sessions refresh automatically. Re-run toggl auth only to switch workspaces or after 4 weeks of inactivity.
Profiles
Use profiles to switch between saved accounts and environments:
toggl profile list
toggl profile current
toggl profile switch user-12345
toggl profile switch # omit name in a TTY: pick from a menu or use the only profile
toggl profile remove user-12345The active profile controls both the account and environment for later commands. You can still override it for one call with the global --profile <name> flag.
Agent skill setup
@togglhq/cli ships a toggl-cli agent skill under skills/toggl-cli. Install it with:
toggl skill setupThis delegates to the skills CLI, listed as a dependency of @togglhq/cli (no separate install). Interactive agent/scope prompts come from that CLI.
After upgrading the CLI, refresh the skill install:
toggl skill syncBy default the installer symlinks into your agent skill dirs so updates track CLI upgrades; use --copy only if you need a detached snapshot (then re-run toggl skill sync after upgrades). Pass flags for non-interactive setup:
toggl skill setup --agent cursor --global --copy --yes
toggl skill setup --agent cursor codex --copy --yesCommand shape
Generated Toggl 2.0 commands look like:
toggl [global flags] <group> … <subcommand> [flags]Many endpoints use two segments (toggl tasks list). Some use nested groups, including:
toggl organization …— organization APIs (nottoggl org …; there is noorgtop-level command). Examples:toggl organization invitations list,toggl organization members get,toggl organization workspaces list.toggl shared …— shared workspace/org data routed through@toggl/querieshelpers (status, holidays, working hours, time off). Example:toggl shared status get.
Core resource groups still include tasks, projects, time-entries, statuses, users, tags, clients, and others surfaced by the public command catalog. Some low-level endpoints are omitted from the CLI and MCP. Existing public command paths and operation IDs stay stable; use toggl --help and toggl <group> --help to explore what shipped.
Typical entity commands:
| Resource | Actions |
| -------------- | -------------------------------------------------------- |
| tasks | list (alias ls), get, create, update, delete |
| projects | list (alias ls), get, create, update, delete |
| time-entries | list (alias ls), start, stop |
| statuses | list (alias ls) |
| users | list (alias ls) |
Bulk mutations use toggl <resource> bulk <verb>; see toggl tasks bulk --help.
Global flags (placed before the command path):
| Flag | Description |
| --------------------- | ------------------------------------------------------------- |
| --json | Pretty-printed JSON output (easier to pipe than human tables) |
| --workspace-id <id> | Override the active workspace for this call |
| --profile <name> | Use a named auth profile |
Per-command flags on generated operations always include --data, --data-file, and --dry-run. --interactive / --no-interactive appear only when the operation’s catalog metadata allows interactive prompting (read-only operations default to non-interactive unless marked otherwise). Interactive prompting requires a TTY and is disabled when you pass --json, --data, --data-file, CI, or TOGGL_NON_INTERACTIVE.
To see scalar flags for an operation, use toggl <group> … <command> --help. To print the resolved operation id and validated body without calling the API, use --dry-run.
Providing input
There are three ways to pass the request body:
1. Scalar flags
Each input field maps to a --field-name flag. Numeric values are coerced automatically.
toggl tasks get --task-id 12345
toggl tasks list --project-id 999 --status-id 111222
toggl time-entries list --date-from 2025-01-01 --date-to 2025-01-07
toggl time-entries start --task-id 12345 --type activityFor update commands, payload fields use a --payload-<field> prefix:
toggl tasks update --task-id 12345 --payload-name "New name" --payload-status-id 456789
toggl projects update --project-id 999 --payload-name "Renamed"2. --data inline JSON
Pass the full input as a JSON string:
toggl tasks list --data '{"project_id": 123456, "per_page": 50}'
toggl tasks create --data '{"name": "Fix login bug", "project_id": 123456}'
toggl tasks update --data '{"task_id": 12345, "payload": {"name": "Updated", "status_id": 456789}}'3. --data - (stdin) or --data-file <path>
Read JSON from stdin or a file:
echo '{"task_id": 12345}' | toggl tasks get --data -
toggl tasks create --data-file ./new-task.jsonOutput and errors
- Successful output goes to stdout as JSON (pretty-printed;
--jsonkeeps JSON while skipping human-oriented formatting helpers). - Validation errors and API errors go to stderr.
- Exit code
0on success,1on error.
Safety flags
--dry-run
Preview the resolved input without making an API call. Output includes dry_run: true, the operation ID, and the validated input object:
toggl tasks delete --task-id 12345 --dry-run
# {"dry_run":true,"operation":"focus.tasks.delete","input":{"task_id":12345}}--yes (destructive operations)
delete commands require --yes to execute. Omitting it prints an error to stderr:
toggl tasks delete --task-id 12345 --yes
toggl projects delete --project-id 999 --yesExamples
Tasks
# List all tasks in a project
toggl tasks list --project-id 123456
# Get a single task
toggl tasks get --task-id 12345
# Create a task
toggl tasks create --data '{"name": "Write release notes", "project_id": 123456}'
# Move task to "In Progress"
toggl tasks update --task-id 12345 --payload-status-id 456789
# Delete a task (requires --yes)
toggl tasks delete --task-id 12345 --yesProjects
toggl projects list
toggl projects get --project-id 123456
toggl projects create --data '{"name": "Q3 Planning", "workspace_id": 789012}'
toggl projects update --project-id 123456 --payload-name "Q3 Planning (archived)"
toggl projects delete --project-id 999 --yesTime entries
# List time entries for a week
toggl time-entries list --date-from 2025-01-01 --date-to 2025-01-07
# Start tracking (defaults type to 'activity')
toggl time-entries start --task-id 12345
# Start a break
toggl time-entries start --type break
# Stop the running timer
toggl time-entries stopReference data
# List workspace statuses (useful for getting status IDs)
toggl statuses list
# List workspace members (useful for getting user IDs)
toggl users listDates
--date-from and --date-to accept:
YYYY-MM-DD— expanded toT00:00:00Z(from) orT23:59:59Z(to)- RFC 3339 datetime — used as-is (e.g.
2025-01-01T08:00:00+02:00)
Troubleshooting
Not authenticated
Not authenticated. Run `toggl auth` to sign in.Run toggl auth. Credentials are stored in ~/.toggl/focus-tools.json. If you previously authenticated with an older version, your session at ~/.toggl-focus-mcp/config.json is still read automatically.
Invalid JSON from --data
Invalid JSON from --data: Unexpected token ...Verify your JSON is well-formed. Use --data-file with a file if quoting is difficult in your shell.
Validation error
Invalid input: date_from: must be YYYY-MM-DD or RFC3339 datetimeCheck field names and types. Use --dry-run to validate input without executing.
Debug API responses
TOGGL_DEBUG=1 toggl tasks listPrints schema validation warnings from API responses to stderr.
Privacy & analytics
Public builds may send product analytics: command path, the leaf command as action, outcome (success or error), client, session id and package version. Command arguments and output are never collected. Signed-in sessions are identified by your Toggl account id so repeat use is not counted as a new person each time; unauthenticated processes stay anonymous.
Disable product analytics:
TOGGL_PRODUCT_ANALYTICS=offError reporting is on by default. It sends a redacted error category, the stack trace with package-relative file paths, the CLI, Node and OS versions, and sampled request timings without query strings. It never sends command arguments, output, exception text, your hostname, local paths, or your project's dependency list. Disable it with TOGGL_SENTRY=off, or send it to your own Sentry project with TOGGL_SENTRY_DSN.
License
Proprietary Toggl software. See LICENSE and Toggl legal terms.
