Connect kagent
kagent runs agents as SandboxAgent custom resources inside your own Kubernetes cluster. On this platform you own the agent definition: Willow only references your SandboxAgent by namespace and name, and never reaches into your cluster to create or reconcile it.
Instead, Deploy (sync) reveals, once, the values you wire onto your CRD by hand:
- the MCP gateway URL the agent should call for its tools,
- the
Authorizationbearer token for that gateway, and - the recommended system message (your prompt with enabled skills folded in).
You apply those as a Secret + RemoteMCPServer and a systemMessage on your SandboxAgent. That RemoteMCPServer is what gives the agent Willow's tools — including reply_to_slack_thread — so its answers flow back the same way every other platform's do.
The kagent controller has no configuration API, and it lives inside your network where Willow's control plane cannot reach it. Rather than push into your cluster, Willow hands you the values and you apply them. This keeps your SandboxAgent the single source of truth.
How it fits together
| Piece | Where it runs | Who owns it |
|---|---|---|
SandboxAgent CRD | Your cluster | You |
RemoteMCPServer + Secret | Your cluster | You (from the values sync reveals) |
| kagent controller | Your cluster | You |
| Willow MCP gateway | Reachable from your cluster | Willow |
At run time, Willow's in-cluster component invokes your agent over the kagent A2A protocol; the agent calls back through the RemoteMCPServer to Willow's gateway for its tools. Willow's control plane is never in the run path.
Prerequisites
- A Kubernetes cluster with the kagent controller installed and a
SandboxAgentyou control. - Network egress from the cluster to Willow's MCP gateway URL.
- The kagent controller base URL (for example
http://kagent-controller.kagent:8083).
Step 1: Connect the platform in Willow
- Go to Manage → Machine Users → Background Agents, open Settings (gear icon), and find kagent under Agent Types.
- Select Set credentials and enter the org-level kagent controller base URL (and an auth token if your controller requires one). These live on the platform connection, not on each agent.
- Select Connect.
Once connected, kagent appears as a selectable platform when creating an agent.
Step 2: Reference your SandboxAgent
When you create the agent, set its platform configuration to point at the CRD you own:
| Field | Meaning |
|---|---|
| Namespace | Kubernetes namespace of the SandboxAgent (defaults to kagent). |
| Agent name | The SandboxAgent CRD name Willow invokes. Required before you can sync. |
| Controller URL | Optional per-agent override of the org connection's base URL. |
| System prompt | The recommended systemMessage. Enabled skills are appended to it when revealed (kagent has no separate skills API). |
Step 3: Deploy to reveal the wiring values
Select Deploy in the detail-page header. On a kagent agent this does not touch your cluster — it rotates the agent's gateway secret and shows the values once:
| Revealed value | What it is |
|---|---|
| MCP gateway URL | The url your RemoteMCPServer points at. |
Authorization header | Bearer <access_key>:<secret> — the rotated gateway token. Shown once. |
| A2A URL | …/api/a2a-sandboxes/{namespace}/{agent}/, where Willow invokes the agent. |
| Secret + RemoteMCPServer manifest | A ready-to-apply YAML block (see below). |
| Recommended system message | Your prompt with enabled skills appended. |
Deploying rotates the gateway secret, which invalidates any header revealed by a previous deploy. Copy the Authorization value now and paste it straight into your Secret — if you lose it, deploy again to mint a new one.
Step 4: Apply to your cluster
Apply the revealed Secret + RemoteMCPServer with kubectl apply -f -. The manifest looks like this (with the values from Step 3 filled in):
apiVersion: v1
kind: Secret
metadata:
name: willow-<agent-slug>-mcp
namespace: kagent
type: Opaque
stringData:
authorization: "Bearer <access_key>:<secret>"
---
apiVersion: kagent.dev/v1alpha2
kind: RemoteMCPServer
metadata:
name: willow-<agent-slug>
namespace: kagent
spec:
description: Willow MCP gateway
protocol: STREAMABLE_HTTP
url: https://<your-willow-gateway>/agent/<agent-slug>
headersFrom:
- name: Authorization
valueFrom:
type: Secret
name: willow-<agent-slug>-mcp
key: authorization
Then reference the RemoteMCPServer from your SandboxAgent so the agent gains Willow's tools:
# Add under spec.declarative.tools of your SandboxAgent:
- type: McpServer
mcpServer:
kind: RemoteMCPServer
apiGroup: kagent.dev
name: willow-<agent-slug>
Finally, set the revealed system message as spec.declarative.systemMessage on your SandboxAgent (your prompt plus enabled skills).
Message flow
- A message (for example a Slack mention) is delivered to Willow's in-cluster component.
- That component invokes your
SandboxAgentover the A2A URL. - The agent calls Willow's MCP gateway through the
RemoteMCPServer, authenticating with the headerSecret. - The agent replies through the
reply_to_slack_threadtool, which returns the answer to the original thread.
Troubleshooting
The agent can't call any Willow tools
The RemoteMCPServer or its header Secret isn't wired correctly. Confirm both were applied in the same namespace as the SandboxAgent, that the Secret's authorization key holds the full Bearer <access_key>:<secret> value, and that the RemoteMCPServer is referenced under spec.declarative.tools.
Tool calls started failing after a deploy
Deploying rotates the gateway secret. Re-apply the Secret with the newly revealed Authorization header — the old one no longer authenticates.
Sync says the agent name is not set
Set the Agent name (the SandboxAgent CRD name) in the agent's platform configuration before deploying. See Step 2.
Replies never reach Slack
The agent needs the reply_to_slack_thread tool, which comes from the Willow RemoteMCPServer. If the wiring in Step 4 is missing, the agent runs but has no way to answer.