Files
doc-forge/README.md

9.5 KiB

docforge

Renderer-agnostic Python documentation compiler that converts Python docstrings into structured documentation for both humans (MkDocs) and machines (MCP / AI agents).

doc-forge statically analyzes source code, builds a semantic model of modules, classes, functions, and attributes, and renders that model into documentation outputs without executing user code.


Installation

Install using pip:

pip install doc-forge

CLI usage

Generate an MkDocs site from a Python package:

doc-forge build --mkdocs --module my_package

Generate MCP JSON documentation:

doc-forge build --mcp --module my_package

Generate MkDocs site and MCP JSON documentation:

doc-forge build --mcp --mkdocs --module my_package

Serve MkDocs locally:

doc-forge serve --mkdocs --module my_package

Serve MCP locally:

doc-forge serve --mcp --module my_package

Core concepts

Loader

Extracts symbols, signatures, and docstrings using static analysis.

Semantic model

Structured, renderer-agnostic representation of the API.

Renderer

Converts the semantic model into output formats such as MkDocs or MCP JSON.

Symbol

Any documentable object

  • module
  • class
  • function
  • method
  • property
  • attribute

Architecture

doc-forge follows a compiler architecture:

Front-end:

Static analysis of modules, classes, functions, type hints, and docstrings.

Middle-end:

Builds a semantic model describing symbols and relationships.

Back-end:

Renders documentation using interchangeable renderers.

This architecture ensures deterministic documentation generation.


Rendering pipeline

Typical flow:

Python package
    ↓
Loader (static analysis)
    ↓
Semantic model
    ↓
Renderer
    ↓
MkDocs site or MCP JSON

Google-Styled Doc-Forge Convention (GSDFC)

GSDFC defines how docstrings must be written so they render correctly in MkDocs and remain machine-parsable by doc-forge and AI tooling.

  • Docstrings are the single source of truth.
  • doc-forge compiles docstrings but does not generate documentation content.
  • Documentation follows the Python import hierarchy.
  • Every public symbol should have a complete and accurate docstring.

General rules

  • Use Markdown headings at package and module level.
  • Use Google-style structured sections at class, function, and method level.
  • Use type hints in signatures instead of duplicating types in prose.
  • Write summaries in imperative form.
  • Sections are separated by ---

Notes subsection grouping

  • Group related information using labeled subsections.

Example: Notes Example:

    Notes:
        **Guarantees:**

            - deterministic behavior

        **Lifecycle:**

            - created during initialization
            - reused across executions

        **Thread safety:**

            - safe for concurrent reads

Example formatting

  • Use indentation for examples.
  • Indent section contents using four spaces.
  • Use code blocks for example code.

Example: Single example:

    Example:

        ```python
        foo = Foo("example")
        process(foo, multiplier=2)
        ```

Multiple examples:

    Example:
        Create foo:

            ```python
            foo = Foo("example")
            ```

        Run engine:

            ```python
            engine = BarEngine([foo])
            engine.run()
            ```

Avoid fenced code blocks inside structured sections.


Separator rules

Use horizontal separators only at docstring root level to separate sections:

---

Allowed locations:

  • package docstrings
  • module docstrings
  • major documentation sections

Do not use separators inside code sections.


Package docstrings

  • Package docstrings act as the documentation home page.

Recommended sections:

# Summary
# Installation
# Quick start
# CLI usage
# Core concepts
# Architecture
# Rendering pipeline
# Examples
# Notes

Example: Package Doc String:

    '''
    Foo-bar processing framework.

    Provides tools for defining Foo objects and executing Bar pipelines.

    ---

    # Installation

    ```bash
    pip install foo-bar
    ```

    ---

    # Quick start

    ```python
    from foobar import Foo, BarEngine

    foo = Foo("example")
    engine = BarEngine([foo])

    result = engine.run()
    ```

    ---
    '''

Module docstrings

  • Module docstrings describe a subsystem.

