> ## Documentation Index
> Fetch the complete documentation index at: https://flokoa.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Give your agents access to external APIs with AgentTool

> Create OpenAPI-backed AgentTool resources, attach them to your agents, and let the LLM call external APIs and internal Kubernetes services.

AgentTools extend your agents beyond pure language model reasoning by giving them the ability to call external APIs and internal Kubernetes services. Each AgentTool is backed by an OpenAPI specification — the operator reads the spec at reconciliation time, and the LLM uses the operation descriptions to decide when and how to invoke each endpoint. Tools can be defined once and shared across every agent in your cluster.

<Tip>
  Write clear, specific `description` values on each AgentTool. This is the text the LLM reads when deciding whether to call the tool, so a vague description leads to missed calls or incorrect usage.
</Tip>

<Steps>
  <Step title="Choose a tool target">
    An AgentTool can point to an API hosted at an external URL or to a Service running inside your Kubernetes cluster. Choose the option that matches your API's location.

    <Tabs>
      <Tab title="External URL">
        Use the `url` field when the target API is reachable over the internet or a routable network address. The operator and the agent container both need egress access to that hostname.

        ```yaml theme={null}
        openApi:
          url: "https://api.weather.com/v1"
          timeoutSeconds: 30
          openApiSchema:
            endpointPath: "/openapi.json"
        ```
      </Tab>

      <Tab title="Internal Kubernetes Service">
        Use `serviceRef` when the API runs inside your cluster. Flokoa resolves the service using Kubernetes DNS, so no external network path is required and the call stays within your cluster.

        ```yaml theme={null}
        openApi:
          serviceRef:
            name: inventory-service
            namespace: backend
            port: 8080
          timeoutSeconds: 10
          openApiSchema:
            endpointPath: "/api/openapi.json"
        ```

        Internal service calls are faster, cheaper, and do not require authentication in most cases — prefer them over external URLs for any API you control.
      </Tab>
    </Tabs>
  </Step>

  <Step title="Create the AgentTool">
    Write a full AgentTool manifest and apply it to your cluster. The examples below show both the external URL and internal ServiceRef patterns.

    **External API:**

    ```yaml theme={null}
    apiVersion: agent.flokoa.ai/v1alpha1
    kind: AgentTool
    metadata:
      name: weather-api
    spec:
      type: openapi
      description: "Get current weather for a location"
      openApi:
        url: "https://api.weather.com/v1"
        timeoutSeconds: 30
        openApiSchema:
          endpointPath: "/openapi.json"
    ```

    **Internal Kubernetes service:**

    ```yaml theme={null}
    apiVersion: agent.flokoa.ai/v1alpha1
    kind: AgentTool
    metadata:
      name: inventory-check
    spec:
      type: openapi
      description: "Check product inventory levels"
      openApi:
        serviceRef:
          name: inventory-service
          namespace: backend
          port: 8080
        openApiSchema:
          endpointPath: "/api/openapi.json"
    ```

    Apply both:

    ```bash theme={null}
    kubectl apply -f weather-api.yaml
    kubectl apply -f inventory-check.yaml
    ```
  </Step>

  <Step title="Attach the tool to your Agent">
    Reference AgentTools from your Agent spec using `toolRef`. You can reference tools in the same namespace or in a different namespace by including the optional `namespace` field.

    **Using toolRef (recommended for shared tools):**

    ```yaml theme={null}
    spec:
      tools:
        - toolRef:
            name: weather-api
        - toolRef:
            name: inventory-check
            namespace: shared-tools
    ```

    **Using an inline tool definition (useful for one-off, agent-specific tools):**

    ```yaml theme={null}
    spec:
      tools:
        - name: petstore
          template:
            type: openapi
            description: "Browse and search the pet store catalog"
            openApi:
              url: "https://petstore3.swagger.io"
              openApiSchema:
                endpointPath: "/api/v3/openapi.json"
    ```

    Both patterns can coexist in a single Agent spec — mix `toolRef` entries for shared tools with inline `template` entries for tools that are specific to one agent.

    <Tip>
      Place commonly used tools in a dedicated namespace such as `shared-tools` and reference them with the `namespace:` field. This lets any team's agents reuse the same tool definition without copying YAML.
    </Tip>
  </Step>

  <Step title="Verify the tool">
    List all AgentTool resources and confirm the operator has successfully validated and stored each spec:

    ```bash theme={null}
    kubectl get agenttools
    ```

    ```
    NAME               AGE
    weather-api        45s
    inventory-check    40s
    ```

    Inspect a specific tool for detailed status conditions:

    ```bash theme={null}
    kubectl describe agenttool weather-api
    ```

    Look for two conditions in the output:

    * **`Validated`** — confirms the spec fields are syntactically correct.
    * **`Stored`** — confirms the operator has persisted the resolved OpenAPI spec in a ConfigMap for runtime use.

    If either condition shows `status: "False"`, the `message` field explains what went wrong — usually an unreachable `endpointPath` or a malformed spec.
  </Step>

  <Step title="Test the tool">
    With the tool attached and the agent running, check the agent logs to confirm the tool is being called during inference:

    ```bash theme={null}
    kubectl logs -l flokoa.ai/agent=my-agent | grep -i tool
    ```

    A successful tool invocation appears in the logs as the agent framework records the call and its result. If you expect the tool to be called but it isn't, re-read the `description` field — the LLM relies on it to decide when invocation is appropriate.
  </Step>
</Steps>

## OpenAPI schema sources

The `openApiSchema` block is required on every AgentTool. You have three options for supplying the schema.

<Accordion title="endpointPath — fetch the spec from the target service">
  The operator issues an HTTP GET to the `url` or `serviceRef` base address combined with `endpointPath` and retrieves the OpenAPI spec at reconciliation time. This is the simplest option when the target API serves its own spec.

  ```yaml theme={null}
  openApiSchema:
    endpointPath: "/openapi.json"
  ```

  Use this when the API already exposes a spec at a known path and that path stays stable across deployments.
</Accordion>

<Accordion title="value — embed the spec inline in the manifest">
  Provide the entire OpenAPI spec as a YAML object nested directly inside the manifest. The operator uses the embedded spec without making any network calls.

  ```yaml theme={null}
  openApiSchema:
    value:
      openapi: "3.0.0"
      info:
        title: Calculator API
        version: "1.0"
      paths:
        /calculate:
          post:
            summary: Perform a calculation
            requestBody:
              content:
                application/json:
                  schema:
                    type: object
                    properties:
                      operation:
                        type: string
                      a:
                        type: number
                      b:
                        type: number
            responses:
              "200":
                description: Calculation result
  ```

  Use this for small, simple APIs where the spec is unlikely to change and you want everything in one file.
</Accordion>

<Accordion title="valueFrom — reference a spec stored in a ConfigMap">
  Point to an existing ConfigMap that holds the OpenAPI spec. This is the right choice when the spec is large, managed separately, or shared across multiple tools.

  ```yaml theme={null}
  openApiSchema:
    valueFrom:
      name: api-specs
      key: openapi.json
  ```

  Create the ConfigMap in the same namespace as the AgentTool:

  ```bash theme={null}
  kubectl create configmap api-specs --from-file=openapi.json=./path/to/openapi.json
  ```
</Accordion>

## Secure API credentials

If the external API requires an authentication header, use a Kubernetes Secret to store the credential and inject it into the agent container as an environment variable. Reference the value from your agent's environment rather than embedding it in the AgentTool manifest.

```yaml theme={null}
# 1. Create the secret
kubectl create secret generic weather-api-key \
  --from-literal=api-key=your-key-here

# 2. Reference it in the Agent env
spec:
  runtime:
    spec:
      container:
        env:
        - name: WEATHER_API_KEY
          valueFrom:
            secretKeyRef:
              name: weather-api-key
              key: api-key
```

Your agent code then reads `WEATHER_API_KEY` from its environment and attaches it as an `Authorization` header when the tool makes a call.
