A Claude Code plugin that mediates interaction with the Atlassian MCP server, keeping Jira and Confluence responses focused and context-efficient.
The Atlassian MCP server returns verbose JSON. A single Confluence page fetch can consume thousands of tokens; a JQL search dumping 20 full issue objects is worse. Without mediation, every Atlassian interaction risks flooding the context window with noise.
- Digest-first output: Summaries by default, full content only on request
- Targeted queries: JQL/CQL patterns that fetch only what's needed
- cloudId injection: A
SessionStarthook loads yourcloud_idfrom a settings file and injects it into the session, so it's never redundantly fetched - Structured research: An autonomous agent for multi-step Atlassian research that keeps raw intermediate results out of the main conversation
| Component | Type | Purpose |
|---|---|---|
atlassian-mediation |
Skill | Teaches Claude the discipline of efficient Atlassian interaction |
/jira |
Command | Search Jira, look up an issue, or create one with digest output |
/confluence |
Command | Search Confluence or fetch a page with digest output |
atlassian-researcher |
Agent | Multi-step autonomous research across Jira + Confluence |
load-atlassian-config |
Hook | SessionStart hook that injects your cloud_id/site_url into each session |
- Atlassian MCP server configured in Claude Code
(
mcp__claude_ai_Atlassian__*tools available) - An Atlassian account with access to your workspace
-
Install the plugin in Claude Code:
/plugin marketplace add MatthewMaker/lean-atlassian /plugin install lean-atlassian@lean-atlassian -
Create your settings file. The plugin's
SessionStarthook looks forlean-atlassian.local.mdin two places, project first, then global:- Global (every project): in your Claude config dir
(
$CLAUDE_CONFIG_DIR, typically~/.claude) - Per-project (overrides global for one repo):
.claude/lean-atlassian.local.md
# global — available everywhere cp .claude/lean-atlassian.local.md.example \ "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/lean-atlassian.local.md"
- Global (every project): in your Claude config dir
(
-
Find your cloud ID — ask Claude:
"What is my Atlassian cloud ID?"
Claude will call
getAccessibleAtlassianResourcesand display it. -
Edit the file you just created:
--- cloud_id: "your-cloud-id-here" site_url: "https://your-org.atlassian.net" ---
Neither location is committed. (If you skip this step, the first
/jiraor/confluencecall will look the ID up via MCP and offer to save it for you.)
/jira PROJ-123
/jira my open bugs
/jira project = MYPROJ AND status = "In Progress"
/jira create bug: Frontend: Fix login button
/jira new Backend: rate-limit the search endpoint
/confluence deployment runbooks
/confluence auth docs in ENG space
/confluence 123456789
Ask naturally:
"Research the background on the auth refactor — check Jira and Confluence."
"Give me a complete picture of PROJ-456: linked issues, history, related docs."
"What Confluence pages exist about our deployment process?"
The atlassian-mediation skill activates automatically whenever you ask Claude
to look up Jira or Confluence content, enforcing context-efficient behavior
without any explicit invocation.
Settings live in lean-atlassian.local.md, loaded by the SessionStart
hook from a cascading lookup (first match wins):
- Per-project —
.claude/lean-atlassian.local.mdin the project root - Global —
lean-atlassian.local.mdin your Claude config dir ($CLAUDE_CONFIG_DIR, typically~/.claude)
Both locations are outside the plugin repo and never committed. See
.claude/lean-atlassian.local.md.example for the template.
This plugin was previously called private-atlassian. Both tiers still accept
a private-atlassian.local.md file, checked after the current name, so an
existing settings file keeps working with no migration. Rename it at your
convenience.
| Field | Description |
|---|---|
cloud_id |
Atlassian workspace UUID (required) |
site_url |
Your Atlassian site URL, e.g. https://acme.atlassian.net |
account_id |
Optional — your Jira accountId; injected so self-assignment skips an atlassianUserInfo lookup |
project_key |
Optional — default project key for searches and new issues |
component_prefix_strip |
Optional — strip a matched Prefix: from a new issue's summary once mapped to a Component (default true) |
The account_id and project_key scalars are injected at SessionStart like
cloud_id. Nested caches — a per-project Component list and a
name → accountId people map — are maintained automatically in the settings
file body and read lazily only when creating issues, so they cost no session
context until used.
When you create a Jira issue whose summary starts with one or more Token:
prefixes (e.g. "Frontend: Backend: Fix login button"), each prefix is matched
case-insensitively against the target project's existing Components and every
match is added to the issue. Unmatched prefixes stay in the summary — nothing is
invented. By default the matched prefixes are stripped from the summary; set
component_prefix_strip: false to keep it verbatim. Component names are
discovered from the project and cached locally so repeat creates skip the lookup.
No build step. Checks, runnable from anywhere in the repo:
tests/hook-cascade.sh # SessionStart hook: precedence, scalars, JSON escaping
tests/manifest-invariants.sh # manifest structure; version declared exactly once
shellcheck plugins/*/hooks/*.sh tests/*.sh
claude plugin validate .CI runs all four on every pull request. See CHANGELOG.md for version history.
MIT — see LICENSE.