Skip to main content

Generate and maintain a complete documentation context layer for any repo — using the LLM already in your IDE.

Project description

Doctyze

Turn any repo into living documentation — for humans and AI agents — using the LLM already in your IDE.

PyPI License: Apache 2.0 AGENTS.md


What it does

Point Doctyze at any repository, any stack. Your IDE's AI assistant then:

  1. Consolidates scattered docs (loose READMEs, wiki notes, design files) into one canonical docs/ tree — non-destructively.
  2. Generates the missing docs from the actual code: feature specs, architecture + Mermaid diagrams, decisions (ADRs), runbooks, observability, dev/testing skills.
  3. Keeps them fresh — when code changes, it flags exactly which docs are now stale.

No API key. Doctyze uses the AI you already have in your IDE (Cursor / Claude Code / Copilot) — it never calls an LLM itself or asks for a key.

The flow at a glance

$ uvx doctyze init                 # install skills + scaffold docs/  (one time)
  ↳ reload your IDE

  in your assistant:  /doctyze      # the agent consolidates existing docs,
  ↳ reads your code and writes:       specs · architecture + Mermaid · ADRs ·
                                      runbooks · observability · dev/testing skills
  ↳ runs the deterministic steps via the `doctyze` CLI — nothing to approve

$ git commit                       # the warn-first hook flags exactly which docs
  ↳ a code change made stale, so you regenerate only those

Get started — one command

In your repo (nothing to install — uvx fetches it on demand):

uvx doctyze init

That one command sets Doctyze up in your repo — it:

  • installs the skills / playbook your assistant runs (.claude/skills, .cursor/rules, AGENTS.md) — this is what powers the doctyze prompt,
  • scaffolds the canonical docs/ structure,
  • registers the Doctyze MCP server in project configs (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, and — if detected — .codex/config.toml, .gemini/settings.json) as an optional, faster transport for the deterministic steps. All repo-scoped and merge-safe (won't touch your other servers).

(Windsurf and Cline only support a global MCP config, so init detects them and prints how to add the server there; both read AGENTS.md, so their playbook is already covered.)

Then reload your IDE and invoke the doctyze prompt (Claude Code: /doctyze — or just say "set up the documentation for this repo with Doctyze"). Your assistant organizes existing docs, reads the code, and writes the new docs — using its own model, no API key. The deterministic steps run via the doctyze CLI (over uvx), so there's nothing to approve — it works right after reload.

Optional — faster MCP tools instead of the CLI. init also registers Doctyze as an MCP server. To use it, approve the server once: project-scoped MCP servers need a one-time OK before their tools load, so reloading alone isn't enough (Claude Code: run /mcp → select doctyzeEnable; Cursor: Settings → MCP; VS Code: Start the server when prompted). The doctyze prompt works either way.

Commit the result and your teammates inherit Doctyze (MCP config + skills) on git clonezero setup for them.

Works with any AI assistant — Claude Code, Cursor, VS Code/Copilot, Codex, Gemini, Windsurf, Cline, and more. The playbook reaches every IDE through the installed skills / rules / AGENTS.md (no setup, no approval); the MCP server additionally serves it as a prompt and exposes the deterministic tools for MCP-native clients that prefer them.

Prefer to add the MCP server manually, or on another IDE?

The server is identical everywhere:

{ "mcpServers": { "doctyze": { "command": "uvx", "args": ["--from", "doctyze[mcp]", "doctyze-mcp"] } } }
Assistant How
Claude Code claude mcp add doctyze -- uvx --from 'doctyze[mcp]' doctyze-mcp
Cursor add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)
VS Code / Copilot run “MCP: Add Server”, or add to .vscode/mcp.json (a servers map with "type": "stdio")
Codex CLI codex mcp add doctyze -- uvx --from doctyze[mcp] doctyze-mcp, or [mcp_servers.doctyze] in .codex/config.toml
Gemini CLI add to .gemini/settings.json (mcpServers)
Windsurf ~/.codeium/windsurf/mcp_config.json (mcpServers) — global only
Cline its “Configure MCP Servers” UI (global)

