> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Demo Your First LangChain MCP Agent

> Demo showing a LangChain-driven agent using an MCP server to run kubectl-like tools against a Kubernetes cluster and produce human friendly reports

Welcome back. This lesson runs a small Python example that uses LangChain to drive an agent which interacts with an MCP server. The example shows how a simple prompt can cause the agent to pick MCP tools, perform a kubectl-like operation against a cluster, and return a human-friendly plain-text answer produced by the LLM.

## What you’ll learn

* How to start an MCP server container configured to talk to a local KinD cluster
* How the sample agent discovers and invokes MCP tools
* How the LLM converts raw tool output into a readable report

## Setup

1. Export the kubeconfig for the kind cluster and save it for use inside Docker:

```bash theme={null}
kind get kubeconfig --name finops-cluster --internal > /tmp/kubeconfig-docker.yaml
```

2. Start the MCP container so it can access the kind network. Replace `IMAGE` with your MCP server image name:

```bash theme={null}
docker run --rm -p 8000:8000 --network kind \
  -v /tmp/kubeconfig-docker.yaml:/home/appuser/.kube/config:ro \
  -e ENABLE_UNSAFE_STREAMABLE_HTTP_TRANSPORT=1 \
  -e PORT=8000 \
  -e HOST=0.0.0.0 \
  IMAGE
```

## Files in this example

| File | Purpose |
| - | - |
| `query_agent.py` | Small entrypoint script that sends a prompt to the LangChain agent and prints the result. |
| `mcp_client.py` | MCP-specific wrapper that handles server connection, tool discovery, tool invocation, and integration with the LLM. |

## The script we run

Here’s the visible entrypoint script (query\_agent.py). It builds a short prompt and calls into the MCP client to run the agent asynchronously.

```python theme={null}
"""Prompt -> LangChain agent -> MCP tools -> plain-text answer."""
import asyncio

from mcp_client import run_agent

PROMPT = "List all namespaces"

async def main() -> None:
    print(await run_agent(PROMPT))

if __name__ == "__main__":
    asyncio.run(main())
```

This prompt is intentionally minimal to demonstrate the end-to-end flow. For production use, prefer structured prompt templates and explicit instructions so outputs are consistent and auditable.

## High-level flow (what the script does)

1. Builds the prompt (here: "List all namespaces").
2. Calls `run_agent`, which:
   * Connects to the configured MCP server.
   * Enumerates available tools exposed by the MCP server.
   * Selects an appropriate tool (for example, `kubectl_get`).
   * Executes the tool against the target cluster and captures the result (JSON or text).
   * Sends the raw tool result to the LLM to create a human-friendly report.
3. Prints the final output to stdout.

## Run the agent

From the project directory run:

```bash theme={null}
python3 query_agent.py
```

## Observed logs and output

Below is an example of the logs and the final LLM-generated answer observed when running the script against a local MCP listening on `http://localhost:8000/mcp`. These logs show connection setup, tool discovery, tool invocation, and the final LLM call.

