OpenCode's MCP support lives in its JSON config file, and unlike Claude Code it doesn't distinguish user/project/local scopes as cleanly — everything hangs off a single mcp block, whether that's in ~/.config/opencode/config.json for machine-wide servers or opencode.json at the repo root for project-specific ones. This topic covers wiring Jira into that config, the JQL and sprint queries that work well from OpenCode's chat interface, and a full sprint-planning example.
Installing and Connecting Jira MCP to OpenCode
Add the server under mcp in opencode.json (repo root) or ~/.config/opencode/config.json (global):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"jira": {
"type": "local",
"command": ["uvx", "mcp-atlassian"],
"environment": {
"JIRA_URL": "https://your-domain.atlassian.net",
"JIRA_USERNAME": "you@company.com",
"JIRA_API_TOKEN": "{env:JIRA_API_TOKEN}",
"JIRA_PROJECTS_FILTER": "PROJ"
},
"enabled": true
}
}
}
The {env:JIRA_API_TOKEN} interpolation pulls from your shell environment at launch — same principle as Claude Code's ${VAR}, different syntax. Set the actual value in a .env file or your shell profile, never inline in the committed config.
If you'd rather run the server as a persistent process instead of spawning it per-session, use the Docker image with type: "local" and a long-running container, or point OpenCode at a remote SSE endpoint if you've deployed mcp-atlassian behind a reverse proxy for team-wide sharing:
{
"mcp": {
"jira": {
"type": "remote",
"url": "https://mcp-jira.internal.company.com/sse",
"enabled": true
}
}
}
Start OpenCode and check the server connected by asking directly — there's no separate mcp list command as of the current release, so the fastest sanity check is a trivial tool call:
opencode run "Call the jira_get_agile_boards tool and list what comes back"
If the config is wrong, OpenCode reports a connection error in its startup log rather than failing silently mid-conversation, which makes debugging faster than it sounds — check the terminal output before assuming the model is the problem.
Tips
- Put the Jira server inopencode.jsonat the repo root, not the global config, if only one project's team needs it — keeps unrelated repos from inheriting credentials they don't need.
- Run the trivialjira_get_agile_boardssanity check immediately after adding the server — it's the fastest way to separate "config is broken" from "prompt is broken."
-{env:VAR}interpolation only works for values set in the environment OpenCode itself launches from — a variable set in a different shell session won't be visible; restart OpenCode after changing.env.
Querying and Updating Issues and Sprints from OpenCode
OpenCode's chat interface handles multi-turn Jira work reasonably well, but it's more literal about tool arguments than Claude Code — vague natural language sometimes needs a follow-up nudge with the exact JQL rather than a rephrase.
> Show me every issue in the active sprint on board 42 that's still In Progress
[tool call: jira_get_sprints_from_board(board_id=42)]
[tool call: jira_get_sprint_issues(sprint_id=118, jql="status = 'In Progress'")]
Found 6 issues in Sprint 24 still In Progress:
- PROJ-501: Fix pagination bug in export endpoint (assignee: J. Torres)
- PROJ-503: Migrate legacy auth middleware (assignee: unassigned)
...
For updates, be explicit about the transition name as it appears in your workflow — OpenCode won't infer "mark it done" maps to a transition literally named "Resolve" if your board uses that wording instead of "Done":
> Transition PROJ-503 through its next valid status and add a comment
> saying the migration was tested against staging
[tool call: jira_get_transitions(issue_key="PROJ-503")]
[tool call: jira_transition_issue(issue_key="PROJ-503", transition_id="21")]
[tool call: jira_add_comment(issue_key="PROJ-503", body="Migration tested against staging.")]
Asking it to call jira_get_transitions first, rather than guessing a transition ID, is a habit worth building into your prompts explicitly — without that instruction, OpenCode will sometimes attempt a transition ID from a previous conversation turn that no longer applies to the current issue's workflow state.
project = PROJ AND sprint in openSprints() AND status = "In Progress"
AND assignee is EMPTY
That query — in-progress work with no assignee — is a genuinely useful daily standup check, and one worth scripting as a saved prompt rather than retyping.
Tips
- Always instruct the agent to calljira_get_transitionsbeforejira_transition_issuein your prompt — it prevents stale transition IDs from a prior turn causing a failed or wrong update.
- Use exact workflow status names ("Resolve," "In Review," "QA") rather than generic phrasing ("mark it done") — OpenCode is less forgiving than Claude Code about inferring workflow-specific terminology.
- Save recurring standup-style queries (unassigned in-progress work, stale review items) as reusable prompt snippets in your project'sAGENTS.mdor equivalent instruction file.
Practical Example: Sprint Planning Recommendations in OpenCode
Here's a full worked example: feeding OpenCode the backlog and last sprint's velocity, and asking for a sprint plan draft.
> Look at the PROJ backlog (project = PROJ AND status = "Backlog" ORDER BY
> Rank ASC) and the last 3 completed sprints on board 42. Calculate average
> velocity in story points, then recommend which backlog items fit into a
> sprint of that size, respecting priority order.
project = PROJ AND status = "Backlog" ORDER BY Rank ASC
[tool call: jira_search(jql="project = PROJ AND status = 'Backlog' ORDER BY Rank ASC")]
[tool call: jira_get_sprints_from_board(board_id=42)]
[tool call: jira_get_sprint_issues(sprint_id=115)] -- sprint N-3
[tool call: jira_get_sprint_issues(sprint_id=116)] -- sprint N-2
[tool call: jira_get_sprint_issues(sprint_id=117)] -- sprint N-1
Average velocity over last 3 sprints: 34 story points
(Sprint 22: 31 pts, Sprint 23: 38 pts, Sprint 24: 33 pts — all completed
without significant carryover)
Recommended Sprint 25 scope (34 pts target), by backlog rank:
1. PROJ-612 (8 pts) - Bug: checkout timeout on mobile
2. PROJ-615 (5 pts) - Add rate limiting to public API
3. PROJ-618 (13 pts) - Migrate notification service to new queue
4. PROJ-620 (5 pts) - Fix flaky integration test suite
5. PROJ-623 (3 pts) - Update dependency: requests 2.31 -> 2.32
Total: 34 pts. PROJ-625 (8 pts) is next in rank but would push to 42 pts,
above your 3-sprint average — recommend leaving it for Sprint 26 unless
the team has capacity headroom this cycle.
This is the kind of output worth reviewing line by line before you accept it — the story-point math is only as good as the estimates already in Jira, and the model has no visibility into planned PTO, on-call rotations, or a team member ramping onto a new codebase area. Treat it as a strong first draft for sprint planning, not a final commitment.
Tips
- Always ask for the underlying calculation (velocity numbers, per-sprint totals) alongside the recommendation — it lets you spot-check the math instead of trusting a bare list of ticket keys.
- Cross-reference the AI's sprint plan against known team capacity changes (PTO, on-call, onboarding) before committing — none of that is visible to the model from Jira data alone.
- Rank backlog items in Jira correctly before running this kind of query —ORDER BY Rank ASCreflects your board's actual backlog order only if someone has kept it groomed.
Known Limitations for Jira MCP in OpenCode
A few things to know going in, so you don't burn an afternoon debugging what's actually a platform limitation:
- No built-in MCP server listing command. Unlike Claude Code's
claude mcp list, OpenCode as of the current release doesn't expose a first-class command to inspect connected servers and their tool inventories from the CLI — you confirm connectivity indirectly, by making a tool call and watching the result. - Team-managed board sprint tools. Same underlying
mcp-atlassianlimitation as everywhere else:jira_create_sprintandjira_update_sprintdon't reliably work against team-managed (next-gen) Scrum boards. This isn't OpenCode-specific, but it surfaces the same way — a write that silently fails or errors ambiguously. - Less forgiving natural language for workflow actions. OpenCode's tool-calling tends to be more literal than Claude Code's about mapping phrases like "close it out" to actual transition names — you'll get better results being explicit about the exact status name from your workflow.
- No native diffing of Jira issue changes. If you ask OpenCode to update multiple fields on an issue, it won't show you a before/after diff the way it might show a code diff — you're relying on the tool call arguments printed in the conversation to know exactly what changed.
Tips
- Confirm connectivity with a real tool call rather than assuming a clean startup log means the Jira server is reachable — the two aren't always the same thing.
- Before promising sprint automation on a client's board, check whether it's company-managed or team-managed; the setting is under board settings and determines whether sprint-mutation tools will work at all.
- When updating multiple fields at once, ask the agent to state clearly what values it's changing to, in plain text, before the tool call — it's your substitute for a diff view.
Tips
OpenCode is a solid, lightweight client for Jira MCP once you learn to be explicit — it rewards precise JQL and exact workflow terminology more than it rewards conversational phrasing, and that trade-off is worth it for the transparency you get into each tool call.
Tips
- Keep your Jira MCP config at the project (opencode.json) level unless multiple unrelated repos genuinely need the same server.
- Front-load exact JQL and exact transition/status names in prompts — OpenCode performs noticeably better with explicit input than with inferred intent.
- Sanity-check sprint-planning or bulk-update output against real team constraints before treating it as final — the model only knows what's in Jira, not what's in your team's calendar.