Agentic Data Plane
Preview

Jira Managed MCP Server

The Jira managed MCP server lets agents search, read, and manage Jira issues. It authenticates with either a shared API token (Basic authentication) or, for per-user identity, user-delegated OAuth. With OAuth it’s the enterprise counterpart to the Slack setup guide, and Atlassian’s flow has its own scope model and quirks worth calling out.

After reading this page, you will be able to:

  • Configure the Jira managed MCP server with Basic authentication or Atlassian’s OAuth flow

  • Pick the right scopes for the tools your agents use

  • Walk a user through the consent flow and verify the connection

What this MCP server does

The Jira managed type exposes the following read tools:

  • query: Search for issues using a JQL query. Returns the matching issues as JSON.

  • get_issue: Retrieve a single issue by its key, for example PROJ-123.

  • list_projects: Return visible Jira projects, optionally filtered by a search query.

  • get_transitions: Return the available workflow transitions for an issue.

It also exposes the following write tools:

  • create_issue: Create a new issue.

  • update_issue: Update fields on an existing issue.

  • transition_issue: Move an issue to a new workflow state.

  • add_comment: Add a comment to an issue.

  • add_worklog: Log time spent on an issue.

  • create_issue_link: Create a directional link between two issues.

It can also expose Jira issues and projects as SQL-queryable tables, through two more tools. SQL exposure is on by default for servers created in the UI. See Expose Jira data as SQL tables.

Prerequisites

  • A Jira (Atlassian Cloud) site and its base URL, for example https://mycompany.atlassian.net.

  • Credentials for one of the following authentication modes:

    • Basic Auth: An Atlassian account email and an API token from id.atlassian.com, with the token stored in the Redpanda Agentic Data Plane secret store.

    • User OAuth: Your own Atlassian OAuth 2.0 (3LO) app, created in the Atlassian developer console, plus an OAuth Provider in Redpanda Agentic Data Plane that uses the Atlassian / Jira preset and carries the app’s client credentials. See Configure User-Delegated OAuth.

Atlassian’s scope model (user-delegated OAuth)

When you use user-delegated OAuth, Atlassian uses a granular, prefixed scope namespace. Request these scopes as a set:

Scope Allows

read:jira-work

Read Jira project and issue data and search for issues. Needed for the read tools.

write:jira-work

Create and edit issues, post comments, and create worklogs. Needed for the write tools.

offline_access

Issue a refresh token so Redpanda can refresh expired access tokens without asking the user to consent again.

Every scope in the server’s Required scopes must also be in the OAuth provider’s scope list, and in the scopes you added to the Atlassian app in the developer console. The Atlassian / Jira preset requests read:jira-work, write:jira-work, read:confluence-content.all, and offline_access. A required scope the provider doesn’t request makes tool calls fail with scope_upgrade_required until each user reconnects and grants it. If the Atlassian app isn’t allowed to grant that scope, every tool call keeps failing.

Configure

  1. Open MCP servers in the sidebar.

  2. Click Add MCP server.

  3. Click the Jira card in the marketplace picker.

  4. Replace the suggested Name, and optionally add a Description.

  5. In the Jira configuration form:

    • Base URL: Your Jira instance URL, for example https://mycompany.atlassian.net.

    • Max Results Per Page (optional): Page size for the query tool when a call doesn’t set one. Leave it at 0 to use the default, 50.

    • Auth: Select Basic Auth or User OAuth.

      • For Basic Auth: Provide the account email and the API-token secret reference.

      • For User OAuth: Pick the Atlassian OAuth Provider you configured, and set Required scopes to read:jira-work and offline_access. Add write:jira-work if your agents use the write tools.

    • Enabled under Queryable: On by default. Turn it off unless your agents need the two SQL tools. See Expose Jira data as SQL tables.

  6. Click Create server.

To narrow which tables and columns the SQL tools expose, use the SQL exposure tab on the server’s page after you create it. See Narrow what the SQL tools expose.

The create form turns Enable code mode on by default for this server type. rpk ai mcp-server create leaves it off unless you pass --code-mode. See Code Mode.

Expose Jira data as SQL tables

The Jira server can present its data as two read-only SQL tables instead of only as tools, so an agent can filter Jira records the way it would query a database. SQL exposure is the Enabled toggle under Queryable in the server’s configuration. The create form turns it on, so a server you create there is queryable unless you turn it off. Creating a server with rpk ai or the API leaves SQL exposure off unless the managed configuration sets it, and a server that already exists keeps whatever it was saved with. SQL exposure adds two tools:

  • list_tables: Return the table catalog. For each table, the catalog lists its columns and their types, which columns can be filtered and with which operators, whether each filter is exact, the page-size limit, and a schema fingerprint that every query response repeats so a caller can tell when the catalog changed.

  • execute_query: Run one query against a table and return a page of rows plus a cursor for the next page.

The execute_query tool reads Jira through the server’s configured authentication, so with user-delegated OAuth a query returns only the records the calling user can see, exactly as the other tools do. The list_tables tool returns the catalog, which is the same for every caller and carries no Jira data. With user-delegated OAuth, a caller who hasn’t connected an Atlassian account yet can still read the catalog and plan a query, while every other tool on the server, including execute_query, keeps asking for that connection. A list_tables call routed through the server’s code mode endpoint needs the connection too. Neither tool writes to Jira.

The tables are:

Table Contents

issues

Jira issues, from Jira’s issue search. Columns: key, project, issue_type, status, priority, summary, description, assignee, reporter, created, updated, and labels. The description column carries the issue description flattened to Markdown. The assignee and reporter columns hold Atlassian account IDs.

projects

Jira projects, from Jira’s project search. Columns: id, key, name, and type.

Not every column can be filtered. A filter is offered only where Jira’s search never drops a matching row, but most filters can return extra rows:

  • On issues, filter on key, project, issue_type, status, or priority for a value or a list of up to 100 values, on assignee or reporter by account ID (and on assignee, whether the issue is unassigned), and on created or updated with a time range. Matching on key, project, issue_type, status, and priority is case-insensitive, so a status filter for done also returns issues in Done. A time range is widened by 15 hours on each side before it reaches Jira, so it can return issues created or updated outside the range. Only the assignee and reporter filters are exact. The summary, description, and labels columns can be returned but not filtered.

  • On projects, filter on id or key for a value or a list of up to 50 values, or on type for a single value. Matching on key and type is case-insensitive, and only the id filter is exact. The name column can be returned but not filtered. A query on this table takes one filter per column, and it can’t filter on id and key together, so pick whichever identifier you have.

Because execute_query returns the rows Jira sends back without re-checking them against your filters, an agent that needs exact results must re-apply its filters to the rows it receives. The list_tables catalog marks which filters are exact.

A list longer than the cap fails rather than being silently cut short.

Two more limits are worth designing around:

  • Every query against issues needs a filter. At least one predicate on key, project, issue_type, status, priority, assignee, reporter, created, or updated is required, and an unfiltered query is refused before Jira is called. A query against projects has no such requirement.

  • A paged scan is best-effort. A page holds at most 100 rows for issues and 50 for projects, and Jira keeps changing under a multi-page scan, so a long scan can miss a row or return one twice. A cursor is bound to the query that produced it. Reusing one with different filters or against another table is refused instead of quietly starting a new scan.

If a data policy masks a column you can also filter on, the mask hides that column’s values but not which rows carry them, because a caller who can run execute_query can still filter on it. The filterable columns on issues are key, project, issue_type, status, priority, assignee, reporter, created, and updated. On projects they are id, key, and type. A mask on a column that can’t be filtered, such as summary, description, labels, or name, isn’t exposed this way. See the data policy limitations.

With SQL exposure on, the two tools are available to every caller of the server, including agents. Turn off Enabled on a server whose agents should only reach the curated Jira tools.

Narrow what the SQL tools expose

A curator can trim the catalog that list_tables reports, table by table, from the SQL exposure tab on the server’s own page. The tab’s Enable SQL exposure switch is the same setting as Enabled in the server’s configuration, and the tab lists the tables only while it is on. With the switch on, the tab lists the tables the server can expose, and for the table you select, which of its columns the catalog reports and which of those it offers as filters. For each table you can:

  • Hide the table completely.

  • Hide columns but keep the table.

  • Keep a column visible in the catalog and stop offering it as a filter. The catalog no longer declares a filter on that column, so execute_query refuses a predicate on it and a caller has to apply the condition to the rows it reads back.

  • Add filter requirements on top of the ones the table already carries. Each requirement must name at least one column that survives your other changes, and a query has to filter on at least one column of every requirement.

Click Save to apply your changes, or Discard to drop them.

Narrowing only takes things away. You can’t make a column filterable that Jira can’t filter on, and you can’t add a table. Hiding a column also removes it from the table’s filter requirements, which is fine until a requirement loses every column it named. A query against issues needs one predicate from a single requirement holding all nine of its filterable columns, so you can hide eight of them and the table still works. Hiding all nine is refused, with a message telling you to exclude the table instead.

If the server’s page has no SQL exposure tab, narrowing isn’t enabled for your organization. The Enabled setting on the server’s configuration still turns the two SQL tools on and off.

  1. Open the Inspector tab.

  2. Run the query tool with a small JQL filter.

  3. The first call fails with a connection-required result that carries an Atlassian authorization URL.

  4. Open the authorization URL. Atlassian asks you to pick a site (Cloud instance) and approve the scopes.

  5. Atlassian redirects back. Your connection appears under Connections.

  6. Run the search again. Results come back.

Use with agents

Point an agent at the Server URL on the server’s Connection tab. Each user calling the agent will trigger their own consent flow on first call.

With user-delegated OAuth, set the server’s required_scopes to every scope your agents' tools need before users connect. An Atlassian app can request only scopes you’ve already added to it in the developer console, and if you widen required_scopes later, users who already connected have to consent again.

Troubleshooting

Symptom What to check

token_expired errors soon after users connect

offline_access wasn’t in the scopes at consent time, so Redpanda has no refresh token. Add it to the provider and to required_scopes, then have users reconnect.

"Resource not found" for a project the user has access to

Atlassian’s OAuth grants are site-scoped. The user authorized for one Cloud instance; the project lives on another. They need to re-consent with the second site.

scope_upgrade_required after widening scopes

The server’s required scopes were extended after users consented, so users reconnect to grant them. If it persists after reconnecting, a required scope is missing from the provider’s scopes or from the Atlassian app.

invalid_grant during refresh

Refresh tokens expire if unused for ~90 days. The user re-consents.

Limitations

  • Atlassian app management: The OAuth app and its callback URLs are managed in developer.atlassian.com, not in Agentic Data Plane.

  • Jira Server / Data Center (self-hosted): This MCP type targets Atlassian Cloud. Self-hosted Jira may need a self-managed MCP server instead. See Register a self-managed MCP server.

  • Confluence access: Separate scope namespace; not exposed by this MCP server.

  • SQL exposure is read-only: The execute_query tool reads issues and projects. Use the write tools to change anything in Jira. See Expose Jira data as SQL tables.