tempo: Tempo Timesheets from the command line
tempo is a command-line interface for Tempo Timesheets on Jira Cloud, built on the Tempo REST API v4. It is meant for AI agents (Claude Code, Gemini CLI, Codex, scripts) and for people who want to log hours without leaving the terminal. You can log time on issues, review and fix worklogs, see which days are missing hours, and submit timesheets. Output is predictable JSON, and safety rails stop agents from logging nonsense.
Unofficial. Not affiliated with or endorsed by Tempo Software or Atlassian.
$ tempo log PROJ-123 1h30m -m "Code review" --yes
$ tempo log PROJ-87 2h -d yesterday -s 14:00 -m "Pairing on the importer" --yes
$ tempo summary
DATE DAY TYPE REQUIRED LOGGED MISSING
2026-09-28 Mon WORKING_DAY 8h 8h
2026-09-29 Tue WORKING_DAY 8h 6h 30m 1h 30m
2026-09-30 Wed WORKING_DAY 8h 8h
...
$ tempo worklogs list -p yesterday -f json
{"worklogs":[{"id":4021,"issue":"PROJ-87","issueId":10087,"summary":"CSV importer","date":"2026-10-02","start":"14:00:00","duration":"2h","seconds":7200,"description":"Pairing on the importer","author":"5b10…"}],"from":"2026-10-02","to":"2026-10-02","count":1,"totalSeconds":7200,"total":"2h","totalHours":2.0}
Features
- Log time naturally. Durations like
1h30m,1.5h,90mor1:30. Dates liketoday,yesterday,-2d,mondayor2026-10-01. Issues by Jira key: the CLI resolves keys to the numeric ids Tempo v4 requires. - Batch logging from JSON or CSV (
tempo log-batch week.json). Every entry is validated before anything is written. - Gap detection.
tempo summarycompares your worklogs with your Tempo work schedule, holidays included, and lists the days with missing hours. - Fix mistakes.
tempo worklogs updatechanges only the fields you pass. Attributes, description and start time are preserved, and billable time follows the duration. - Find issues. Open issues assigned to you, issues you logged on recently, full-text search or JQL.
- Work attributes, accounts, approval periods, timesheet submission, plus an
apiescape hatch for any Tempo or Jira endpoint. - Agent-friendly:
- JSON when piped
- compact views
--fields- stable exit codes
- JSON errors with hints
tempo schemaintrospection- a ready-made agent skill and a Claude Code plugin
Install
Requires Python 3.11+.
pipx install tempo-jira-cli # or: uv tool install tempo-jira-cli
# development version:
pipx install git+https://github.com/lore2601/tempo-jira-cli
Optional: keep tokens in the OS keyring with pipx install "tempo-jira-cli[keyring]" and export TEMPO_TOKEN_STORE=keyring.
Set up (2 minutes)
You need two tokens. Neither needs admin rights, and both act with your own permissions. Details are in docs/setup.md.
- Tempo API token: in Jira, open Tempo → Settings → API integration → New token. Give it access to worklogs and schedules.
- Atlassian API token: create one at https://id.atlassian.com/manage-profile/security/api-tokens. It is used to resolve issue keys and your account id.
tempo auth login # prompts for Jira URL, email and both tokens (hidden input)
tempo auth status --check
If your Tempo data lives in a regional cluster, add --region eu or --region us. Agents and CI can use environment variables instead: TEMPO_API_TOKEN, JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN.
Commands
| Command | What it does |
|---|---|
tempo log ISSUE DURATION [-d DATE] [-s HH:MM] [-m TEXT] [-a KEY=VALUE]… |
Log time on an issue |
tempo log-batch FILE|- |
Log many worklogs from JSON/CSV |
tempo worklogs list [-p week|last-week|month…] [--from/--to] [-i ISSUE] [--project KEY] [-u me|ID|all] |
List worklogs with totals |
tempo worklogs get|update|delete ID |
Inspect, change or delete a worklog |
tempo summary [-p …] [--by day|issue] |
Logged vs required per day, or totals per issue |
tempo issues list [--preset assigned|recent|watching] [-q TEXT] [--jql …] / issues get KEY |
Find issues to log on |
tempo attributes list [--required] |
Work attributes and allowed values |
tempo accounts list |
Tempo accounts |
tempo approvals periods|status|reviewers|submit |
Timesheet approvals |
tempo api METHOD PATH [--jira] [-p JSON] [-b JSON] |
Any Tempo (or Jira) REST endpoint |
tempo auth login|status|logout |
Credentials |
tempo config show|init |
Effective policy and file locations |
tempo schema [COMMAND] |
Every command, option and exit code as JSON |
Periods: today, yesterday, week, last-week, month, last-month. Weeks start on Monday. Run tempo COMMAND --help for every option.
Batch file format
[
{"issue": "PROJ-1", "duration": "4h", "date": "monday", "start": "09:00", "description": "Sprint planning"},
{"issue": "PROJ-7", "duration": "3h30m", "date": "monday", "attributes": {"_Role_": "Developer"}}
]
CSV works too: issue,duration,date,start,description,attributes, with attributes written as K=V;K2=V2.
Output and exit codes
- stdout carries only data. On a terminal you get tables; when piped you get JSON. Force a format with
-f json|ndjson|tableorTEMPO_FORMAT. --fields id,issue,durationtrims output.--rawreturns untouched Tempo objects.- Errors are a single JSON object on stderr, for example
{"error": {"exitCode": 4, "reason": "duplicateWorklog", "message": "…", "hint": "…"}}.
| Exit code | Meaning |
|---|---|
| 0 | Success |
| 1 | Tempo/Jira API or network error (incl. partial batch failure) |
| 2 | Authentication problem |
| 3 | Invalid input (bad key, duration, date, …) |
| 4 | Blocked by local policy, duplicate, or confirmation (--yes) missing |
| 5 | Internal error (please report it) |
Safety rails
Timesheets feed payroll, invoicing and approvals, so mistakes are expensive. Before anything is written, tempo checks:
| Check | Default | Override |
|---|---|---|
Writes need --yes when not on a TTY (agents, scripts); --dry-run previews |
on | none |
| Identical worklog already exists (same issue, day, duration, description) | refuse | --allow-duplicate |
| A single worklog longer than N hours | 12h | max_worklog_hours / TEMPO_MAX_WORKLOG_HOURS |
| Day total above N hours, existing worklogs included | 14h | max_daily_hours / TEMPO_MAX_DAILY_HOURS |
| Worklogs dated in the future | refuse | allow_future_dates / TEMPO_ALLOW_FUTURE_DATES |
Logging for another user (--author) |
refuse | allow_other_authors / TEMPO_ALLOW_OTHER_AUTHORS |
| Project allowlist | any | projects = ["PROJ"] / TEMPO_ALLOW_PROJECTS |
| Read-only mode | off | read_only / TEMPO_READ_ONLY=1 |
Configure them in ~/.config/tempo-cli/config.toml (tempo config init writes a commented template). Tokens are stored with 0600 permissions or in the OS keyring, and no command ever prints them. All arguments (issue keys, ids, dates, attribute keys) are validated before they reach a URL.
Using it with AI agents
- Claude Code plugin:
/plugin marketplace add lore2601/tempo-jira-cli, then/plugin install tempo@tempo-jira-cli. - Any agent: copy
skills/tempo/SKILL.mdinto its instructions, or let it runtempo schema. - Typical prompt: "Log today's work: 2h on PROJ-12 (code review), the rest on PROJ-40, then show me what's missing this week." The agent runs
tempo issues list --preset recent, previews with--dry-run, asks you, then logs with--yes.
See docs/agents.md for permission rules and recipes.
Configuration reference
| Variable | Purpose |
|---|---|
TEMPO_API_TOKEN |
Tempo token |
TEMPO_REGION / TEMPO_BASE_URL |
eu, us, global (default) / explicit base URL |
JIRA_URL, JIRA_EMAIL, JIRA_API_TOKEN |
Jira Cloud site and Atlassian API token |
TEMPO_ACCOUNT_ID |
Your Atlassian account id (skips the Jira lookup) |
TEMPO_CONFIG_DIR / TEMPO_CONFIG / TEMPO_CREDENTIALS_FILE |
File locations (default ~/.config/tempo-cli/) |
TEMPO_TOKEN_STORE |
file (default) or keyring |
TEMPO_FORMAT |
Default output format |
TEMPO_READ_ONLY, TEMPO_ALLOW_PROJECTS, TEMPO_MAX_WORKLOG_HOURS, TEMPO_MAX_DAILY_HOURS, TEMPO_ALLOW_FUTURE_DATES, TEMPO_ALLOW_OTHER_AUTHORS |
Policy overrides |
Limitations
- Jira Cloud with Tempo Cloud only. Jira Data Center uses a different Tempo API.
- Without Jira credentials you can still use numeric issue ids (
tempo log 10001 1h), but not keys, summaries or the project allowlist. summaryuses the schedule of the token's owner, so it only covers your own timesheet.
Contributing
Issues and PRs are welcome: see CONTRIBUTING.md. Report security issues privately (SECURITY.md).
License
Metadata
Release files for tempo-jira-cli 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tempo_jira_cli-0.1.0.tar.gz | 56.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tempo_jira_cli-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 109.7 kB
Release files / tempo_jira_cli-0.1.0.tar.gz
| Download URL | tempo_jira_cli-0.1.0.tar.gz |
|---|---|
| Size | 56.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3e887265d196fe6ebc6581d4e8a7fc8ec4bdb2cbbf58594a94e7a237583ebcbd
|
|
BLAKE2b-256 checksum How to use checksums |
e31fb736b5a3210df44337a83c6dfbd5a20961ea2322ed7c9e6c712813f77a9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency logRelease files / tempo_jira_cli-0.1.0-py3-none-any.whl
| Download URL | tempo_jira_cli-0.1.0-py3-none-any.whl |
|---|---|
| Size | 53.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f5a32947b1413c85b1459f309b846742c2ebc892d2545e900c4c2e2917b9614d
|
|
BLAKE2b-256 checksum How to use checksums |
180810c15ff4a1edc3ef92aa53bc8189e998d50359d96e4451e99ea3235289c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.
Transparency log