Skip to content
mdFly

Docs

Install

Pick one. All three put an mdfly binary on your path.

Shell installer

curl -fsSL https://mdfly.dev/install.sh | sh

The installer verifies the download against the release checksums.

Homebrew

brew install Abir66/mdfly/mdfly

Go

go install github.com/Abir66/mdfly/cmd/mdfly@latest

A binary built with go install reports its version as dev.

Platforms

Release binaries are built for macOS (amd64, arm64), Linux (amd64, arm64) and Windows (amd64). Check the install with mdfly --version.

Quick start

No account and no signup. Publish a file and the URL is the only thing printed to stdout.

mdfly publish notes.md
# https://mdfly.dev/abc12345

Follow linked pages and folders

-r walks linked markdown files and folders into one document.

mdfly publish docs/index.md -r

Publish text without a file

Pipe text in, or pass it with -m.

echo "# Quick note" | mdfly publish
mdfly publish -m "# Quick note"

Open or copy the result

mdfly publish notes.md --open
mdfly publish notes.md | pbcopy

Progress lines such as uploaded 3/3 go to stderr, so piping stdout never picks them up.

Update and delete

mdfly update notes.md
mdfly delete abc12345

Commands

Run mdfly <command> --help for the full flag list. delete, open and remove take a slug or the path of a file you published from this machine. update takes the file; use --slug to target by slug.

Edit tokens

Publishing mints an edit token. mdFly stores it locally under ~/.mdfly/ and sends it when you update or delete that document. Set MDFLY_CONFIG_DIR to keep that state somewhere else. The token is never shown on stdout.

publish [file]

Upload a file, or inline text, and print its URL.

Flag Effect
-r, --recursive Follow linked .md files and linked folders transitively.
-m, --message <text> Publish inline text instead of a file.
--open Open the URL in your browser after publishing.

With no file and no -m, publish reads stdin.

update [file]

Push changes to an existing document. The URL stays the same, and the 30-day lifetime restarts.

Flag Effect
--slug <slug> Target a document by slug, for text updates, recovery or when a file maps to several documents.
-m, --message <text> Update with inline text instead of a file.
-r, --recursive Follow linked .md files and linked folders.
--force Overwrite without the concurrency check against the last version you pushed.
--open Open the URL after updating.

Without --force, an update fails with a conflict if the document changed since you last pushed it.

delete [slug-or-file]

Take a document down on the server. Its URL then answers 410. It asks for confirmation; pass -y to skip the prompt, which is required when stdin is not a terminal.

Flag Effect
--slug <slug> Target a document by slug when a file maps to several.

list

Print the documents you published from this machine, newest first. It reads local state and makes no network call. Columns are slug, tier, updated time, path and URL. With --json it prints an array.

open [slug-or-file]

Open a published document in your browser.

Flag Effect
--slug <slug> Target a document by slug when a file maps to several.

remove [slug-or-file]

Forget a document locally. This touches local state only: the document stays online, and you lose the edit token, so you can no longer update or delete it.

Flag Effect
--slug <slug> Target a document by slug when a file maps to several.
--all Remove every tracked document from local state. Cannot be combined with a target or --slug.

Global flags

Every command accepts these flags.

Flag Effect
--json Print machine-readable JSON instead of text.
-q, --quiet Suppress non-error output.
-y, --yes Skip the confirmation prompt of delete and remove --all.
--api <url> Override the API base URL.

Output streams

stdout carries only the result: the URL, or the --json object. Everything else, including progress and errors, goes to stderr.

API base URL

The API base resolves in this order: --api, the MDFLY_API environment variable, config.toml in the state directory, then the built-in default.

Limits

Each published document is capped at:

Limit Value
Total bundle size 25 MB
File count 50 files
Single file size 10 MB
Lifetime 30 days

The CLI checks size and file count before uploading and stops early with exit code 2. The server checks again.

Expiry and removal

Documents expire 30 days after they are published or last updated. An expired or deleted document answers 410 Gone at both its page and raw URLs.

Rate limits

Publishing, updating and deleting are limited to 10 requests per minute and 30 per hour. Reading documents is not limited. Hitting a limit exits with code 5.

Troubleshooting

Exit codes

Every failure maps to one exit code, so scripts can branch on it.

Code Meaning
0 Success.
1 Unrecognized failure.
2 Bad input: invalid flag or argument, no content, a missing file, a bundle over the limits, or a request the server rejects as malformed.
3 Missing or invalid edit token.
4 Conflict: the document changed since your last push.
5 Over quota: bundle too large for the server, or rate limited.
6 Server error, network failure, or an upload that kept failing after retries.

Rate limited

Exit code 5 with a rate-limit message means you passed 10 writes per minute or 30 per hour. Wait for the minute or hour window to reset (the server’s Retry-After says how long) and retry.

Update conflict

Exit code 4 means the document changed since you last pushed it. If you intend to replace it, run mdfly update <file> --force.

Lost edit token

The token lives in ~/.mdfly/. If it is gone, you cannot update or delete that document. Publish again for a new URL; the old one expires after 30 days.

Delete refuses without confirmation

When stdin is not a terminal, mdfly delete exits with code 2 unless you pass -y.

410 Gone

The document was deleted or has expired. Publish it again to get a new URL.