Auto-generated MDX command docs for discord.py bots — attach one line and your commands page writes itself on startup.
Project description
Auto-generated command docs for discord.py bots — attach one line and your commands page writes itself on startup.
Your bot already knows every command, parameter, type, description, permission, and cooldown. slashdocs turns that into three kinds of output, kept in sync every time the bot starts — no annotations required to get started:
- MDX pages for a docs site (Fumadocs, Nextra, Docusaurus, Starlight): one page per command, a category index, sidebar metadata.
- commands.json — a stable, documented JSON feed for building your own
interactive
/commandspage. - commands.html — a zero-dependency, self-contained searchable command browser (category sidebar with counts, live search, parameter chips, permission badges) for bots without a website.
Install
pip install slashdocs # or: uv add slashdocs
Quickstart
import slashdocs
from slashdocs import docs
@bot.tree.command(description="Bet money on a coin flip.")
@docs(category="Economy", example="/coinflip 500 heads")
async def coinflip(interaction: discord.Interaction, amount: int, side: str): ...
slashdocs.attach(bot, out="docs/commands")
bot.run(TOKEN)
Want the interactive command browser (and/or the JSON feed) too? Configure outputs explicitly — one walk feeds them all:
from slashdocs import attach, mdx, commands_json, commands_page
attach(bot, outputs=[
mdx("docs/content/commands"), # docs-site MDX (as above)
commands_json("site/public/commands.json"), # feed your own /commands UI
commands_page("site/public/commands.html", # instant searchable page
title="MyBot Commands", accent="#5865F2"),
])
On startup slashdocs walks the loaded command tree (slash, prefix, and hybrid commands, groups, cogs), diffs against the previous run, and writes only what changed:
INFO slashdocs: 12 added, 0 changed, 0 removed -> docs/commands
Second startup with nothing changed:
INFO slashdocs: docs up to date (12 commands)
The @docs decorator (optional)
Everything discord.py knows is picked up automatically. @docs adds what it
can't express:
@docs(
category="Economy", # docs-site grouping (default: cog name)
example="/coinflip 500 heads", # str or list[str]
hidden=True, # exclude from generated docs
notes="Requires the Economy module to be enabled.",
permissions="Booster Only", # custom permission badges (str or list[str])
tier="Premium", # renders a 👑 tier badge
)
Standard permissions and cooldowns are picked up without @docs:
@app_commands.default_permissions(...) on slash commands,
@commands.has_permissions(...) / has_guild_permissions(...) and
@commands.cooldown(...) on prefix and hybrid commands. The bot's real
command_prefix is rendered too (pass attach(..., prefix="?") to override —
needed when the prefix is a callable).
Works above or below the command decorator, on slash, prefix, and hybrid
commands and groups. Commands marked hidden=True in discord.py's own
@commands.command(hidden=True) are excluded too, as is discord.py's
auto-injected default help command.
Wiring the output into your docs site
slashdocs writes plain MDX with frontmatter plus meta.json. Point it at your
content directory:
- Fumadocs —
attach(bot, out="content/docs/commands").meta.jsonis picked up natively for sidebar order. - Nextra —
attach(bot, out="pages/commands")(orcontent/for Nextra 4). - Docusaurus —
attach(bot, out="docs/commands"); frontmattertitleanddescriptionare used as-is;meta.jsonis ignored (harmless). - Astro Starlight —
attach(bot, out="src/content/docs/commands").
Generated files carry generated_by: slashdocs in their frontmatter; slashdocs
only ever deletes files bearing that marker, so hand-written pages in the same
folder are safe.
The commands.json feed
commands_json(path) writes a deterministic, schema-versioned JSON document —
the same manifest slashdocs uses internally:
{
"schema_version": 2,
"prefix": "!",
"commands": [
{
"name": "ban", "slug": "ban", "kind": "slash", // "slash" | "prefix" | "hybrid"
"description": "...", "category": "Moderation",
"params": [{ "name": "user", "type": "user", "required": true,
"description": "...", "choices": [], "default": null }],
"permissions": ["Ban Members"], "tier": "",
"cooldown_rate": 0, "cooldown_per": 0.0,
"aliases": [], "examples": [], "notes": "",
"subcommands": [] // same shape, nested
}
]
}
Fetch it from any frontend and render search/filter UI however you like. The file is only rewritten when its content changes, so it's safe to serve statically and cache.
The static commands page
commands_page(path, title=..., accent=...) emits a single HTML file with the
data embedded and zero external requests — drop it on any static host. It
renders a category sidebar with counts, live search over names/aliases/
descriptions, and cards with parameter chips, permission and tier badges,
cooldowns, and slash/prefix indicators — hybrid commands show both invocation
forms. Light and dark themes follow the visitor's system preference.
API
slashdocs.attach(bot, out=None, *, outputs=None, prefix=None, base_slug="/commands", clean=True)
slashdocs.mdx(path, *, base_slug="/commands", clean=True)
slashdocs.commands_json(path)
slashdocs.commands_page(path, *, title="Commands", accent="#5865F2")
slashdocs.docs(*, category=None, example=None, hidden=False, notes="", permissions=None, tier="")
slashdocs.__version__
attach(bot, out="docs/commands") is shorthand for a single mdx() output.
attach()'s on_ready hook can never crash your bot: every output is attempted
even if another fails, and any failure is caught, logged to the slashdocs
logger, and never re-raised into the bot. Calling generate() directly (e.g.
from a script) instead raises OutputGenerationError if any output failed,
after every output has been attempted — so a CI job or build script can tell
generation actually failed rather than reading a false "up to date".
Requirements
- Python ≥ 3.10
- discord.py ≥ 2.4
License
MIT
Project details
Release history Release notifications | RSS feed
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 slashdocs-0.2.0.tar.gz.
File metadata
- Download URL: slashdocs-0.2.0.tar.gz
- Upload date:
- Size: 162.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 |
355877808f3529896f93b188d0d3a297486ead927b83541b8a0954ba0ec5515b
|
|
| MD5 |
03ff00428a2b4a13b8f3a42d3e13ea08
|
|
| BLAKE2b-256 |
ff240d023b04251b92d252dd48d68e2486758240178510021d4b1e31d9f2c280
|
Provenance
The following attestation bundles were made for slashdocs-0.2.0.tar.gz:
Publisher:
publish.yml on dorochadev/slashdocs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slashdocs-0.2.0.tar.gz -
Subject digest:
355877808f3529896f93b188d0d3a297486ead927b83541b8a0954ba0ec5515b - Sigstore transparency entry: 2194675340
- Sigstore integration time:
-
Permalink:
dorochadev/slashdocs@0d6cd63843ea33de88086c1627200aeec14a3537 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/dorochadev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0d6cd63843ea33de88086c1627200aeec14a3537 -
Trigger Event:
release
-
Statement type:
File details
Details for the file slashdocs-0.2.0-py3-none-any.whl.
File metadata
- Download URL: slashdocs-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.5 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 |
40f1d281df7c5f7c3df0e06c20e80d377a24f44ae21665ecdf0a8b15c0aa264d
|
|
| MD5 |
f46def32d8157d41282f6958b7d2521c
|
|
| BLAKE2b-256 |
60553068e9f0c69d8b2a43aeea7f5f6e1bb87be26d912cdd802320b2fff63965
|
Provenance
The following attestation bundles were made for slashdocs-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on dorochadev/slashdocs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
slashdocs-0.2.0-py3-none-any.whl -
Subject digest:
40f1d281df7c5f7c3df0e06c20e80d377a24f44ae21665ecdf0a8b15c0aa264d - Sigstore transparency entry: 2194675347
- Sigstore integration time:
-
Permalink:
dorochadev/slashdocs@0d6cd63843ea33de88086c1627200aeec14a3537 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/dorochadev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0d6cd63843ea33de88086c1627200aeec14a3537 -
Trigger Event:
release
-
Statement type: