Skip to content

Expose functions as MCP tools

Add an mcp facade to a function-mode AgentRuntime so other Omnia agents and external MCP clients can call the function as a typed tool. The pod serves Streamable HTTP MCP next to POST /functions/{name}, advertising one tool whose inputSchema is the function’s spec.inputSchema.

  • A function-mode AgentRuntime. See Define Functions.
  • spec.externalAuth configured on it. Without it the external listener’s validator chain is empty and rejects every request with a 401. See Configure Authentication.

List an mcp facade beside the rest facade. The entry turns the MCP server on, and mcp.port defaults to 9998.

apiVersion: omnia.altairalabs.ai/v1alpha1
kind: AgentRuntime
metadata:
name: weather-lookup
spec:
mode: function
promptPackRef:
name: weather-pack
facades:
- type: rest
port: 8080
- type: mcp
mcp:
port: 9998
inputSchema:
type: object
required: ["latitude", "longitude"]
properties:
latitude: { type: "number" }
longitude: { type: "number" }
outputSchema:
type: object
required: ["temperature_celsius", "conditions"]
properties:
temperature_celsius: { type: "number" }
conditions: { type: "string" }

The Service exposes port 8080 for POST /functions/{name} and port 9998 for MCP. The dashboard’s /functions catalog shows an MCP badge on functions that have an mcp facade.

If the function’s inputSchema root uses oneOf, anyOf, allOf, not, $ref, if, enum, const or a non-object type, callers send the input under arguments.input. See Schema adaptation.

Add the endpoint as an mcp handler in a ToolRegistry, then reference that registry from the consuming agent’s spec.toolRegistryRef:

apiVersion: omnia.altairalabs.ai/v1alpha1
kind: ToolRegistry
metadata:
name: weather-tools
spec:
handlers:
- name: weather
type: mcp
mcpConfig:
transport: streamable-http
endpoint: http://weather-lookup.default.svc.cluster.local:9998/mcp
auth:
type: bearer
secretRef:
name: weather-token
key: token

The consuming agent’s PromptPack must list the tool in a prompt’s tools. See Connect MCP servers for the handler fields.

Set expose.enabled: true on the mcp facade entry (it needs the chart’s defaultExposure Gateway, as for any agent). The operator creates an HTTPRoute named <agent>-mcp on <agent>-mcp.<namespace>.<baseDomain>, routed to the agent’s Service on port 9998; set expose.host on that entry to override the hostname. Without a default-exposure Gateway, create an HTTPRoute yourself whose backendRef names the agent’s Service on port 9998. Either way, once the operator observes the route, status.facade.endpoints lists an entry with protocol: mcp. Point the client at that URL with the Bearer token:

{
"mcpServers": {
"weather-lookup": {
"url": "<url from status.facade.endpoints>",
"headers": { "Authorization": "Bearer <token>" }
}
}
}

A tool call on the external listener is cancelled after 30 seconds. For longer work, set facades[].async and call POST /functions/{name}?mode=async.

Port-forward the Service and list the tools with a token your spec.externalAuth accepts:

Terminal window
kubectl port-forward svc/weather-lookup 9998:9998
Terminal window
curl -s -X POST http://localhost:9998/mcp \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

The result holds one tool, named after the AgentRuntime in lower case, with the inputSchema and outputSchema from the spec. To confirm the management-plane twin:

Terminal window
kubectl get agentruntime weather-lookup \
-o jsonpath='{.status.managementEndpoints.mcp}'

The command prints 19998.

SymptomCause
401 from an external clientspec.externalAuth is unset or does not accept the token
403 origin not allowedA browser sent an Origin outside the allowed list. See Origin check
isError: true resultThe text starts with the outcome. See Errors
Legacy SSE client cannot connectThe server supports Streamable HTTP only
Client needs several functionsEach pod serves one function as one tool; connect to each endpoint