Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs-site/content/kagent/1.x/agents/agent-harness.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ The `kagent` harness accepts every AgentTemplate feature. Codex and Claude run a
| A subagent binding cannot itself carry tools, skills, plugins, or nested agents, and must use the same provider and credentials as the agent that binds it. | `codex`, `claude` |
| The agent sees every tool that an {{< gloss "MCP" >}}MCP{{< /gloss >}} server offers, because Claude does not support partial tool selection. A binding that names a subset of tools binds the whole server instead. The Agent still reconciles, and reports the decision in `status.warnings` as `Claude RemoteMCPServer "<name>" does not support partial tool selection`. | `claude` |
| A RemoteMCPServer must use the `STREAMABLE_HTTP` protocol. `SSE` is rejected. | `codex` |
| A RemoteMCPServer that sets `tokenPassthrough` is rejected. | `codex`, `claude` |
| Structured output is rejected, with `Harness runtime "<name>" does not support structured output`. | `codex`, `claude`, `byo` |

For more information about what an AgentTemplate can bind, see [About tools]({{< link path="skills-and-mcp/about-tools" >}}).
Expand Down
30 changes: 28 additions & 2 deletions docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ tools:

### Tool selection on the Claude harness

Claude's MCP configuration has no per-tool allowlist. On the Claude harness, the `tools` list does not narrow a server, and the agent reaches every tool that the server serves. kagent admits the {{< gloss "Revision" >}}revision{{< /gloss >}} either way. Unless the list exactly matches the tools that kagent currently discovers on the server, kagent also records a warning on the Agent.
Claude's MCP configuration does not have a per-tool allowlist. On the Claude harness, the `tools` list does not narrow a server, and the agent reaches every tool that the server serves. kagent admits the {{< gloss "Revision" >}}revision{{< /gloss >}} either way. Unless the list exactly matches the tools that kagent currently discovers on the server, kagent also records a warning on the Agent.

```sh
kubectl get agent <name> -n <namespace> -o jsonpath='{.status.warnings}'
Expand All @@ -49,6 +49,32 @@ To keep an agent on the Claude harness away from a tool, limit what the server e

For the bundled tool server, see the installation-level settings that drop providers and write tools in [Tools ecosystem]({{< link path="reference/tools-ecosystem#narrow-what-kagent-tool-server-serves" >}}).

### Caller token passthrough

An MCP server that authorizes each user individually needs the caller's token. For the authorizing server, set `tokenPassthrough: true` on its RemoteMCPServer resource. The agent sends the bearer token from the incoming agent-to-agent (A2A) request to the server as its `Authorization` header. When the incoming request does not present a bearer token, the MCP request fails.

```yaml
apiVersion: api.kagent.dev/v1alpha3
kind: RemoteMCPServer
metadata:
name: user-mcp-server
namespace: kagent
labels:
kagent.dev/discovery: disabled
spec:
description: An MCP server that authenticates each caller.
url: https://mcp.example.com/mcp
protocol: STREAMABLE_HTTP
tokenPassthrough: true
```

| Field | Description |
| ----- | ----------- |
| `kagent.dev/discovery` label | The controller does not have a caller token, so controller-side tool discovery against this server fails. Set the label to `disabled` to turn discovery off. For more information, see [Turn tool discovery off for a server]({{< link path="reference/tools-ecosystem#turn-tool-discovery-off-for-a-server" >}}). |
| `tokenPassthrough` | Sends the caller's bearer token as `Authorization: Bearer <token>`. The RemoteMCPServer cannot also set an `Authorization` header in `headersFrom`. The `codex` and `claude` harnesses reject a RemoteMCPServer that sets this field. For more information, see [Tool and skill support]({{< link path="agents/agent-harness#tool-and-skill-support" >}}). |

Every model and MCP server that an agent reaches at the server's origin must also forward the caller's token. Otherwise, the Agent reports the `Compatible` condition as `False`. For more information, see [Forward the caller's token]({{< link path="setup/model-providers/about-model-providers#forward-the-callers-token" >}}).

## Subagents as tools

A `subAgent` binding points at another AgentTemplate in the same namespace so that one agent can route work to another agent. The model reads the `description` when it decides whether to route work here. A description that states plainly what the bound agent is for therefore matters more than the detail of its configuration.
Expand All @@ -70,7 +96,7 @@ Every field is required. For the complete schema, see the [API reference]({{< li
| `subAgent.description` | The text that tells the parent agent when to route work here. |
| `subAgent.templateRef.name` | The AgentTemplate to bind, in the same namespace. |

kagent compiles the bound template into the parent agent's own configuration and runs it inside the parent's {{< gloss "Actor" >}}Actor{{< /gloss >}}, so the two agents share one sandbox. A bound template is not an MCP server and has no endpoint of its own. A bound template also does not need an {{< gloss "Agent" >}}Agent{{< /gloss >}} resource because the parent's Agent runs it.
kagent compiles the bound template into the parent agent's own configuration and runs it inside the parent's {{< gloss "Actor" >}}Actor{{< /gloss >}}, so the two agents share one sandbox. A bound template is not an MCP server and does not have an endpoint of its own. A bound template also does not need an {{< gloss "Agent" >}}Agent{{< /gloss >}} resource because the parent's Agent runs it.

> [!NOTE]
> Dedicated subagents, which would give a bound agent its own Harness, Session, and Actor, are not part of the served API. The `subAgent.agentRef` field that would select one is unavailable, so `templateRef` is the only binding that you can write today.
Expand Down
Loading