Skip to main content

CLI that turns local Markdown notes into structured SEO content packages using LLMs while keeping the human in the loop.

Project description

Build

Scribae

From Latin scribae, "the scribes." The professional copyists and secretaries of the ancient world.

Scribae is a CLI that turns local Markdown notes into structured SEO content packages with human-in-the-loop review. It keeps the research-to-publication flow reproducible by combining deterministic prompts, typed outputs, and LLMs via OpenAI-compatible APIs.

Why Scribae?

  • Keep source material local. Point the CLI at a Markdown note and run everything against an OpenAI-compatible API endpoint you control.
  • Human in the loop. Each stage is designed for review and editing before you publish.
  • Repeatable prompts. Each command builds structured prompts and validates model responses to catch schema drift early.
  • End-to-end workflow. Move from ideation to translation within one tool instead of juggling separate scripts.

Installation

pip install scribae

Or with pipx for isolated installation:

pipx install scribae

Translation support

Translation uses PyTorch and Hugging Face Transformers. Install with the translation extra:

pip install scribae[translation]

Prerequisites

Scribae requires an OpenAI-compatible API endpoint. The easiest option is Ollama running locally:

# Install Ollama (see https://ollama.com for other platforms)
curl -fsSL https://ollama.com/install.sh | sh

# Start the server
ollama serve

# Pull the default model
ollama pull ministral-3:8b

Alternatively, point Scribae at any OpenAI-compatible endpoint:

export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_API_KEY="sk-..."

Quick start

  1. Generate ideas from a Markdown note:

    scribae idea --note my-notes.md --json
    
  2. Create an SEO brief from your note:

    scribae brief --note my-notes.md --out brief.json
    
  3. Write a draft using the brief:

    scribae write --note my-notes.md --brief brief.json --out draft.md
    
  4. Add metadata to your draft:

    scribae meta --body draft.md --brief brief.json --format frontmatter --out draft.md
    
  5. Translate to another language:

    scribae translate --src en --tgt de --in draft.md --out draft.de.md
    

Run scribae --help to see all commands and options.

Core workflow

idea → brief → write → meta → translate
  1. idea — Brainstorm article ideas from a note with project-aware guidance.
  2. brief — Generate a validated SEO brief (keywords, outline, FAQ, metadata).
  3. write — Produce an article draft using your note, project context, and brief.
  4. meta — Create publication metadata/frontmatter for a finished draft.
  5. translate — Translate Markdown using MT + LLM post-edit while preserving formatting.

Configuration

Environment variables

Variable Default Description
OPENAI_BASE_URL http://localhost:11434/v1 API endpoint URL
OPENAI_API_KEY no-key API key (not needed for Ollama)

You can also use OPENAI_API_BASE as an alternative to OPENAI_BASE_URL.

Project files

Create a scribae.yaml in your project directory to set defaults:

site_name: My Blog
domain: https://example.com
audience: developers interested in Python
tone: conversational
language: en
keywords:
  - python
  - programming

Usage examples

Idea discovery

Start with a note and generate a structured list of candidate articles:

scribae idea --note notes.md --project demo --out ideas.json

Use --language or --model to override project defaults, and --dry-run to preview the prompt without calling the model.

SEO brief creation

Convert a note into a validated brief, optionally anchored to a specific idea:

# From a note directly
scribae brief --note notes.md --out brief.json

# From a specific idea
scribae brief --note notes.md --ideas ideas.json --idea-index 1 --out brief.json

# Generate briefs for all ideas
scribae brief --note notes.md --ideas ideas.json --idea-all --out-dir briefs/

Draft writing

Turn a note + brief into a draft:

# Full article
scribae write --note notes.md --brief brief.json --out draft.md

# Only sections 1-3
scribae write --note notes.md --brief brief.json --section 1..3 --out draft.md

# Require citations
scribae write --note notes.md --brief brief.json --evidence required --out draft.md

Metadata generation

Create JSON frontmatter or merge into an existing draft:

scribae meta --body draft.md --brief brief.json --format both --out meta.json

Use --overwrite to control how existing fields are preserved.

Translation

Translate Markdown while preserving structure:

scribae translate --src en --tgt de --in draft.md --out draft.de.md

Options:

  • --glossary — Lock specific terminology
  • --postedit / --no-postedit — Toggle LLM cleanup pass
  • --allow-pivot — Enable English pivoting for unsupported language pairs
  • --debug — Write detailed translation report

Supported language pairs

Direct MarianMT pairs: ende/es/fr/it/pt, dees/fr/it/pt, esde/fr/it/pt

Pivoting: When no direct pair exists and --allow-pivot is enabled, Scribae routes through English (src → en → tgt).

NLLB fallback: For other pairs, the pipeline falls back to NLLB. Standard ISO codes (en, de, es) are mapped automatically, or pass NLLB codes directly (eng_Latn, deu_Latn).

Development

Setup

git clone https://github.com/fmueller/scribae.git
cd scribae
uv sync --locked --all-extras --dev

For CPU-only PyTorch (~200MB vs ~2GB):

uv sync --locked --all-extras --dev --index pytorch-cpu

Running from source

uv run scribae --help

Testing

uv run ruff check   # Lint
uv run mypy         # Type check
uv run pytest       # Run tests

License

This project is licensed under the Apache License 2.0. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

scribae-0.1.0.tar.gz (55.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scribae-0.1.0-py3-none-any.whl (68.6 kB view details)

Uploaded Python 3

File details

Details for the file scribae-0.1.0.tar.gz.

File metadata

  • Download URL: scribae-0.1.0.tar.gz
  • Upload date:
  • Size: 55.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","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

Hashes for scribae-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f7f86decd71a5b71be7292fdf17b1403800fb9580704f72a0d55dad613f9543c
MD5 2d394494c07ff8940671ee76a74eda21
BLAKE2b-256 2a101d96a0465e2eb2590ed94682c06969d483aaa26db66899e40bd34dc57b72

See more details on using hashes here.

File details

Details for the file scribae-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: scribae-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 68.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.9.18 {"installer":{"name":"uv","version":"0.9.18","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

Hashes for scribae-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2750bd7de3ac880bab2edfb84e2f9174792ea2daf8dfbc3523f839693b5d409d
MD5 b091465ebea41b5d3f6d980c859d2c7b
BLAKE2b-256 03ca0fa403597c897b33ae0f40a93f91b3d95b41ac6fcb793aac127e1f9c3494

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page