@kody/jira
README.md
206 lines · 10.1 KB · Markdown@kody/jira
Official Jira app logomark from Atlassian Design / @atlaskit/logo.
Intent
Provide reusable, headless Jira Cloud helpers so Kody agents can list sites and projects, read and search issues, add comments, and apply transitions on the caller's Jira Cloud site — not a shared platform workspace. Auth is a bring-your-own Atlassian OAuth 2.0 (3LO) app and/or an Atlassian API token plus account email. Mutations support dryRun. Multi-account uses jira / jira-*. No personal project keys are hard-coded.
This listing is meant to be forked. After you fork, connect your Jira Cloud site and run ./smoke-test on your copy. Do not treat the live @kody/jira connection as yours.
Share this listing as https://kody.codes/@kody/jira.
This official OAuth/API-token package is the preferred invoke path. Setup is harder: bring your own Atlassian OAuth 2.0 (3LO) app or an API token plus account email. For a faster first win, connect Atlassian MCP in Get started and use @kody/atlassian-mcp.
When To Use
- List Jira Cloud sites granted to an OAuth token, or confirm an API-token site
- Search projects the caller can browse
- Read one issue or search issues with caller-supplied JQL
- Preview issue create, comment, or transition with
dryRun: true - Call an unwrapped Jira Cloud REST v3 path through
./request
Do not use this package for Jira Data Center, Confluence, Bitbucket, or Jira Service Management-specific APIs.
Agent setup
There is no built-in Jira platform app. Pick one lane (or both). Do not paste tokens, emails, or client secrets into chat.
Lane A — Atlassian API token + email (fastest)
- Create a token at Atlassian account API tokens.
- Save the Atlassian account email and API token (do not paste values here):
https://kody.codes/account/secrets/new?name=jiraEmail&description=Atlassian%20account%20email%20used%20with%20a%20Jira%20Cloud%20API%20token%20(Basic%20auth%20username).&scope=userhttps://kody.codes/account/secrets/new?name=jiraApiToken&description=Atlassian%20API%20token%20for%20Jira%20Cloud%20REST%20(Basic%20auth%20password).&scope=user- In the account secrets UI, approve host
{your-site}.atlassian.neton both secrets (for exampleacme.atlassian.net). - Call helpers with
site: "acme"(the*.atlassian.netsubdomain) andauth: "token"if an OAuth connection namedjiraalso exists.
For a second account named jira-work, save jiraEmail-work and jiraApiToken-work the same way, then pass account: "jira-work".
Lane B — OAuth 2.0 (3LO)
- Create an OAuth 2.0 integration at the Atlassian developer console.
- Authorization → OAuth 2.0 (3LO) → register redirect URI exactly
https://kody.codes/connect/oauth. - Permissions → add Jira API scopes
read:jira-user,read:jira-work, andwrite:jira-work. - Open this prefilled connect URL while signed in to Kody. Paste the client ID and client secret into the Kody form only:
https://kody.codes/connect/oauth?provider=jira&authorizeUrl=https%3A%2F%2Fauth.atlassian.com%2Fauthorize&tokenUrl=https%3A%2F%2Fauth.atlassian.com%2Foauth%2Ftoken&apiBaseUrl=https%3A%2F%2Fapi.atlassian.com&flow=confidential&scopes=offline_access%20read%3Ajira-user%20read%3Ajira-work%20write%3Ajira-work&allowedHosts=auth.atlassian.com%2Capi.atlassian.com&dashboardUrl=https%3A%2F%2Fdeveloper.atlassian.com%2Fconsole%2Fmyapps%2F&extraAuthorizeParams=%7B%22audience%22%3A%22api.atlassian.com%22%2C%22prompt%22%3A%22consent%22%7D&providerSetupInstructions=Create%20an%20OAuth%202.0%20(3LO)%20app%20at%20https%3A%2F%2Fdeveloper.atlassian.com%2Fconsole%2Fmyapps%2F.%20Enable%20Authorization%20%E2%86%92%20OAuth%202.0%20(3LO).%20Register%20redirect%20URI%20exactly%20https%3A%2F%2Fkody.codes%2Fconnect%2Foauth.%20Under%20Permissions%2C%20add%20the%20Jira%20API%20scopes%20read%3Ajira-user%2C%20read%3Ajira-work%2C%20and%20write%3Ajira-work.%20Paste%20the%20client%20id%20and%20client%20secret%20into%20this%20Kody%20form.%20Do%20not%20paste%20them%20into%20chat.Decoded:
- Redirect / callback:
https://kody.codes/connect/oauth - Authorize:
https://auth.atlassian.com/authorize - Token:
https://auth.atlassian.com/oauth/token - API base:
https://api.atlassian.com - Flow:
confidential - Scopes:
offline_access read:jira-user read:jira-work write:jira-work - Extra authorize params:
audience=api.atlassian.com,prompt=consent - Hosts:
auth.atlassian.com,api.atlassian.com
- Run
./smoke-test. If the token can access more than one site, passsiteorcloudIdon later calls.
To connect a second Atlassian account, change provider to jira-work (or another jira-* name) in that URL, then pass account: "jira-work" on every helper.
Reconnect later at https://kody.codes/connect/oauth?provider=jira.
Auth model
| Kind | Used by this package? |
|---|---|
| Built-in Jira OAuth | No. There is no jira platform app. |
| BYO Atlassian OAuth 2.0 (3LO) | Yes — integration name jira or jira-*. |
| Atlassian API token + email | Yes — secrets jiraEmail + jiraApiToken (or jiraEmail-work + jiraApiToken-work). |
| API key / raw token pasted into chat | Never. |
Default helper input: omit account (jira). Helpers try the OAuth integration named jira first, then the API-token secrets. Pass auth: "oauth" or auth: "token" to pin a lane. Pass site for the API-token lane and whenever more than one OAuth site is granted.
OAuth calls use https://api.atlassian.com/ex/jira/{cloudId}/rest/api/3. API-token calls use https://{site}.atlassian.net/rest/api/3.
Multiple accounts
Every export accepts optional account (default jira). Names must be jira or jira-<purpose>.
import listProjects from 'kody:@kody/jira/list-projects'
export default async function main() {
return listProjects({ account: 'jira-work', site: 'acme' })
}Do not hard-code personal workspace aliases or project keys.
Mutation safety
create-issue, add-comment, transition-issue, and mutating request calls never write when dryRun: true. A live write also requires confirm: true after the user approved the exact issue or fields.
import createIssue from 'kody:@kody/jira/create-issue'
const preview = await createIssue({
projectKey: 'PROJ',
summary: 'Follow up with the customer',
issueType: 'Task',
dryRun: true,
})Smoke test
After connect, invoke ./smoke-test (or the root export) from execute. Prefer packages.invoke so OAuth and secret mounts run in package runtime.
import { packages } from 'kody:runtime'
export default async function main() {
return await packages.invoke("kody:@kody/jira", {
exportName: './smoke-test',
params: {
// account: 'jira-work',
// site: 'acme',
},
})
}Static import (bundle-time published snapshot):
import jira from 'kody:@kody/jira'
export default async function main() {
return await jira({ dryRun: true })
}Without credentials this returns { ok: true, live: false } plus the setup URLs. With credentials it reads /myself and does not return email.
Exports
kody:@kody/jira— action dispatcher (defaults tosmoke-test)kody:@kody/jira/setup— prefilled connect and secret URLskody:@kody/jira/smoke-test— credential smoke test (read-only)kody:@kody/jira/list-sites— OAuth accessible resources or the API-token sitekody:@kody/jira/list-projects— project search (read-only)kody:@kody/jira/get-issue— one issue (read-only)kody:@kody/jira/search— JQL search (read-only)kody:@kody/jira/create-issue— create issue (dryRun/confirm)kody:@kody/jira/list-comments— issue comments (read-only)kody:@kody/jira/add-comment— add comment (dryRun/confirm)kody:@kody/jira/list-transitions— available transitions (read-only)kody:@kody/jira/transition-issue— apply a transition (dryRun/confirm)kody:@kody/jira/request— generic Jira Cloud REST v3 escape hatch
Examples
import searchIssues from 'kody:@kody/jira/search'
export default async function main() {
return await searchIssues({
jql: 'assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC',
maxResults: 10,
// site: 'acme',
})
}import addComment from 'kody:@kody/jira/add-comment'
export default async function main() {
return await addComment({
issueIdOrKey: 'PROJ-123',
body: 'Posted from Kody after review.',
dryRun: true,
})
}Troubleshooting
- OAuth authorize fails: confirm redirect URI is exactly
https://kody.codes/connect/oauthand the Jira API permissions are added on the Atlassian app. audienceerrors: reconnect with the prefilled URL soextraAuthorizeParamsincludesaudience=api.atlassian.comandprompt=consent.- Host approval: OAuth needs
api.atlassian.com(andauth.atlassian.comfor token refresh). API token needs{site}.atlassian.neton both secrets. - Several OAuth sites: pass
siteorcloudIdfrom./list-sites. This package will not pick a default project or site. - CAPTCHA /
AUTHENTICATION_DENIED: unlock the Atlassian account in the browser, then retry.
Branding
community-icon.svg is the official Jira app logomark (blue tile #1868db with the white stacked mark) taken from Atlassian's public logo package (@atlaskit/logo → Jira icon). Paths are unmodified except for explicit fill colors so the mark stays legible at 56 pixels. Jira® is a trademark of Atlassian Pty Ltd. This package is not affiliated with or endorsed by Atlassian.