Skip to main content

Connect Jira

Tasks call Jira Cloud through qbash.integrations.jira with a credential saved on the Connectors page. A credential connects one Jira site, through Sign in with Atlassian or with an account email and an Atlassian API token. Both ways give tasks the same modes. Tasks act as the account that connected, so a task sees the projects that account can browse and changes only what that account may change.

After you connect Jira, you can add its tools to a qbash MCP server for ChatGPT, Claude and other MCP clients, or call it from a Python task. The Jira MCP server page lists what the connector can do.

Choose the account​

Connect as a dedicated Jira account, such as an integration user that belongs to no one person. Every issue, comment and link a task writes names that account as its author, and the credential keeps working when people leave.

Give the account these project permissions for the modes your tasks call:

  • Browse Projects for every read
  • Create Issues for create_ticket
  • Edit Issues for update_ticket
  • Transition Issues for transition_ticket
  • Add Comments for add_comment
  • Link Issues for link_tickets and add_remote_link

To post internal comments on Jira Service Management requests, the account also needs an agent seat on that service project.

Sign in with Atlassian​

  1. Open Connectors, then Jira, and click Connect.
  2. Enter a credential name. Sign in with Atlassian is already selected. If your tasks post internal comments on Jira Service Management requests, tick This site uses Jira Service Management. Then click the Sign in with Atlassian button.
  3. In the Atlassian window, sign in as the account you chose for qbash, pick the Jira site and click Accept.
  4. If that account has allowed qbash on more than one Jira site, the form lists them. Pick the site for this credential and click Add Credential.
  5. In the task editor, open Resources → Integrations and select this credential. See Connect resources.

qbash renews the sign-in every hour, so scheduled tasks keep running without anyone signing in again. The sign-in ends when someone removes qbash from the account's connected apps at id.atlassian.com, or when a site administrator removes qbash from the site. qbash then marks the credential as needing reconnection, and Reconnect on the credential opens the Atlassian window again.

To connect a second site, add another credential.

With the Jira Service Management box ticked, Atlassian lists only sites that have Jira Service Management. Leave it clear on a site without it. A credential connected without it runs every mode except internal comments, and add_comment with is_internal=True returns an error that says to reconnect with the box ticked.

Connect with an API token instead​

An API token suits a site whose administrators do not allow apps like qbash, or a team that already manages Atlassian tokens.

  1. Sign in to id.atlassian.com as the account you chose for qbash.
  2. Open Security, then API tokens.
  3. Click Create API token. The option with scopes calls Jira through a different address, which the connector does not support yet.
  4. Name the token and pick an expiry date. Atlassian allows up to one year.
  5. Copy the token. Atlassian shows it once.

When the token expires, Jira refuses it and qbash marks the credential as needing reconnection. Scheduled tasks that use it fail until you paste a new token into the credential, so note the expiry date and replace the token before it arrives.

Then add it in qbash:

  1. Open Connectors, then Jira, and click Connect.
  2. Enter a credential name and choose API token. Enter your site URL, such as https://your-site.atlassian.net, then the account's email, and paste the API token. qbash asks Jira which account the token belongs to before saving the credential.
  3. In the task editor, open Resources → Integrations and select this credential. See Connect resources.

When editing a credential, leave a field blank to keep its saved value.

qbash connects to the site over https, on port 443 or 80, and only to a public host. A Jira site on a private network or another port cannot be connected.

Read and search issues from a task​

report = qbash.integrations.jira.get_ticket(ticket_id="PROJ-123", comment_limit=5)
ticket = report["ticket"]
print(ticket["key"], ticket["summary"], ticket["status"]["name"])
for comment in ticket["comments"]:
print(comment["created"], comment["author"]["displayName"], comment["body"])

get_ticket returns the issue with its newest comments, attachments, issue links and the custom fields that have a value. comments_total counts every comment, and list_comments pages through the rest. Pass an attachment id to download_attachment to fetch the file. Descriptions and comment bodies arrive as plain text.

found = qbash.integrations.jira.search_tickets(
text="export timeout",
project="PROJ",
updated_within_days=30,
)
for issue in found["tickets"]:
print(issue["key"], issue["summary"], issue["status"]["name"])

