agentleFS
vancebsvancebs/skills/atlassian-jira-confluence/SKILL.md

atlassian-jira-confluence

Skill1 starsChanged 6 months agoApache-2.0View on GitHub

This skill should be used when the user asks to "create a Jira issue", "update Confluence page", "search issues with JQL", "add comment to ticket", "get sprint info", or "list Confluence spaces". Supports all Jira and Confluence CRUD operations via atlassian-python-api SDK.

  • Installs packages

The file

We split this skill into the rules it gives an agent

3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    What this skill does: Create, read, update, and delete Jira issues/projects/sprints/boards and Confluence pages/spaces/attachments using …

    line 33
  2. Very specific:

    Create $WORKSPACE/.config/atlassian-jira-confluence.json (or ~/.config/atlassian-jira-confluence.json):

    line 60
  3. Distinctive:

    Always use this code block so config-file priority is respected automatically.

    line 198

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Atlassian Jira & Confluence Skill

What this skill does: Create, read, update, and delete Jira issues/projects/sprints/boards and Confluence pages/spaces/attachments using the atlassian-python-api SDK.

Requires: Python 3 + pip install atlassian-python-api (run once)


路径约定: 以下所有 scripts/... 路径均相对于本 Skill 目录(.agents/skills/atlassian-jira-confluence/)。

✅ Setup Checklist

Complete these steps once before using the skill.

Step 1 — Install SDK

pip install atlassian-python-api
# or: python -m pip install atlassian-python-api

It's safe to run multiple times.

Step 2 — Configure Credentials

Choose one of the two options below. Config file takes priority over env vars.

Option A — Config file (recommended for persistent setups)

Create $WORKSPACE/.config/atlassian-jira-confluence.json (or ~/.config/atlassian-jira-confluence.json):

{
  "JIRA_URL": "https://your-jira.example.com",
  "JIRA_PAT_TOKEN": "your-pat-token",
  "JIRA_USERNAME": "you@example.com",
  "CONFLUENCE_URL": "https://your-confluence.example.com",
  "CONFLUENCE_PAT_TOKEN": "your-pat-token",
  "CONFLUENCE_USERNAME": "you@example.com"
}

Option B — Environment variables

# Confluence
export CONFLUENCE_URL="https://your-confluence.example.com"
export CONFLUENCE_PAT_TOKEN="your-pat-token"
export CONFLUENCE_USERNAME="you@example.com"   # Cloud only

# Jira
export JIRA_URL="https://your-jira.example.com"
export JIRA_PAT_TOKEN="your-pat-token"
export JIRA_USERNAME="you@example.com"         # Cloud only

Windows CMD / PowerShell:

set JIRA_URL=https://your-jira.example.com
set JIRA_PAT_TOKEN=your-pat-token
set CONFLUENCE_URL=https://your-confluence.example.com
set CONFLUENCE_PAT_TOKEN=your-pat-token

PAT Token: Personal Access Token. On Atlassian Cloud, generate at https://id.atlassian.com/manage-profile/security/api-tokens (use as password).
*_USERNAME is only required for Atlassian Cloud (.atlassian.net).

Step 3 — Test the Connection

# Save as test_connection.py and run: python test_connection.py
import sys, os
from atlassian import Jira

# (paste get_jira() helper below here, or copy from the Initialize Clients section)
jira = get_jira()
print(jira.myself())

⚡ Quick Reference

TaskSDK call
Create issuejira.issue_create(fields={...})
Get issuejira.issue("PROJ-123")
Update issuejira.update_issue_field("PROJ-123", fields={...})
Transition issuejira.transition_issue("PROJ-123", "Done")
JQL searchjira.jql("project=PROJ AND status='Open'", limit=50)
Add commentjira.add_comment("PROJ-123", "Comment text")
Create Confluence pageconfluence.create_page("SPACE", "Title", "<p>Body</p>")
Get page by titleconfluence.get_page_by_title("SPACE", "Title")
Update pageconfluence.update_page(page_id, "Title", "<p>New body</p>")
Search Confluence (CQL)confluence.cql('space="SPACE" AND text~"keyword"', limit=20)

📋 Task Workflows

Workflow A — Triage / Update a Jira Issue (Step-by-Step Checklist)

  • 1. Install SDK if needed: pip install atlassian-python-api
  • 3. Copy the Initialize Clients code block below into the script
  • 4. Search for issues:
    issues = jira.jql("project = PROJ AND status = 'To Do' ORDER BY priority DESC", limit=20)
    for issue in issues.get("issues", []):
        print(issue["key"], issue["fields"]["summary"])
  • 5. Get full details of a specific issue:
    issue = jira.issue("PROJ-123")
    print(issue["fields"]["status"]["name"])
  • 6. Update a field:
    jira.update_issue_field("PROJ-123", fields={"priority": {"name": "High"}})
  • 7. Transition to new status:
    jira.transition_issue("PROJ-123", "In Progress")
  • 8. Add a comment:
    jira.add_comment("PROJ-123", "Investigating root cause.")

