Skip to main content

Large Language Model Markdown Document Generator (llm-mddocgen)

llm-mddocgen is a markdown based prompt builder for generating documents with large language models.

llm-mddocgen connects to any OpenAI-compatible LLM backend and produces reports, summaries, research documents, code, and more — driven by a configured set of tasks. It is not a chatbot or an agentic system. Markdown, text, and pdf data goes in, an LLM generated document comes out.


Philosophy

task + persona + template + sources → LLM synthesis → output document

llm-mddocgen is a one-directional pipeline. There is no interactive loop, it treats your model like a compiler. If the output needs adjustment, edit your task, persona, or template and run again. The goal is to produce reliable definitions of what you want to generate and get a progressivly better collection of documents or queue up various projects and questions and generate weekly digests to review on demand.


Getting Started

The fastest way to understand llm-mddocgen is to look at the examples/ directory. It contains example tasks and projects which you can copy to another location to get started. Copy the llm-mddocgen.toml.example to the location where you execute llm-mddocgen and configure your backend against it, then provide a task and project or if you have multiple you can provide a task-dir and/or project-dir, projects are optional if your task does not define one.

llm-mkdocgen --help

llm-mddocgen --task examples/tasks/roman-statesmen.md
llm-mddocgen --tasks-dir examples/tasks/
llm-mddocgen --task examples/tasks/marcus-agrippa-life-summary.md --project examples/projects/marcus-agrippa-research.md

Use --dry-run to preview what would run without calling the model:

llm-mddocgen --tasks-dir examples/tasks/ --dry-run

Core Concepts

Tasks

A task is a unit of work — a document you want generated. Each task is a markdown file with a YAML frontmatter block that declares which persona should perform the work and which template defines the output format.

---
name: roman-statesmen
persona: historian
template: report
tags: [history, rome]
---

Produce a structured list of famous Roman statesmen and their accomplishments,
spanning the Republic and Imperial periods.

Required frontmatter fields: name, persona, template. Optional fields:

Field Description
project Links the task to a shared project context
tags One or more tags merged into the output document's frontmatter
enabled Set to false to skip this task without deleting it (default: true)

The body of the task file is passed directly to the model as the user prompt. Any other .md or .txt files in the same task directory are automatically collected and injected as source material.

Personas

A persona is a role definition — it becomes the system prompt for the model. Each persona is a markdown file with a YAML frontmatter block and a body that describes the expert's behavior, style, and priorities.

---
name: my-analyst
description: Evaluates source material and surfaces key findings.
personality: direct, skeptical, evidence-oriented
behavior:
  - lead with the strongest supported findings
  - distinguish confident conclusions from inferences
  - flag gaps and unresolved questions explicitly
---

You are a research analyst. Your job is to evaluate sources, identify the
strongest claims, and surface gaps in the available evidence.

Distinguish primary from secondary sources. Flag uncertainty explicitly
rather than smoothing it over.

Personas live in personas/<name>/persona.md (directory layout) or as a flat personas/<name>.md file. Files placed in personas/<name>/data/ are injected as source material on every run of that persona. A tags field in persona frontmatter is merged into the output's tag list.

A full set of built-in personas is included — see the table below. Use them as-is or copy one as a starting point for a custom persona.

Templates

A template is an output format contract. It defines the sections, structure, and style a generated document must follow. Templates are reusable across tasks.

---
name: brief
default_persona: analyst
tags: [brief]
---

Produce a short, focused brief. Essential information only.

Required sections:
- **Brief** — two to four sentence summary of the situation
- **Key Facts** — three to five bullets, each a single concrete claim
- **Recommendation** — one clear action or conclusion

When a task sets template: brief, the template body is appended to the user prompt. If default_persona is set, it is used when the task has no persona field.

A full set of built-in templates is included — see the table below.

Projects

A project is a shared context for a group of related tasks — an optional markdown file with a YAML frontmatter block and a body that provides standing background relevant to multiple tasks.

---
name: marcus-agrippa-research
description: Research on the life, career, and legacy of Marcus Vipsanius Agrippa
---

Produce a comprehensive research paper on Marcus Vipsanius Agrippa —
the Roman general, statesman, and close ally of Augustus Caesar.

Tasks reference a project via the project: frontmatter field. Project content is injected as source material alongside task-specific sources. Projects live in a projects/ directory at the project root. A tags field in project frontmatter is merged into the output's tag list.

Tags and Output Frontmatter

Any tags field defined in a task, persona, template, or project is collected and merged into the generated document as YAML frontmatter. Duplicate tags are removed. If no tags are defined anywhere, no frontmatter is added.

---
tags:
  - history
  - rome
  - report
---

# Roman Statesmen
...

This makes llm-mddocgen output compatible with tools like Obsidian that read tags from document frontmatter.


Built-in Personas