search_tickets takes a JQL query on its own, or any of text, project and updated_within_days, which it joins with AND. It reads one page per call. Pass next_cursor back as cursor with the same query until it is None.

Before writing to a project, read how it is set up. list_projects and list_issue_types return the keys and issue types. get_create_fields lists the fields a new issue needs, with their allowed values, and get_edit_fields lists what the account may change on an existing issue. list_transitions shows the workflow steps open to an issue right now. list_fields and list_link_types cover the whole site. get_ticket_history reads status changes, or changes to any other field, for up to 1000 issues per call.

Draft an issue for a person to approve​

All six write modes (create_ticket, update_ticket, transition_ticket, add_comment, link_tickets and add_remote_link) accept read_only=True. The connector then checks the request against the site's fields, workflow and tickets, and returns the exact body without sending it to Jira. A task can show that draft to a person and file the issue on a later run, once they approve it.

jira = qbash.integrations.jira
case_id = qbash.inputs.get("case_id")
if not str(case_id).isdigit():
raise ValueError("case_id must be digits")
source_label = f"src-zendesk-{case_id}"

existing = jira.search_tickets(jql=f'labels = "{source_label}"')
if existing["count"] > 0:
qbash.output({"already_filed": existing["tickets"][0]["key"]})
else:
request = dict(
project="SUP",
issue_type="Bug",
summary=qbash.inputs.get("summary"),
description=qbash.inputs.get("description"),
labels=[source_label],
)
if not qbash.inputs.get("approved"):
qbash.output({"draft": jira.create_ticket(**request, read_only=True)})
else:
created = jira.create_ticket(**request)
jira.add_remote_link(
ticket_id=created["ticket_id"],
url=qbash.inputs.get("case_url"),
title=f"Zendesk ticket {case_id}",
global_id=f"zendesk-ticket-{case_id}",
)
qbash.output({"filed": created["ticket_id"]})

The source label is the duplicate guard. The task searches for it before creating anything and stops when an issue already carries it. add_remote_link attaches the support record to the issue. Jira keys a remote link by its global_id, so sending the same global_id again updates the existing link.

update_ticket sets several fields in one call and can add or remove labels without replacing the whole list. transition_ticket fills the fields on the transition's screen and can add a comment in the same step. add_comment posts a public comment by default. With is_internal=True it posts an internal comment on a Jira Service Management request, and visibility limits a comment to a role or a group.

The SDK Reference lists every method and parameter.

Start a task from Jira​

A Jira webhook can start a task. Add the Jira integration event in the task's Triggers panel, then register the URL qbash generates as a webhook in Jira's system settings, which needs a Jira administrator. The run's inputs carry the event type, the issue key, its status and its project. An issue update also carries previous_status and changed_fields, which lists each changed field with its old and new value.

Prepare test data​

Create a test project with a few issues in different statuses. On one issue, add a comment, an attachment, a link to another issue and a value in a custom field, so a single get_ticket call returns every section. To test internal comments, add a Jira Service Management project with one request.

Run each write with read_only=True first. Then give a test issue a label such as src-test-1 and confirm the duplicate guard finds it.

Details that affect results​

  • Jira's search index can lag behind a new issue, so a search right after create_ticket can miss it. Two runs for the same source record in quick succession can both pass the duplicate guard and file two issues.
  • text matches keywords after stemming. An issue that describes the same problem in other words does not match. To find duplicate candidates, search for a few key terms and rank the results in the task, for example with an inline prompt.
  • Internal comments exist only on Jira Service Management requests, and add_comment returns an error for any other issue instead of posting a public comment. A comment without is_internal or visibility is visible to everyone who can see the issue.
  • Jira Cloud allows at most 2000 issue links, 2000 remote links and 5000 comments on one issue, and refuses further ones.
  • Jira answers with 429 when a site goes over its rate limit. Reads retry twice, waiting as long as Jira asks, up to 10 seconds. Writes are never retried, because the first attempt may have gone through. After a failed create, search for the source label before trying again.
  • A 403 means the account lacks a permission for that call, and the credential stays connected. Only a rejected token or an ended sign-in marks the credential for reconnection.
  • Rich text loses its formatting on read. Links, mentions and tables arrive as plain text.
  • Jira Server and Data Center are not supported. Every mode calls REST API v3 paths that only Jira Cloud serves.