Workflow B — Create / Update a Confluence Page (Step-by-Step Checklist)

  • 1. Copy the Initialize Clients code block below into the script
  • 3. Find the target space key (list all spaces):
    spaces = confluence.get_all_spaces(start=0, limit=50)
    for s in spaces.get("results", []):
        print(s["key"], s["name"])
  • 4. Check if the page already exists:
    page = confluence.get_page_by_title("MYSPACE", "My Page Title")
  • 5a. If page does NOT exist — create it:
    result = confluence.create_page(
        space="MYSPACE",
        title="My Page Title",
        body="<p>Content in storage format.</p>",
        parent_id=None,   # or a parent page ID
    )
    print(result["id"], result["_links"]["webui"])
  • 5b. If page EXISTS — update it:
    page_id = page["id"]
    confluence.update_page(page_id, "My Page Title", "<p>Updated content.</p>")
  • 6. (Optional) Add a label:
    confluence.set_page_label(page_id, "my-label")

Initialize Clients (Code Template)

Always use this code block so config-file priority is respected automatically.

import json, os
from pathlib import Path
from atlassian import Jira, Confluence


def _load_skill_config(skill_name: str) -> dict:
    """Load {cwd}/.config/{skill}.json or ~/.config/{skill}.json."""
    for p in [Path.cwd() / ".config" / f"{skill_name}.json",
              Path.home() / ".config" / f"{skill_name}.json"]:
        if p.is_file():
            try:
                d = json.loads(p.read_text(encoding="utf-8"))
                return d if isinstance(d, dict) else {}
            except (json.JSONDecodeError, OSError):
                pass
    return {}


def _is_cloud(url: str) -> bool:
    return "atlassian.net" in url


def get_jira():
    """Return authenticated Jira client (config file preferred, env vars fallback)."""
    cfg   = _load_skill_config("atlassian-jira-confluence")
    url   = (cfg.get("JIRA_URL") or os.environ.get("JIRA_URL", "")).strip().rstrip("/")
    token = (cfg.get("JIRA_PAT_TOKEN") or os.environ.get("JIRA_PAT_TOKEN", "")).strip()
    user  = (cfg.get("JIRA_USERNAME") or os.environ.get("JIRA_USERNAME", "")).strip()
    if not url or not token:
        raise EnvironmentError(
            "Jira credentials missing.\n"
            "  Option 1: create .config/atlassian-jira-confluence.json with JIRA_URL and JIRA_PAT_TOKEN\n"
            "  Option 2: set JIRA_URL and JIRA_PAT_TOKEN environment variables."
        )
    if _is_cloud(url):
        return Jira(url=url, username=user, password=token, cloud=True)
    return Jira(url=url, token=token)


def get_confluence():
    """Return authenticated Confluence client (config file preferred, env vars fallback)."""
    cfg   = _load_skill_config("atlassian-jira-confluence")
    url   = (cfg.get("CONFLUENCE_URL") or os.environ.get("CONFLUENCE_URL", "")).strip().rstrip("/")
    token = (cfg.get("CONFLUENCE_PAT_TOKEN") or os.environ.get("CONFLUENCE_PAT_TOKEN", "")).strip()
    user  = (cfg.get("CONFLUENCE_USERNAME") or os.environ.get("CONFLUENCE_USERNAME", "")).strip()
    if not url or not token:
        raise EnvironmentError(
            "Confluence credentials missing.\n"
            "  Option 1: create .config/atlassian-jira-confluence.json with CONFLUENCE_URL and CONFLUENCE_PAT_TOKEN\n"
            "  Option 2: set CONFLUENCE_URL and CONFLUENCE_PAT_TOKEN environment variables."
        )
    if _is_cloud(url):
        return Confluence(url=url, username=user, password=token, cloud=True)
    return Confluence(url=url, token=token)

Configuration Reference

Config Reference

Env varRequiredDescription
JIRA_URL✅Jira base URL, e.g. https://your-jira.example.com
JIRA_PAT_TOKEN✅Jira Personal Access Token
JIRA_USERNAMECloud onlyAtlassian account email
CONFLUENCE_URL✅Confluence base URL, e.g. https://your-confluence.example.com
CONFLUENCE_PAT_TOKEN✅Confluence Personal Access Token
CONFLUENCE_USERNAMECloud onlyAtlassian account email

Set env vars:

export JIRA_URL="https://your-jira.example.com"
export JIRA_PAT_TOKEN="your-pat-token"
export CONFLUENCE_URL="https://your-confluence.example.com"
export CONFLUENCE_PAT_TOKEN="your-pat-token"

Windows CMD: set VAR=value | PowerShell: $env:VAR = "value"


Execution Rules (Important for All Models)

  1. Always call load_config() at the start — it reads from environment variables.
  2. Handle errors gracefully:
    from atlassian.errors import ApiError
    try:
        result = jira.issue("PROJ-123")
    except ApiError as e:
        print(f"API error {e.status_code}: {e.reason}")
    except Exception as e:
        print(f"Error: {e}")

Jira Operations Reference

Full reference: references/jira-operations.md

