For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Plugins
Understand what a plugin contains, and what kagent does with one when an agent starts.
A pluginPluginA bundle that an AgentTemplate attaches with spec.plugins. A plugin carries skills and can also declare Model Context Protocol servers. Plugins follow the Agent Plugins specification.Learn more is a bundle that an AgentTemplateAgentTemplateA Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once an Agent pairs it with a Harness.Learn more attaches with spec.plugins. A plugin contains skillsSkillA packaged piece of know-how that an agent can pick up: a directory holding a SKILL.md file of instructions, plus any scripts, command-line tools, or reference files those instructions use. You attach a skill to an AgentTemplate by specifying where it comes from.Learn more and can also declare Model Context ProtocolModel Context ProtocolAn open protocol for exposing tools and resources to a model. kagent reaches an MCP server through a RemoteMCPServer resource, and an AgentTemplate binds individual tools from it.Learn more (MCP) servers. Plugins follow the Agent Plugins 1.0.0 specification. To attach a skill that is published on its own, see Skills.
Plugin contents
A plugin root contains a manifest, and optionally the skills and the MCP servers that the plugin contributes.
plugin.json(required): The manifest that gives the plugin its name.skills/: One subdirectory per skill, each with aSKILL.mdfile at its root.mcp.json: Declares MCP servers that kagent adds to the agent’s tools.
kagent reads name from the manifest and ignores the rest. A manifest that sets version, description, author, homepage, repository, license, keywords, or extensions is accepted, but none of those fields change what the agent gets.
The name must be at most 64 characters. It must start and end with a lowercase letter or a digit, and the characters between can be lowercase letters, digits, dots, and hyphens. A name that contains -- or .. is rejected.
The manifest’s $schema must be exactly https://agent-plugins.org/schemas/1.0.0/plugin.schema.json. kagent compares that value literally. kagent does not fetch the schema, and it does not check the manifest against the schema.
Attach a plugin to an AgentTemplate
Use spec.plugins to attach a plugin and list the skills that the agent needs from it.
apiVersion: api.kagent.dev/v1alpha3
kind: AgentTemplate
metadata:
name: incident-responder
namespace: kagent
spec:
modelConfig:
name: default-model-config
systemPrompt: You help engineers work through production incidents.
plugins:
- source:
git:
url: https://github.com/example/agent-plugins
commit: <full-commit-id>
path: bundles/observability
skills:
- log-search
- runbook-lookup| Field | Description |
|---|---|
plugins[].source | The location to fetch the plugin from. The source root must contain a plugin.json manifest. |
plugins[].skills | The names of the skills inside that plugin to enable, up to 50. Omit the list, or leave it empty, to enable none of them. |
source.path | The directory to select inside the artifact, when the content is not at its root. The path must be relative, and it cannot climb out of the artifact with .. segments. |
One AgentTemplate accepts up to 20 plugins.
Skill allowlist
List the name of each skill that you want in plugins[].skills. A skill’s name is the name of its subdirectory under skills/ in the plugin.
Attaching a plugin does not enable the skills that it contains, and an empty list does not enable any of them. kagent accepts an empty list rather than reporting an error, and the agent starts with no skills from that plugin. An explicit list also means that a later version of the plugin cannot add skills to your agent. To enable a new skill, add its name.
Plugin names must be unique. If two entries in plugins declare the same name in their manifests, the agent fails to start. Skill names come from your AgentTemplate, so kagent checks them before it fetches anything. A plugin name comes from the plugin’s own manifest, and kagent can only check that name as each plugin is fetched.
Claude-format plugins
kagent reads plugin.json at the plugin root. A plugin that instead keeps its manifest at .claude-plugin/plugin.json is a Claude-format plugin. kagent handles a Claude-format plugin differently on each HarnessHarnessA Kubernetes custom resource defining how an agent is allowed to run: which harness executes the agent, its workload image, and its WorkerPool and snapshot storage. An Agent pairs it with the AgentTemplate that it runs.Learn more.
- On the Claude harness, kagent hands the whole plugin to the Claude CLI. The
plugins[].skillsallowlist does not apply, and the agent gets every skill in the plugin. - On every other harness, the agent fails to start, with the error
plugin is Claude-format; only the Agent Plugins format (plugin.json at the plugin root) is supported here.
kagent also does not check the $schema value in a Claude-format manifest.
MCP servers
A plugin that includes mcp.json contributes MCP servers alongside any bound directly on the AgentTemplate. Only the kagent harness reads mcp.json. On every other harness, an agent gets only the servers that its AgentTemplate binds. The file has an mcpServers object, keyed by server name, and its $schema must be exactly https://agent-plugins.org/schemas/1.0.0/mcp.schema.json.
Each server specifies a transport in its type field, and the transport determines which other fields are allowed.
| Transport | Fields | Description |
|---|---|---|
stdio | command, args, env, cwd | Runs a process in the agent’s sandbox. Specifying url or headers is rejected. |
streamable-http | url, headers | Calls a remote server. Specifying command, args, env, or cwd is rejected. |
sse | url, headers | Calls a remote server over Server-Sent Events. Accepts the same fields as streamable-http. |
The path rules on a stdio server keep a plugin self-contained. A plugin can run only what it ships or what the agent’s image already provides, and it can write only to its own data directory.
- A
stdiocommand must be a bare name on the agent’sPATH, or a path that begins with./and resolves inside the plugin directory. A command that uses a path separator any other way or that contains whitespace is rejected. - A
cwdmust begin with./,${PLUGIN_ROOT}, or${PLUGIN_DATA}, and it must resolve inside the plugin directory or that plugin’s data directory. Omitcwdto run the command in the plugin directory. If acwdunder${PLUGIN_DATA}does not exist yet, kagent creates it. - A remote
urlmust behttporhttps, and it must not carry user information or fragments. Any host other than a loopback address must use HTTPS. - Unrecognized fields are rejected rather than ignored.
If one server in the file is invalid, kagent logs the problem and skips that server, but the rest of the file is still loaded. A whole mcp.json contributes nothing when it fails to parse, declares an unexpected $schema, or omits mcpServers.
Referring to plugin files
A stdio server often needs to run something that the plugin ships, or to write somewhere durable. kagent expands two variables in args, in env values, and in cwd.
${PLUGIN_ROOT}: The directory that the plugin was unpacked into. Treat it as read-only.${PLUGIN_DATA}: The data directory that kagent creates for that plugin. Use it for anything that the server writes.
kagent also sets PLUGIN_ROOT and PLUGIN_DATA as environment variables on every stdio server, so a server can read them without the plugin declaring them. A plugin cannot override either variable. An env block that sets one of them is rejected.
Plugin limits
kagent measures a plugin after fetching it and before mounting anything. A plugin is rejected if it contains more than 10,000 filesystem entries or more than 100 MB of regular files. A .git directory is skipped and counts toward neither. A symlink that resolves outside the artifact root is also rejected.
Every source is immutable
A skill or a plugin changes what an agent does, so kagent only accepts artifact references that cannot shift underneath a running agent. Each source specifies exactly one of three kinds of artifact, and every kind must be pinned in its own way.
oci: An image reference pinned to a digest, in the form<repository>@sha256:<digest>. A tag alone is rejected, because a tag can be moved to different content later.git: A repository URL together with a full commit identifier. An abbreviated commit, a branch, or a tag is rejected.bucket.s3: An endpoint, bucket, and key, together with theversionIdof that exact object version. A region is included where the service requires one for request signing.
If a source sets more than one kind, or none of them, the API server rejects the AgentTemplate with the error exactly one of the fields in [oci git bucket] must be set.
Publishing a new version means updating the AgentTemplate to reference the new digest, commit, or object version. The update produces a new revision. Agents that are already running keep the content that they started with.