Name Description
advisor Practical, patient life and decision advisor focused on frugality, quality, and long-term wellbeing
analyst Objective and data-driven with a focus on measurable results
coder Explains software systems, produces code examples, and evaluates design tradeoffs
copywriter Engaging, narrative-focused writer with a focus on improving writing and prose quality
critic Rigorous, logic-testing skeptic designed to find flaws in arguments or ideas
diplomat Empathetic, fair-minded mediator for navigating difficult human interactions
educator Patient and focused on building understanding through clear, simple explanations
engineer Technical, systems-focused, and concerned with real-world implementation constraints
historian Produces factual, sourced accounts of historical events and individuals
manager Execution-oriented organizer focused on unblocking dependencies and making decisions
researcher Synthesizes source material into structured research documents on any topic
strategist High-level, risk-aware planner focused on trade-offs and long-term impacts
writer Produces clear, well-structured prose for documents, articles, and reports

Built-in Templates

Name Description
analysis Analytical breakdown that interprets evidence and produces a defensible judgment
assessment Balanced evaluation of opposing sides of a core dilemma with pros and cons
brief Short decision-support document with essential facts and a single clear recommendation
code Complete, runnable source code implementation with explanation and known limitations
critique Critical evaluation with specific strengths, weaknesses, and a clear overall verdict
decision Factor-by-factor comparison of multiple choices to force a logical verdict
design Structured design document defining components, interfaces, constraints, and open questions
detailed Comprehensive, exhaustive breakdown with deep and granular detail
draft Structured interpersonal correspondence with tone-setting and a clear purpose
instruct Sequential, actionable instructions with prerequisites and success criteria
plan Time-based organization into daily priorities and milestones toward a goal
proofread Line-level proofreading with structural feedback and a clear revision verdict
question Anticipated question-and-answer pairs extracted from raw source material
recommend Decision-focused recommendation for an approach or outcome
report Formal structured report with background, findings, analysis, and conclusions
research Research document surfacing what is known, uncertain, and still missing on a topic
review Opinionated breakdown of media and products with general consensus and a final score
summary Bottom-line up front, key takeaways, and a final recommendation

Custom personas and templates can be added to ~/.llm-mddocgen/custom/personas/ and ~/.llm-mddocgen/custom/templates/. User-defined files override built-ins with the same name.


Workspace Layout

llm-mddocgen.toml         # Per-project config (optional; overrides ~/.llm-mddocgen/config.toml)
personas/                 # Custom persona definitions (optional)
  <name>/
    persona.md            # Required: system prompt + frontmatter
    data/                 # Optional: source files injected on every run
templates/                # Custom template definitions (optional)
  <name>.md
tasks/                    # Task definitions
  <name>/
    task.md               # Required: task body + frontmatter
    *.md / *.txt          # Optional: source files injected into this task
projects/                 # Shared project context files (optional)
  <name>.md
profile/                  # Standing user context injected into every run
  default/
    profile.md            # Max 20 lines; use --profile <name> for alternates
output/                   # Output reports (written by llm-mddocgen; resolved from CWD)
  tasks/
    <task-name>-<timestamp>.md
  projects/
    <project-name>/
      <task-name>-<timestamp>.md
  logs/
    <timestamp>.md        # Per-task generation logs and run summaries

Global config and built-in assets live at ~/.llm-mddocgen/.


Install

Recommended: uv

uv manages the virtualenv automatically — no activation step needed.

# Install uv (once)
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies and run
uv sync
uv run python -m llm_mddocgen --help

# Install as a system command
uv tool install .
llm-mddocgen --version

PyPI

pip install llm-mddocgen
llm-mddocgen --version

pip (from source)

python -m venv .venv
source .venv/bin/activate
pip install -e .
llm-mddocgen --version

Docker

# Runs against the examples/ directory by default
docker compose up

# Run against a custom workspace
WORKSPACE_PATH=/path/to/your/tasks docker compose up

Configuration

llm-mddocgen loads config from one of two places:

  • ./llm-mddocgen.toml — used if present in the current directory; global config is ignored
  • ~/.llm-mddocgen/config.toml — global fallback

Copy llm-mddocgen.toml.sample to get started:

# Per-project config. Values here override the global ~/.llm-mddocgen/config.toml.

# Uncomment to use project-local persona/template directories.
# personas_root = "personas"
# templates_root = "templates"

# Profile root for standing user context injected into every prompt.
# profile_root = "profile"

# Projects root for task-scoped shared context.
# projects_root = "projects"

# Output directory. Resolved relative to the current working directory.
generated_root = "output"

[llm]
# Set to true to enable LLM synthesis. False uses the deterministic fallback.
enabled = false

# Any OpenAI-compatible endpoint: Ollama, vLLM, OpenAI, etc.
base_url = "http://localhost:11434/v1"
model = "llama3.2"

# Auth key (or use LLM_MDDOCGEN_API_KEY env var).
api_key = ""

