Live Demo Edition 1

From CLI to MCP
in 20 Minutes

Demystifying MCP Servers

Yaacov Zamir <yzamir@redhat.com>
DevConf.CZ 2026
Agenda 2
This session
includes:
  • Language Models Basic Building Blocks
  • Inference Servers OpenAI API, De Facto Standard
  • Skills or Tools What Is Best for My Use Case
  • From CLI to MCP Adding MCP Support to My CLI
Red Hat
Language Models

Language
Models

  • Text Completion
  • Template Completion
Red Hat
Language Models

Language Models

Base Model, Text Completion

from transformers import AutoModelForCausalLM, AutoTokenizer

model_path = "ibm-granite/granite-4.1-8b-base"
tokenizer = AutoTokenizer.from_pretrained(model_path)
model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto")

prompt = "If you want to migrate a virtual machine to KubeVirt,"
outputs = model.generate(tokenizer(prompt, return_tensors="pt").to("mps"))
print(tokenizer.decode(outputs[0]))
# Output: " you must first prepare the source environment.
#   This book covers migrations from VMware vSphere ..."

* Language models complete texts.

Red Hat
Language Models

Language Models

Text Completion — Predict the Next Word

Language model text completion Red Hat
Language Models

Instruct Model

Fine-Tuned to Follow Instructions

chat = [{"role": "user", "content": "How do I list VM migrations?"}]
prompt = tokenizer.apply_chat_template(chat, add_generation_prompt=True)
print(prompt)
# <|start_header|>user<|end_header|>
# How do I list VM migrations?<|eot|>
# <|start_header|>assistant<|end_header|>
outputs = model.generate(tokenizer(prompt, return_tensors="pt").to("mps"))
print(tokenizer.decode(outputs[0]))

* We can fine-train language models to read hints and play roles.

Red Hat
Language Models

Instruct Model

Fine-Tuned to Complete User–Assistant Templates

Instruct model with user and assistant roles Red Hat
Inference Servers

Inference
Servers

  • Template with Tools
  • From Template to API
  • OpenAI API
Red Hat
Inference Servers

Conversational Mode

What Happens Without Tools?

curl http://localhost:1234/v1/chat/completions -d '{
  "messages": [
    {"role": "user", "content": "Fetch migration plans inside the cluster"}
  ],
  "tools": []
}'
# Output: "I cannot access the cluster directly.
#   Please run: kubectl mtv get plans"

* The /v1/chat/completions endpoint is the OpenAI-compatible API — the de facto standard spoken by LM Studio, vLLM, Ollama, and others.

Red Hat
Inference Servers

Tool Usage

Fine-Tuned to Complete Text by Choosing a Tool

Model using tools to act Red Hat
Inference Servers

Tool Usage

The Request — Including a List of Available Tools

curl http://localhost:1234/v1/chat/completions -d '{
  "messages": [{"role": "user", "content": "Fetch migration plans"}],
  "tools": [{"type": "function", "function": {
    "name": "mtv_read",
    "description": "Query MTV resources (read-only)",
    "parameters": {
      "properties": {"command": {"type": "string"}, "flags": {"type": "object"}},
      "required": ["command"]
    }
  }}]
}'

* This model was trained to use tools and can pick the correct tool for a task.

Red Hat
Inference Servers

Tool Usage

The Response — A Structured Tool Call Instead of Text

{"choices": [{
  "message": {
    "role": "assistant",
    "content": null,
    "tool_calls": [{
      "function": {"name": "mtv_read",
                   "arguments": "{\"command\": \"get plan\"}"}
    }]
  },
  "finish_reason": "tool_calls"
}]}
Red Hat
Skills or Tools

Skills or Tools

  • Do You Really Need Your Own MCP?
  • How to Use Existing Tools
  • How to Write Your Own Tools
Red Hat
Skills or Tools

Bash Tool vs. MCP Server

One Shell to Rule Them All, or Dedicated Servers?

# Bash tool: the agent runs arbitrary commands
bash -c "kubectl mtv get plan | grep -i fail"
# → unrestricted, unpredictable, no schema
// MCP server: the agent calls a typed function
{"method": "tools/call",
 "params": {"name": "mtv_read",
            "arguments": {"command": "get plan"}}}
// → sandboxed, discoverable, self-describing

