From 0dd236e3f6870ad3da978e10dd402fbb95739f52 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Sun, 25 Oct 2026 10:26:41 +0000 Subject: [PATCH 1/2] [Automated] Draft docs (kagent): feat: add token passthrough for remote MCP servers Signed-off-by: GitHub Action --- .../kagent/1.x/agents/agent-harness.md | 1 + .../1.x/get-started/your-first-mcp-tool.md | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+) 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/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md index 90f6c864..577f0d64 100644 --- a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md +++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md @@ -176,6 +176,34 @@ A `RemoteMCPServer` points at any MCP server that the cluster can reach, whether 3. Create another Session to run the revision that includes the new binding. +### Use the caller token for MCP server authentication {#use-the-caller-token-for-mcp-server-authentication} + +If your MCP server authorizes each user with the caller's bearer token, create a separate RemoteMCPServer with `tokenPassthrough: true`. With token passthrough, the server receives the token as its `Authorization` header. The MCP request fails when the agent invocation has no caller token. + +```yaml +kubectl apply -f - <`. A RemoteMCPServer that sets `tokenPassthrough` cannot also set an `Authorization` header in `headersFrom`. | + +The `codex` and `claude` harnesses reject a RemoteMCPServer that sets `tokenPassthrough`. + ## Clean up > [!IMPORTANT] @@ -185,6 +213,7 @@ If you created a RemoteMCPServer of your own in [Bind your own MCP server](#bind ```bash kubectl delete remotemcpserver my-mcp-server -n kagent +kubectl delete remotemcpserver user-mcp-server -n kagent ``` ## Next steps From 2a8fcfb3d620386ecd1fef2558317d770c28687f Mon Sep 17 00:00:00 2001 From: Rachael Graham Date: Tue, 27 Oct 2026 09:06:52 -0500 Subject: [PATCH 2/2] conventions Signed-off-by: Rachael Graham --- .../1.x/get-started/your-first-mcp-tool.md | 29 ------------------ .../kagent/1.x/skills-and-mcp/about-tools.md | 30 +++++++++++++++++-- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md index 577f0d64..90f6c864 100644 --- a/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md +++ b/docs-site/content/kagent/1.x/get-started/your-first-mcp-tool.md @@ -176,34 +176,6 @@ A `RemoteMCPServer` points at any MCP server that the cluster can reach, whether 3. Create another Session to run the revision that includes the new binding. -### Use the caller token for MCP server authentication {#use-the-caller-token-for-mcp-server-authentication} - -If your MCP server authorizes each user with the caller's bearer token, create a separate RemoteMCPServer with `tokenPassthrough: true`. With token passthrough, the server receives the token as its `Authorization` header. The MCP request fails when the agent invocation has no caller token. - -```yaml -kubectl apply -f - <`. A RemoteMCPServer that sets `tokenPassthrough` cannot also set an `Authorization` header in `headersFrom`. | - -The `codex` and `claude` harnesses reject a RemoteMCPServer that sets `tokenPassthrough`. - ## Clean up > [!IMPORTANT] @@ -213,7 +185,6 @@ If you created a RemoteMCPServer of your own in [Bind your own MCP server](#bind ```bash kubectl delete remotemcpserver my-mcp-server -n kagent -kubectl delete remotemcpserver user-mcp-server -n kagent ``` ## Next steps 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.