How to Use an MCP Server (Without Overthinking It)
# How to Use an MCP Server (Without Overthinking It)
If you've used Claude Desktop, Cursor, or another AI app and connected it to Slack, GitHub, or a database, you've already used MCP — the Model Context Protocol. Here's the short version of what it is and how to actually use one.
## What MCP Is, in One Sentence
MCP is an open standard that lets an AI application (the **host**) talk to external tools and data (via a **server**) through a common language, instead of every app needing a custom integration for every tool.
Three pieces work together:
- **Host** — the app you're using (Claude Desktop, Cursor, etc.)
- **Client** — the connector inside the host that speaks MCP
- **Server** — a lightweight service that exposes specific capabilities: tools to run, resources to read, prompts to reuse
## Using an MCP Server: The Basic Flow
1. **Find a server.** MCP registries and directories list thousands of servers — for GitHub, Postgres, filesystems, Slack, and more.
2. **Connect it to your host.** Most apps have a settings page or config file where you point to the server (a local command for STDIO servers, or a URL for remote ones).
3. **Let the client discover tools.** Once connected, the host automatically lists what the server can do — no manual wiring required.
4. **Use it in conversation.** Ask the AI to do something the server enables ("create a GitHub issue," "query this table"), and it calls the right tool behind the scenes.
## What's New in 2026
The protocol matured a lot this year. The **2026-07-28 specification** made MCP fully stateless at the protocol layer — servers no longer need sticky sessions or a shared session store to run at scale, so they can sit behind an ordinary load balancer. That release also added **MCP Apps** (server-rendered UI components) and **Tasks** (support for long-running work), plus tighter OAuth-based authorization.
Practically, this means remote MCP servers are getting easier to deploy and more reliable to use — good news whether you're connecting to one or building your own.
## Example: A DevOps Engineer Debugging Kubernetes
Here's what MCP looks like in practice. Say an engineer connects a Kubernetes MCP server (several open-source options wrap `kubectl` and expose it as typed tools) to their AI assistant, alongside servers for Prometheus and GitHub.
**The engineer types:** *"The checkout-service pods keep restarting in staging — figure out why and open a PR if it's a config issue."*
Behind the scenes, the assistant:
1. Calls `kubectl_get` and `kubectl_describe` on the pods to see restart counts and recent events
2. Calls `kubectl_logs` to pull the crashing container's logs
3. Cross-checks memory/CPU pressure via a Prometheus tool
4. Finds the pods are hitting an OOM kill from a memory limit set too low in the Helm values
5. Opens a GitHub PR adjusting the resource limits, using a GitHub MCP server tool
No custom script was written for any of this — the engineer just needed the relevant servers connected once. The AI reasons about *what* to check next based on each tool's response, the same way a human would `kubectl describe` after seeing a restart count.
A few practical notes from teams doing this in production:
- **Start read-only.** Most Kubernetes MCP servers default to (or offer) read-only tools — listing, describing, logs — so the AI can diagnose without being able to change anything until you're confident in it.
- **Scope credentials narrowly.** Point the server at a specific kubeconfig context (e.g., staging) rather than a cluster-admin credential.
- **Layer in more servers as trust grows.** Terraform, Helm, and cloud-cost tools are commonly added alongside Kubernetes ones so incidents can be diagnosed across the whole stack in one conversation.
## A Glimpse: Writing Your Own Kubernetes MCP Server
You don't need much code to expose `kubectl` as tools an AI can call. Using the Python SDK's `FastMCP` helper, a minimal read-only Kubernetes server looks like this:
```python
# k8s_server.py
import subprocess
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("Kubernetes DevOps")
def _kubectl(*args: str) -> str:
result = subprocess.run(["kubectl", *args], capture_output=True, text=True)
return result.stdout if result.returncode == 0 else f"Error: {result.stderr}"
@mcp.tool()
def kubectl_get(resource: str, namespace: str = "default") -> str:
"""List Kubernetes resources (e.g. pods, deployments) in a namespace."""
return _kubectl("get", resource, "-n", namespace)
@mcp.tool()
def kubectl_describe(resource: str, name: str, namespace: str = "default") -> str:
"""Describe a specific Kubernetes resource, showing events and status."""
return _kubectl("describe", resource, name, "-n", namespace)
@mcp.tool()
def kubectl_logs(pod: str, namespace: str = "default", tail: int = 100) -> str:
"""Get recent logs from a pod."""
return _kubectl("logs", pod, "-n", namespace, "--tail", str(tail))
if __name__ == "__main__":
mcp.run()
```
That's a working server: three tools, each just a thin, read-only wrapper around `kubectl`. Point it at a specific kubeconfig context via an environment variable before running it, so it can only see the cluster you intend.
To use it, register it with your host — for Claude Desktop, add it to the config file:
```json
{
"mcpServers": {
"kubernetes": {
"command": "python",
"args": ["/path/to/k8s_server.py"]
}
}
}
```
Restart the host, and the three tools show up automatically — no manual schema writing, since the type hints and docstrings *are* the schema. From here, growing it into the full incident-triage workflow from the example above is just a matter of adding more tools (`helm_diff`, `terraform_plan`, a Prometheus query) the same way.
## Should You Build One?
If you have an internal tool, API, or dataset you want an AI assistant to use safely and repeatably, writing a small MCP server is usually simpler than a custom plugin: define your tools, expose them over the protocol, and any MCP-compatible host can use them immediately.
Comments
Post a Comment