Skip to main content

Convert Markdown to Atlassian Document Format (ADF) and upload to Confluence

Project description

md-to-adf

Convert Markdown to Atlassian Document Format (ADF) and publish to Confluence Cloud.

Tests PyPI License: MIT

Install

pip install md-to-adf          # Python
npm install -g md2adf           # Node (wraps the Python package)
brew tap imzak31/md-to-adf && brew install md-to-adf  # macOS

Quick start

# 1. Set up your Confluence credentials (one-time)
md-to-adf init

# 2. Preview what will be uploaded
md-to-adf upload docs/ --dry-run

# 3. Push to Confluence
md-to-adf upload docs/ --space ENG

Titles are auto-extracted from each file's first # Heading. No --title flag needed.

CLI Commands

init — Set up credentials

md-to-adf init

Interactive wizard that saves your Confluence domain, email, and API token to ~/.md-to-adf/config.toml. Generate a token at https://id.atlassian.com/manage-profile/security/api-tokens.

upload — Push markdown to Confluence

md-to-adf upload <file|directory|glob> [options]
Option Description
--space KEY Target Confluence space
--title TEXT Override auto-extracted title (single file only)
--page-id ID Update an existing page (single file only)
--parent-id ID Create under a parent page
--dry-run Preview files and titles without uploading
--recursive Include markdown in subdirectories
--mermaid STRATEGY Diagram handling: auto, macro, image, code
# Single file
md-to-adf upload docs/architecture.md --space ENG

# Entire directory
md-to-adf upload docs/ --space ENG

# Glob pattern
md-to-adf upload "docs/*.md" --space ENG

# Preview first
md-to-adf upload docs/ --dry-run

# Update an existing page
md-to-adf upload docs/guide.md --page-id 12345

Batch uploads process each file independently — failures don't stop the rest. A summary is printed at the end.

convert — Generate ADF JSON

md-to-adf convert <file> [options]
Option Description
--output FILE Write to file instead of stdout
--validate Check ADF validity after conversion
--compact Minified JSON output
--mermaid STRATEGY Diagram handling strategy

validate — Check ADF validity

md-to-adf validate docs/my-page.md
md-to-adf validate output.adf.json

spaces — List available spaces

md-to-adf spaces

Configuration

Config file: ~/.md-to-adf/config.toml

[confluence]
domain = "myorg.atlassian.net"
email = "me@example.com"
token = "my-api-token"
space_key = "ENG"

[mermaid]
strategy = "auto"

Settings can also be provided via environment variables or CLI flags:

Setting Config key Env var CLI flag
Domain confluence.domain MD_TO_ADF_DOMAIN --domain
Email confluence.email MD_TO_ADF_EMAIL --email
Token confluence.token MD_TO_ADF_TOKEN --token
Space confluence.space_key MD_TO_ADF_SPACE --space
Mermaid mermaid.strategy MD_TO_ADF_MERMAID --mermaid

Priority: CLI flags > env vars > config file > defaults

Use --debug on any command to see full error details.

Named spaces

For teams that publish to multiple spaces, add shortcuts to your config:

[spaces.eng]
key = "ENG"
name = "Engineering"
parent_id = "12345"

[spaces.product]
key = "PROD"
name = "Product Docs"

When uploading without --space, a picker appears if multiple spaces are configured. Recent spaces are tracked automatically.

Mermaid diagrams

Fenced mermaid code blocks are converted according to the selected strategy:

Strategy Description
auto Confluence macro if available, otherwise code block
macro Confluence Mermaid macro (requires the Mermaid app)
image Render to PNG locally via mmdc and attach
code Keep as a code block

Claude Code integration

Install the /md-to-confluence skill to push markdown from Claude Code:

curl -sL https://raw.githubusercontent.com/imzak31/md_to_adf/main/skill/md-to-confluence.md \
  -o ~/.claude/skills/md-to-confluence.md

Then use /md-to-confluence in any conversation. The skill runs --dry-run first to preview, then uploads on confirmation.

Python API

from md_to_adf import convert, validate

adf = convert("# Hello\n\nThis is **bold** text.")
errors = validate(adf)  # [] if valid
from md_to_adf.confluence.auth import build_token_auth_header
from md_to_adf.confluence.client import ConfluenceClient

auth = build_token_auth_header("me@example.com", "my-api-token")
client = ConfluenceClient("myorg.atlassian.net", auth)
result = client.create_page(adf, space_key="ENG", title="My Page")

Contributing

  1. Fork and create a feature branch
  2. pip install -e ".[dev]"
  3. pytest tests/ -v
  4. Open a pull request

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

md_to_adf-1.1.0.tar.gz (39.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

md_to_adf-1.1.0-py3-none-any.whl (29.3 kB view details)

Uploaded Python 3

File details

Details for the file md_to_adf-1.1.0.tar.gz.

File metadata

  • Download URL: md_to_adf-1.1.0.tar.gz
  • Upload date:
  • Size: 39.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for md_to_adf-1.1.0.tar.gz
Algorithm Hash digest
SHA256 821359b6bc77b07774a920cecb69723eb473db64219c694c78558020e7abe8f5
MD5 7a1efc96289e5cc252002e6134114a20
BLAKE2b-256 bacdfd920bc2a3445e4f10c350de3bca316f7fda978946d75dc48bf18b8d8952

See more details on using hashes here.

Provenance

The following attestation bundles were made for md_to_adf-1.1.0.tar.gz:

Publisher: release.yml on imzak31/md_to_adf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file md_to_adf-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: md_to_adf-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for md_to_adf-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e70bb739d8120ef7bdb39c6aea11a2d5f0d359df5e43bc52c1e7e867ee8a1fd0
MD5 d53c2c761de6635ea9611cc093677c3a
BLAKE2b-256 c3983d776c9fa044969a4ffe598d36365b52dd5e3031790c99c8c5fc26e3c358

See more details on using hashes here.

Provenance

The following attestation bundles were made for md_to_adf-1.1.0-py3-none-any.whl:

Publisher: release.yml on imzak31/md_to_adf

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page