📚 OpenDocs
Convert GitHub READMEs, Markdown files, and Jupyter Notebooks into structured, multi-format documentation — instantly.
#opensource | #documentation | #markdown | #ai | #devtools | #python | #jupyter | #llm
What is OpenDocs?
OpenDocs (by ioteverythin) takes a GitHub repository README, local Markdown file, or Jupyter Notebook (.ipynb) and automatically generates beautiful, professional documentation in multiple formats:
| Output | Format | Status |
|---|---|---|
| Technical Report | .docx (Word) |
Available |
| Executive Deck | .pptx (PowerPoint) |
Available |
| PDF Documentation | .pdf |
Available |
| Blog Post | .md (SEO-ready) |
Available |
| Jira Tickets | .json (Epic + Stories) |
Available |
| Changelog / Release Notes | .md |
Available |
| Academic Paper | .tex (LaTeX / IEEE) |
Available |
| One-Pager / Datasheet | .pdf (executive) |
Available |
| Social Cards | .json (OG + posts) |
Available |
| FAQ Document | .md |
Available |
| Analysis Report | .md (Markdown) |
Available |
| Architecture Diagrams | .mmd + .png (5 views) |
Available |
| Mermaid Diagrams | PNG rendering | Available |
| Knowledge Graph | Entity extraction | Available |
| Interactive Graph | .html (vis.js) |
Available |
| Graph Export | .json (queryable) |
Available |
| Knowledge Wiki | Markdown folder | Available |
| LLM Summaries | Stakeholder views | Available |
What's New in v0.9.0
- Interactive Knowledge Graph -- Explorable HTML graph (vis.js) with search, filtering, god-node analysis, community clusters, provenance labels, and surprising connections
- Graph JSON Export -- Persistent
graph.jsonwith nodes, edges, communities, provenance, god nodes, surprising connections, and suggested questions. Query weeks later without re-processing - Community Detection -- Label propagation clustering groups entities by edge density. No external dependencies
- Provenance Labels -- Every entity and relation tagged EXTRACTED, INFERRED, or AMBIGUOUS so you always know what was found vs guessed
- Suggested Questions -- 5 auto-generated questions the graph is uniquely positioned to answer, based on structural signals
- God Nodes & Surprising Connections -- Highest-degree hub entities and cross-type edges ranked by surprise score
- Knowledge Wiki Export -- Wikipedia-style linked Markdown articles: one per community, plus index and entity catalog. Inspired by Graphify
--wiki - Semantic Similarity Edges -- Entities co-occurring in the same section but with no structural link get automatic SIMILAR_TO edges, surfacing hidden conceptual connections
- Jupyter Notebook Ingestion -- Parse
.ipynbfiles and convert markdown cells, code cells, and outputs into polished reports - Parameterized Report Templates -- Inject project name, author, version, date, and organisation into document headers, footers, and title pages via
--configYAML/JSON or CLI flags - File Watcher + Auto-PR --
opendocs watchdaemon monitors repos for changes and auto-regenerates docs; supports cron mode (--once) and automatic pull requests (--auto-pr) - 5 LLM Providers -- OpenAI, Anthropic (Claude), Google (Gemini), Ollama (local), Azure OpenAI
- 25 Built-in Themes -- 15 original + 10 new modern themes (Aurora, Carbon, Lavender, Graphite, Obsidian, Coral, Zen, Nebula, Sand, Glacier)
- AI Reader Files -- Auto-generate
llms.txt,llms-full.txt,AGENTS.md, andCLAUDE.mdfor LLMs and coding agents
Two Engines
1. Pipeline (Deterministic + LLM)
The core pipeline parses Markdown/Notebooks and generates all 12 selectable output formats:
- Basic mode -- Pure Markdown AST parsing, no LLM required. Fast, free, predictable.
- LLM mode -- Uses any supported LLM provider to extract entities, build knowledge graphs, and generate executive summaries + stakeholder views (CTO, Investor, Developer).
2. DocAgent (Agentic)
A full LangGraph-powered agent that generates 8 enterprise document types (PRD, Proposal, SOP, Report, Slides, Changelog, Onboarding, Tech Debt) from any GitHub repo.
Quick Start
Install from PyPI
pip install opendocs
For LLM features:
pip install opendocs[llm]
For all LLM providers:
pip install opendocs[all-providers]
For YAML config file support:
pip install opendocs[templates]
Install from source
git clone https://github.com/ioteverythin/OpenDocs.git
cd OpenDocs
pip install -e ".[dev,llm]"
Basic Usage
# Generate all formats from a GitHub README
opendocs generate https://github.com/owner/repo
# Generate specific format with a theme
opendocs generate https://github.com/owner/repo --format word --theme aurora
# From a local Markdown file
opendocs generate ./README.md --local
# LLM mode with knowledge graph + stakeholder summaries
opendocs generate ./README.md --local --mode llm --api-key sk-...
# Use Claude instead of OpenAI
opendocs generate ./README.md --local --mode llm --provider anthropic
# List available themes (25 themes)
opendocs themes
Incremental Builds
Generated artifacts are cached by content, so re-running the pipeline only
rebuilds what actually changed. This matters most for opendocs watch, which
otherwise regenerates every format on every save.
opendocs generate ./README.md --local # cached automatically
opendocs generate ./README.md --local --no-cache # force a full rebuild
opendocs generate ./README.md --local --cache-dir /tmp/od-cache
opendocs cache # show location, entry count, and size
opendocs cache --clear # empty it
The cache key covers the document content, the knowledge graph, the theme, the template variables, the output format, and the installed opendocs version, so changing any of them rebuilds rather than reusing. A cache hit reproduces the stored artifact byte for byte; the one thing it does not refresh is the generation timestamp, which is what makes identical inputs produce identical output.
LLM responses are cached too. In --mode llm, re-running over an unchanged
README previously re-paid for every API call. Responses are now stored on disk
keyed by provider, model, temperature, token limit, and the exact prompt, so a
repeat run costs nothing and returns instantly:
opendocs generate ./README.md --local --mode llm # first run calls the API
opendocs generate ./README.md --local --mode llm # second run is free
export OPENDOCS_LLM_CACHE=0 # disable response caching only
opendocs generate ./README.md --local --mode llm --no-cache # disable both
Note this deliberately trades novelty for cost and reproducibility: with
temperature > 0 the provider would have returned a different answer, and
you get the earlier one. Change the temperature, the model, or the prompt and
it re-asks; use --no-cache when you specifically want a fresh generation.
What Changed Since the Last Release
opendocs diff compares two versions of your documentation and reports what
moved — new and removed sections, concepts, and relationships — then renders
it as release notes. Deterministic and offline.
# Two files
opendocs diff old/README.md new/README.md
# Two git revisions of the same file
opendocs diff v0.8.0 HEAD --git . --path README.md
# Two previously exported graphs
opendocs diff v1_graph.json v2_graph.json
# Draft release notes
opendocs diff v0.8.0 HEAD --git . --format markdown -o RELEASE_NOTES.md
# Machine-readable, including which formats are worth regenerating
opendocs diff old.md new.md --format json
# CI gate: fail if documentation drifted
opendocs diff committed.md generated.md --fail-on-change
The summary also reports which output formats are worth regenerating, so a docs pipeline can rebuild only what the change actually affects.
What Isn't Documented
opendocs lint checks the quality of what your docs say. opendocs coverage
reports what they miss, by comparing the real API surface against what the
documentation actually mentions:
opendocs coverage . # report
opendocs coverage . --show-missing # list every gap
opendocs coverage . --fail-under 80 # CI gate
opendocs coverage . --json # machine-readable
opendocs coverage . --docs README.md --docs docs/guide.md
Dimension Covered Total Coverage
docstrings:functions 87 88 98.9%
docstrings:classes 185 187 98.9%
env-vars 4 7 57.1%
cli-flags 41 76 53.9%
tech-stack 4 14 28.6%
Overall: 86.3%
Four dimensions are scored, each chosen because it has an objective answer:
docstrings on public symbols, environment variables the code reads, CLI flags
it defines, and detected technologies. Test files and private helpers are
excluded by default (--include-tests, --include-private to include them),
and the overall figure is weighted by item count so a single missed flag does
not outweigh hundreds of documented symbols.
It deliberately does not judge whether prose is good — that is not objectively measurable, and a score nobody can verify is worse than none.
Everything runs offline with no LLM. Exit codes: 0 pass, 1 below
--fail-under, 2 analysis failed.
Linting Documentation in CI
opendocs lint checks documentation quality and exits non-zero when it
regresses, so a pull request can fail on a broken README the same way it fails
on a broken test:
opendocs lint ./README.md --local # errors fail the build
opendocs lint ./README.md --local --fail-on warning # be stricter
opendocs lint ./README.md --local --fail-on never # report only
opendocs lint ./README.md --local --json # machine-readable
opendocs lint https://github.com/owner/repo --check-links
All rules run offline; --check-links is the only one that uses the network.
| Rule | Severity | Catches |
|---|---|---|
no-title |
error | No level-1 heading to use as a title |
no-description |
error | No prose at all, only headings and code |
placeholder |
error | Unreplaced template text (your-project-name, CHANGEME) |
dead-link |
error | 4xx links (--check-links) |
missing-installation / missing-usage / missing-license |
warning | Conventional section absent |
thin-content |
warning | Fewer than 50 words of prose |
todo-marker |
warning | TODO / FIXME / TBD left in published docs |
ragged-table |
warning | Table rows that do not match the header, so it silently renders as plain text |
image-no-alt |
warning | Images without alt text |
heading-jump |
info | Heading levels skipping (H2 to H4) |
duplicate-heading |
info | The same heading repeated at one level |
unlabelled-code |
info | Fenced code with no language annotation |
Use it in a workflow:
- name: Lint documentation
run: |
pip install opendocs
opendocs lint ./README.md --local
Exit codes: 0 clean, 1 findings at or above --fail-on, 2 the source
could not be read.
Querying a Graph Later
opendocs generate writes a graph.json alongside the documents. opendocs
query answers questions about it without re-processing the source — no LLM,
no API key, no network:
# Overview: top entities and suggested questions
opendocs query output/myproject_graph.json
# Structural queries
opendocs query graph.json --stats
opendocs query graph.json --list-types
opendocs query graph.json --search redis
opendocs query graph.json --entity "PostgreSQL"
opendocs query graph.json --dependents "PostgreSQL" # what would be affected
opendocs query graph.json --dependencies "API Gateway" # what it relies on
opendocs query graph.json --neighbors "Redis"
opendocs query graph.json --path "API Gateway" "S3" # how two things connect
opendocs query graph.json --type database
opendocs query graph.json --community 2
opendocs query graph.json --provenance AMBIGUOUS # review low-confidence finds
opendocs query graph.json --god-nodes
# Plain-English questions, answered from graph structure
opendocs query graph.json "what depends on Redis?"
opendocs query graph.json "how are the API and S3 connected?"
opendocs query graph.json "which databases are used?"
Add --json to any query for machine-readable output, and --limit N to
control how many rows come back.
Exit codes make it scriptable: 0 success, 1 the query matched nothing,
2 the graph file could not be read.
Offline / Air-Gapped Use
The interactive knowledge graph normally loads vis.js from a CDN. To produce a page that renders with no network access at all:
opendocs generate ./README.md --local --embed-graph-assets
The library is downloaded once and cached (~/.cache/opendocs), so subsequent
runs need no network. On a fully air-gapped machine, supply it yourself:
export OPENDOCS_VIS_NETWORK_JS=/path/to/vis-network.min.js
opendocs generate ./README.md --local --embed-graph-assets
Diagram rendering can be disabled the same way, which also makes builds fully offline and much faster:
export OPENDOCS_MERMAID_BACKEND=none # auto | mmdc | ink | none
| Variable | Purpose |
|---|---|
OPENDOCS_MERMAID_BACKEND |
Diagram backend: auto (default), mmdc, ink, or none to disable |
OPENDOCS_VIS_NETWORK_JS |
Path to a local vis-network bundle for --embed-graph-assets |
OPENDOCS_CACHE_DIR |
Override the asset cache location (default ~/.cache/opendocs) |
OPENDOCS_LLM_CACHE |
Set to 0 to disable LLM response caching |
OPENDOCS_MODEL_CACHE |
Where local SLM weights are cached (--provider slm) |
AZURE_OPENAI_ENDPOINT |
Azure endpoint URL (--provider azure) |
AZURE_OPENAI_API_VERSION |
Azure API version (--provider azure) |
Jupyter Notebook Ingestion
Generate polished reports from research notebooks and data-science projects:
# Generate docs from a Jupyter Notebook
opendocs generate ./analysis.ipynb --local
# Generate only Word report from notebook
opendocs generate ./research.ipynb --local --format word --theme carbon
# Exclude cell outputs
opendocs generate ./notebook.ipynb --local --no-outputs
The notebook parser extracts: - Markdown cells -- parsed into headings, paragraphs, lists, tables, etc. - Code cells -- preserved with language detection and execution count - Cell outputs -- text output, images (PNG/SVG/JPEG as data URIs), HTML previews, error tracebacks
Parameterized Report Templates
Inject variables into document headers, footers, and title pages:
# Via CLI flags
opendocs generate ./README.md --local \
--project-name "My Project" \
--author "Jane Doe" \
--doc-version "2.1.0" \
--org "Acme Corp" \
--department "Engineering" \
--confidentiality "Internal"
# Via YAML/JSON config file
opendocs generate ./README.md --local --config opendocs.yaml
Example opendocs.yaml:
project_name: "My Project"
author: "Jane Doe"
version: "2.1.0"
date: "2026-02-28"
organisation: "Acme Corp"
department: "Engineering"
confidentiality: "Internal"
custom:
reviewer: "John Smith"
status: "Draft"
These values automatically appear in: - Word (.docx) -- document header, footer, and expanded metadata table on title page - PowerPoint (.pptx) -- title slide footer with org, author, version, and date - PDF -- inherits from Word generator
File Watcher + Auto-PR
Monitor a repository for changes and auto-regenerate documentation:
# Continuous watch (checks every 30 seconds)
opendocs watch ./my-repo
# One-shot mode for cron jobs
opendocs watch ./my-repo --once
# Watch + auto-create pull requests
opendocs watch ./my-repo --auto-pr --branch docs-update
# Custom interval and file patterns
opendocs watch ./my-repo --interval 60 --patterns "README.md,docs/*.md,*.ipynb"
Cron integration -- add to crontab for hourly checks:
0 * * * * cd /path/to/repo && opendocs watch . --once --auto-pr
How it works:
1. Discovers files matching watch patterns (README.md, CHANGELOG.md, docs/**/*.md, *.ipynb)
2. Computes SHA-256 hashes and compares against saved state (.opendocs-watch-state.json)
3. If changes detected: runs the full pipeline for each changed file
4. If --auto-pr: creates a timestamped git branch, commits outputs, pushes, and opens a PR via GitHub CLI (gh)
Multi-LLM Provider Support
Use any of the 5 supported LLM providers:
# OpenAI (default)
opendocs generate ./README.md --local --mode llm --provider openai --api-key sk-...
# Anthropic Claude
opendocs generate ./README.md --local --mode llm --provider anthropic
# Google Gemini
opendocs generate ./README.md --local --mode llm --provider google
# Ollama (local, no API key needed)
opendocs generate ./README.md --local --mode llm --provider ollama
# Azure OpenAI
opendocs generate ./README.md --local --mode llm --provider azure --base-url https://your-resource.openai.azure.com/
| Provider | Models | Env Variable |
|---|---|---|
openai |
gpt-4o-mini (default), gpt-4o, etc. | OPENAI_API_KEY |
anthropic |
claude-sonnet-4-20250514, claude-3-haiku, etc. | ANTHROPIC_API_KEY |
google |
gemini-1.5-flash (default), gemini-pro, etc. | GOOGLE_API_KEY |
ollama |
llama3.1 (default), any local model | None (local) |
azure |
Any Azure-deployed model | AZURE_OPENAI_API_KEY |
Format Flags Reference
Use -f / --format to generate only what you need:
| Flag | Output | File |
|---|---|---|
word |
Word document | .docx |
pdf |
PDF document | .pdf |
pptx |
PowerPoint deck | .pptx |
blog |
SEO blog post | .md (with front-matter) |
jira |
Jira tickets (Epic + Stories) | .json |
changelog |
Release notes | .md |
latex |
IEEE-style academic paper | .tex |
onepager |
Executive one-pager | .pdf |
social |
Social cards + post text | .json (OG, Twitter, LinkedIn, Reddit) |
faq |
FAQ document | .md |
architecture |
Architecture diagrams (5 views) | .mmd + .png + .md report |
all |
Everything above (default) | all formats |
25 Built-in Themes
| Category | Themes |
|---|---|
| Classic | corporate, ocean, sunset, dark, minimal, emerald, royal |
| Professional | slate, rose, nordic, cyber, terracotta, sapphire, mint, monochrome |
| Modern | aurora, carbon, lavender, graphite, obsidian, coral, zen, nebula, sand, glacier |
# List all themes with color previews
opendocs themes
Python API
from opendocs.pipeline import Pipeline
from opendocs.core.models import OutputFormat
from opendocs.core.template_vars import TemplateVars
# Basic usage
pipeline = Pipeline()
pipeline.run("https://github.com/owner/repo", theme_name="aurora")
# From a Jupyter Notebook with template variables
tvars = TemplateVars(
project_name="Q4 Analysis",
author="Data Team",
version="1.0",
organisation="Acme Corp",
)
pipeline.run(
"./notebook.ipynb",
local=True,
formats=[OutputFormat.WORD, OutputFormat.PDF],
template_vars=tvars,
)
# LLM mode with Claude
pipeline.run(
"./README.md",
local=True,
mode="llm",
api_key="sk-ant-...",
provider="anthropic",
)
Features
- 15 Output Formats -- Word, PDF, PPTX, Blog Post, Jira Tickets, Changelog, LaTeX Paper, One-Pager PDF, Social Cards, FAQ, Architecture Diagrams, Mindmap, Interactive Graph, Graph JSON, Knowledge Wiki
- Interactive Knowledge Graph -- Single-file HTML visualization with search, legend, community clusters, god nodes, surprising connections, provenance bar, and suggested questions. Loads vis.js from a CDN by default; pass
--embed-graph-assetsto inline it and get a page that renders fully offline - Graph JSON Export -- Persistent queryable
graph.jsonwith nodes, edges, communities, provenance labels, god nodes, surprising connections, and suggested questions - Knowledge Wiki -- Wikipedia-style inter-linked Markdown articles (one per community) with navigable index and full entity catalog
- Community Detection -- Label propagation algorithm groups entities into clusters by edge density (zero external dependencies)
- Provenance Labels -- Every entity/relation tagged EXTRACTED (deterministic), INFERRED (LLM), or AMBIGUOUS (low confidence)
- God Nodes & Surprising Connections -- Highest-degree hub entities and cross-type edges ranked by composite surprise score
- Suggested Questions -- Auto-generated questions the graph is uniquely positioned to answer
- Semantic Similarity Edges -- Cross-type entities co-occurring in the same section get automatic SIMILAR_TO edges
- AI Reader Files -- Auto-generate
llms.txt,llms-full.txt,AGENTS.md, andCLAUDE.mdfor LLMs and coding agents - Jupyter Notebook Support -- Parse
.ipynbfiles including markdown cells, code cells, and outputs (images, tables, text) - Parameterized Templates -- Inject project name, author, version, org, date into headers/footers via config file or CLI
- File Watcher + Auto-PR -- Monitor repos for changes, auto-regenerate docs, and create pull requests
- 5 LLM Providers -- OpenAI, Anthropic (Claude), Google (Gemini), Ollama (local), Azure OpenAI
- 25 Built-in Themes -- Classic, Professional, and Modern theme categories
- Smart Table Sorting -- 6 strategies (smart, alpha, numeric, column:N, column:N:desc, none)
- Knowledge Graph -- Extracts 17 entity types (projects, technologies, APIs, metrics, frameworks, databases, etc.)
- Architecture Diagrams -- 5 auto-generated views: System Architecture (C4-style), Tech Stack Layers, Data Flow, Dependency Tree, Deployment View
- Mermaid -> PNG -- Renders mermaid diagrams to images via mermaid.ink API
- LLM Summaries -- Executive summary + CTO / Investor / Developer stakeholder views
Architecture
GitHub URL / Local .md / .ipynb
|
v
+-------------------+
| README Fetch / | <-- httpx + GitHub API
| Notebook Parser | <-- .ipynb cell extraction
+--------+----------+
v
+-------------------+
| Markdown Parser | <-- mistune 3.x AST
+--------+----------+
v
+-------------------+
| Template Vars | <-- YAML/JSON config or CLI flags
+--------+----------+
v
+-------------------+
| Table Sorting | <-- 6 strategies
+--------+----------+
v
+-------------------+
| KG Extraction | <-- Semantic + optional LLM (5 providers)
+--------+----------+
v
+-------------------+
| Community Detect | <-- Label propagation clustering
+--------+----------+
v
+-------------------+
| Diagram Renderer | <-- mermaid.ink API
+--------+----------+
|
+----+----+----+----+------+------+-------+------+-----+------+------+------+------+------+
v v v v v v v v v v v v v v
Word PDF PPTX Blog Jira Change LaTeX 1-Pgr Social FAQ Arch iGraph JSON Wiki
log Diag .html .json .md/
File Watcher Flow
opendocs watch ./repo
|
v
Discover watched files (README.md, *.ipynb, docs/)
|
v
SHA-256 hash each file
|
v
Compare against .opendocs-watch-state.json
|
v
If changed --> Pipeline.run() for each file
|
v
Update state file
|
v
If --auto-pr --> git branch + commit + push + gh pr create
Optional Dependencies
pip install opendocs[llm] # OpenAI LLM features
pip install opendocs[anthropic] # Claude support
pip install opendocs[google] # Gemini support
pip install opendocs[all-providers] # All LLM providers
pip install opendocs[templates] # YAML config file support
pip install opendocs[agents] # DocAgent (agentic system)
Development
# Install dev dependencies
pip install -e ".[dev,llm,templates]"
# Run tests
pytest
# Lint
ruff check src/
Contributing
Contributions are welcome! Please open issues and PRs on GitHub.
License
MIT License -- see LICENSE for details.