A Discord bot that loads Python plugins from the plugins/ folder.
- Install deps
python -m pip install -r requirements.txt- Create
config.json
- Copy
sample_config.jsontoconfig.json - Put your Discord bot token in
BOT_TOKEN - Enable plugins via
ENABLED_PLUGINS
- Run
python main.pyBOT_TOKEN(required): Discord bot tokenENABLED_PLUGINS(recommended): list of plugin slugs to load (folder names). Use"*"to load all.DEV_GUILD_ID(optional): set to your test server ID to sync slash commands instantly to that guild. Use0or omit for global sync.BOT_OWNERS(optional): list of Discord user IDs allowed to manage plugins via/util ...(admins in a guild are also allowed).DISABLED_PLUGINS(optional): list of plugin slugs to force-disable. Useful whenENABLED_PLUGINSis"*".
Each plugin is a folder under plugins/<slug>/ containing:
plugin.json(manifest)plugin.py(entrypoint by default)
Minimal example:
{
"name": "My Plugin",
"version": "0.1.0",
"entrypoint": "plugin.py",
"description": "What it does",
"author": "You",
"api_version": 1
}Entrypoint must expose setup(ctx) where ctx is a PluginContext:
ctx.client: the running Discord clientctx.tree: the globalapp_commands.CommandTree(add slash commands here)ctx.config: loaded config dictctx.manifest: parsed plugin manifestctx.plugin_dir: plugin folder pathctx.data_dir: plugin data folder (plugin_data/<slug>/)ctx.logger: logger namespaced asplugin.<slug>
See plugins/ping/ for a working example.
These commands require either:
- the user is listed in
BOT_OWNERS, or - the user is a server administrator (when used in a guild)
Commands:
/util add local_plugin name:<plugin_name>: enables a plugin already present inplugins/<slug>//util add url_plugin url:<url>: downloads a manifest JSON from GitHub, installs it intoplugins/<slug>/, enables it, and attempts to hot-load it/util disable plugin:<plugin>: disables a plugin (updatesDISABLED_PLUGINSand attempts to remove its commands)/util delete plugin:<plugin>: disables + deletesplugins/<slug>/from disk and resyncs commands
See TRUSTED_PLUGINS.md for a curated list of trusted plugin manifest URLs you can install with /util add url_plugin.
Plugins are arbitrary Python code and run in-process with the bot.
That means there is no safe way to run untrusted third-party plugins without a sandbox (separate process/container/VM) and a permission model. For a public plugin ecosystem, only load plugins you trust, or move plugin execution out-of-process.