diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 239963b2..d5bcde9b 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -84,6 +84,18 @@ npm run start yarn start ``` +## Keeping the lock file in sync + +Cloudflare Pages runs `npm ci`, which requires `package-lock.json` to match `package.json` exactly. If you change dependencies in `package.json`, update the lock file and commit it: + +```bash +npm install +git add package-lock.json +git commit -m "chore: update package-lock.json" +``` + +If the Cloudflare build fails with errors like "lock file's X does not satisfy X" or "Missing: X from lock file", run `npm install` in the website directory and commit the updated `package-lock.json`. + ## Deployment The site is automatically deployed when changes are pushed to the main branch. The deployment process includes: diff --git a/package-lock.json b/package-lock.json index 61e541d0..ec6c812d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@eslint/eslintrc": "^3", - "@opennextjs/cloudflare": "^0.2.1", + "@opennextjs/cloudflare": "^1.14.8", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", diff --git a/src/app/docs/kagent/concepts/agents/page.mdx b/src/app/docs/kagent/concepts/agents/page.mdx index 4c2aefde..4aeb1c18 100644 --- a/src/app/docs/kagent/concepts/agents/page.mdx +++ b/src/app/docs/kagent/concepts/agents/page.mdx @@ -141,8 +141,19 @@ Here's how you could reference an existing agent (`promql-agent`) as a tool: toolNames: - k8s_get_resources - k8s_get_available_api_resources - # Referencing an existing agent as a tool + # Referencing an existing agent as a tool (same namespace) - type: Agent agent: - ref: promql-agent -``` \ No newline at end of file + name: promql-agent + # Referencing an agent in another namespace + - type: Agent + agent: + name: promql-agent + namespace: other-namespace +``` + +### MCP server endpoint + +A2A-enabled agents are automatically exposed as an MCP server on the kagent controller. The MCP endpoint is available at `/mcp` on the same port as the A2A endpoint (default 8083). + +For more information, see the [MCP tools](/docs/kagent/examples/agents-mcp) guide. diff --git a/src/app/docs/kagent/concepts/tools/page.mdx b/src/app/docs/kagent/concepts/tools/page.mdx index 46397f81..f61b7d51 100644 --- a/src/app/docs/kagent/concepts/tools/page.mdx +++ b/src/app/docs/kagent/concepts/tools/page.mdx @@ -22,9 +22,60 @@ You can check out the full list of built-in tools [here](/tools). The built-in tools are meant as a good starting point for any agents running in kubernetes, however we don't envision them covering all possible use-cases, so we support multiple tool extension points to allow you to bring in your own tools. +### Cross-namespace tool references + +You can refer to tools from MCP servers in other namespaces by using the `namespace/name` format. This way, you can share tool servers across namespaces without duplicating them. + +Example: Reference to a RemoteMCPServer in the `tools` namespace. + +```yaml +tools: + - type: McpServer + mcpServer: + name: kagent-tool-server + namespace: tools + kind: RemoteMCPServer + toolNames: + - k8s_get_resources +``` + +The same format applies when referring to Services or MCPServers in other namespaces. + +### Headers for tool calls + +You can add headers to requests sent from an agent to a tool using `headersFrom`. This ability is useful for passing API keys, authentication tokens, or other per-request metadata to MCP servers. Header values are resolved from Secrets or ConfigMaps in the same namespace as the Agent. + +Example: Add an API key header when calling a tool. + +```yaml +tools: + - type: McpServer + mcpServer: + name: kagent-tool-server + kind: RemoteMCPServer + toolNames: + - k8s_get_resources + headersFrom: + - name: Authorization + valueFrom: + type: Secret + name: tool-api-secret + key: api-key +``` + +Headers specified in `headersFrom` override any headers of the same name configured on the tool itself. + ## Agents as Tools -You also have an option of using agents as tools. Any agent you create can be referenced and used by other agents you have. +You also have an option of using agents as tools. Any agent you create can be referenced and used by other agents you have. You can refer to agents in other namespaces by using the `namespace/name` format. + +```yaml +tools: + - type: Agent + agent: + name: promql-agent + namespace: other-namespace +``` ## MCP Tools diff --git a/src/app/docs/kagent/examples/a2a-byo/page.mdx b/src/app/docs/kagent/examples/a2a-byo/page.mdx index d509b31b..1549d170 100644 --- a/src/app/docs/kagent/examples/a2a-byo/page.mdx +++ b/src/app/docs/kagent/examples/a2a-byo/page.mdx @@ -4,6 +4,8 @@ pageOrder: 1 description: "Bring your own ADK agent to kagent" --- +import { Tabs, Tab } from '@/components/mdx/tabs'; + export const metadata = { title: "Bringing your own ADK agent to kagent", description: "Learn how to bring your own ADK agent to kagent", @@ -63,6 +65,12 @@ Now that you have your own custom agent image, you can create a BYO Agent resour 3. Create a BYO Agent resource. + + +
```yaml kubectl apply -f - < + +
+ For agent images that are in private container registries, you can use an image pull secret with the credentials to the registry. + + First, create the Secret. + ```sh + kubectl create secret docker-registry my-registry-secret --docker-server= --docker-username= --docker-password= -n kagent + ``` + + Then, add `imagePullSecrets` to refer to the Secret that you just created. + ```yaml + kubectl apply -f - < ## Testing the A2A endpoint @@ -296,3 +339,22 @@ To use lifespan hooks in your ADK agent, create a lifespan function and pass it lifespan=lifespan.lifespan # Pass the lifespan function ) ``` + +### A2A max payload size + +BYO agents accept A2A requests with a default maximum payload size of 10 MB. For agents that need to handle larger payloads (for example, when processing large file attachments), set the `A2A_MAX_CONTENT_LENGTH` environment variable in the agent deployment. + +Example: Allow 50 MB payloads: + +```yaml +spec: + type: BYO + byo: + deployment: + image: ghcr.io/my-org:latest + env: + - name: A2A_MAX_CONTENT_LENGTH + value: "52428800" # 50 MB in bytes +``` + +Set to `0`, `none`, or `unlimited` for no limit (use with caution). diff --git a/src/app/docs/kagent/examples/skills/page.mdx b/src/app/docs/kagent/examples/skills/page.mdx index 7f4a17c6..cb328a90 100644 --- a/src/app/docs/kagent/examples/skills/page.mdx +++ b/src/app/docs/kagent/examples/skills/page.mdx @@ -49,7 +49,6 @@ To create a container-based skill, package your skill files into a container ima name: k8s-deploy-skill description: Deploy simple applications to Kubernetes with customizable replicas and port --- - # Kubernetes simple deploy skill Use this skill when users want to deploy a basic app on the Kubernetes cluster. @@ -286,9 +285,9 @@ spec: name: kagent-tool-server kind: RemoteMCPServer toolNames: - - k8s_apply_manifest - k8s_get_resources - k8s_describe_resource + - k8s_apply_manifest systemMessage: | You are a Kubernetes assistant that helps users deploy and manage applications. You have access to skills that can help automate common tasks. diff --git a/src/app/docs/kagent/operations/operational-considerations/page.mdx b/src/app/docs/kagent/operations/operational-considerations/page.mdx index 4998b923..90fd281d 100644 --- a/src/app/docs/kagent/operations/operational-considerations/page.mdx +++ b/src/app/docs/kagent/operations/operational-considerations/page.mdx @@ -4,6 +4,8 @@ pageOrder: 1 description: "Important operational considerations when running kagent in production." --- +import { Tabs, Tab } from '@/components/mdx/tabs'; + export const metadata = { title: "Operational Considerations", description: "Important operational considerations when running kagent in production.", @@ -84,3 +86,73 @@ database: controller: replicas: 3 ``` + +## Secure execution environment + +Kagent supports Kubernetes security contexts to run agents and tool servers with reduced privileges. Configure `securityContext` and `podSecurityContext` on your Agent or ToolServer resources to enforce secure execution. + +Common settings include: + +- **`runAsNonRoot: true`**: Ensures the container does not run as root. +- **`runAsUser`**: Specifies the user ID for the container process. +- **`readOnlyRootFilesystem`**: Mounts the root filesystem as read-only when possible. + +At the Helm chart level, you can set global defaults with `podSecurityContext` and `securityContext` in your values. For more information, see the [Kubernetes SecurityContext documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/). + + + +
+Set these in `spec.declarative.deployment.podSecurityContext` and `spec.declarative.deployment.securityContext`. + +```yaml +spec: + type: Declarative + declarative: + deployment: + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false +``` +
+ +
+Set these in `spec.byo.deployment.podSecurityContext` and `spec.byo.deployment.securityContext`. + +```yaml +spec: + type: BYO + byo: + deployment: + podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: false +``` +
+ +## Proxy configuration for agent traffic + +When agents and MCP servers run behind an API gateway or proxy, you can configure kagent to route agent-to-agent and agent-to-MCP traffic through that proxy. Set `proxy.url` in your Helm values to the proxy endpoint. + +The proxy applies to: + +- Agent-to-agent traffic (when one agent invokes another agent as a tool) +- Agent-to-MCP-server traffic (when agents call ToolServers, Services, or RemoteMCPServers with internal Kubernetes URLs) + +Example Helm configuration: + +```yaml +proxy: + url: "http://proxy.kagent.svc.cluster.local:8080" +``` + +The controller rewrites internal URLs to use the proxy and sets the `x-kagent-host` header so the proxy can route requests to the correct backend. External URLs (for example, RemoteMCPServers pointing to `https://external.example.com`) are not rewritten. + diff --git a/src/app/docs/kagent/resources/helm/page.mdx b/src/app/docs/kagent/resources/helm/page.mdx index 20aa3fb4..5e18e9bb 100644 --- a/src/app/docs/kagent/resources/helm/page.mdx +++ b/src/app/docs/kagent/resources/helm/page.mdx @@ -108,9 +108,9 @@ A Helm chart for kagent, built with Google ADK | controller.service.ports.port | int | `8083` | | | controller.service.ports.targetPort | int | `8083` | | | controller.service.type | string | `"ClusterIP"` | | -| controller.streaming.initialBufSize | string | `"4Ki"` | | -| controller.streaming.maxBufSize | string | `"1Mi"` | | -| controller.streaming.timeout | string | `"600s"` | | +| controller.streaming.initialBufSize | string | `"4Ki"` | Initial size of the A2A streaming buffer. | +| controller.streaming.maxBufSize | string | `"1Mi"` | Maximum size of the A2A streaming buffer. | +| controller.streaming.timeout | string | `"600s"` | Timeout for A2A streaming connections. | | controller.tolerations | list | `[]` | Node taints which will be tolerated for `Pod` [scheduling](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/). | | controller.volumeMounts | list | `[]` | | | controller.volumes | list | `[]` | | @@ -126,7 +126,7 @@ A Helm chart for kagent, built with Google ADK | grafana-mcp.resources.requests.cpu | string | `"100m"` | | | grafana-mcp.resources.requests.memory | string | `"128Mi"` | | | imagePullPolicy | string | `"IfNotPresent"` | | -| imagePullSecrets | list | `[]` | | +| imagePullSecrets | list | `[]` | Image pull secrets for pulling agent and tool images from private registries. You can also set `imagePullSecrets` per agent in the Agent `deployment` spec. | | kagent-tools.enabled | bool | `true` | | | kagent-tools.fullnameOverride | string | `"kagent-tools"` | | | kagent-tools.replicaCount | int | `1` | | @@ -178,7 +178,7 @@ A Helm chart for kagent, built with Google ADK | providers.openAI.apiKeySecretRef | string | `"kagent-openai"` | | | providers.openAI.model | string | `"gpt-4.1-mini"` | | | providers.openAI.provider | string | `"OpenAI"` | | -| proxy.url | string | `""` | | +| proxy.url | string | `""` | Proxy URL for routing agent-to-agent and agent-to-MCP traffic through a gateway (for example, `http://proxy.kagent.svc.cluster.local:8080`). When set, the controller routes internal Kubernetes URLs (agents, MCP servers, services) through this proxy. The proxy uses the `x-kagent-host` header for routing. Omit for direct connections. | | querydoc.image.pullPolicy | string | `"IfNotPresent"` | | | querydoc.image.registry | string | `"ghcr.io"` | | | querydoc.image.repository | string | `"kagent-dev/doc2vec/mcp"` | | diff --git a/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx b/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx index 8a53e50a..807b9915 100644 --- a/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx +++ b/src/app/docs/kagent/supported-providers/amazon-bedrock/page.mdx @@ -1,25 +1,74 @@ --- title: "Amazon Bedrock" pageOrder: 1 -description: "Use Amazon Bedrock models with kagent via the OpenAI Chat Completions API." +description: "Use Amazon Bedrock models with kagent via the native Bedrock provider or the OpenAI Chat Completions API." --- export const metadata = { title: "Amazon Bedrock", - description: "Use Amazon Bedrock models with kagent via the OpenAI Chat Completions API.", + description: "Use Amazon Bedrock models with kagent via the native Bedrock provider or the OpenAI Chat Completions API.", author: "kagent.dev" }; # Amazon Bedrock -You can use Amazon Bedrock models with kagent by leveraging AWS Bedrock's [OpenAI Chat Completions API](https://docs.aws.amazon.com/bedrock/latest/userguide/inference-chat-completions.html). +You can use Amazon Bedrock models with kagent in two ways: the native Bedrock provider (recommended) or the OpenAI-compatible API interface. -## Step 1: Prepare your AWS details +## Option 1: Native Bedrock provider + +The native Bedrock provider uses AWS IAM credentials and the Bedrock API directly. Use this option when you want the simplest configuration and full Bedrock feature support. + +### Step 1: Prepare your AWS credentials + +1. Create an IAM user or role with permissions for Bedrock. You need at least `bedrock:InvokeModel` for the models you use. For more information, see the [AWS Bedrock model access docs](https://docs.aws.amazon.com/bedrock/latest/userguide/model-access.html). + +2. Choose the AWS region and Bedrock model. Refer to the [AWS Bedrock supported models documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html). + - Example regions: `us-east-1` or `us-west-2` + - Example model IDs: `us.anthropic.claude-sonnet-4-20250514-v1:0` or `amazon.titan-text-express-v1` + +3. Create a Kubernetes secret with your AWS credentials in the same namespace as your agent, typically `kagent`: + + ```bash + kubectl create secret generic bedrock-credentials -n kagent \ + --from-literal=AWS_ACCESS_KEY_ID= \ + --from-literal=AWS_SECRET_ACCESS_KEY= + ``` + +### Step 2: Create the ModelConfig + +```yaml +kubectl apply -f - <.amazonaws.com/openai/v1`. | - -## Next Steps - - Now that you configured your Bedrock model, you can [create or update an agent](https://kagent.dev/docs/kagent/getting-started/first-agent) to use this model configuration. +### Step 2: Create the ModelConfig + +```yaml +kubectl apply -f - <.amazonaws.com/openai/v1`. | + +## Next steps + +Now that you configured your Bedrock model, you can [create or update an agent](https://kagent.dev/docs/kagent/getting-started/first-agent) to use this model configuration. diff --git a/src/config/navigation.json b/src/config/navigation.json index 80bb0375..1f1d3c17 100644 --- a/src/config/navigation.json +++ b/src/config/navigation.json @@ -99,7 +99,7 @@ { "title": "Amazon Bedrock", "href": "/docs/kagent/supported-providers/amazon-bedrock", - "description": "Use Amazon Bedrock models with kagent via the OpenAI Chat Completions API." + "description": "Use Amazon Bedrock models with kagent via the native Bedrock provider or the OpenAI Chat Completions API." }, { "title": "Anthropic",