Every entry runs the same server: uvx --from "doctyze[mcp]" doctyze-mcp.

What you get: a docs/ tree — specs/, architecture/{diagrams,decisions}/, runbooks/, observability/, guides/, skills/ — with a docs/index.md table of contents, fanned out to AGENTS.md / .cursor/rules / Claude Code skills so every assistant on the repo inherits the context.

Each generated doc carries a freshness anchor so a code change flags the specific docs it makes stale:

---
doctyze:
  artifact: spec
  generated_by: write-spec
  affects: [src/payments/**]
  last_verified: 2026-06-28
---

For CI & automation (optional)

The same operations are a small CLI, for pipelines and scripting (this is what the assistant calls under the hood — you don't need it for normal use):

pip install doctyze
doctyze --help     # init · consolidate · bootstrap · index · distribute · watch

Wire doctyze watch into a pre-commit hook or PR check to keep docs from drifting. These commands are deterministic (file moves, drift detection) and never call an LLM — generation stays with your IDE/CI agent.

Freshness in CI — warn or block? (you choose)

The check is just a CLI command, so it runs in any CI (GitHub, GitLab, Jenkins, CircleCI, Azure…). The GitHub Action below is only a convenience wrapper around it.

# Any CI: report only (warn-first) — the raw primitive
doctyze watch --base "origin/$BASE_BRANCH"

# Any CI: gate the merge (fail the job when a doc is stale)
doctyze watch --base "origin/$BASE_BRANCH" --exit-code

⚠️ In CI you must pass --base and fetch full history. A CI checkout is clean — the change is already committed — so the default working-tree diff sees nothing and the check silently passes. --base origin/<target-branch> diffs the PR against its base so committed changes are detected. Make sure the base ref is fetched (e.g. fetch-depth: 0, or git fetch origin <target-branch>).

GitHub Action (wraps the above):

# .github/workflows/docs-freshness.yml
- uses: actions/checkout@v4
  with: { fetch-depth: 0 }                 # REQUIRED so the base ref exists
- uses: actyze/doctyze@v0.3.4              # pin to a released tag
  with:
    base: origin/${{ github.base_ref }}    # the PR's target branch
    fail-on-stale: false                   # default: warn-only (report, don't block)
    # fail-on-stale: true                  # opt-in: fail the check to gate a merge

GitLab CI (no Action — just the CLI):

docs-freshness:
  image: python:3.12
  variables: { GIT_DEPTH: 0 }              # full history
  script:
    - pip install doctyze
    - doctyze watch --base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME" --exit-code

Recommendation (best practice):

  • Local pre-commit stays warn-only — always. A hook can't regenerate a doc (that needs your agent's model), so blocking the commit just trains git commit --no-verify. Doctyze will not make the local hook blocking.
  • Enforce at the merge, not the commit — only if you want to. Set fail-on-stale: true and mark the check required in branch protection. It gates the shared branch without interrupting anyone's local flow.
  • Only turn the gate on if your affects: anchors are narrow. Broad anchors flag every PR as "stale" and the check becomes noise people disable. Warn-first is the safe default.

The full rationale is in ADR-0006 (amending ADR-0004).

Doing AI-assisted code review? The deterministic check flags which docs to revisit; when you already have a model in the loop (an IDE agent or a CI agent), you can also check semantic drift — does the changed functionality exist in the docs, is it net-new, has an existing doc drifted. See Checking Documentation Drift for exactly what to invoke and how (interactive /doctyze, headless claude -p, or a local model), plus a copy-paste reference prompt.


Works alongside your other tools — Graphify

Doctyze and Graphify solve adjacent halves of the same problem, and they compose cleanly because the seam between them is a directory of files, not an API.

  • Doctyze authors the prose. It writes the grounded artifacts — feature specs, architecture + Mermaid, ADRs, runbooks, AGENTS.md — by having your IDE's agent read the actual code, then keeps them consolidated and fresh. What lands on disk is a docs/ tree of Markdown.
  • Graphify indexes it. It turns your code plus those artifacts into one queryable knowledge graph (graph.json) — code structure via tree-sitter AST, docs turned into concept nodes — reachable over a CLI and an MCP server.

Neither reimplements the other: Doctyze has no graph or query layer, and Graphify authors no documentation. The output of one is the input of the other.

Doctyze Graphify (graphifyy)
Job Generate & maintain grounded docs Index code + docs into a queryable graph
Produces docs/ Markdown (specs, ADRs, arch+Mermaid, runbooks), AGENTS.md graphify-out/graph.json + MCP retrieval
Retrieval surface affects: anchors + git diff (freshness), not search query / path / explain / affected + MCP tools
LLM usage BYO-agent; never calls an LLM itself BYO-agent for docs/images; code AST is free/local

Both are BYO-agent — they borrow the model already in your IDE rather than shipping a key — so the pairing adds no new credentials.

# 1. Doctyze authors the docs/ tree from your code (agent-written prose)
uvx doctyze init            # scaffold docs/, install skills, register optional MCP
#   …then invoke /doctyze in your IDE to generate the specs/ADRs/architecture/runbooks

# 2. Graphify indexes code + those docs into one graph
uv tool install graphifyy   # note the double-y PyPI name
graphify install            # register the skill in your assistant
/graphify .                 # run the pipeline over the repo (code AST + docs/ extraction)

# 3. Query the merged graph
graphify query "how does auth token refresh work?"
python -m graphify.serve graphify-out/graph.json   # or expose it to an agent over MCP

Affected-docs across both (proposed, not yet built). Doctyze already answers "which docs did this change make stale?" deterministically via affects: anchors + git diff; Graphify ships its own graphify affected (reverse-BFS impact over the code graph). They're separate today. Using Graphify's deterministic code-dependency graph to give Doctyze transitive reachability — the one thing hand-written globs can't do — is a promising integration, evaluated in ADR-0007. Its doc↔code cross-links are LLM-inferred, so that layer stays advisory; the deterministic anchor+diff remains the gate.


How it's built

A deterministic Python engine (no LLM, no key) exposed as both an MCP server and a CLI, plus agent-run generation skills. See CONTRIBUTING.md and docs/architecture/decisions/0003-pivot-to-context-layer-generator.md.

License

Apache 2.0. Free and open source for everyone.

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

doctyze-0.3.4.tar.gz (53.1 kB view details)

Uploaded Source

Built Distribution

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

doctyze-0.3.4-py3-none-any.whl (50.3 kB view details)

Uploaded Python 3

File details

Details for the file doctyze-0.3.4.tar.gz.

File metadata

  • Download URL: doctyze-0.3.4.tar.gz
  • Upload date:
  • Size: 53.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for doctyze-0.3.4.tar.gz
Algorithm Hash digest
SHA256 8ee755caa1e9b7d8ae6e16b94c5ae9e22eb779016184df1f9246253ef4224907
MD5 5432669287573e4ffd5fb0f2ded2ffd9
BLAKE2b-256 bfac403642efba7e846c6c42a337a23a5bd38875b89b47ac31dd01449686775c

See more details on using hashes here.

Provenance

The following attestation bundles were made for doctyze-0.3.4.tar.gz:

Publisher: release.yml on actyze/doctyze

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file doctyze-0.3.4-py3-none-any.whl.

File metadata

  • Download URL: doctyze-0.3.4-py3-none-any.whl
  • Upload date:
  • Size: 50.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for doctyze-0.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 7622f924249709593d49b702b84a7dccaf4049fd7974568a4bc573932723f0dd
MD5 4c862f272ffa12b3b86526ff5af19d05
BLAKE2b-256 41a4e0ba2fb78157c7f4972873eabcf0070e2f70cf7394c2d464b3b82c91cfa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for doctyze-0.3.4-py3-none-any.whl:

Publisher: release.yml on actyze/doctyze

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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