Skip to main content

blog-cli

Agent-friendly CLI for managing a personal blog: create drafts, upload media, generate preview links, publish articles, and manage project tags.

Install

From PyPI:

pip install -U blog-cli

Or install it as an isolated command-line tool:

pipx install blog-cli
uv tool install blog-cli

For development:

git clone https://github.com/tanaka-mambinge/personal-cli
cd personal-cli
uv sync --extra dev

Configure

The CLI stores the server URL, API key, and site URL in its configured keyring backend. On first use it prints a local setup URL; open it in a browser, enter the three values, and submit. The values are validated against the server before they are saved.

For local development, run the CLI through scripts/docker-cli. Docker uses a persistent container-only credential volume and never mounts the host keyring:

./scripts/docker-cli run article list --type blog

All commands support --json for machine-readable output and --server-url to override the configured API URL for one command. Commands also support --insecure to skip TLS certificate verification when needed for local development.

Check the installed version:

blog-cli version

Articles

Create a blog post

Blog posts are drafts by default:

blog-cli article blog create \
  --title "My Post" \
  --description "A short summary" \
  --markdown "# My Post\n\nHello."

Use a Markdown file instead:

blog-cli article blog create \
  --title "My Post" \
  --description "A short summary" \
  --markdown-file post.md

Create a project

blog-cli article project create \
  --title "My Project" \
  --description "A short summary" \
  --tag python \
  --tag agents \
  --markdown-file project.md

Projects can also use --pinned and --sort-order.

List and show articles

# List all articles
blog-cli article list

# List published blog posts
blog-cli article list --type blog --status published

# List projects
blog-cli article list --type project

# Show one article
blog-cli article show my-post

Update an article

blog-cli article update my-post --title "A Better Title"
blog-cli article update my-post --description "An updated summary"
blog-cli article update my-post --markdown-file updated-post.md
blog-cli article update my-post --cover-image hero-image
blog-cli article update my-post --clear-cover-image

The update command also accepts --type, --status, --tag, --pinned, --not-pinned, and --sort-order.

Preview and publish

Generate a time-limited preview link:

blog-cli article preview my-post
blog-cli article preview my-post --ttl-hours 4

Override the configured site URL for a preview:

blog-cli article preview my-post --site-url https://preview.example.com

Publish an article explicitly:

blog-cli article publish my-post --published-by agent

Archive or restore an article:

blog-cli article delete my-post
blog-cli article unarchive my-post

Project tags

# List tags on a project
blog-cli article tag-list my-project

# Add tags
blog-cli article tag-add my-project --tag python --tag agents

# Remove a tag
blog-cli article tag-remove my-project --tag agents

ChatGPT / Codex skill

The repository skill lives at skills/blog-cli/SKILL.md. It is loaded by agents from the repository and is not managed through CLI commands.

Media

Upload media using a stable name, then reference that name from article Markdown:

blog-cli media upload --name hero-image ./hero.jpg

Replace an existing file without changing its name:

blog-cli media update --name hero-image ./new-hero.jpg

Soft-delete media:

blog-cli media delete --name hero-image

Markdown references use the media name:

![Hero image](hero-image)

<video controls width="100%" src="demo-video"></video>

The site resolves these names to their full media URLs.

Publishing new CLI versions

The repository includes a GitHub Actions workflow at .github/workflows/publish.yml. It runs when you push a version tag matching v*.*.* and will:

  1. Install dependencies with uv.
  2. Run the test suite.
  3. Build the wheel and source distribution with uv build --no-sources.
  4. Publish both distributions to PyPI with uv publish.

After configuring PyPI Trusted Publishing for the GitHub Actions workflow, release a new version with:

uv version --bump patch
git add pyproject.toml uv.lock
git commit -m "Release blog-cli"
git tag v0.2.4
git push origin main --tags

Use the version from pyproject.toml when creating the tag.

Testing

./scripts/docker-cli test

The CLI tests use an in-memory fake API client, run with networking disabled, and reuse Docker's cached dependencies. The CLI architecture is:

blog-cli (httpx) → FastAPI server → MongoDB/GridFS

License

MIT

Release files for blog-cli 0.4.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for blog-cli 0.4.5
File Size Uploaded
blog_cli-0.4.5.tar.gz 19.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for blog-cli 0.4.5
File Interpreter ABI Platform
blog_cli-0.4.5-py3-none-any.whl Python 3 none any Details

Total release size: 36.7 kB

Release files / blog_cli-0.4.5.tar.gz

Download URL blog_cli-0.4.5.tar.gz
Size 19.6 kB
Tags Source
SHA-256 checksum
How to use checksums
45d6f43cef5a87177be88b1ede3c3d97506442b6c7d514dfd6aaf3ab672136ab
BLAKE2b-256 checksum
How to use checksums
a473af9b5ac657f5432a0c521dd27f3f03ee9115ed2a173c672c3212363a7b5a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / blog_cli-0.4.5-py3-none-any.whl

Download URL blog_cli-0.4.5-py3-none-any.whl
Size 17.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fe315a389dc0b80859805ba666e8b9f39a87541aa9a145d56e5cd1d2f1a0eb26
BLAKE2b-256 checksum
How to use checksums
dc6a9eb9e3c82fed11a213b5695482b34bda8158d800090947ce4900d2564b3a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.4.5 This release

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.4

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page