<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tariqul Islam Ronnie</title>
    <description>The latest articles on DEV Community by Tariqul Islam Ronnie (@tariqulislam).</description>
    <link>https://dev.to/tariqulislam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F466542%2F4df94a4f-8e57-4879-b095-02c030391e9a.png</url>
      <title>DEV Community: Tariqul Islam Ronnie</title>
      <link>https://dev.to/tariqulislam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tariqulislam"/>
    <language>en</language>
    <item>
      <title># Building a Confluence MCP Server for Claude Code: From Setup to Skills</title>
      <dc:creator>Tariqul Islam Ronnie</dc:creator>
      <pubDate>Tue, 16 Jun 2026 14:32:23 +0000</pubDate>
      <link>https://dev.to/tariqulislam/-building-a-confluence-mcp-server-for-claude-code-from-setup-to-skills-k95</link>
      <guid>https://dev.to/tariqulislam/-building-a-confluence-mcp-server-for-claude-code-from-setup-to-skills-k95</guid>
      <description>&lt;p&gt;Automate your Confluence workflow directly from Claude Code — publish pages, sync content, and upload images without leaving your terminal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/tariqulislam/confluence-mcp-server" rel="noopener noreferrer"&gt;https://github.com/tariqulislam/confluence-mcp-server&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What is an MCP Server?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP&lt;/strong&gt; stands for &lt;strong&gt;Model Context Protocol&lt;/strong&gt; — an open standard that lets AI assistants like Claude Code connect to external tools and services. An MCP server acts as a bridge: it exposes a set of &lt;em&gt;tools&lt;/em&gt; that Claude Code can call, allowing it to interact with third-party systems (like Confluence) on your behalf.&lt;/p&gt;

&lt;p&gt;In this guide you will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the Confluence MCP server is structured&lt;/li&gt;
&lt;li&gt;How environment variables wire credentials into the server&lt;/li&gt;
&lt;li&gt;How the server is registered with Claude Code&lt;/li&gt;
&lt;li&gt;How Claude Code Skills wrap the tools into friendly slash commands&lt;/li&gt;
&lt;li&gt;How to use every skill end-to-end&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;confluence-mcp-mock/
├── .env                     ← your credentials (never committed)
├── .env.example             ← template
├── .mcp.json                ← registers MCP servers with Claude Code
├── confluence-mcp/
│   ├── src/
│   │   ├── index.ts         ← entry point
│   │   ├── server.ts        ← tool registration
│   │   ├── config.ts        ← env validation (Zod)
│   │   ├── confluence/
│   │   │   ├── client.ts    ← Axios HTTP client
│   │   │   ├── api.ts       ← REST API calls
│   │   │   ├── parser.ts    ← XHTML to structured data
│   │   │   └── markdown-converter.ts
│   │   └── tools/           ← one file per MCP tool
│   │       ├── connection-check.ts
│   │       ├── list-pages.ts
│   │       ├── publish-page.ts
│   │       ├── read-save-page.ts
│   │       ├── upload-images.ts
│   │       └── sync-pages.ts
│   └── build/               ← compiled output
└── .claude/skills/          ← slash command definitions
    ├── confluence-conn-check/
    ├── confluence-page-list/
    ├── publish-to-confluence/
    ├── confluence-upload-images/
    └── confluence-sync-pages/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1 — Configure Your .env File
&lt;/h2&gt;

&lt;p&gt;The server reads all credentials from a single &lt;code&gt;.env&lt;/code&gt; file at the project root. Copy the example template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then fill in the four Confluence variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .env  (never commit this file)&lt;/span&gt;
&lt;span class="nv"&gt;CONFLUENCE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://your-confluence-instance.com/confluence/
&lt;span class="nv"&gt;CONFLUENCE_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your.email@company.com
&lt;span class="nv"&gt;CONFLUENCE_PERSONAL_ACCESS_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_token_here
&lt;span class="nv"&gt;CONFLUENCE_SPACE_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MYSPACE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four variables you need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONFLUENCE_URL&lt;/strong&gt; — Base URL of your Confluence instance. Must end with a trailing slash.&lt;br&gt;
Example: &lt;code&gt;https://confluence.company.com/confluence/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONFLUENCE_USER&lt;/strong&gt; — The email address tied to your Confluence account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONFLUENCE_PERSONAL_ACCESS_TOKEN&lt;/strong&gt; — A Bearer token generated in Confluence settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CONFLUENCE_SPACE_KEY&lt;/strong&gt; — The space key where new pages will be created. Example: &lt;code&gt;ENGINEERING&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  How to generate a Personal Access Token
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log into Confluence and click your avatar → &lt;strong&gt;Profile&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Personal Access Tokens&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create token&lt;/strong&gt;, give it a name, set an expiry date&lt;/li&gt;
&lt;li&gt;Copy the token immediately — it is shown only once&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  Step 2 — How the Server Loads Credentials
&lt;/h2&gt;

