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:

<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:
- Install dependencies with uv.
- Run the test suite.
- Build the wheel and source distribution with
uv build --no-sources. - 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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file blog_cli-0.4.4.tar.gz.
File metadata
- Download URL: blog_cli-0.4.4.tar.gz
- Upload date:
- Size: 19.2 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
115684af519366eab258404e52939b430fa64642bf731ecebe7061cf1398d9be
|
|
| MD5 |
95dd33f8b8b3a1d06ba5e6406b735bfd
|
|
| BLAKE2b-256 |
54c1bfbe662244088bcdf968b68ffe1c42d62c85e292aebc391b6ba3b661b915
|
File details
Details for the file blog_cli-0.4.4-py3-none-any.whl.
File metadata
- Download URL: blog_cli-0.4.4-py3-none-any.whl
- Upload date:
- Size: 17.0 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
71414d3cfecc58e6862a2dbd930cea05583b74e23d2b57ffb7180366a6f22813
|
|
| MD5 |
12600a56569b4df9957902e38a99b9e8
|
|
| BLAKE2b-256 |
573d363ac082315be529204d7ceea07af2f44d62ef5952a35d6055b8431273d7
|