```text theme={null}
[INFO] MCP server "k8s": initializing with: {'url': 'http://localhost:8000/mcp', 'transport': 'streamable_http'}
[INFO] MCP server "k8s": Pre-validating authentication
[INFO] HTTP Request: POST http://localhost:8000/mcp "HTTP/1.1 200 OK"
[INFO] MCP server "k8s": Authentication validation passed: 200
[INFO] MCP server "k8s": connecting via Streamable HTTP (explicit) to http://localhost:8000/mcp
[INFO] HTTP Request: POST http://localhost:8000/mcp "HTTP/1.1 200 OK"
[INFO] Negotiated protocol version: 2025-11-25
[INFO] MCP server "k8s": connected
[INFO] HTTP Request: POST http://localhost:8000/mcp "HTTP/1.1 202 Accepted"
[INFO] HTTP Request: POST http://localhost:8000/mcp "HTTP/1.1 200 OK"
[INFO] MCP server "k8s": 8 tool(s) available:
[INFO] - kubectl_get
[INFO] - kubectl_describe
[INFO] - kubectl_logs
[INFO] - kubectl_context
[INFO] - kubectl_reconnect
[INFO] - explain_resource
[INFO] - list_api_resources
[INFO] - ping
[INFO] MCP servers initialized: 8 tool(s) available in total
[INFO] HTTP Request: POST https://api.ai.kodekloud.com/v1/chat/completions "HTTP/1.1 200 OK"
[INFO] MCP tool "k8s"/"kubectl_get" received input: {'resourceType': 'namespaces', 'name': None, 'namespace': 'default', 'output': 'json', 'allNamespaces': False, 'labelSelector': None, 'fieldSelector': None, 'sortBy': None, 'context': ''}
[INFO] HTTP Request: POST http://localhost:8000/mcp "HTTP/1.1 200 OK"
[INFO] MCP tool "k8s"/"kubectl_get" received result (size: 1618)
[INFO] HTTP Request: POST https://api.ai.kodekloud.com/v1/chat/completions "HTTP/1.1 200 OK"
[INFO] MCP server "k8s": session closed

Here are all the namespaces in the cluster:

1. **airline** - Active (Created: 2026-07-11T04:37:20Z)
2. **booking-api** - Active (Created: 2026-07-11T04:37:20Z)
3. **default** - Active (Created: 2026-07-11T04:36:53Z)
4. **flight-search** - Active (Created: 2026-07-11T04:37:20Z)
5. **inventory** - Active (Created: 2026-07-11T04:37:20Z)
6. **kube-node-lease** - Active (Created: 2026-07-11T04:36:52Z)
7. **kube-public** - Active (Created: 2026-07-11T04:36:52Z)
8. **kube-system** - Active (Created: 2026-07-11T04:36:52Z)
9. **local-path-storage** - Active (Created: 2026-07-11T04:36:57Z)
10. **payment** - Active (Created: 2026-07-11T04:37:20Z)

The cluster has 10 namespaces total. The first 4 system namespaces (kube-node-lease, kube-public, kube-system, local-path-storage) are Kubernetes infrastructure namespaces, while the remaining 6 (airline, booking-api, default, flight-search, inventory, payment) appear to be application-specific namespaces.
(.venv) ➜ k8-finops-agent git:(main) *
```

## Quick notes on the flow

* The agent does not run a local `kubectl` in your environment. Instead, it invokes MCP tools (for example, `kubectl_get`) that run on the MCP server and operate against the cluster configured for that server.
* Raw tool output is forwarded to the LLM, which generates the final human-friendly report printed by the script.
* The LLM endpoint shown in the logs (e.g., `https://api.ai.kodekloud.com/...`) is environment-specific. Configure the LLM provider you use (OpenAI, Anthropic, a self-hosted model, etc.) in your environment.

## Example MCP tools discovered

| Tool name | Typical use |
| - | - |
| `kubectl_get` | Retrieve Kubernetes resources (pods, namespaces, services) in JSON/text |
| `kubectl_describe` | Show detailed resource descriptions |
| `kubectl_logs` | Fetch container logs |
| `kubectl_context` | Inspect or switch cluster context |
| `kubectl_reconnect` | Re-establish a connection to the cluster |
| `explain_resource` | Provide explanations for a resource kind |
| `list_api_resources` | Enumerate available API resources on the cluster |
| `ping` | Health check / connectivity test |

## Next steps and practical extensions

* For FinOps or governance agents, collect labels and annotations across workloads and services. Use structured prompts and scripts to aggregate tags and apply FinOps rules or policy checks.
* Expand the agent’s prompt template to ask for specific data (e.g., costs, owner tags, environment labels) and produce CSV or JSON summaries suitable for automation.
* Add unit tests or integration tests for `mcp_client.py` to validate tool selection and result parsing.

## Links and references

* [Kubernetes Basics](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/)
* [KinD — Kubernetes in Docker](https://kind.sigs.k8s.io/)
* [LangChain documentation](https://python.langchain.com/en/latest/)
* [Docker documentation](https://docs.docker.com/)

If you want, I can also:

* Show an expanded `mcp_client.py` example demonstrating tool discovery and invocation.
* Provide a more robust prompt template for production FinOps agents.

> **[Watch Video](https://learn.kodekloud.com/user/courses/building-kubernetes-finops-ai-agent/module/d9a1ac50-d5f4-4cc1-a8d4-379664950054/lesson/a2a8c9e6-2611-4760-b3a5-eb52ef83c75f)**

> **[Practice Lab](https://learn.kodekloud.com/user/courses/building-kubernetes-finops-ai-agent/module/d9a1ac50-d5f4-4cc1-a8d4-379664950054/lesson/03fa7686-b600-4ecc-9025-68f894fdddf3)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.