CategoryOperations
Issuescreate, read, update, delete, transition, link, clone, archive
SearchJQL queries, CQL autocomplete, CSV export
Comments & Worklogsadd/edit/delete comments, log time
Attachmentsupload files, download all
ProjectsCRUD, components, versions, issue types, permissions
Boards & SprintsAgile boards, sprint management, backlog
Users & Groupslookup, create groups, manage membership
Epicsepic issues, move to backlog
Adminreindex, permissions, application properties, custom fields

Confluence Operations Reference

Full reference: references/confluence-operations.md

CategoryOperations
Pagescreate, read, update, delete, move, append, export as PDF
Spaceslist, get, archive, permissions, export
Attachmentsupload file/content, download, delete, version history
Labelsadd/remove labels on pages
Commentsadd inline and page-level comments
Templatescreate, update, list, delete global/space templates
Whiteboardscreate, get, delete (Cloud only)
Search (CQL)full-text and structured search
Permissionsspace-level for users, groups, anonymous
Propertiesset/get/delete page properties and inline task checkboxes

Quick Examples

Create a Jira Issue

fields = {
    "project": {"key": "PROJ"},
    "summary": "Fix login bug",
    "description": "Users cannot log in with SSO.",
    "issuetype": {"name": "Bug"},
    "priority": {"name": "High"},
}
new_issue = jira.issue_create(fields=fields)
print(new_issue["key"])

JQL Search

issues = jira.jql("project = PROJ AND status = 'In Progress' ORDER BY created DESC", limit=50)
for issue in issues.get("issues", []):
    print(issue["key"], issue["fields"]["summary"])

Create a Confluence Page

body = "<p>This is the page content in storage format.</p>"
result = confluence.create_page(
    space="MYSPACE",
    title="My New Page",
    body=body,
    parent_id=None,  # or pass a parent page ID
)
print(result["id"], result["_links"]["webui"])

Search Confluence with CQL

results = confluence.cql('space = "MYSPACE" AND type = page AND text ~ "deployment"', limit=20)
for item in results.get("results", []):
    print(item["title"], item["_links"]["webui"])

⛔ 约束与禁止事项

不支持的场景

场景原因处理动作
HTTP 401 Unauthorizedtoken / 密码错误或已过期终止并提示用户重新生成 API token;不重试
HTTP 403 Forbidden账号无该操作权限终止并提示用户联系管理员授权;不重试
HTTP 404 Not FoundIssue key / page ID / space key 不存在终止当前操作,输出明确错误;不继续依赖该资源的后续步骤
HTTP 429 Rate Limited请求频率超限等待响应头 Retry-After 秒数后重试一次;仍失败则终止
HTTP 5xx Server Error服务端故障最多重试 3 次(指数退避 1s/2s/4s),超限后输出错误并终止
响应体非 JSON / 解析失败代理层返回 HTML 错误页输出原始响应前 200 字符,提示用户检查 url 配置
创建页面时父页面不存在parent_id 无效先调用 confluence.get_page_by_id(parent_id) 验证存在,不存在则停止并提示
JQL / CQL 语法错误查询字符串格式错误捕获 ApiError(400),输出错误信息,提示用户修正查询语法
并发编辑 Confluence 页面(版本冲突)另一用户同时编辑捕获 ApiError(409),获取最新版本号后重试一次;仍冲突则停止并提示
附件大小超过实例限制(通常 50–250 MB)服务端拒绝上传前检查文件大小;超过 50 MB 时提示用户确认服务端限制

明确禁止的操作

  • ⛔ 禁止硬编码 url, username, api_token:必须从环境变量读取
  • ⛔ 禁止在日志/输出中打印 api_token 或 password:不论任何错误情况
  • ⛔ 禁止在没有环境变量时静默使用空凭据运行:必须 exit 1 并提示配置
  • ⛔ 禁止 delete 操作不经用户确认:删除 Jira issue、Confluence page、space 前必须在报告中列明将要删除的内容,等待用户确认

边界条件

参数范围超限行为
JQL / CQL limit1–1000;推荐 ≤ 100超过 1000 → 截断为 1000,记录 WARNING
Confluence page body 大小推荐 < 5 MB超过 5 MB → 警告用户,发布可能超时
附件文件大小≤ 50 MB(默认实例限制)超限前提示用户;不自动分块上传
JQL 字符串长度≤ 32768 字符超限 → 截断并输出 WARNING

幂等性声明

操作幂等性说明
jira.issue(), confluence.get_page_by_id()✅ 幂等只读操作
jira.issue_create(), confluence.create_page()❌ 非幂等重复调用会创建重复条目;调用方负责先检查是否存在
jira.issue_update(), confluence.update_page()⚠️ 非幂等(有版本保护)需传入正确版本号(version.number);否则返回 409
jira.transition_issue()⚠️ 非幂等(有保护)Jira 会拒绝已处于目标状态的转换(返回 400)

For the complete API reference with all method signatures, see:

  • references/jira-operations.md
  • references/confluence-operations.md
  • scripts/setup_check.py — verifies environment and SDK installation

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.