Tools¶
A LanguageTool is an MCP-compatible service that agents call to do things beyond generating text — query a database, search the web, run code, read files. The operator manages the Deployment and Service, discovers what the tool can do, and injects its endpoint into every agent that references it.
How it works¶
When you create a LanguageTool, the operator:
- Deploys the tool image as a standard Kubernetes Deployment and Service
- Waits for the pod to become ready, then calls
tools/listto discover what the tool exposes - Stores the discovered schemas in
status.toolSchemas - Injects the tool's endpoint into every referencing agent via
/etc/agent/config.yaml
Agents connect to tools directly over MCP — the operator doesn't proxy or inspect tool traffic.
Deploying a tool¶
A LanguageTool is self-contained. You provide an image; the operator creates the Deployment and Service:
apiVersion: langop.io/v1alpha1
kind: LanguageTool
metadata:
name: mem0-memory
namespace: language-operator-myapp
spec:
image: myregistry/mem0-mcp:latest
port: 8080
That's enough to get a running tool with an in-cluster endpoint at http://mem0-memory.language-operator-myapp.svc.cluster.local:8080.
The deploymentMode field controls whether the tool runs as a shared service (default) or as a sidecar inside each agent pod:
service— one Deployment shared across all agents that reference the tool. Good for stateless tools.sidecar— injected into each agent pod. Gets access to the agent's workspace volume. Good for tools that need per-agent state.
MCP protocol¶
The tool must implement MCP on the port defined in spec.port. The operator calls two methods: tools/list for schema discovery, and agents call tools/call at runtime.
Tool listing¶
POST /mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {}}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "remember",
"description": "Store information in long-term memory",
"inputSchema": {
"type": "object",
"properties": {
"content": { "type": "string", "description": "Information to remember" },
"tags": { "type": "array", "items": { "type": "string" } }
},
"required": ["content"]
}
}
]
}
}
Tool invocation¶
POST /mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "remember",
"arguments": { "content": "User prefers metric units", "tags": ["preferences"] }
}
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [{ "type": "text", "text": "Stored successfully." }]
}
}
Health check¶
The operator uses GET /health to determine when the tool is ready before attempting schema discovery:
Error responses¶
Tool errors should use MCP error format rather than HTTP error status codes:
{
"jsonrpc": "2.0",
"id": 2,
"error": {
"code": -32603,
"message": "Memory store unavailable",
"data": { "reason": "connection refused" }
}
}
| Code | Meaning |
|---|---|
-32700 |
Parse error |
-32600 |
Invalid request |
-32601 |
Method not found |
-32602 |
Invalid params |
-32603 |
Internal error |
How agents receive tool endpoints¶
The operator writes each tool's endpoint into the referencing agent's /etc/agent/config.yaml under the tools: key:
tools:
mem0-memory:
endpoint: http://mem0-memory.language-operator-myapp.svc.cluster.local:8080
protocol: mcp
Runtime adapters (like openclaw-adapter and opencode-adapter) read this file and translate it into their runtime's native tool configuration before the agent starts.
Checklist¶
A compliant tool image must:
- [ ] Implement MCP JSON-RPC at the port defined in
spec.port - [ ] Respond to
tools/listwith all available tools and their input schemas - [ ] Respond to
tools/callwith the result of invoking the named tool - [ ] Expose
GET /healthreturning200 OKwith{"status":"ok"}when ready - [ ] Return MCP error objects for failures, not HTTP error status codes