Your first plugin
You will build ops-tools: a plugin with a tool that reports disk space and system facts, and an agent, ops-helper, that answers questions about the machine it runs on. Because the tool runs on the job's home node, the answer is about that node.
You need the binaries and the runtime bundle from the Quickstart, and an Anthropic key for the agent.
Scaffold it
orchestrator-zero plugin new ops-tools --template python-agent \
--description "Answers questions about the machine it runs on"
cd ops-tools
ops-tools/
├── oz0-plugin.yaml the manifest
├── pyproject.toml the Python project (mcp==2.2.0)
├── agents/ops-tools.yaml the agent
├── prompts/ops-tools.md its instructions
├── skills/ops-tools/SKILL.md
└── src/ops_tools/server.py the MCP server
Write the tool
Replace src/ops_tools/server.py. Every @server.tool() function becomes a function agents can call as ops_tools.<function>; its docstring and type hints tell the model what it does.
"""MCP server for ops-tools: facts about the machine it runs on."""
import os
import platform
import shutil
from mcp.server import MCPServer
server = MCPServer("ops-tools")
@server.tool()
def disk_usage(path: str = "/") -> dict:
"""Total, used and free space of the disk that holds path, in gigabytes."""
total, used, free = shutil.disk_usage(path)
gb = 1024**3
return {
"path": path,
"total_gb": round(total / gb, 1),
"used_gb": round(used / gb, 1),
"free_gb": round(free / gb, 1),
}
@server.tool()
def system_info() -> dict:
"""Host name, operating system, architecture and number of CPUs of this machine."""
return {
"host": platform.node(),
"os": platform.system(),
"release": platform.release(),
"arch": platform.machine(),
"cpus": os.cpu_count(),
}
def main() -> None:
server.run("stdio")
if __name__ == "__main__":
main()
Keep the tool on the home node
The template sets affinity: any, which lets the tool run on any node. A tool about this machine must run where the job runs, so remove that line and the default, node, applies:
apiVersion: oz0/v1
name: ops-tools
version: 0.1.0
description: Answers questions about the machine it runs on
runtime: python
tools:
- id: ops_tools
mcp: ["python", "-m", "ops_tools.server"]
agents: [agents/]
skills: [skills/]
Write the agent
Rename the agent and give it the two functions:
name: ops-helper
description: Answers questions about the machine it runs on
runtime: pydantic-ai
model:
primary: anthropic/claude-sonnet-5-5
fallback: [anthropic/claude-haiku-4-5]
instructions: prompts/ops-tools.md
tools: [ops_tools.disk_usage, ops_tools.system_info]
limits:
max_steps: 10
max_tokens: 50000
timeout: 2m
You are ops-helper. You answer questions about the machine you run on.
Use ops_tools.system_info and ops_tools.disk_usage to get facts; never guess them.
Answer in two or three sentences and name the host.
Update skills/ops-tools/SKILL.md to say when to use the two functions.
Lint and run it
uv lock
orchestrator-zero plugin lint
orchestrator-zero dev
plugin lint runs the same checks the edge runs before an install: unknown fields are errors, so a typo does not pass. dev prints the export OZ0_CONTEXT=... line and ops-tools ... ready in ...: ops_tools.disk_usage, ops_tools.system_info. In a second terminal:
export OZ0_CONTEXT=... # the line dev printed
printf %s "$ANTHROPIC_API_KEY" | orchestrator-zero secret set ANTHROPIC_API_KEY
orchestrator-zero run ops-helper "How much free disk does this machine have?"
The agent calls ops_tools.system_info and ops_tools.disk_usage on the node that picked up the job, and answers with that machine's numbers.
Publish it
A plugin installs from Git. Commit it, tag a release and push it to a repository the edge can reach:
git init -b main && git add . && git commit -m "ops-tools 0.1.0"
git tag v0.1.0
git remote add origin https://github.com/your-org/ops-tools.git
git push -u origin main --tags
Then, against your cluster:
orchestrator-zero plugin install https://github.com/your-org/ops-tools
orchestrator-zero catalog
Every node of the tenant builds it and starts the tool, and ops-helper can run anywhere in the fleet. Ask it from different nodes' points of view by giving them labels and requiring one in the agent (see Routing).
Next
- Tools: affinity, environment and what the model sees.
- Agents: every field of an agent definition.
- Develop and test: the dev loop and calling a tool directly.
- Publish and version: refs, tags and pinning.