Agent Plugins
An Agent Plugin is one package that carries skills and MCP servers together, behind
one activation. The format is
Agent Plugins v1.0.0: a directory holding plugin.json,
and optionally skills/<name>/SKILL.md and mcp.json.
It is the only artifact that bundles both. A skill on its own is instructions. An MCP server on its own is tools. A plugin is a skill that knows how to drive the tools it ships with, reviewed and enabled as one thing.
Inspecting what is installed
nanoinfra agent-plugins list
nanoinfra agent-plugins show <name>
list names every installed package and whether it is active. show gives one
package's components and why it is or is not active. That is the question that
matters when a plugin is present and its tools are not.
Activation is config, not a directory
tools.agentPlugins lists the plugin identities the operator has activated:
{
"tools": {
"agentPlugins": ["acme.deploy-runbook"]
}
}
That list is the authority. The executor reconciles activation markers against it.
The marker is not in the config directory, and that placement is the point. The agent
account owns the data directory, so a marker there would let the agent write its own
activation. And enabling a package that ships an mcp.json grants a new stdio process.
The marker lives under the executor-owned gate tree instead, at exec_user:ipc_group
mode 2750: the executor writes it, the shared group reads it. Skill loading runs in the
agent process and only ever reads.
So the decision to trust a package is a change to a git-reviewed file, not something the process the model steers can make for itself.
Activation is bound to content, not to a path
Any change to an enabled package invalidates its marker on the next read. A package that mutates after you reviewed it stops being active until it is reviewed again.
This is the property that makes a directory safe to enable. A path-bound activation would keep trusting whatever later occupies the path.
What a plugin may carry
| File | Holds |
|---|---|
plugin.json | identity, description, repository — the portable core |
skills/<name>/SKILL.md | one or more skills, loaded the same way a workspace skill is |
mcp.json | MCP servers, which is the half that grants a new process |
nanoinfra's own extension fields use the dev.nanoinfra reverse-domain namespace. The
spec has namespaces exactly so a client can add fields without touching the portable
core. So the identity, description, repository, skills and MCP parts of a package stay
readable by any other client.
PLUGIN_DATA is the plugin's own scratch directory. It carries no authority.
Related
- Skills — how an agent narrows which skills it loads
- Configure MCP tools — an MCP server on its own, without a plugin
- Capability Gates — what an MCP tool's calls meet once the server is running
- Deployment — the accounts and modes the activation boundary is built from