Monithub가 Prometheus MCP 서버와 통신하는 방법
본 문서는 우리 Monithub 백엔드(Golang), Prometheus MCP 서버(Python), 그리고 LLM(Ollama/Gemini) 간의 통신 프로토콜과 메시지 포맷에 대해 설명하는 문서입니다.

1. 시스템 아키텍처
백엔드 (Client): 모델 컨텍스트 프로토콜(MCP) 클라이언트 역할을 수행합니다. Stdio 또는 SSE 전송 방식을 사용하여 MCP 서버에 연결합니다.
Prometheus MCP 서버: Prometheus의 기능(쿼리, 메타데이터, 메트릭 목록 조회)을 “도구(Tools)” 형태로 노출합니다.
LLM: 추론 엔진입니다. 백엔드가 준비한 컨텍스트 객체(메트릭, 값)를 수신하여 자연어 응답이나 JSON 설정을 생성합니다.
2. 통신 프로토콜: JSON-RPC 2.0 (MCP)
백엔드와 MCP 서버 간의 상호작용은 Model Context Protocol (MCP) 사양을 따르며, JSON-RPC 2.0 메시지를 사용합니다.
공통 메시지 구조
요청 (Client -> Server):
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "tool_name",
"arguments": { ... }
}
}응답 (Server -> Client):
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "..."
}
]
}
}3. 상세 통신 예시
시나리오 1: 사용자가 “내 서버의 현재 CPU 사용량은 얼마야?“라고 질문했을 때
1단계: 백엔드 초기화 및 도구 탐색 (Tool Discovery)
백엔드가 채팅 요청 처리를 시작할 때, 먼저 MCP 서버로부터 사용 가능한 도구들을 탐색합니다.
백엔드 -> MCP 서버 (tools/list):
{
"jsonrpc": "2.0",
"id": 101,
"method": "tools/list"
}MCP 서버 -> 백엔드:
{
"jsonrpc": "2.0",
"id": 101,
"result": {
"tools": [
{
"name": "list_metrics",
"description": "List all available metrics in Prometheus...",
"inputSchema": { ... }
},
{
"name": "execute_query",
"description": "Execute a PromQL instant query...",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
}
}
]
}
}2단계: 컨텍스트 수집 (메트릭 조회)
백엔드는 list_metrics를 호출하여 관련 메트릭 이름들을 LLM의 시스템 프롬프트에 주입할 준비를 합니다.
백엔드 -> MCP 서버 (call_tool: list_metrics):
{
"jsonrpc": "2.0",
"id": 102,
"method": "tools/call",
"params": {
"name": "list_metrics",
"arguments": {}
}
}MCP 서버 -> 백엔드:
{
"jsonrpc": "2.0",
"id": 102,
"result": {
"content": [
{
"type": "text",
"text": "{\"metrics\": [\"node_cpu_seconds_total\", \"node_memory_MemTotal_bytes\", \"container_cpu_usage_seconds_total\", ...]}"
}
]
}
}3단계: LLM 프롬프트 구성
백엔드는 MCP로부터 가져온 데이터를 통합하여 시스템 프롬프트를 구성합니다.
백엔드 -> LLM (프롬프트 전송):
SYSTEM:
You are Monithub AI, a specialized dashboard generator.
Current available metrics in Prometheus:
[
"node_cpu_seconds_total",
"node_memory_MemTotal_bytes"
]
[KNOWLEDGE BASE]
- Title: CPU Usage, Expr: 100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100), Unit: percent
User Request: "What is the current CPU usage of my server?"
INSTRUCTIONS:
... (PromQL 문법, 집계 규칙 등에 대한 지침) ...4단계: 데이터 검증 (옵션/동적)
사용자가 구체적인 값을 물었거나 대시보드에 현재 데이터를 보여줘야 하는 경우, 백엔드는 execute_query를 호출하여 실제 값을 가져와 컨텍스트에 포함시킬 수 있습니다.
백엔드 -> MCP 서버 (call_tool: execute_query):
{
"jsonrpc": "2.0",
"id": 103,
"method": "tools/call",
"params": {
"name": "execute_query",
"arguments": {
"query": "100 - (avg(rate(node_cpu_seconds_total{mode='idle'}[5m])) * 100)"
}
}
}MCP 서버 -> 백엔드:
{
"jsonrpc": "2.0",
"id": 103,
"result": {
"content": [
{
"type": "text",
"text": "{\"status\":\"success\",\"data\":{\"resultType\":\"vector\",\"result\":[{\"value\":[1715660000,\"12.5\"]}]}}"
}
]
}
}5단계: 최종 응답 생성
LLM은 제공된 컨텍스트를 사용하여 최종 응답을 생성합니다.
LLM -> 백엔드:
The current CPU usage of your server is approximately **12.5%**.
I used the following query to calculate this:
`100 - (avg(rate(node_cpu_seconds_total{mode='idle'}[5m])) * 100)`