diff --git a/docs-site/content/kagent/1.x/agents/agent-harness.md b/docs-site/content/kagent/1.x/agents/agent-harness.md index 73b02ff9..7faa0db9 100644 --- a/docs-site/content/kagent/1.x/agents/agent-harness.md +++ b/docs-site/content/kagent/1.x/agents/agent-harness.md @@ -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 "" 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 "" 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" >}}). diff --git a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md index e31f61c8..2af54969 100644 --- a/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md +++ b/docs-site/content/kagent/1.x/skills-and-mcp/about-tools.md @@ -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 -n -o jsonpath='{.status.warnings}' @@ -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 `. 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. @@ -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.