Skip to main content

File-based social media publisher. Write markdown, post to LinkedIn, Bluesky, and Mastodon.

Project description

mdsend — File-based social media publisher

mdsend

Write markdown posts, run mdsend, and it cross-posts to your social media platforms.

The main purpose is simple: set up a git repo with a simple directory structure and publish from it to various destinations. Your posts are in a single unified format that works across different social media platforms. You get a version-controlled archive that can be queried and managed by AI should the need arise.

Want to know what you've been focusing on, what your next posts should be, how to improve your writing, or which tags to use? Just ask your AI tool — it can read the repo and answer and provide you with a perspective.

This approach keeps you disconnected from the destination network so you don't get pulled into everyone else's feeds.

Supported platforms

Platform Max chars Max media API auth
LinkedIn 3,000 1 image OAuth 2.0 (Bearer)
Bluesky 300 4 images AT Protocol (App Password)
Mastodon 500 4 images OAuth (Access Token)

How it works

Each post is a directory named YYYY-MM-DD_HH-MM_slug/ containing:

  • post.md — the post text (markdown or plain text)
  • Optional media files (jpg, png, gif, mp4, mov)
posts/
├── 2026-05-03_15-30_my-thoughts/
│   ├── post.md
│   └── image.jpg
└── 2026-05-04_18-00_hello-world/
    └── post.md

Per-post platform targeting

By default every post goes to all platforms. To control this per post, add an optional front matter block at the top of post.md:

---
platforms: [bluesky]
---

This post will only appear on Bluesky.
---
platforms: []
---

This post is a draft — it will never be published.

Installation

pip install mdsend

Or from source:

git clone https://github.com/algodesigner/mdsend
cd mdsend
pip install -e .

Setup

Create a .env file with your API credentials:

cp .env.example .env

Fill in the credentials for the platforms you want to use. See .env.example for the full list of required fields.

Usage

# Preview what would be posted (default — no API calls made)
cd /path/to/your/posts
mdsend

# Actually post live
mdsend --publish

# Post to specific platforms
mdsend --platforms bluesky
mdsend --platforms bluesky --publish

Creating a new post

# Create a post directory and open the editor
mdsend --new "my-post-slug"

This creates a directory like 2026-05-04_21-30_my-post-slug/ with a post.md file containing a front matter template, then opens it in your $EDITOR (or vi by default).

Dry run

mdsend runs in dry-run mode by default — it prints what would be posted without calling any API. Use --publish to post live.

Multi-post threading (Bluesky & Mastodon)

Posts longer than the platform limit are automatically split into threaded replies. Each chunk is prefixed with 🧵 (n/N) so readers know it's part of a multi-part post. Media is attached to the first chunk only. Links are moved to the first chunk so the preview card appears at the top of the thread.

Idempotent publishing

Each platform gets its own sentinel file under posts/.published/. Re-running is safe — already-published platforms are skipped.

License

BSD 3-Clause. See LICENSE.

Happy microblogging! ☕

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

mdsend-0.3.1.tar.gz (13.8 kB view details)

Uploaded Source

Built Distribution

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

mdsend-0.3.1-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file mdsend-0.3.1.tar.gz.

File metadata

  • Download URL: mdsend-0.3.1.tar.gz
  • Upload date:
  • Size: 13.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mdsend-0.3.1.tar.gz
Algorithm Hash digest
SHA256 0e6ddea04d2a22a2cddb230457133544d83c19f9464ae7c9ca7f43ac5fc3a712
MD5 5b04b6ca053e8b7a6ee5cb74b118c44f
BLAKE2b-256 016adcb03488379fbb499e8e6643e230c6462047b5063ca78c566a0be4763d95

See more details on using hashes here.

File details

Details for the file mdsend-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: mdsend-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mdsend-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 05e2fc1988d8729e8dcf501809bfff43ba5ffb15d257191247b605a2f6e729df
MD5 0df1d61a513b85823ea2b96ca0a605a2
BLAKE2b-256 2b50adc8ac56d2acf3f05dab991a603587c69bccffd2348090563fb8f68f9bbc

See more details on using hashes here.

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