gadak

Query your Jira backlog with SQL.

gadak mirrors the Jira Cloud projects and Confluence spaces you choose into one SQLite file on your machine. Issue titles, bodies, comments and wiki pages land in one search index, and searching it opens no connection. SQL over the same file answers the counts JQL cannot express. The desktop app, the browser tab, the CLI and a coding agent read that file; writes go to Jira first, and the file is a cache you can delete.

Recording: search over a 20,000-issue mirror built from the demo snapshot. Screen capture, not an animation.

Why not Rovo MCP?

Rovo MCP is hosted by Atlassian and needs no local MCP server installation. It searches Jira and Confluence and has write tools, but no native aggregation tool and no offline reads. gadak runs SQL against a synchronized local mirror, so a count over the whole backlog or a join across the change history is one query. The costs are a local binary, an initial sync, and reads that trail Jira by one sync interval.

Rovo MCP (hosted) gadak (local mirror)
Where the query runs Atlassian’s cloud your machine, in SQLite
Open issues per epic no native aggregation tool one GROUP BY; 22 ms on 3,296 issues (2026-08-26)
Network required for search yes no, once the selected data is synced
Searches Jira and Confluence yes yes, for the spaces you select
Writes: comment, transition, assign yes yes, through Jira first
Freshness Atlassian’s hosted data the last synced state, one interval behind
Local setup none a local binary and an initial sync
Rate limits 429 and a Retry-After none on reads — they come off your disk
Who maintains it Atlassian one person, and Apache-2.0

The same comparison for jira-cli, Linear and Jira’s own UI: docs/FAQ.md#how-it-compares

JQL has no GROUP BY.

The REST API returns issues a page at a time, and no totals. Once the data is a local file, the count is one query:

gadak sql "select epic_key, count(*) from issues_full where resolved_at is null
           and epic_key <> '' group by epic_key order by 2 desc"

Run this query on the demo snapshot in your browser (Datasette Lite, nothing installed) →
On a live Cloud site with 3,296 issues (2026-08-26, medians): 4,761 ms over 8 API pages aggregated client-side, against 22 ms for this query.

The same questions, measured

Jira REST API gadak
Simple filter, 100 issues 583 ms 19 ms 31×
One issue + full changelog 710 ms 28 ms 25×
Free-text search 543 ms 41 ms 13×
Open issues per epic (GROUP BY) 4,761 ms 22 ms 214×
A count over the change history no native aggregate 14 ms —
Rate limit on mirror reads 429 + Retry-After none —

Measured 2026-08-26 against a live Atlassian Cloud site: a real work project, 3,296 issues. Medians. The gadak numbers include full CLI process startup. In this measurement the epic count took 8 API pages, aggregated client-side, against one query on the mirror. The history count has no native aggregate; crawling and counting it client-side takes about 28 minutes. The rate-limit row is about reads, which stay local. A first full sync of that site took 3.7 minutes (2026-09-09), and the mirror trails Jira by one sync interval. Method, re-measurements, and the rows where gadak loses: docs/BENCHMARKS.md.

Use the CLI from your coding agent

You and your agent read the same file. The CLI is the agent interface: create, claim, transition, and SQL over the mirror, while the board in front of you updates. Writes go through Jira first, and an agent’s comments and the issues it creates carry its name. An agent that reads your mirror sends what it reads to whatever model it talks to; scope the mirror to what the agent should see.

A Claude Code session in gadak’s own terminal pane filters the issue list, then saves and opens a dashboard in the same window. Time-lapsed while the agent works.

Install the skill for Claude Code:

gadak skill install

For Claude Desktop, register the MCP server:

gadak mcp install claude-desktop

One paste per host → docs/AGENT_SETUP.md
More recordings: dashboards, a team theme, a launcher, a live MCP session → docs/SHOWCASE.md

The same cache, on a phone Beta

The iOS app pairs with a gadak serve you already run, over your own network — no gadak account, and nothing hosted in between. Whatever the cache holds, the phone shows: fields, attachments, linked issues, wiki pages, the active sprint and every sprint behind it. What is one line to say, the phone writes through the origin first, the way the desk does — a comment, a label, a due date, a photo, an issue filed under its epic. Editing a page or a custom field, authoring a view, laying out a dashboard and moving cards stay on the desktop, and the app says so where the control would be.

One take per language, recorded from the app at its own size. The writes are real: the demo snapshot is served as a tracker of its own, so the status, the comment and the photo actually land.

Beta, and that is the whole status: builds go to TestFlight for internal testers, and there is no public download. An App Store listing waits on a way for a reviewer to see the app without joining your network.

What gets copied, where it lives, and what leaves your machine

Every outbound destination and its condition → SECURITY.md
Every connection and its off switch → docs/NETWORK.md

Install

The desktop app, CLI included:

brew install --cask midagedev/tap/gadak

CLI only, on macOS or Linux. The same UI opens in a browser tab via gadak serve:

brew install midagedev/tap/gadak-cli

On Windows, the desktop app is on the Microsoft Store.

Connect to your team’s Jira Cloud site. It asks for the site, your email, an API token and the projects to mirror; add --spaces to include the wiki:

gadak init && gadak serve

All platforms →

Status and limits

What each origin supports · Earlier projects in this area · Hard questions · Who maintains this · Source

If you used it on your own project, say so

What question did gadak answer, and did you go back to it?

Keep real issue data, tokens, and site URLs out of public reports.

Open a GitHub issue · Email midagedev@gmail.com