$npx -y skills add testdouble/han --skill markdown-to-confluencePublishes a local Markdown file to a user-specified Confluence location, creating a new page or updating an existing one through the Atlassian MCP server. Use when the user wants to post, publish, push, or sync a Markdown file to a Confluence space or page. Requires a configured
| 1 | # Markdown to Confluence |
| 2 | |
| 3 | This skill takes one local Markdown file and publishes it to a Confluence |
| 4 | location that **the user must specify** — creating a new page or updating an |
| 5 | existing one through the Atlassian MCP server. It owns everything about the |
| 6 | posting itself: the MCP preflight, resolving the destination, reading the file, |
| 7 | the create-or-update call, and reporting the result. It does not write the |
| 8 | Markdown; the caller supplies an existing file. |
| 9 | |
| 10 | Callers that supply an explicit publish mode and location (for example |
| 11 | `han-atlassian:project-documentation-to-confluence`) run this skill straight through without |
| 12 | re-asking. Invoked on its own with pieces missing, it asks for them and defaults |
| 13 | to a safe unpublished draft. |
| 14 | |
| 15 | ## Step 0: Atlassian MCP Preflight (hard requirement) |
| 16 | |
| 17 | This skill cannot run without a configured and connected Atlassian MCP server. |
| 18 | |
| 19 | Confirm the server is reachable by calling |
| 20 | `mcp__claude_ai_Atlassian__getAccessibleAtlassianResources` to retrieve the |
| 21 | cloud ID(s). If the tool is not available, the call errors, or it returns no |
| 22 | accessible resources (typically an authentication or configuration problem), |
| 23 | **stop immediately**. Tell the user this skill requires the Atlassian MCP server |
| 24 | to be installed, configured, and authenticated, and that they can re-run the |
| 25 | skill once it is connected. |
| 26 | |
| 27 | If more than one cloud / site is accessible, note which sites are available; |
| 28 | you will confirm the correct one while resolving the location in Step 2. |
| 29 | |
| 30 | ## Step 1: Confirm the Source Markdown File |
| 31 | |
| 32 | Resolve the Markdown file path from the arguments or conversation. Read it and |
| 33 | confirm it exists and has content. If no file path was provided, or the path |
| 34 | does not resolve to a readable file, ask the user for the path with |
| 35 | `AskUserQuestion` and do not proceed without one. This is the exact content that |
| 36 | will be posted; do not rewrite, summarize, or restructure it. |
| 37 | |
| 38 | A body may legitimately contain embedded Confluence storage macros mixed into the |
| 39 | Markdown — for example, an orchestrating skill such as |
| 40 | `han-atlassian:plan-a-feature-to-confluence` rewrites its cross-page links into |
| 41 | title-based page-link macros (the `<ac:link><ri:page ri:content-title="..."/>…</ac:link>` |
| 42 | form, link body included) before handing the file over. Post these verbatim along |
| 43 | with the rest of the body; do not strip or escape them. |
| 44 | |
| 45 | ## Step 2: Resolve the Target Confluence Location (required) |
| 46 | |
| 47 | **This skill does not search Confluence for the right place.** A typical |
| 48 | Confluence instance is large and full of duplicate or similarly-named pages, so |
| 49 | guessing the destination is unreliable. The user must name the exact location. |
| 50 | |
| 51 | 1. **Find a location in the request.** Check the arguments and conversation for |
| 52 | either of: |
| 53 | - a **Confluence page URL** (to update that page, or to create a child page |
| 54 | under it), or |
| 55 | - a **space** (key or name) plus an optional **parent page** (title, ID, or |
| 56 | URL). |
| 57 | 2. **If no location was provided, ask for one.** Use `AskUserQuestion` to |
| 58 | request it, and explain plainly that the skill needs an exact destination |
| 59 | because it does not search Confluence. Offer both accepted forms (a page URL, |
| 60 | or a space plus parent page). This is required: do not proceed without a |
| 61 | location. |
| 62 | 3. **Resolve the location concretely now, so failures surface early.** Use the |
| 63 | cloud ID from Step 0 for every call. |
| 64 | - **From a page URL:** extract the page ID from the `/pages/<id>/` segment and |
| 65 | call `mcp__claude_ai_Atlassian__getConfluencePage` to confirm it exists and |
| 66 | to read its space and title. Then determine the intent: **update that page**, |
| 67 | or **create a new child page under it**. If the user did not already say, |
| 68 | ask with `AskUserQuestion`. |
| 69 | - **From a space (+ parent):** call |
| 70 | `mcp__claude_ai_Atlassian__g |