Plugins and marketplaces
A plugin packages what extends the agent: skills, slash commands, agent types, MCP servers and hooks. A marketplace is a catalog of plugins and where to fetch each one. malac installs plugins written for Claude Code and plugins that follow the open Agent Plugins specification, from folders, GitHub, GitLab or any git host, private repositories included.
malac plugin marketplace add lobirus/agent-pluginsmalac plugin install server-setup@lobirus # install and enablemalac plugin listStart with lobirus/agent-plugins, the official marketplace. It is provider-agnostic: every plugin in it is both an Agent Plugins package and a Claude Code plugin, so the same marketplace works in malac, Claude Code, Codex, Copilot, VS Code and Cursor. Its marketplace name is lobirus, so its plugins install as <plugin>@lobirus.
In a session, /context lists the plugins in use with their skills and commands. The agent can manage plugins too; see Asking the agent.
What a plugin brings
Section titled “What a plugin brings”| Component | Becomes |
|---|---|
| Skills | <plugin>:<skill> in the skill list and the skill tool, and a slash command of that name |
| Commands | /<plugin>:<command>; /<command> alone works when no other command has that name |
| Agent types | <plugin>:<agent> for agent_spawn. Claude Code’s tool names (Read, Grep, Bash, …) map to malac’s, and a model that is not provider/model is ignored. |
| MCP servers | A server named <plugin> or <plugin>-<server>, with its tools prefixed the same way. One you configure under the same name wins. |
| Hooks | Commands that run on session start, on each prompt and around tool calls |
Changes apply to new sessions. The web UI’s Apply reloads idle tabs right away.
Hooks use Claude Code’s format: a shell command that gets the event as JSON on stdin, runs in the session’s directory with CLAUDE_PLUGIN_ROOT, CLAUDE_PLUGIN_DATA and CLAUDE_PROJECT_DIR set, for at most timeout seconds (60 by default).
| Event | When | What its output can do |
|---|---|---|
SessionStart, SubagentStart |
Before the first request of a session or subagent | Add text to the system prompt |
UserPromptSubmit |
Each prompt | Add text to the prompt, or refuse it |
PreToolUse |
Before a tool call | Deny it with a reason, force a question, skip the question, or change the input |
PostToolUse |
After a tool call | Send feedback to the agent |
matcher is a regular expression for the tool name; Claude Code’s names (Bash, Write|Edit) and malac’s (bash, web_fetch) both match. Deny rules in [permissions] still win over a hook that allows. Stop, SubagentStop, PreCompact, Notification and SessionEnd hooks are not run.
Formats
Section titled “Formats”malac reads every layout a plugin uses and combines what it finds, so one package can serve several agents.
| Format | Manifest | Components |
|---|---|---|
| Claude Code | .claude-plugin/plugin.json, optional |
skills/, commands/*.md (and Gemini CLI’s commands/*.toml), agents/*.md, hooks/hooks.json, .mcp.json, or paths in the manifest |
| Agent Plugins | plugin.json with the Agent Plugins $schema |
skills/<name>/SKILL.md, mcp.json; malac-only parts under extensions["io.malac"] and io.malac/ |
| Plain folder | none | Any of skills/, commands/, agents/, hooks/hooks.json, .mcp.json, mcp.json, or a SKILL.md; named after the folder |
Agent Plugins manifests are checked as the specification says: unknown fields are reported and ignored, an invalid name rejects the plugin, paths must stay inside it, and an invalid server entry skips only that server. ${PLUGIN_ROOT} and ${PLUGIN_DATA} (a folder per plugin that survives updates) are expanded in a server’s args, env and cwd. In Claude Code plugins, ${CLAUDE_PLUGIN_ROOT} and ${CLAUDE_PLUGIN_DATA} are filled in wherever they appear in skills, commands, agents, hook commands and server settings.
malac plugin show reports what malac does not run: output styles, LSP servers, userConfig options, MCP bundles, hook types other than command, and the hook events above.
Marketplaces
Section titled “Marketplaces”malac plugin marketplace add <source> takes:
| Source | Example |
|---|---|
| A folder, read in place, so edits show up in the next session | ./tools/marketplace, ~/plugins |
| GitHub, optionally with a branch or tag | owner/repo, owner/repo#v2 |
| Any git URL | https://gitlab.com/group/plugins.git, git@gitlab.example.com:team/plugins.git |
The URL of a marketplace.json |
https://example.com/plugins/marketplace.json |
Repositories are cloned with your own git, so SSH keys, credential helpers (gh auth, the macOS keychain) and private repositories work as they do in a terminal. GitHub shorthand is cloned over HTTPS and retried over SSH. git never prompts: without credentials, adding fails with git’s message.
The catalog is read from .claude-plugin/marketplace.json, marketplace.json, .agents/plugins/marketplace.json (Codex), .github/plugin/marketplace.json or .cursor-plugin/marketplace.json, whichever comes first. Entries may point inside the marketplace or at other repositories. A repository without a catalog is a marketplace too: one plugin if it is a plugin itself, otherwise the plugins in its plugins/ folder. So malac plugin install owner/repo installs a repository that is a plugin in one step.
Scopes
Section titled “Scopes”| Scope | File | For |
|---|---|---|
| user | ~/.malac/plugins/plugins.toml |
You, everywhere |
| project | <project>/.malac/plugins.toml |
The team: commit it |
| built-in | none | Ships with malac; on while [plugins] defaults = true |
[marketplaces]lobirus = "lobirus/agent-plugins"
[plugins]"server-setup@lobirus" = true"ponytail@malac" = false--project on marketplace add, install, enable and disable writes the project’s file, and enabling a plugin there also records its marketplace. A teammate who pulls runs malac plugin install without a name, which installs everything the project enables. The project’s file wins over yours for the plugins it names. Installed files are per machine, in ~/.malac/plugins/cache/.
Approval before code runs
Section titled “Approval before code runs”- Installing runs nothing. It copies the files and shows what the plugin contains.
- Hooks, MCP servers and scripts need your approval.
malac plugin installandenablelist what the plugin runs and ask;--yesapproves. Approvals are recorded per plugin in~/.malac/plugins/installed.json, never in a project file. - A repository cannot turn code on. A cloned repository’s
.malac/plugins.tomlcan enable a plugin, but its hooks and MCP servers stay off until you approve them on your machine. Its skills and commands load, as itsAGENTS.mddoes. - Updates do not widen access. Hooks or servers an update adds stay off until
malac plugin enableapproves them. - Scripts run through
bash, under the usual permission mode and rules. - The agent asks you. Enabling a plugin that runs code through
malac_configureasks you, even in autopilot.
Plugins are code from someone else. Read what malac plugin show lists before you approve, as you would before running a script from the internet.
ponytail, built in
Section titled “ponytail, built in”malac ships ponytail by Dietrich Gebert (MIT) as its default best-practices plugin, ponytail@malac: the smallest change that fully solves the task, reviews and audits for bugs, risk and bloat, and a ledger of deliberate shortcuts. It brings six skills (ponytail, ponytail-review, ponytail-audit, ponytail-debt, ponytail-gain, ponytail-help), each also a slash command:
/ponytail-reviewThe skills are copied unchanged and compiled into the binary, so a default that is part of every prompt never depends on the network or changes without review. ponytail’s hooks, status line and task board are written for other agents and are left out.
Turn it off with malac plugin disable ponytail@malac (--project for one repository), or all built-in plugins with [plugins] defaults = false. To follow upstream instead, malac plugin marketplace add DietrichGebert/ponytail and malac plugin install ponytail@ponytail; an installed ponytail replaces the built-in copy.
Commands
Section titled “Commands”| Command | What it does |
|---|---|
malac plugin marketplace add <source> |
Fetch a marketplace and record it |
malac plugin marketplace list |
Marketplaces and their plugins |
malac plugin marketplace update [name] |
Fetch the latest catalogs |
malac plugin marketplace remove <name> |
Forget one; its plugins stay installed |
malac plugin install [plugin] |
Install and enable a plugin (name, name@marketplace, or a folder or repository holding one); without a name, what the project enables |
malac plugin enable <plugin> |
Turn on, approving what runs code |
malac plugin disable <plugin> |
Turn off, built-in plugins included |
malac plugin uninstall <plugin> |
Remove the files and your entry; its data folder stays |
malac plugin update [plugin] |
Fetch and reinstall |
malac plugin list |
Installed, built-in and project plugins |
malac plugin show <plugin> |
Its contents, path, approvals and warnings |
--project (on marketplace add and remove, install, enable and disable) writes the project’s file instead of yours. --yes approves hooks, MCP servers and scripts without asking, --no-enable installs without enabling, and --json on the list commands prints JSON. The CLI reference has the synopsis.
Asking the agent
Section titled “Asking the agent”“Add the lobirus marketplace and install release-tools” works too. malac_configure has the same operations (marketplace_add, plugin_install, plugin_enable, …, with file set to user or project), and malac_settings lists plugins and marketplaces with show: "plugins". See Configure malac by asking.
Publish a marketplace
Section titled “Publish a marketplace”A marketplace that every agent can read is a git repository:
- Put each plugin in
plugins/<name>/with an Agent Pluginsplugin.json($schema,name,version,description,license) and a.claude-plugin/plugin.jsonwith the same metadata. - Put portable parts in the standard places:
skills/<name>/SKILL.mdwithscripts/andreferences/, and MCP servers inmcp.jsonwith./commands and${PLUGIN_ROOT}. Claude Code reads servers from.mcp.json, so ship both when you have servers. - Put client-specific parts where each client looks:
commands/,agents/andhooks/hooks.jsonfor Claude Code (malac reads them too), and anything only malac should load underio.malac/. - List the plugins in
.claude-plugin/marketplace.jsonwith./plugins/<name>sources, which Claude Code, Copilot and VS Code read. Add the same list to.cursor-plugin/marketplace.jsonfor Cursor and to.agents/plugins/marketplace.jsonfor Codex. The Agent Plugins specification defines no catalog, so each client keeps its own; malac reads any of them. - Push it to GitHub or GitLab, public or private.
Check it locally first with malac plugin marketplace add ./my-marketplace and malac plugin show <plugin>, which prints what each part became and warns about anything malac skipped. lobirus/agent-plugins is a complete example, with catalogs for Claude Code, Codex and Cursor and a script that validates every manifest.
~/.malac/plugins/├── plugins.toml your marketplaces and enabled plugins├── installed.json installed plugins, their source and commit, approvals├── marketplaces/<name>/ git clones, or a downloaded marketplace.json├── cache/<marketplace>/<plugin>/ installed copies├── data/<plugin>@<marketplace>/ PLUGIN_DATA, kept across updates and uninstalls└── builtin/<plugin>/ built-in plugins, written on first usemalac is created by lobirus and released under the MIT license. About malac