&lt;p&gt;When the server starts, &lt;code&gt;config.ts&lt;/code&gt; reads the &lt;code&gt;.env&lt;/code&gt; file and validates every variable using &lt;strong&gt;Zod&lt;/strong&gt; — a TypeScript schema library. If any variable is missing or malformed, the server exits with a clear error instead of failing silently later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// confluence-mcp/src/config.ts  (simplified)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;dotenv&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;dotenv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;envSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;CONFLUENCE_URL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;CONFLUENCE_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;CONFLUENCE_PERSONAL_ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;CONFLUENCE_SPACE_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;envSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The validated config is imported by &lt;code&gt;client.ts&lt;/code&gt;, which creates a single Axios instance used by every tool:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// confluence-mcp/src/confluence/client.ts  (simplified)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONFLUENCE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;CONFLUENCE_PERSONAL_ACCESS_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Credentials are set once here and never repeated anywhere else in the codebase.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Register the Server with Claude Code
&lt;/h2&gt;

&lt;p&gt;Claude Code discovers MCP servers through the &lt;code&gt;.mcp.json&lt;/code&gt; file in the project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"confluence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"./confluence-mcp/build/index.js"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Claude Code: &lt;em&gt;"When this project is open, launch the node process at that path and communicate with it over stdio."&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4 — Build and Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;confluence-mcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Compile TypeScript to JavaScript&lt;/span&gt;
npm run build

&lt;span class="c"&gt;# Restart Claude Code to load the new server&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During development, use watch mode so the server recompiles on every save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run watch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Understanding the Server Architecture
&lt;/h2&gt;

&lt;p&gt;The server follows a clean three-layer pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Claude Code
    │  (MCP protocol over stdio)
    ▼
server.ts         ← registers tools, routes calls
    │
    ▼
tools/*.ts        ← one file per tool, handles input/output
    │
    ▼
confluence/api.ts ← REST API calls (Confluence v1 endpoints)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How a tool is registered
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;server.ts&lt;/code&gt; declares every tool's name, description, and input schema in the &lt;code&gt;ListToolsRequestSchema&lt;/code&gt; handler. Claude Code reads this to understand what tools exist. Calls are then routed in the &lt;code&gt;CallToolRequestSchema&lt;/code&gt; handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.ts  (simplified)&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ListToolsRequestSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_connection_check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Verify connection to Confluence and check authentication.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_list_pages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List all child pages under a parent page.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;parent_page_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ID of the parent page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;parent_page_id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setRequestHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;CallToolRequestSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_connection_check&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;handleConnectionCheck&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_list_pages&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;handleListPages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Available MCP Tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;confluence_connection_check&lt;/strong&gt; — Verifies auth and returns server/user info&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confluence_list_pages&lt;/strong&gt; — Lists all child pages under a parent&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confluence_read_save_page&lt;/strong&gt; — Downloads a page (sections, tables, images, comments) to local JSON&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confluence_publish_page&lt;/strong&gt; — Converts markdown to Confluence XHTML and creates/updates a page&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confluence_upload_images&lt;/strong&gt; — Bulk-uploads images from a local directory as page attachments&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;confluence_sync_pages&lt;/strong&gt; — Syncs all child pages to local markdown with change tracking&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6 — Creating Skills (Slash Commands)
&lt;/h2&gt;

&lt;p&gt;Skills are the user-friendly layer on top of raw MCP tools. A skill is a directory under &lt;code&gt;.claude/skills/&lt;/code&gt; containing a &lt;code&gt;SKILL.md&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.claude/skills/confluence-conn-check/
└── SKILL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SKILL.md format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;confluence-conn-check&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Verify Confluence server connection and authentication.&lt;/span&gt;
&lt;span class="na"&gt;argument-hint&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;(no arguments required)&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="c1"&gt;# Confluence Connection Check&lt;/span&gt;

&lt;span class="s"&gt;Test the connection to Confluence and verify your credentials.&lt;/span&gt;

&lt;span class="c1"&gt;## Usage&lt;/span&gt;

&lt;span class="s"&gt;/confluence-conn-check&lt;/span&gt;

&lt;span class="c1"&gt;## MCP Tool&lt;/span&gt;

&lt;span class="s"&gt;confluence_connection_check&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The three frontmatter fields that matter:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;name&lt;/strong&gt; — becomes the slash command (e.g. &lt;code&gt;/confluence-conn-check&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;description&lt;/strong&gt; — shown in the &lt;code&gt;/&lt;/code&gt; autocomplete menu and used for auto-discovery by Claude&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;argument-hint&lt;/strong&gt; — hint shown in autocomplete, e.g. &lt;code&gt;&amp;lt;parent_page_id&amp;gt;&lt;/code&gt; or &lt;code&gt;(no arguments required)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When you type &lt;code&gt;/confluence-conn-check&lt;/code&gt; in Claude Code, it reads &lt;code&gt;SKILL.md&lt;/code&gt;, knows which MCP tool to call, and formats the response back to you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7 — Using Every Skill
&lt;/h2&gt;

&lt;h3&gt;
  
  
  /confluence-conn-check
&lt;/h3&gt;

&lt;p&gt;Verify your credentials before doing anything else.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/confluence-conn-check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"displayName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jane Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jane.doe@company.com"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8.5.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://confluence.company.com/confluence"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  /confluence-page-list &amp;lt;parent_page_id&amp;gt;
&lt;/h3&gt;

&lt;p&gt;List all child pages under a parent so you can find page IDs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/confluence-page-list 123456789
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Found 3 child page(s)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"987654321"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Getting Started"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"987654322"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API Reference"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  /confluence-page-read-save-content &amp;lt;page_id&amp;gt;
&lt;/h3&gt;

&lt;p&gt;Download a full page — sections, tables, images, and comments — and save it locally as structured JSON.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/confluence-page-read-save-content 987654321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saves to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;confluence-docs/con_&amp;lt;parentId&amp;gt;_&amp;lt;pageId&amp;gt;/
├── sections_and_sub_sections_contents.json
├── comments_contents.json
└── images/
    ├── screenshot.png
    └── diagram.jpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  /publish-to-confluence &amp;lt;parent_id&amp;gt; &amp;lt;file.md&amp;gt; [page_id]
&lt;/h3&gt;

&lt;p&gt;Convert a markdown file to Confluence storage format and publish it. Images referenced in the markdown are automatically uploaded as attachments.&lt;/p&gt;

&lt;p&gt;Create a new page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/publish-to-confluence 123456789 docs/architecture.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update an existing page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/publish-to-confluence 123456789 docs/architecture.md 987654321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The markdown converter handles headings, bold/italic, fenced code blocks with syntax highlighting, ordered and unordered lists (nested), pipe tables, local and external images, blockquotes, and horizontal rules.&lt;/p&gt;




&lt;h3&gt;
  
  
  /confluence-upload-images &amp;lt;page_id&amp;gt; &amp;lt;dir&amp;gt; [batch_size] [delay_ms]
&lt;/h3&gt;

&lt;p&gt;Bulk-upload images from a local directory with configurable rate-limit control.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Default (3 parallel, 2 s delay between batches)&lt;/span&gt;
/confluence-upload-images 987654321 ./screenshots

&lt;span class="c"&gt;# Conservative — slow instance or large files&lt;/span&gt;
/confluence-upload-images 987654321 ./screenshots 1 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rate-limit tuning guide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;batch_size=1, delay_ms=3000&lt;/code&gt; — safest, use on aggressive instances&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;batch_size=3, delay_ms=2000&lt;/code&gt; — default, works for most instances&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;batch_size=5, delay_ms=1000&lt;/code&gt; — faster, for lightly loaded on-premise servers&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  /confluence-sync-pages &amp;lt;parent_page_id&amp;gt;
&lt;/h3&gt;

&lt;p&gt;Download all child pages under a parent as local markdown files. On repeat runs, only pages that actually changed (version bump or new attachment) are re-downloaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/confluence-sync-pages 6656101928
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;confluence_doc_md/
└── parent_6656101928/
    ├── manifest.json      ← change-tracking index
    ├── page_987654321/
    │   ├── page.md
    │   ├── comments.json
    │   └── images/
    └── page_987654322/
        └── page.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;page.md&lt;/code&gt; starts with a metadata header:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Page Title&lt;/span&gt;
&lt;span class="gt"&gt;
&amp;gt; Page ID: 987654321&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Version: 5&lt;/span&gt;
&lt;span class="gt"&gt;&amp;gt; Last modified: 2026-05-20T10:30:00.000Z&lt;/span&gt;

[page body]
&lt;span class="p"&gt;
---
&lt;/span&gt;
&lt;span class="gu"&gt;## Comments&lt;/span&gt;

&lt;span class="gu"&gt;### Comment by jane.doe (2026-05-19T09:00:00.000Z)&lt;/span&gt;

Comment text here.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change detection logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First sync (no manifest) → download everything&lt;/li&gt;
&lt;li&gt;Page version number increased → re-download body, comments, attachments&lt;/li&gt;
&lt;li&gt;Attachment has newer timestamp → re-download attachments&lt;/li&gt;
&lt;li&gt;Nothing changed → skip the page entirely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  End-to-End Workflow Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Verify credentials&lt;/span&gt;
/confluence-conn-check

&lt;span class="c"&gt;# 2. Find the parent page ID&lt;/span&gt;
/confluence-page-list 100000001

&lt;span class="c"&gt;# 3. Write docs locally in your editor&lt;/span&gt;
&lt;span class="c"&gt;# (create docs/my-feature.md)&lt;/span&gt;

&lt;span class="c"&gt;# 4. Publish&lt;/span&gt;
/publish-to-confluence 100000002 docs/my-feature.md

&lt;span class="c"&gt;# 5. Update after edits&lt;/span&gt;
/publish-to-confluence 100000002 docs/my-feature.md 987654321

&lt;span class="c"&gt;# 6. Back up all pages under a parent&lt;/span&gt;
/confluence-sync-pages 100000001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Adding a New Tool
&lt;/h2&gt;

&lt;p&gt;To extend the server with a custom tool, follow four steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create the tool file&lt;/strong&gt; at &lt;code&gt;confluence-mcp/src/tools/your-tool.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yourToolSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;page_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The Confluence page ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleYourTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;yourToolSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Register in server.ts&lt;/strong&gt; — add to the tool list and the switch statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handleYourTool&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./tools/your-tool.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// in ListToolsRequestSchema handler:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_your_tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// in CallToolRequestSchema handler:&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confluence_your_tool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;handleYourTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Create the skill&lt;/strong&gt; at &lt;code&gt;.claude/skills/your-tool/SKILL.md&lt;/code&gt; following the format in Step 6.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Rebuild and restart:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;confluence-mcp &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build
&lt;span class="c"&gt;# Restart Claude Code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP server not loading&lt;/strong&gt;&lt;br&gt;
Run &lt;code&gt;npm run build&lt;/code&gt; inside &lt;code&gt;confluence-mcp/&lt;/code&gt; and check for TypeScript errors. Verify &lt;code&gt;.mcp.json&lt;/code&gt; points to &lt;code&gt;./confluence-mcp/build/index.js&lt;/code&gt;. Fully restart Claude Code — the server process is launched at startup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;401 Authentication Error&lt;/strong&gt;&lt;br&gt;
Regenerate your Personal Access Token in Confluence settings. Confirm &lt;code&gt;CONFLUENCE_USER&lt;/code&gt; is the email associated with the token.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;URL errors&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;CONFLUENCE_URL&lt;/code&gt; must end with a trailing slash. If behind a VPN, connect before running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Publishing formatting issues&lt;/strong&gt;&lt;br&gt;
Tables need a header separator row (&lt;code&gt;|---|---|&lt;/code&gt;). Avoid emoji and raw angle bracket characters (&lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;) directly inside table cells — Confluence's XHTML parser rejects them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limit exceeded during image upload&lt;/strong&gt;&lt;br&gt;
Slow down: &lt;code&gt;/confluence-upload-images &amp;lt;page_id&amp;gt; &amp;lt;dir&amp;gt; 1 4000&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;The full stack in one view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; — credentials, never committed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config.ts&lt;/code&gt; — Zod validates env at startup&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;client.ts&lt;/code&gt; — single Axios instance with Bearer auth&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api.ts&lt;/code&gt; — Confluence REST v1 endpoint calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tools/*.ts&lt;/code&gt; — one handler per MCP tool&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.ts&lt;/code&gt; — declares tools to Claude Code via MCP protocol&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.mcp.json&lt;/code&gt; — tells Claude Code where to find the server&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.claude/skills/*/SKILL.md&lt;/code&gt; — slash commands that wrap MCP tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this architecture you can publish markdown documentation, sync entire Confluence spaces, and upload images — all from a single Claude Code session.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt; &lt;a href="https://github.com/tariqulislam/confluence-mcp-server" rel="noopener noreferrer"&gt;github.com/tariqulislam/confluence-mcp-server&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>claude</category>
      <category>mcp</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