* Bash is like eval() on untrusted input; MCP is like a type-safe RPC contract. MCP tools are sandboxed, self-describing, and discoverable — no manual scraping needed.

Red Hat
Skills or Tools

Bash Tool vs. MCP Server

Many Tools vs. One Shell with a System Prompt

Bash tool versus MCP server comparison Red Hat
Skills or Tools

Agent-Ready CLIs

Semantic Help for Agentic Flow

$ oc mtv help
Migration Toolkit for Virtualization (MTV) CLI.
Migrate virtual machines from VMware vSphere, oVirt (RHV),
OpenStack, and OVA to KubeVirt on OpenShift/Kubernetes.

Available Commands:
  create      Create resources
  delete      Delete resources
  get         Get resources
  health      Check the health of the MTV/Forklift system
  mcp-server  Start the MCP (Model Context Protocol) server

* AI agents can use --help to learn how to use new CLI commands they don't know.

Red Hat
Skills or Tools

Your First MCP Server

Implementing the Tool Call

from fastmcp import FastMCP
import subprocess

mcp = FastMCP("mtv")

@mcp.tool()
def get_plan(namespace: str = "default") -> str:
    """Get migration plans from the cluster"""
    return subprocess.run(
        ["kubectl", "mtv", "get", "plan", "-n", namespace],
        capture_output=True, text=True).stdout

mcp.run(transport="sse", port=8081)

* MCP (Model Context Protocol) standardizes how tools are discovered and called, regardless of model or server.

Red Hat
From CLI to MCP

From CLI
to MCP

  • From CLI to MCP
  • The MCP Protocol
  • Demo
Red Hat
From CLI to MCP

So You Want to Implement MCP?

Add Custom Code to Your CLI, or Just Automate Using --help

# Scan the CLI's --help output → generate MCP tools
cli2mcp scan kubectl-mtv -o mtv.tools.json

# Start an MCP server exposing those tools (streamable HTTP)
cli2mcp serve mtv.tools.json -t streamable-http
                                    MCP client
                                        |
cli2mcp scan kubectl-mtv  →  .json      |
                               |        |
                          cli2mcp serve <+
                               |
                          subprocess.run(["kubectl-mtv", ...])

* Works with any CLI: auto-detects GNU, Cobra, and plain --help styles.

Red Hat
From CLI to MCP

Establishing the SSE Channel

Step 1

curl -i -N http://localhost:8081/sse
HTTP/1.1 200 OK
Content-Type: text/event-stream
Connection: keep-alive

event: endpoint
data: /message?sessionId=session_9a7c3b21
Red Hat
From CLI to MCP

Handshake and Tool Discovery

Step 2

# Initialize handshake
curl -X POST "$ENDPOINT" -d '{"jsonrpc": "2.0",
  "method": "initialize", "id": 1,
  "params": {"protocolVersion": "2024-11-05",
             "clientInfo": {"name": "demo", "version": "1.0"}}}'

# Discover available tools
curl -X POST "$ENDPOINT" -d '{"jsonrpc": "2.0",
  "method": "tools/list", "id": 2}'
Red Hat
From CLI to MCP

Tool Execution

HTTP vs. CLI

# Path A: via MCP HTTP POST
curl -X POST "$ENDPOINT" -d '{"jsonrpc": "2.0",
  "method": "tools/call", "id": 3,
  "params": {"name": "mtv_read",
             "arguments": {"command": "get plan"}}}'
# Path B: via CLI
kubectl mtv get plans
Red Hat
From CLI to MCP

Live Agent Session

An Agent Picks the Right Tool for the Job

Agent selecting the right tool Red Hat
From CLI to MCP

Live Agent Session

Tracing with mtv-agent

mtv-agent run --dump-http-dir ./dumps

# User: "Why is migration plan 'plan-01' failing?"

# LLM request/response dumps saved to: ./dumps/
# {"model":"instruct", "messages":[...],
#  "tools":[{"name":"mtv_read"}]}
Red Hat
From CLI to MCP

References

Tools Used in This Talk

Red Hat
From CLI to MCP

Cat

A Cat

Cat Red Hat
DevConf.CZ 2026

Thank You

Questions?

Yaacov Zamir <yzamir@redhat.com>
github.com/kubev2v/forklift
Presentation GitHub QR code