For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Your first MCP tool
Give an agent a Model Context Protocol tool by binding an MCP server to its AgentTemplate.
A system prompt tells an agent how to behave. Tools tell it what it can do. This guide binds a 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) tool to the agent that you built in Your first agent, so that the agent can read live data out of your cluster instead of answering from the model alone. For the full tool bindingTool bindingOne entry in an AgentTemplate's spec.tools list. Each binding selects exactly one source: tools from a Model Context Protocol server, or another AgentTemplate used as a tool.Learn more schema, including binding one agent as another agent’s tool, see About tools.
Before you begin
Complete Your first agent. This guide edits the
my-first-agentAgentTemplate that the agent guide creates, so keep that AgentTemplate and themy-first-harnessHarness in place.Confirm that you have the kagent CLI and
jqinstalled.
Bind the tool to your AgentTemplate
kagent ships an MCP server of its own, and installs a RemoteMCPServer that points at it, so the built-in server is the shortest path to a working tool. An AgentTemplateAgentTemplateA Kubernetes custom resource defining what an agent does: its model, system prompt, tools, skills, and plugins. It runs only once a Harness accepts it.Learn more takes tools through an mcp binding, which names one server and, optionally, the tools to take from it. This guide names the tools specifically, so that the agent gets only the two tools it needs rather than the server’s whole catalog.
kagent records what it discovered on the server’s status, so the tool names come from the cluster. This guide binds k8s_get_resources and k8s_get_pod_logs. For the full catalog that the built-in server serves, see the tools ecosystem reference.
List the RemoteMCPServersRemoteMCPServerA Kubernetes custom resource pointing at a Model Context Protocol server that the cluster can reach. It is the only server kind that an AgentTemplate tool binding accepts.Learn more in the
kagentnamespace.kubectl get remotemcpserver -n kagentExample output: The
ACCEPTEDcolumn reports whether kagent reached the server and read its catalog. No tool can be bound from a server that is notTrue.NAME PROTOCOL URL ACCEPTED AGE kagent-tool-server STREAMABLE_HTTP http://kagent-tools.kagent:8084/mcp True 14mTo see the tools that the server offers, read the discovered set from its status.
kubectl get remotemcpserver kagent-tool-server -n kagent \ -o jsonpath='{range .status.discoveredTools[*]}{.name}{"\t"}{.description}{"\n"}{end}'Note
The built-in server is installed only when the
kagent-tools.enabledHelm value istrue, which is the default. If the command returns no resources, either re-install with that value enabled, or use your own server as described in Bind your own MCP server.Re-apply the
my-first-agentAgentTemplate with aspec.toolslist and a system prompt that tells the model what the tools are for.kubectl apply -f - <<EOF apiVersion: kagent.dev/v1alpha3 kind: AgentTemplate metadata: name: my-first-agent namespace: kagent labels: kagent.dev/harness: my-first-harness spec: description: My first kagent agent modelConfig: name: default-model-config systemPrompt: |- You are a concise, helpful assistant with read access to a Kubernetes cluster. Use your tools to answer questions about what is running in the cluster. When a question cannot be answered from the tools that you have, say so. tools: - mcp: server: kind: RemoteMCPServer name: kagent-tool-server tools: - k8s_get_resources - k8s_get_pod_logs EOFField Description mcp.server.kindThe kind of server resource. RemoteMCPServeris the only accepted value.mcp.server.nameThe server’s name. A binding resolves in the AgentTemplate’s own namespace, so it cannot reach a server in another namespace. mcp.toolsOptional. The names of the tools to bind, up to 50. An omitted or empty list exposes every tool on the server. An AgentTemplate takes at most 50 bindings in total. Confirm that kagent compiled a new revisionRevisionThe compiled, immutable output of one Harness and AgentTemplate pairing, identified by a content digest. An AgentInstance runs the revision it was created from for its whole life, so editing either resource affects only instances created afterward. for the edited AgentTemplate. Every edit produces a new desired revision, and the pair is current when the latest successful revision matches it.
kubectl get agenttemplate my-first-agent -n kagent \ -o jsonpath='{range .status.harnesses[*]}{.harness}{"\t"}{.desiredRevision}{"\t"}{.latestSuccessfulRevision}{"\n"}{end}'Example output:
my-first-harness 7c1f9a2b4e8d3f60a5b7c9e1d2f4a6b8c0d2e4f68a9b1c3d5e7f9a1b3c5d7e9f 7c1f9a2b4e8d3f60a5b7c9e1d2f4a6b8c0d2e4f68a9b1c3d5e7f9a1b3c5d7e9fWhen the two values differ, kagent is still compiling, or compilation failed. A binding that names a RemoteMCPServer that does not exist in the namespace fails at the
ResolvedRefscondition with the reasonReferenceResolutionFailed.Warning
kagent resolves the server, but it does not check the tool names against the tools that the server actually serves. A misspelled tool name compiles into a ready revision, and the only symptom is an agent that never calls the tool that you expected. If a bound tool appears to be missing, check the spelling against the server’s catalog.
Create an AgentInstance that has the tool
An AgentInstanceAgentInstanceA running, conversational pairing of a Harness and an AgentTemplate. Unlike the two, it is not a Kubernetes resource: kagent's gRPC API creates it and its database tracks it.Learn more runs the revision that it was created from, and keeps running that revision for its whole life. The instance from the agent guide still runs the revision without tools, so create a second instance to pick up the binding.
Create a second AgentInstance from the same Harness and AgentTemplate pair. The command is the one that you ran in the agent guide, but the pair has a newer revision now, so this instance picks up the tools.
kagent create agent-instance --harness my-first-harness --agent-template my-first-agentExample output:
+--------------------------------------+----------------+------------------+-------+----------------------+ | ID | AGENT TEMPLATE | HARNESS | STATE | CREATED | +--------------------------------------+----------------+------------------+-------+----------------------+ | 0198c4e2-8b3f-7d45-a1c6-9e2f4b8d6a03 | my-first-agent | my-first-harness | READY | 2026-08-31T16:20:38Z | +--------------------------------------+----------------+------------------+-------+----------------------+Save the new AgentInstance’s ID to an environment variable.
export TOOL_INSTANCE_ID=$(kagent get agent-instance -o json \ | jq -r '[.agentInstances[] | select(.agentTemplate.name == "my-first-agent")] | sort_by(.createdAt) | last | .id') echo $TOOL_INSTANCE_IDAsk the agent something that it can answer only by calling a tool.
kagent invoke --agent-instance $TOOL_INSTANCE_ID --task "Which pods are running in the kagent namespace?"The agent calls
k8s_get_resourcesand answers from the result rather than from the model’s own knowledge.Ask a follow-up question that uses the second tool. The AgentInstance holds the transcriptTranscriptThe record of an AgentInstance's conversation, held server-side and append-only. It survives the Actor suspending between turns, and a resumed runtime cannot shrink it. of the conversation, so the agent can act on the pods that it just listed.
kagent invoke --agent-instance $TOOL_INSTANCE_ID --task "Show me the last few log lines from the kagent controller pod."
Bind your own MCP server
A RemoteMCPServer points at any MCP server that the cluster can reach, whether it runs in the cluster or outside it. Create one, then bind it in the same way that you bound the built-in server.
Apply a
RemoteMCPServerfor your own server.kubectl apply -f - <<EOF apiVersion: kagent.dev/v1alpha3 kind: RemoteMCPServer metadata: name: my-mcp-server namespace: kagent spec: description: An MCP server of my own. url: http://my-mcp-server.my-namespace:3000/mcp protocol: STREAMABLE_HTTP timeout: 30s EOFField Description descriptionA short description of the server. This field is required. urlThe address of the server’s MCP endpoint. protocolThe transport to use, either STREAMABLE_HTTPorSSE. Defaults toSTREAMABLE_HTTP.timeoutHow long to wait on a request to the server. Defaults to 30s.headersFromHeaders to send with each request, sourced from a Secret or ConfigMap. Use this field for a server that requires an API key. allowedNamespacesWhich namespaces may reference this server. Defaults to the server’s own namespace. tlsTrust settings for an HTTPS upstream whose certificate the agent does not already trust. Setting this field alongside an http://URL is rejected.Add a second binding to the AgentTemplate’s
spec.toolslist, naming the new server and the tools to take from it.tools: - mcp: server: kind: RemoteMCPServer name: kagent-tool-server tools: - k8s_get_resources - k8s_get_pod_logs - mcp: server: kind: RemoteMCPServer name: my-mcp-server tools: - my_toolCreate another AgentInstance to run the revision that includes the new binding.
Clean up
Important
Leave the Harness, AgentTemplate, and AgentInstances in place. Other guides build on them, and Your first agent covers removing them when you are finished with the kagent guides. Leave kagent-tool-server in place as well, because the kagent installation owns it.
If you created a RemoteMCPServer of your own in Bind your own MCP server, delete it.
kubectl delete remotemcpserver my-mcp-server -n kagent