# Request tuning. Suggested starting points by provider:
#   Ollama (llama3, mistral)  — temperature = 0.2,  max_tokens = 1200
#   Qwen3 standard            — temperature = 0.2,  max_tokens = 4096
#   Qwen3 thinking mode       — temperature = 0.7,  max_tokens = 10000
#   OpenAI gpt-4o             — temperature = 0.3,  max_tokens = 2048
timeout_seconds = 60
temperature = 0.2
max_tokens = 1200

# Web search via tool use (requires a model that supports function calling, e.g. llama3.1+).
# llm-mddocgen asks the model to generate search queries, fetches results from DuckDuckGo,
# and injects them as source documents before synthesis.
# web_search = false
# web_search_max_queries = 3
# web_search_max_results = 5

# Save model reasoning output (<think>...</think> blocks) to a separate file.
# thinking_output = false

Quick Start

1. Point llm-mddocgen at your LLM.

Edit llm-mddocgen.toml with your endpoint and model, or set enabled = false to use the deterministic fallback (good for testing workspace structure without a running model).

2. Try the examples.

llm-mddocgen --tasks-dir examples/tasks/

Or scaffold a new task from scratch:

llm-mddocgen --init-task tasks/my-first-task/task.md

Edit the scaffolded file to set your persona, template, and task body.

3. Run it.

llm-mddocgen --task tasks/my-first-task/task.md

4. Read the output.

Reports land in output/tasks/ for standalone tasks, or output/projects/<name>/ for project-linked tasks.


CLI Reference

Task execution

Flag Description
--task <path> Task file to run (repeatable)
--tasks-dir <path> Run all tasks found in a directory
--project <path> Project file to associate with --task
--project-dir <path> Directory of project files for auto-association
--fail-fast Stop on the first task failure

Output and profile

Flag Description
--output-path <path> Override the output directory
--profile <name> Load a named profile from the profile root
--profile-path <path> Override the profile root directory

Configuration

Flag Description
--config <path> Use a specific TOML config file

Utility actions

Flag Description
--list personas|tasks|templates List available personas, tasks, or templates
--init-task <path> Write a starter task.md and exit
--dry-run Show what would run without executing
--version Print version and exit

Source Injection

On each run, llm-mddocgen collects source documents from several locations and injects them into the prompt:

Source Content
Task directory All .md and .txt files alongside task.md
Task data/ Subdirectory of supporting files
Persona data/ Reference files for the active persona
Project file Shared context declared in project: frontmatter
Profile Standing user context from profile/default/profile.md
Previous output The most recent generated report for this task (for iterative refinement)
Web search DuckDuckGo results fetched via tool use (if enabled)

PDF files are supported when allow_pdf_materials = true in config.


Profile

The profile is a standing context document injected into every task run. Use it for user identity, preferences, or constraints that apply across all your tasks.

I am a software engineer at a mid-stage startup. I prefer direct, no-hedging analysis.
Assume I have strong technical context and skip basic explanations.
Prioritize actionable output over comprehensive coverage.
  • Location: profile/default/profile.md
  • Maximum 20 lines (enforced)
  • Use --profile <name> to load an alternate profile from profile/<name>/profile.md

Fallback Mode

When llm.enabled = false (the default), llm-mddocgen uses a deterministic fallback synthesizer. It extracts bullet points from source files and structures them into a fixed-section report. No model is called. This is useful for testing your workspace configuration and verifying that sources are collected correctly before connecting an LLM.


Development

# Install dev dependencies
uv sync --dev

# Run tests
uv run pytest -q

# Install as a system command
uv tool install .

Dev dependencies are declared using PEP 735 dependency groups in pyproject.toml. Use uv sync --dev — not pip install -e ".[dev]" — to install them.

Metadata

Release files for llm-mddocgen 0.1.0

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

Source distribution (sdist)

Source distribution for llm-mddocgen 0.1.0
File Size Uploaded Provenance
llm_mddocgen-0.1.0.tar.gz 85.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for llm-mddocgen 0.1.0
File Interpreter ABI Platform
llm_mddocgen-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 151.2 kB

Release files / llm_mddocgen-0.1.0.tar.gz

Download URL llm_mddocgen-0.1.0.tar.gz
Size 85.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2a6bb173054193f8d330257e27eab8cbe300844f8c2963e77df872815c002a6c
BLAKE2b-256 checksum
How to use checksums
5d24e24b8f35c0600d788b6df1131c482b208b75df4aab9596759549b37c8fd6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2026.

Transparency log

Release files / llm_mddocgen-0.1.0-py3-none-any.whl

Download URL llm_mddocgen-0.1.0-py3-none-any.whl
Size 65.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a52c2bdeac2b015dc011944ca6ecb968957b58e29206d62b65800ba2d09be82e
BLAKE2b-256 checksum
How to use checksums
4b93995e074d3453a785385f893669ac3d02a1becdc9c1b8a45dbb83d5dca50e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2026.

Transparency log

Security for llm-mddocgen 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for llm_mddocgen-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 13, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

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