Create a Plugin
Plugins extend the agent’s capabilities by bundling one or more components — MCP servers, skills, agent definitions, lifecycle hooks, and slash commands — into a single installable package. This guide walks through creating a plugin, testing it locally, and publishing it so others can install it.
1. Understand the plugin structure
Section titled “1. Understand the plugin structure”A plugin is a directory containing a manifest.json and any number of component files. There is no build step required — Magia reads the files directly.
my-plugin/├── manifest.json├── servers/│ └── my-server.json├── skills/│ └── summarize.md├── agents/│ └── reviewer.json├── hooks/│ └── pre-bash.js└── commands/ └── deploy.mdOnly manifest.json is required. Every other file is optional.
2. Write the manifest
Section titled “2. Write the manifest”manifest.json declares the plugin’s identity and lists its component files:
{ "name": "my-plugin", "version": "1.0.0", "description": "A short description of what this plugin does.", "author": "your-name", "components": { "mcpServers": ["servers/my-server.json"], "skills": ["skills/summarize.md"], "agents": ["agents/reviewer.json"], "hooks": ["hooks/pre-bash.js"], "commands": ["commands/deploy.md"] }}All fields except name are optional. Omit any components key whose array would be empty. A minimal plugin that only ships one skill looks like this:
{ "name": "summarizer", "version": "1.0.0", "description": "Adds a /summarize skill for condensing long files.", "author": "your-name", "components": { "skills": ["skills/summarize.md"] }}3. Component types
Section titled “3. Component types”MCP servers
Section titled “MCP servers”An MCP server component is a JSON file that describes a Model Context Protocol server. The server exposes additional tools to the agent. When the plugin is enabled, Magia configures the agent to connect to this server automatically.
{ "name": "my-mcp-server", "command": "node", "args": ["./server.js"], "env": { "API_KEY": "${MY_API_KEY}" }}command and args are passed directly to the process spawner. env is merged into the process environment. Use ${VAR_NAME} syntax to reference environment variables from the host system.
Skills
Section titled “Skills”A skill is a Markdown file containing a reusable prompt template. Skills can be invoked with the /skillname slash command in the chat input.
---name: summarizedescription: Summarize the content of a file or selection.userInvocable: true---
Please summarize the following content concisely, highlighting the key points:
{{content}}The YAML frontmatter defines:
| Field | Required | Description |
|---|---|---|
name | yes | The slash command name (no / prefix) |
description | yes | Short description shown in the command menu |
userInvocable | no | If true, the skill appears in the / command menu. Defaults to false. |
The Markdown body is the prompt template. Use {{variable}} placeholders for dynamic values.
Agents
Section titled “Agents”An agent component defines a pre-configured agent persona with its own system prompt, tool restrictions, and model preferences. Agents appear in the session creation dialog as an alternative to the default agent configuration.
{ "name": "code-reviewer", "description": "Focused code review agent that checks for correctness, security, and style.", "systemPrompt": "You are an expert code reviewer. Focus on correctness, security vulnerabilities, and adherence to the project's style guide. Be concise and constructive.", "model": "claude-opus-4-5", "tools": ["read_file", "list_directory", "bash"]}A hook is a JavaScript file that runs before or after specific agent actions. Hooks give you a way to intercept and modify agent behavior.
// Runs before every bash command the agent executes.export default async function preBash({ command }) { if (command.includes("rm -rf")) { return { block: true, reason: "Destructive rm -rf commands are blocked by policy." }; } return { block: false };}The function receives an event payload specific to the hook type and returns an object. Returning { block: true } prevents the action. Returning { block: false } (or any falsy value) allows it to proceed.
Supported hook points: PreToolUse, PostToolUse, UserPromptSubmit.
Commands
Section titled “Commands”A command is a Markdown file that defines a slash command available in the chat input. Commands are similar to skills but are intended for single-action operations rather than reusable prompt templates.
---name: deploydescription: Trigger a deployment for this project.---
Run the deployment script and report the outcome:
```sh./scripts/deploy.shReport any errors clearly and suggest next steps if the deployment fails.
## 4. Develop locally
You do not need to publish anything to test your plugin. Use a **local marketplace source** that points to the directory containing your plugin folder.
1. Place your plugin directory somewhere on disk, for example:~/plugins/my-plugin/ ├── manifest.json └── skills/summarize.md
2. Open **Settings → Plugins → Marketplaces** and click **Add Marketplace**.
3. Set the **Source type** to `local` and the **Path** to the parent directory of your plugin folder — in this example, `~/plugins/`.
4. Save. Magia scans the directory and your plugin appears in the plugin browser under **Settings → Plugins**.
5. Click **Install** on your plugin to install it globally (or project-scoped).
### Reloading changes
Changes to your plugin files do not hot-reload automatically. To pick up edits:
1. Go to **Settings → Plugins → Installed**.2. Toggle your plugin off, then on again.
For faster iteration, keep the settings panel open and use the toggle as your reload mechanism.
## 5. Test your plugin
Once installed, verify each component type:
- **MCP servers** — open a session and use `/doctor` to check that the MCP server is registered and connected.- **Skills** — type `/` in the chat input and look for your skill name in the SKILLS section of the menu.- **Agents** — create a new session (`Cmd+N`) and check whether your agent persona appears in the agent selector.- **Hooks** — trigger the relevant action and verify in the tool output that the hook ran (or blocked the action as expected).- **Commands** — type `/` and confirm your command appears in the menu. Run it and verify the output.
## 6. Publish to GitHub
To make your plugin available to others through a GitHub marketplace source:
### Create the repository
1. Create a new public GitHub repository — for example, `your-username/magia-my-plugin`.
2. The repository root must contain a `marketplace.json` index file that lists available plugins. For a single-plugin repository, the index is minimal:
```json{"plugins": [ { "name": "my-plugin", "description": "A short description.", "author": "your-name", "path": "." }]}If the repository hosts multiple plugins, place each in its own subdirectory and list them:
{ "plugins": [ { "name": "plugin-a", "path": "plugin-a" }, { "name": "plugin-b", "path": "plugin-b" } ]}- Commit and push your plugin directory (with
manifest.jsonand all component files) and themarketplace.jsonto the repository.
Add the marketplace in Magia
Section titled “Add the marketplace in Magia”- Open Settings → Plugins → Marketplaces → Add Marketplace.
- Set the Source type to
github. - Set Repository to
your-username/magia-my-plugin(theowner/repoformat). - Optionally specify a Branch (defaults to
main). - Save.
Your plugin now appears in the plugin browser for anyone who adds your repository as a marketplace source.
Versioning
Section titled “Versioning”Bump the version field in manifest.json when you release an update. Magia compares the installed version with the marketplace version to determine when to show the update badge.
Use semantic versioning (MAJOR.MINOR.PATCH) and tag your releases in GitHub so users can pin to a specific version if they need to.