pm_tasks, and uses them during session classification. Every time you close a coding or research session, Meridian’s classifier checks which ticket that work most likely belongs to and writes a ticket_links row to its database — no timesheets, no manual updates required.
Meridian supports two ways to authenticate to Jira Cloud:
- Browser OAuth (recommended) — one command, no API token, your site is discovered automatically, and access tokens auto-refresh.
- Static API token (fallback) — three environment variables. Use this when your Atlassian org blocks third-party OAuth apps or you need a fully scripted, headless setup.
Prerequisites
- A Jira Cloud account (Jira Data Center is not supported)
- Meridian installed and the daemon running (
meridian statusto confirm) - For OAuth: a desktop browser on the machine running Meridian
Connect with browser OAuth (recommended)
The installer offers OAuth inline duringmeridian setup / ./install.sh. You can also run the login at any time after install:
- Generates a PKCE verifier and opens your default browser to Atlassian’s consent screen.
- Waits for you to click Accept. Atlassian redirects back to a short-lived loopback server at
http://127.0.0.1:9123/callback. - Exchanges the authorization code for an access token and a refresh token.
- Writes them to
~/.meridian/oauth/jira.json(mode0600, owner-only readable).
~/.meridian/.env.
Scopes requested
The Atlassian consent screen lists the four scopes Meridian asks for:| Scope | Why Meridian needs it |
|---|---|
read:jira-work | Read open issues you’re assigned to. |
write:jira-work | Post worklogs to issues you classify against (only after you approve a draft in the dashboard). |
read:jira-user | Used by meridian doctor’s /myself health probe to confirm the token works. |
offline_access | Issues a refresh token so the daemon can mint new access tokens in the background — without this, you’d be re-prompted every hour. |
The token store
Tokens live at~/.meridian/oauth/jira.json:
meridian restart, or revoke the grant from your Atlassian account’s connected apps page. The next daemon start will fall back to static API-token auth if it is configured, otherwise it will report jira: not configured.
Override the OAuth client ID
Meridian ships with a public Atlassian client ID baked in — PKCE has no client secret, so there is nothing to protect. If your organisation runs its own Atlassian app (for example, to scope OAuth to an internal site allowlist), override the baked-in value:meridian oauth-login jira.
Connect with a static API token (fallback)
Use this path ifmeridian oauth-login jira fails with an org-approval error (“site admin must authorize this app” or user app installs disabled), or when running Meridian in a headless environment where you cannot open a browser.
Create a Jira API token
Navigate to id.atlassian.com/manage-profile/security/api-tokens, click Create API token, give it a descriptive label such as
meridian-local, and copy the value. Atlassian only shows the token once.JIRA_BASE_URL; OAuth requests instead go through https://api.atlassian.com/ex/jira/{cloudId} with a Bearer token. Both paths share the same request layer, so the rest of Meridian — classification, doctor, worklog drafts — works identically.
How Meridian picks an auth path
On every Jira request, the daemon resolves credentials in this order:- If
~/.meridian/oauth/jira.jsonexists, use OAuth. Refresh the access token first if it’s near expiry. - Otherwise, if
JIRA_BASE_URL,JIRA_EMAIL, andJIRA_API_TOKENare all set, use basic auth. - Otherwise, report
jira: not configuredand skip Jira sync.
.env as a documented fallback — they will simply be ignored as long as the token store exists.
Verify the connection
Run a health check
jira: connected in the output. The check calls Jira’s /myself endpoint, which works under both OAuth (via the read:jira-user scope) and basic auth.Limit which projects are synced
By default Meridian fetches every open ticket assigned to you. To restrict it to one or more projects, setJIRA_PROJECT_KEYS to a comma-separated list of project keys:
JIRA_PROJECT_KEYS applies to both auth paths.
Force-refresh the Jira task cache
The daemon refreshespm_tasks automatically at startup and on its background poll cycle. To pull the latest data on demand without restarting, run:
Troubleshooting
meridian oauth-login jira fails with an org-approval error
meridian oauth-login jira fails with an org-approval error
Some Atlassian organisations require a site admin to authorize third-party OAuth apps before any user can grant consent. If you see “site admin must authorize this app” or “user app installs are disabled”, switch to the static API token path — basic auth works without org-level approval.
login() fails with 'no refresh token returned'
login() fails with 'no refresh token returned'
Atlassian only issues a refresh token when the
offline_access scope is granted. If the consent screen omits it, the daemon refuses the response so you don’t end up with a token that silently expires after an hour. Re-run meridian oauth-login jira and make sure all four scopes are listed on the consent screen.401 Unauthorized after basic-auth setup
401 Unauthorized after basic-auth setup
pm_tasks table is empty after connecting
pm_tasks table is empty after connecting
An empty
pm_tasks table means the JQL query returned no issues. Check that:- Your account has at least one open issue assigned to it in the targeted projects.
- If you set
JIRA_PROJECT_KEYS, confirm the keys are correct (they are case-sensitive, e.g.KANnotkan).
meridian tasks-sync to force a re-sync after fixing the configuration.meridian doctor reports jira: not configured
meridian doctor reports jira: not configured
Jira is considered configured when either:
- The OAuth token store exists at
~/.meridian/oauth/jira.json, OR - All three of
JIRA_BASE_URL,JIRA_EMAIL, andJIRA_API_TOKENare set in~/.meridian/.env.
ls -l ~/.meridian/oauth/jira.json to check for the token store, or meridian config edit to confirm the static creds.