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.
What it does
Point Doctyze at any repository, any stack. Your IDE's AI assistant then:
- Consolidates scattered docs (loose READMEs, wiki notes, design files) into one canonical
docs/tree — non-destructively. - Generates the missing docs from the actual code: feature specs, architecture + Mermaid diagrams, decisions (ADRs), runbooks, observability, dev/testing skills.
- 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 thedoctyzeprompt, - 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.
initalso 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→ selectdoctyze→ Enable; Cursor: Settings → MCP; VS Code: Start the server when prompted). Thedoctyzeprompt works either way.
Commit the result and your teammates inherit Doctyze (MCP config + skills) on git clone — zero 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
--baseand 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, orgit 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: trueand 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 adocs/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 owngraphify 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8ee755caa1e9b7d8ae6e16b94c5ae9e22eb779016184df1f9246253ef4224907
|
|
| MD5 |
5432669287573e4ffd5fb0f2ded2ffd9
|
|
| BLAKE2b-256 |
bfac403642efba7e846c6c42a337a23a5bd38875b89b47ac31dd01449686775c
|
Provenance
The following attestation bundles were made for doctyze-0.3.4.tar.gz:
Publisher:
release.yml on actyze/doctyze
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
doctyze-0.3.4.tar.gz -
Subject digest:
8ee755caa1e9b7d8ae6e16b94c5ae9e22eb779016184df1f9246253ef4224907 - Sigstore transparency entry: 2082753203
- Sigstore integration time:
-
Permalink:
actyze/doctyze@269ba39e70dc50d2af32d775fa94d06d27338e40 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/actyze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@269ba39e70dc50d2af32d775fa94d06d27338e40 -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7622f924249709593d49b702b84a7dccaf4049fd7974568a4bc573932723f0dd
|
|
| MD5 |
4c862f272ffa12b3b86526ff5af19d05
|
|
| BLAKE2b-256 |
41a4e0ba2fb78157c7f4972873eabcf0070e2f70cf7394c2d464b3b82c91cfa8
|
Provenance
The following attestation bundles were made for doctyze-0.3.4-py3-none-any.whl:
Publisher:
release.yml on actyze/doctyze
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
doctyze-0.3.4-py3-none-any.whl -
Subject digest:
7622f924249709593d49b702b84a7dccaf4049fd7974568a4bc573932723f0dd - Sigstore transparency entry: 2082753205
- Sigstore integration time:
-
Permalink:
actyze/doctyze@269ba39e70dc50d2af32d775fa94d06d27338e40 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/actyze
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@269ba39e70dc50d2af32d775fa94d06d27338e40 -
Trigger Event:
push
-
Statement type: