MCP Tools

Model Context Protocol (MCP) is a standard interface for providing tools to LLMs. ark-operator connects agent pods to MCP servers at startup, making those tools available in the LLM’s tool-use loop.


Connecting an MCP server

Add servers to spec.mcpServers on an ArkAgent:

spec:
  model: llama3.2
  systemPrompt: "You are a research agent with web search capabilities."
  mcpServers:
    - name: web-search
      url: https://search.mcp.internal/sse
    - name: memory
      url: https://memory.mcp.internal/sse

At pod startup, the agent runtime reads AGENT_MCP_SERVERS (a JSON array injected by the operator) and establishes SSE connections to each server. Tool definitions from all connected servers are collected and passed to the LLM provider on every call.


Tool name prefixing

To prevent collisions when multiple servers expose tools with the same name, tool names are prefixed with the server name using double underscore:

web-search__search
web-search__fetch_page
memory__store
memory__recall

The LLM provider receives prefixed names; the runtime strips the prefix before forwarding calls to the MCP server.


Authenticated MCP servers

Use mcpServers[].headers to pass authentication credentials. Credentials can be injected from a Kubernetes Secret:

spec:
  mcpServers:
    - name: private-search
      url: https://search.internal/sse
      headers:
        - name: Authorization
          valueFrom:
            secretKeyRef:
              name: mcp-credentials
              key: search-token
        - name: X-API-Version
          value: "2"

The operator resolves secretKeyRef values at reconcile time and injects them as environment variables into agent pods with a deterministic prefix (ARK_MCP_<SERVERNAME>_HEADER_<HEADERNAME>). The agent runtime reads these and includes them in SSE connection requests.

Create the secret before applying the agent:

kubectl create secret generic mcp-credentials \
  --from-literal=search-token=your-token-here \
  --namespace my-org

Inline webhook tools

For simple HTTP tools, skip the MCP server entirely. Define tools directly in spec.tools:

spec:
  model: llama3.2
  systemPrompt: "You are a news assistant."
  tools:
    - name: fetch_news
      description: "Fetch the latest news headlines for a given topic."
      url: "http://news-api.internal/headlines"
      method: POST
      inputSchema: |
        {
          "type": "object",
          "properties": {
            "topic": {"type": "string", "description": "The news topic to search for"}
          },
          "required": ["topic"]
        }
    - name: get_weather
      description: "Get current weather for a city."
      url: "http://weather-api.internal/current"
      method: GET
      inputSchema: |
        {
          "type": "object",
          "properties": {
            "city": {"type": "string"}
          },
          "required": ["city"]
        }

When the LLM calls fetch_news({"topic": "AI"}), the agent runtime:

  1. POSTs the tool input as JSON to http://news-api.internal/headlines
  2. Returns the response body to the LLM as the tool result
Field Required Description
name yes Tool identifier exposed to the LLM. Must be unique within the deployment.
description no Explains the tool’s purpose. The LLM uses this to decide when to call the tool.
url yes HTTP endpoint the agent calls.
method no HTTP method. Defaults to POST.
inputSchema no JSON Schema (as a raw JSON string). The LLM uses this to construct valid inputs.

Failure behavior

Connection failures at startup: Non-fatal. The agent starts with a reduced toolset. Only tools from servers that connected successfully are available. This prevents a single unavailable tool server from taking down the entire agent pool.

Tool call failures at runtime: The error is returned to the LLM as the tool result. The model decides how to proceed — it may retry, use an alternative approach, or report the failure in its response.


MCP vs inline webhook tools

  MCP server Inline webhook
Setup effort Requires a separate server Just a URL
Tool count Many tools per server One tool per entry
Tool discovery Dynamic (server advertises tools) Static (defined in spec)
Auth support Via headers Not yet supported
Best for Rich tool ecosystems, shared tooling Simple HTTP calls, internal APIs

See also


Apache 2.0 · ARKONIS