Recommended sections:

# Summary
# Examples
# Notes

Example: Module Doc String:

    '''
    Foo execution subsystem.

    Provides utilities for executing Foo objects through Bar stages.

    ---

    Example:

        ```python
        from foobar.engine import BarEngine
        from foobar.foo import Foo

        foo = Foo("example")

        engine = BarEngine([foo])
        engine.run()
        ```

    ---
    '''

Class docstrings

  • Class docstrings define object responsibility, lifecycle, and attributes.

Recommended sections:

Attributes:
Notes:
Example:
Raises:

Example: Simple Foo:

```python
class Foo:
    '''
    Represents a unit of work.

    Attributes:
        name (str):
            Identifier of the foo instance.

        value (int):
            Numeric value associated with foo.

    Notes:
        Guarantees:

            - instances are immutable after creation

        Lifecycle:

            - create instance
            - pass to processing engine

    Example:
        Create and inspect a Foo:

            ```python
            foo = Foo("example", value=42)
            print(foo.name)
            ```
    '''
```

Complex Bar:

```python
class BarEngine:
    '''
    Executes Foo objects through Bar stages.

    Attributes:
        foos (tuple[Foo, ...]):
            Foo instances managed by the engine.

    Notes:
        Guarantees:

            - deterministic execution order

    Example:
        Run engine:

            ```python
            foo1 = Foo("a")
            foo2 = Foo("b")

            engine = BarEngine([foo1, foo2])
            engine.run()
            ```
    '''
```

Function and method docstrings

  • Function docstrings define API contracts.

Recommended sections:

Args:
Returns:
Raises:
Yields:
Notes:
Example:

Example: Simple process method:

```python
def process(foo: Foo, multiplier: int) -> int:
    '''
    Process a Foo instance.

    Args:
        foo (Foo):
            Foo instance to process.

        multiplier (int):
            Value used to scale foo.

    Returns:
        int:
            Processed result.

    Raises:
        ValueError:
            If multiplier is negative.

    Notes:
        Guarantees:

            - foo is not modified

    Example:
        Process foo:

            ```python
            foo = Foo("example", value=10)

            result = process(foo, multiplier=2)
            print(result)
            ```
    '''
```

Multiple Examples:

```python
def combine(foo_a: Foo, foo_b: Foo) -> Foo:
    '''
    Combine two Foo instances.

    Args:
        foo_a (Foo):
            First foo.

        foo_b (Foo):
            Second foo.

    Returns:
        Foo:
            Combined foo.

    Example:
        Basic usage:

            ```python
            foo1 = Foo("a")
            foo2 = Foo("b")

            combined = combine(foo1, foo2)
            ```

        Pipeline usage:

            ```python
            engine = BarEngine([foo1, foo2])
            engine.run()
            ```
    '''
```

Property docstrings

  • Properties must document return values.

Example: Property Doc String:

    ```python
    @property
    def foos(self) -> tuple[Foo, ...]:
        '''
        Return contained Foo instances.

        Returns:
            tuple[Foo, ...]:
                Stored foo objects.

        Example:
            ```python
            container = FooContainer()

            foos = container.foos
            ```
        '''
    ```

Attribute documentation

  • Document attributes in class docstrings using Attributes:.

Example: Attribute Doc String:

    ```python
    '''
    Represents a processing stage.

    Attributes:
        id (str):
            Unique identifier.

        enabled (bool):
            Whether the stage is active.
    '''
    ```

Parsing guarantees

GSDFC ensures doc-forge can deterministically extract:

  • symbol kind (module, class, function, property, attribute)
  • symbol name
  • parameters
  • return values
  • attributes
  • examples
  • structured Notes subsections

This enables:

  • reliable MkDocs rendering
  • deterministic MCP export
  • accurate AI semantic interpretation

Notes: - doc-forge never executes analyzed modules. - Documentation is generated entirely through static analysis.