Generate project status reports from Jira issues and publish to Confluence...
status report, project status, weekly update, daily standup, Jira report, project summary, blockers, progress update, Confluence report, sprint report, project update, publish to Confluence, write to Confluence, post report
Automatically query Jira for project status, analyze issues, and generate formatted status reports published to Confluence.
CRITICAL: This skill should be interactive. Always clarify scope (time period, audience, Confluence destination) with the user before or after generating the report. Do not silently skip Confluence publishingβalways offer it.
Generating a status report follows these steps:
IMPORTANT: If the user's request is missing key information, ASK before proceeding with queries. Do not assume defaults without confirmation for Confluence publishing.
Clarify these details:
Project identification:
Time period:
Target audience:
Report destination:
Use the searchJiraIssuesUsingJql tool to fetch issues. Build JQL queries based on report needs.
For comprehensive queries, use the scripts/jql_builder.py utility to programmatically build JQL strings. For quick queries, reference references/jql-patterns.md for examples.
All open issues in project:
project = "PROJECT_KEY" AND status != Done ORDER BY priority DESC, updated DESC
Issues updated in last week:
project = "PROJECT_KEY" AND updated >= -7d ORDER BY priority DESC
High priority and blocked issues:
project = "PROJECT_KEY" AND (priority IN (Highest, High) OR status = Blocked) AND status != Done ORDER BY priority DESC
Completed in reporting period:
project = "PROJECT_KEY" AND status = Done AND resolved >= -7d ORDER BY resolved DESC
For most reports, execute multiple targeted queries rather than one large query:
Use maxResults: 100 for initial queries. If pagination is needed, use nextPageToken from results.
For each issue, capture:
key (e.g., "PROJ-123")summary (issue title)status (current state)priority (importance level)assignee (who's working on it)created / updated / resolved datesdescription (if needed for context on blockers)Process the retrieved issues to identify:
Metrics:
Key insights:
Categorization: Group issues logically:
Select the appropriate template based on audience. Templates are in references/report-templates.md.
Use Executive Summary Format:
Keep it concise - 1-2 pages maximum. Focus on what matters to decision-makers.
Use Detailed Technical Format:
Include more detail - Team needs issue-level visibility.
Use Daily Standup Format:
Keep it brief - This is a quick sync, not comprehensive analysis.
After generating the report, ALWAYS offer to publish to Confluence (unless user explicitly said not to).
If user hasn't specified Confluence details yet, ask:
Use the createConfluenceContent tool to publish the report.
Before authoring the body, load the authoring guidance. getContentFormatGuide is not a
primary tool, so run it through execute (see Calling non-primary tools).
Note that toolName takes the
content key createConfluencePage, not the name of the tool you are about to call:
executeRead( # or execute(...) if your client exposes a single execute tool
name="getContentFormatGuide",
inputs={"toolName": "createConfluencePage"}
)
Never skip the body because the guidance failed to load β load it first, then build a real body.
Then load the space instructions. Spaces can carry durable authoring guidance that is authoritative and overrides authoring defaults on conflict. Apply this decision rule:
getConfluenceContent call for content in the target space returned
metadata.hasSpaceInstructions=false.getConfluenceSpace once before authoring:executeRead( # or execute(...) if your client exposes a single execute tool
name="getConfluenceSpace",
cloudId="...",
inputs={"spaceIdOrKey": "[space ID or key]"}
)
spaceInstructions. If a successful response omits them, no instructions
are configured β author with defaults and do not block.Reuse the result for the rest of the task: do not call getConfluenceSpace again for the same
space, and do not follow it with a separate getConfluenceSpaceInstructions call.
Page creation:
createConfluenceContent(
cloudId="[obtained from listConfluenceSpaces or URL]",
parent={"spaceId": "[numerical space ID]"},
contentType="page",
title="[Project Name] - Status Report - [Date]",
body={"format": "markdown", "value": "[formatted report]"}
)
To nest the report under an existing page, add parentContentId to parent:
parent={"spaceId": "[numerical space ID]", "parentContentId": "[parent page ID]"},
Title format examples:
Body formatting:
Write the report content in Markdown and pass it as body={"format": "markdown", "value": ...},
following the spec returned by getContentFormatGuide. Use:
#, ##, ###) for structure**text**) for emphasis[PROJ-123](https://yourinstance.atlassian.net/browse/PROJ-123)Best practices:
If the user doesn't specify a Confluence space:
listConfluenceSpaces to list available spaces. This is not a primary tool, so run it
through execute: executeRead(name="listConfluenceSpaces", cloudId="...")If updating an existing page instead of creating new:
detail="full" returns the body (the default summary returns
only a title, excerpt, and counts), and the doc-type response carries the snapshotToken you
must pass back on the update, plus metadata.hasSpaceInstructions for step 3:getConfluenceContent(
cloudId="...",
content_id="123456",
content_format="markdown",
detail="full",
include_metadata=True
)
toolName is the content key, not the tool you call):executeRead( # or execute(...) if your client exposes a single execute tool
name="getContentFormatGuide",
inputs={"toolName": "updateConfluencePage"}
)
metadata.hasSpaceInstructions=false. Reuse
the result if you already loaded it for this space during this task:executeRead( # or execute(...) if your client exposes a single execute tool
name="getConfluenceSpace",
cloudId="...",
inputs={"spaceIdOrKey": "[space ID or key]"}
)
snapshotToken is required for document edits β pass the
value from the step 1 response. Omitting it will fail the update:updateConfluenceContent(
cloudId="...",
contentId="123456",
snapshotToken="[snapshotToken from the step 1 response]",
body={"format": "markdown", "value": "[updated report content]"},
versionMessage="Updated with latest status - Dec 8, 2025"
)
Concurrency note: the
snapshotTokenties your edit to the version you read. Do not reuse a stale token across edits β re-read the content withgetConfluenceContentbefore each update.
User request: "Generate a status report for Project Phoenix and publish it to Confluence"
Step 1 - Identify scope:
Step 2 - Query Jira:
# Find project key first
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHOENIX" OR project = "PHX"',
maxResults=1
)
# Query completed issues
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status = Done AND resolved >= -7d',
maxResults=50
)
# Query blocked issues
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status = Blocked',
maxResults=50
)
# Query in-progress high priority
searchJiraIssuesUsingJql(
cloudId="...",
jql='project = "PHX" AND status IN ("In Progress", "In Review") AND priority IN (Highest, High)',
maxResults=50
)
Step 3 - Analyze:
Step 4 - Format: Use Executive Summary Format from templates. Create concise report with metrics, highlights, and blockers.
Step 5 - Publish:
# Find appropriate space (not a primary tool - run it through execute)
executeRead(name="listConfluenceSpaces", cloudId="...")
# Load authoring guidance before composing the body
executeRead(name="getContentFormatGuide", inputs={"toolName": "createConfluencePage"})
# Load space instructions (skip only if hasSpaceInstructions was false for this space)
executeRead(name="getConfluenceSpace", cloudId="...", inputs={"spaceIdOrKey": "PHX"})
# Create page
createConfluenceContent(
cloudId="...",
parent={"spaceId": "12345"},
contentType="page",
title="Project Phoenix - Weekly Status - Dec 3, 2025",
body={"format": "markdown", "value": "[formatted markdown report]"}
)
Be data-driven:
Highlight what matters:
Make it actionable:
Keep it consistent:
Provide context:
Python utility for programmatically building JQL queries. Use this when you need to construct complex or dynamic queries. Import and use the helper functions rather than manually concatenating JQL strings.
Quick reference of common JQL query patterns for status reports. Use this for standard queries or as a starting point for custom queries.
Detailed templates for different report types and audiences. Reference this to select the appropriate format and structure for your report.
The Atlassian Rovo MCP server exposes only a small set of primary tools directly in your tool list. Everything else lives in the catalog and is reached through meta-tools:
discover β describe the goal in natural language when you do not know an operation's name.
It returns the exact name and inputs to use. Do not call discover for an operation you
already have as a primary tool.execute, others expose executeRead / executeWrite /
executeDestructive and expect the tier matching the operation. The arguments are identical:executeRead( # or execute(...) if your client exposes a single execute tool
name="<operationName>",
cloudId="...",
inputs={"param": "value"}
)
Rules that matter:
cloudId is a top-level argument, a sibling of name and inputs β never put it inside
inputs. Operations declared omitCloudId (such as getContentFormatGuide) take no cloudId.inputs is a flat object. The server routes each parameter to path, query, or body itself.discover result first.discover with different keywords and use the
name it returns rather than guessing.