blogger-cli-mcp
by tai1mo
README.md
# Blogger Post CLI Script
[日本語版ドキュメントはこちら (README.ja.md)](README.ja.md)
A Python utility to create and publish posts on Blogger using the Google Blogger API v3 from the command line.
## Features
- **Title and Content Specification**: Create or update posts by passing raw HTML content strings (`--content`) or specifying a path to an HTML file (`--file`).
- **Draft or Live Status**: Save as a draft or publish immediately to your blog.
- **Labels Management**: Attach comma-separated labels (tags) to your posts.
- **OAuth 2.0 Authentication**: Automatically handles authorization via web browser and securely caches tokens locally.
- **Update and History Tracking**: Update existing posts using `blogger_update.py`. Post history is automatically saved to `post_history.json`.
- **Fetch Post Information**: Retrieve current live status, content, and other metadata of existing posts directly from Blogger using `blogger_get.py`. Output can be dynamically filtered by specific fields.
- **Module Support**: Import modules into other Python scripts to programmatically create or update posts.
- **Multi-Blog Support**: Dynamically route posts to different blogs based on genre or alias using the `--target_blog` parameter.
- **MCP Server Support**: Includes `Blogger_mcp_server.py` (FastMCP) allowing AI assistants to post or update articles directly.
---
## Setup Instructions
### 1. Install Dependencies
Create a Python 3.x virtual environment and install the required packages:
```bash
# Create virtual environment
python3 -m venv venv
# Activate virtual environment
source venv/bin/activate
# Install required packages
pip install -r requirements.txt
```
### 2. Configure Environment Variables and Credentials
To run this tool, you need to set up two configuration files in the script directory:
1. **`.env` File**
Create a `.env` file in the same directory as the script with the following content:
```env
BLOG_ID=YOUR_DEFAULT_BLOG_ID
BLOG_ID_SITE1=YOUR_SITE1_BLOG_ID (Optional: links with --target_blog site1)
BLOG_ID_SITE2=YOUR_SITE2_BLOG_ID (Optional: links with --target_blog site2)
GCS_BUCKET_NAME=YOUR_GCS_BUCKET_NAME
GCP_PROJECT_ID=YOUR_GCP_PROJECT_ID
```
2. **`client_secret.json` File**
Download your Desktop Application OAuth 2.0 client credentials JSON file from the Google Cloud Console, rename it to `client_secret.json`, and place it in the script directory.
3. **GCS Authentication for Image Uploads (ADC)**
To use the image upload feature (`image_post.py`), run the following command locally and complete the browser authentication for Application Default Credentials (ADC):
```bash
gcloud auth application-default login
```
> [!WARNING]
> For security, `.env`, `client_secret.json`, and the auto-generated `token.json` are excluded from Git commits via `.gitignore`. Be careful not to expose your credentials.
---
## Usage
Make sure your virtual environment is activated before running the script.
### Create a Post (Save as Draft)
Provide a title and HTML string content to save a draft post:
```bash
python blogger_post.py \
--title "My First API Post" \
--content "<h1>Hello World</h1><p>This is a test post from Blogger API.</p>"
```
### Read from HTML File and Publish (Live Status)
Specify an HTML file path using `--file` and set `--status live` to publish the post immediately:
```bash
python blogger_post.py \
--title "Article Loaded from HTML File" \
--file "path/to/article.html" \
--status live
```
### Add Labels to Your Post
Pass labels as a comma-separated string using the `--labels` option:
```bash
python blogger_post.py \
--title "Post with Labels" \
--content "<p>Testing Blogger API v3 labels.</p>" \
--labels "Python, Blogger API, Test"
```
### Route Post to a Specific Blog (Multi-Blog Support)
If you have configured multiple blog IDs in your `.env` (e.g., `BLOG_ID_SITE1`), use the `--target_blog` argument to dynamically switch the destination:
```bash
python blogger_post.py \
--title "Site 1 News" \
--content "<p>This goes to the site1 blog.</p>" \
--target_blog "site1"
```
### Update an Existing Post
Use `blogger_update.py` to update an existing post by its `post_id`:
```bash
python blogger_update.py \
--post_id 1234567890123456789 \
--title "Updated Title" \
--content "<p>Updated content.</p>" \
--status live
```
*Note: You can also specify an HTML file using `--file "path/to/article.html"` instead of `--content`. Successful posts and updates are automatically recorded in `post_history.json`.*
### Fetch Post Information
Use `blogger_get.py` to retrieve the current status, content, or other metadata of a specific `post_id`. You can extract only specific fields using the `--fields` argument.
**Available Fields (`--fields`)**:
- `id`: The ID of the post
- `title`: The title of the post
- `status`: The publication status (e.g., `LIVE`, `DRAFT`, `SCHEDULED`)
- `url`: The public URL of the post
- `labels`: A list of labels (tags) attached to the post
- `content`: The HTML content of the post
- `published`: The time the post was published
- `updated`: The time the post was last updated
- `replies`: Comment information
- `author`: Information about the author
```bash
python blogger_get.py \
--post_id 1234567890123456789 \
--fields "title,status,url"
```
### Use as a Module
You can also import the script into other Python projects:
```python
from blogger_post import post_article
try:
url = post_article(
title="My API Post",
content="<p>This is posted via Python module.</p>",
labels=["Python", "Module"],
status="draft"
)
print(f"Posted successfully: {url}")
except Exception as e:
print(f"Failed to post: {e}")
```
### Use as an MCP Server
The included `Blogger_mcp_server.py` script runs a FastMCP server. By configuring your AI assistant (e.g., Claude) to use this script as an MCP server, it exposes the following tools:
- `post_to_blogger`: Publish or draft new articles and automatically save the history locally. Accepts HTML strings (`content`) or local HTML file paths (`file_path`), as well as `target_blog` to route posts dynamically.
- `update_blogger_post`: Update existing articles by their `post_id` and sync the local history. Accepts HTML strings (`content`) or local HTML file paths (`file_path`), and `target_blog`.
- `upload_image_to_gcs`: Uploads a single local image to GCS (automatically converts to WebP and resizes) and returns the public URL.
- `replace_html_images_with_gcs`: Reads local image links within an HTML document, uploads all of them to GCS, and returns a new HTML string with replaced image URLs.
- `get_blogger_post`: Retrieves the current information of a specific post directly from the Blogger API. You can specify which fields (e.g., status, url) to extract.
*Note: Ensure the `mcp`, `google-cloud-storage`, `Pillow`, and `beautifulsoup4` packages are installed (`pip install -r requirements.txt`) before running the MCP server.*
---
## Error Handling
If any issue occurs, the script catches the exception and outputs localized troubleshooting advice:
- **File Errors**: Warns you if the HTML file is missing, lacks read permissions, or is not UTF-8 encoded.
- **Network Connection Errors**: Catches failures when there is no internet connection, Google servers are unreachable, or the request times out (maximum **30-second socket timeout** to prevent hanging).
- **HTTP Errors (403, 404, 500, etc.)**: Suggests causes and fixes depending on the status code (e.g. check Blogger API enablement for 403, verify BLOG_ID for 404, or wait for Google servers for 500).
- **Authentication Errors**: Guides you if credentials are invalid or expired. This includes a **120-second timeout** for the local browser OAuth flow; if it times out (common when your Google Cloud project is in "Testing" mode and the current account is not registered as a "Test User"), the script will abort and print steps to configure test users in Google Cloud Console.
---
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Disclaimer
- This script is provided "AS IS", without warranty of any kind.
- The authors are not responsible for any damage, data loss, or API quota consumption caused by using this software.
- Please comply with Google's API terms of service when using this tool.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues