Skip to content

sgrassie/BlogHelper9000

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

340 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BlogHelper9000

A CLI + TUI toolkit + MCP server for Jekyll blogging with an embedded Neovim editor

CI Status Coverage Status CodeQL Advanced .NET License


BlogHelper9000 is a .NET toolset for managing Jekyll blog posts. It ships as three executables: a CLI tool (bloghelper) for scripting and quick operations, a TUI workspace with an embedded Neovim editor for an integrated writing experience, and an MCP server (bloghelper-mcp) that exposes blog management capabilities to AI agents (like GitHub Copilot, Claude, and VS Code) — all from your terminal.

Features

  • CLI tool — Create posts & drafts, publish drafts, inspect blog stats, and batch-fix YAML front matter
  • TUI workspace — Full terminal UI with file browser, command palette, and embedded Neovim editor
  • MCP server — Expose blog management tools to AI agents via the Model Context Protocol (stdio transport)
  • Embedded Neovim — Real Neovim running headless via MsgPack-RPC, rendered as a Terminal.Gui view with full mode/cursor support
  • Featured image generation — Search Unsplash, download images, and generate branded featured images with ImageSharp
  • YAML front matter management — Parse, serialise, and bulk-fix front matter (published status, descriptions, tags)
  • Safe mode — Run the TUI with --no-nvim for a plain-text editor fallback when Neovim isn't available

Installation

As a .NET global tool

dotnet tool install --global BlogHelper9000

Once installed, the bloghelper command is available globally.

Building from source

git clone https://github.com/sgrassie/BlogHelper9000.git
cd BlogHelper9000
./build.sh

Quick Start

All CLI commands operate on a Jekyll blog directory. Pass --base-directory to point at your blog root, or configure it in bloghelper9000.json.

Get blog info

bloghelper info --base-directory /path/to/blog

Shows total post count, drafts, days since last post, and recent posts.

Create a new draft

bloghelper add "My New Post" --base-directory /path/to/blog --is-draft

Create a published post

bloghelper add "My New Post" --base-directory /path/to/blog

Publish a draft

bloghelper publish "my-draft-post" --base-directory /path/to/blog

Moves the draft from _drafts/ into _posts/<year>/, sets the published date, and updates the YAML front matter.

Fix metadata across all posts

# Fix published status (extract dates from filenames)
bloghelper fix --base-directory /path/to/blog --status

# Migrate legacy descriptions
bloghelper fix --base-directory /path/to/blog --description

# Normalize and de-duplicate tags
bloghelper fix --base-directory /path/to/blog --tags

Add a featured image from Unsplash

bloghelper add-image "my-post" --image-query "mountains" --base-directory /path/to/blog

Configure Unsplash credentials

bloghelper unsplash-credentials --access-key YOUR_KEY --secret-key YOUR_SECRET

Credentials are stored in ~/Documents/bloghelper9000.json.

TUI Workspace

The TUI provides a full terminal workspace for writing and managing blog posts. It uses Terminal.Gui v2 and embeds a real Neovim instance for editing.

Launch

dotnet run --project BlogHelper9000.Tui -- --base-directory /path/to/blog

Launch without Neovim (safe mode)

dotnet run --project BlogHelper9000.Tui -- --no-nvim --base-directory /path/to/blog

Keyboard Shortcuts

Shortcut Action
Ctrl+B Toggle file browser
Ctrl+P Open command palette
Ctrl+Q Quit

Command Palette

Press Ctrl+P to open the command palette. It provides filtered access to blog operations:

Command Description
New Draft Create a new draft post
New Post Create a new published post
Publish Draft Publish an existing draft
Blog Info Show blog statistics
Fix Metadata: Status Fix published status on all posts
Fix Metadata: Description Migrate legacy descriptions
Fix Metadata: Tags Fix and normalize tags

MCP Server

The MCP server exposes BlogHelper9000's blog management capabilities to AI agents via the Model Context Protocol. This allows AI assistants like Claude Desktop, GitHub Copilot, and VS Code to directly manage your Jekyll blog posts.

Available MCP Tools

Tool Name Description
add_post Create a new blog post or draft with title and metadata
publish_post Publish a draft from _drafts/ to _posts/ with date prefix
get_blog_info Get blog statistics (post count, drafts, recent posts, days since last post)
list_drafts List all draft blog posts in the _drafts/ directory
fix_metadata Batch-fix YAML front matter (published status, descriptions, tags)
add_featured_image Generate and apply a featured image from Unsplash with title overlay

Installation

Install as a .NET global tool:

dotnet tool install --global BlogHelper9000.Mcp

Or run directly from source:

dotnet run --project BlogHelper9000.Mcp

Configuration

The MCP server reads the blog base directory from:

  1. BLOG_BASE_DIRECTORY environment variable
  2. First positional argument
  3. Current working directory (fallback)

Claude Desktop

Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "bloghelper9000": {
      "command": "bloghelper-mcp",
      "args": ["/path/to/your/jekyll/blog"]
    }
  }
}

Or use the environment variable approach:

{
  "mcpServers": {
    "bloghelper9000": {
      "command": "bloghelper-mcp",
      "env": {
        "BLOG_BASE_DIRECTORY": "/path/to/your/jekyll/blog"
      }
    }
  }
}

VS Code / Copilot

Add to your workspace or user settings (.vscode/settings.json):

{
  "mcp.servers": {
    "bloghelper9000": {
      "command": "dotnet",
      "args": ["run", "--project", "/path/to/BlogHelper9000.Mcp"],
      "env": {
        "BLOG_BASE_DIRECTORY": "/path/to/your/jekyll/blog"
      }
    }
  }
}

Example Usage

Once configured, you can ask your AI assistant to:

  • "Create a new draft post titled 'Understanding MCP'"
  • "List all my draft posts"
  • "Show me blog statistics"
  • "Publish the draft 'understanding-mcp'"
  • "Add a featured image about 'programming' to my latest post"

The AI will use the appropriate MCP tool to execute your request.

Solution Architecture

BlogHelper9000.sln
├── BlogHelper9000.Core/           Core domain logic
├── BlogHelper9000.Imaging/        Image processing
├── BlogHelper9000/                CLI executable
├── BlogHelper9000.Mcp/            MCP server executable
├── BlogHelper9000.Nvim/           Neovim client
├── BlogHelper9000.Tui/            TUI executable
├── BlogHelper9000.Tests/          CLI tests
├── BlogHelper9000.Mcp.Tests/      MCP server tests
├── BlogHelper9000.Nvim.Tests/     Neovim tests
├── BlogHelper9000.Tui.Tests/      TUI tests
└── BlogHelper9000.TestHelpers/    Shared test infra
Project Type Description
BlogHelper9000.Core classlib Domain logic — PostManager, MarkdownHandler, YamlConvert, BlogService. No UI dependencies.
BlogHelper9000.Imaging classlib Featured image generation — ImageProcessor, UnsplashClient, FontManager. Uses SixLabors.ImageSharp.
BlogHelper9000 exe CLI tool using TimeWarp.Nuru mediator pattern. Packaged as a dotnet tool.
BlogHelper9000.Mcp exe MCP server exposing blog management tools via stdio transport for AI agents (Claude, VS Code, etc.). Packaged as a dotnet tool.
BlogHelper9000.Nvim classlib Embedded Neovim client. NvimProcess manages nvim --embed --headless. MsgPackRpcClient handles MsgPack-RPC framing. NvimGrid maintains a 2D screen buffer.
BlogHelper9000.Tui exe Terminal.Gui v2 workspace. NvimEditorView renders the Neovim grid. CommandPalette exposes blog operations. KeyTranslator maps Terminal.Gui keys to Neovim notation.
BlogHelper9000.Tests test xUnit tests for CLI commands
BlogHelper9000.Mcp.Tests test xUnit tests for MCP server tools
BlogHelper9000.Nvim.Tests test Tests for grid operations, MsgPack serialization, and UI event parsing (no nvim required)
BlogHelper9000.Tui.Tests test Tests for TUI workspace components
BlogHelper9000.TestHelpers classlib JekyllBlogFilesystemBuilder and shared test infrastructure using MockFileSystem

Tech Stack

Dependency Version Purpose
.NET 10.0 Runtime & SDK
C# latest Language version with nullable reference types
Terminal.Gui 2.0.0-develop.5027 TUI framework (v2 develop track)
MessagePack v3 MsgPack-RPC serialization for Neovim communication
SixLabors.ImageSharp 3.1.12 Image processing & featured image generation
SixLabors.Fonts 2.1.3 Font rendering for image overlays (bundled Ubuntu fonts)
TimeWarp.Nuru 2.1.0-beta.32 Mediator pattern for CLI command routing
Spectre.Console 0.54.0 CLI console output formatting
MinVer 7.0.0 Git-based semantic versioning
Cake Build Build orchestration
xUnit v3 Test framework
FluentAssertions Test assertion library
NSubstitute Mocking framework
System.IO.Abstractions 22.1.0 File system abstraction for testability

Building & Testing

BlogHelper9000 uses Cake for build orchestration.

# Build
./build.sh

# Build and run tests
./build.sh --target=tests

# Build, test, and pack as NuGet tool
./build.sh --target=pack --configuration=release

# Run all tests directly
dotnet test BlogHelper9000.sln

# Run specific test projects
dotnet test BlogHelper9000.Tests/BlogHelper9000.Tests.csproj
dotnet test BlogHelper9000.Nvim.Tests/BlogHelper9000.Nvim.Tests.csproj

# Run a single test by name
dotnet test BlogHelper9000.Tests/BlogHelper9000.Tests.csproj --filter "FullyQualifiedName~YamlConvertTests.Can_Serialise"

Configuration

Unsplash API Credentials

To use featured image generation, configure your Unsplash API credentials:

bloghelper unsplash-credentials --access-key YOUR_ACCESS_KEY --secret-key YOUR_SECRET_KEY

This stores credentials in ~/Documents/bloghelper9000.json.

Base Directory

All commands accept --base-directory to specify the Jekyll blog root directory. This should point to the directory containing your _posts/ and _drafts/ folders.

License

This project is licensed under the MIT License.

Copyright (c) 2022 Stuart Grassie


See the original blog post: Automating Jekyll with .NET

About

A tool to automate some aspects of a Jekyll blog

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •