Commit 6c86bda
feat: add Mastra Code plugin system (#18658)
Adds the first Mastra Code plugin system so users can install trusted
local or GitHub plugins and expose their tools inside the TUI.
Plugins can be a local path, or installed via a github url. When
installing from github it will clone it to the installed scope (project
or global) and MC will then periodically check if it needs to pull new
commits down.
For local plugins, it hot reloads tool changes, allowing MC to work on
its own tools via a plugin. It can modify the tool, call it, modify, etc
in a loop until it works properly.
```ts
import { defineMastraCodePlugin, createTool, z } from 'mastracode/plugin';
export default defineMastraCodePlugin({
id: 'example.plugin',
name: 'Example Plugin',
tools: {
example_tool: {
tool: createTool({
id: 'example_tool',
description: 'Run an example plugin tool',
inputSchema: z.object({ message: z.string() }),
execute: async context => ({ message: context.message }),
}),
},
},
});
```
Plugins can define tools, optional config, render hints, bundled slash
commands and skills, and plugin instructions. The `/plugins` UI handles
install, scaffold, details, config, enable/disable, and local/GitHub
source management. Local plugin edits reload at execution time, and
GitHub checkouts poll for updates while preserving local changes on
backup branches before resetting.
This also adds project-level plugin blocking, progress streaming for
plugin tools, subagent-style rendering for plugin tools that ask for it,
and a README note that plugins should only be installed from trusted
sources.
Smoke tested with Alexandria: the expert tool executes, config persists,
and bundled command/skill loading was tested earlier. Focused unit
tests, typecheck, and `pnpm build:mastracode` pass.
example plugin:
https://github.com/mastra-ai/alexandria/blob/main/.mastracode/plugins/sources/local/alexandria/src/index.ts#L101
<img width="675" height="103" alt="Screenshot 2026-06-29 at 5 07 24 PM"
src="https://github.com/user-attachments/assets/74db5628-e546-421b-9916-f68a9eed281d"
/>
<img width="890" height="328" alt="Screenshot 2026-06-29 at 5 07 39 PM"
src="https://github.com/user-attachments/assets/9b3c6add-1d98-4583-8e74-0a0f9fdbe99d"
/>
<img width="721" height="336" alt="Screenshot 2026-06-29 at 5 07 34 PM"
src="https://github.com/user-attachments/assets/f2d3e0be-c9b8-41ed-9208-56ff82f380ed"
/>
<img width="564" height="506" alt="Screenshot 2026-06-29 at 5 07 44 PM"
src="https://github.com/user-attachments/assets/6f082267-52c5-43a0-98af-3b3e06d4f582"
/>
<img width="2530" height="1156" alt="image (34)"
src="https://github.com/user-attachments/assets/e964bf8c-dbd3-4ead-b25e-3ea848ac93bf"
/>
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## ELI5
This PR adds a way for Mastra Code to load “trusted plugin” code so it
can learn new tools and commands. You can install plugins from your
computer or GitHub, manage them in the terminal UI, and see their tool
progress update live—plus reload plugins automatically when local code
changes or GitHub has updates.
## Summary
- Introduces the first Mastra Code plugin system:
- Public plugin API/types (`defineMastraCodePlugin`) and
`writeToolProgress` support
- `.mastracode-plugin.json` manifest handling
- Local + GitHub install, local discovery, scoped plugin registries
(load/merge/save), and a full plugin loader pipeline
- A `PluginManager` that tracks active plugins, supports reloads, and
handles local hot-reload + GitHub polling/update with backup/dirtiness
safety
- Project-level plugin blocking via `disabledPlugins`
- Wires plugins into the app runtime so plugin contributions work
everywhere:
- Merges plugin tool names into mode allowlists and dynamically builds
toolsets from loaded plugin tools
- Appends plugin-provided instructions into generated agent prompts
- Exposes plugin-provided assets via TUI/session state
(skills/commands/instructions), and treats plugin command dirs as extra
high-priority slash-command sources
- Adds `/plugins` TUI management with end-to-end flows:
- Install new plugins, scaffold plugin projects, view details, configure
plugin config values (including model selection + API key prompting),
enable/disable, uninstall
- Install-source management (local path vs GitHub URL) with
trust-confirmation guidance
- Includes block/disabled handling in the UI and behavior
(hidden/conflicted/blocked states)
- Improves plugin tool UX in chat/TUI:
- Streams plugin tool progress from core → TUI using
`data-mastracode-tool-progress`, emitting tool updates and rendering
progress output
- Adds “subagent-style” rendering for tools that request it, including
static subagent component handling and replay for previously stored tool
calls
- Supports local hot reloading and GitHub polling/update scenarios
- Tests + release notes:
- Adds unit tests for plugin loader/manager/registry/scaffold, plugin
instruction generation, tool-progress streaming, and tool rendering
precedence
- Adds TUI unit tests for `/plugins`
- Adds E2E fixtures covering bundled commands/skills, tool streaming,
local hot reload, GitHub poll updates, blocking/config behavior, and
scaffold/install/execute flows
- Updates docs and adds a changeset publishing “Mastra Code” plugin
support.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Mastra Code (openai/gpt-5.5) <noreply@mastra.ai>1 parent 6f578ac commit 6c86bda
66 files changed
Lines changed: 5440 additions & 69 deletions
File tree
- .changeset
- mastracode
- e2e
- fixtures
- tui
- src
- __tests__
- agents
- __tests__
- plugins
- __tests__
- tui
- __tests__
- commands
- __tests__
- components
- __tests__
- handlers
- __tests__
- utils
- __tests__
- packages/core/src
- agent-controller
- agent
- tools/tool-builder
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
101 | 101 | | |
102 | 102 | | |
103 | 103 | | |
| 104 | + | |
104 | 105 | | |
105 | 106 | | |
106 | 107 | | |
| |||
111 | 112 | | |
112 | 113 | | |
113 | 114 | | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
114 | 119 | | |
115 | 120 | | |
116 | 121 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
Lines changed: 34 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
Lines changed: 34 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
371 | 371 | | |
372 | 372 | | |
373 | 373 | | |
| 374 | + | |
374 | 375 | | |
375 | 376 | | |
376 | 377 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
76 | 86 | | |
77 | 87 | | |
78 | 88 | | |
| |||
209 | 219 | | |
210 | 220 | | |
211 | 221 | | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
212 | 230 | | |
213 | 231 | | |
214 | 232 | | |
| |||
0 commit comments