Skip to content

Commit c286a8b

Browse files
committed
upload: v0.1 code
0 parents  commit c286a8b

File tree

14 files changed

+1304
-0
lines changed

14 files changed

+1304
-0
lines changed

.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# If you prefer the allow list template instead of the deny list, see community template:
2+
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3+
#
4+
# Binaries for programs and plugins
5+
*.exe
6+
*.exe~
7+
*.dll
8+
*.so
9+
*.dylib
10+
11+
# Test binary, built with `go test -c`
12+
*.test
13+
14+
# Output of the go coverage tool, specifically when used with LiteIDE
15+
*.out
16+
17+
# Dependency directories (remove the comment below to include it)
18+
# vendor/
19+
20+
# Go workspace file
21+
go.work
22+
go.work.sum
23+
24+
# env file
25+
.env

Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM golang:1.24.2-alpine as builder
2+
WORKDIR /data/prometheus-mcp-server-code
3+
ENV GOPROXY=https://goproxy.cn
4+
RUN apk add --no-cache upx ca-certificates tzdata
5+
COPY ./go.mod ./
6+
COPY ./go.sum ./
7+
RUN go mod download
8+
COPY . .
9+
RUN CGO_ENABLED=0 go build -ldflags "-s -w" -o prometheus-mcp-server
10+
11+
FROM golang:1.24.2-alpine as runner
12+
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
13+
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
14+
COPY --from=builder /data/prometheus-mcp-server-code/prometheus-mcp-server /prometheus-mcp-server
15+
EXPOSE 8000
16+
CMD ["/prometheus-mcp-server"]

LICENSE

Lines changed: 674 additions & 0 deletions
Large diffs are not rendered by default.

README-zh.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Prometheus MCP Server
2+
[Model Context Protocol][mcp] 这是一个基于Golang开发的Prometheus-MCP-Server,目前只支持sse运行模式
3+
![img.png](docs/cursor.png)
4+
5+
[mcp]: https://modelcontextprotocol.io
6+
7+
## 功能
8+
- [x] Prometheus MCP Tools
9+
- [x] 列出可用指标 (prometheus_list_metrics)
10+
- [x] 发现并探索指标 (prometheus_get_targets)
11+
- [x] 获取特定指标的元数据 (prometheus_get_metric_metadata)
12+
- [x] 查看即时查询结果 (prometheus_execute_query)
13+
- [x] 查看不同步长间隔的范围查询结果 (prometheus_execute_range_query)
14+
- [x] 查看最近时长查询结果 (prometheus_execute_last_query)
15+
- [x] 支持身份验证
16+
- [x] 通过环境变量进行基本身份验证
17+
- [x] 通过环境变量进行 Bearer Token 身份验证
18+
- [x] 支持 Docker 容器化
19+
20+
## 使用方法
21+
22+
1. 确保你的prometheus-mcp-server容器可以与prometheus-server通信.
23+
24+
2. 使用以下命令运行prometheus-mcp-server容器
25+
26+
```bash
27+
# 默认以sse方式运行mcp-server (prometheus无认证)
28+
# 如需stdio模式,请自行将 MCP_SERVER_TRANSPORT=sse 修改为 MCP_SERVER_TRANSPORT=stdio
29+
docker run -d --name prometheus-mcp-server \
30+
-e PROMETHEUS_URL=http://your-prometheus-server:9090 \
31+
-e MCP_SERVER_TRANSPORT=sse \
32+
shaxiaozz/prometheus-mcp-server:latest
33+
```
34+
35+
```bash
36+
# 默认以sse方式运行mcp-server (prometheus basic auth)
37+
# 如需stdio模式,请自行将 MCP_SERVER_TRANSPORT=sse 修改为 MCP_SERVER_TRANSPORT=stdio
38+
docker run -d --name prometheus-mcp-server \
39+
-e PROMETHEUS_URL=http://your-prometheus-server:9090 \
40+
-e PROMETHEUS_USERNAME=your_username \
41+
-e PROMETHEUS_PASSWORD=your_password \
42+
-e MCP_SERVER_TRANSPORT=sse \
43+
shaxiaozz/prometheus-mcp-server:latest
44+
```
45+
46+
```bash
47+
# 默认以sse方式运行mcp-server (prometheus token auth)
48+
# 如需stdio模式,请自行将 MCP_SERVER_TRANSPORT=sse 修改为 MCP_SERVER_TRANSPORT=stdio
49+
docker run -d --name prometheus-mcp-server \
50+
-e PROMETHEUS_URL=http://your-prometheus-server:9090 \
51+
-e PROMETHEUS_TOKEN=your_token \
52+
-e MCP_SERVER_TRANSPORT=sse \
53+
shaxiaozz/prometheus-mcp-server:latest
54+
```
55+
56+
3. 将服务器配置添加到客户端配置文件中。例如,Cursor Desktop:
57+
58+
url可直接通过命令: ```docker logs prometheus-mcp-server``` 查看
59+
```json
60+
{
61+
"mcpServers": {
62+
"prometheus-mcp-server": {
63+
"url": "http://10.0.0.1:8000/sse"
64+
}
65+
}
66+
}
67+
```
68+
![img.png](docs/cursor.png)
69+
70+
## 构建镜像
71+
```bash
72+
git clonse https://github.com/shaxiaozz/prometheus-mcp-server.git && cd prometheus-mcp-server
73+
docker build -t prometheus-mcp-server .
74+
```
75+
76+
## 致谢
77+
- [mark3labs/mcp-go](https://github.com/mark3labs/mcp-go)
78+
- [pab1it0/prometheus-mcp-server](https://github.com/pab1it0/prometheus-mcp-server)
79+
80+
## License
81+
GNU v3.0

config/config.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package config
2+
3+
import (
4+
"log"
5+
"os"
6+
)
7+
8+
var Config config
9+
var (
10+
PrometheusUrl, PrometheusUserName, PrometheusPassword, PrometheusToken, McpServerTransport string
11+
)
12+
13+
type config struct {
14+
}
15+
16+
func (c *config) InitConfig() {
17+
if os.Getenv("PROMETHEUS_URL") == "" {
18+
log.Fatalf("PROMETHEUS_URL env variable not set")
19+
} else {
20+
PrometheusUrl = os.Getenv("PROMETHEUS_URL")
21+
}
22+
23+
if os.Getenv("PROMETHEUS_USERNAME") != "" {
24+
PrometheusUserName = os.Getenv("PROMETHEUS_USERNAME")
25+
}
26+
27+
if os.Getenv("PROMETHEUS_PASSWORD") != "" {
28+
PrometheusPassword = os.Getenv("PROMETHEUS_PASSWORD")
29+
}
30+
31+
if os.Getenv("PROMETHEUS_TOKEN") != "" {
32+
PrometheusToken = os.Getenv("PROMETHEUS_TOKEN")
33+
}
34+
35+
if os.Getenv("MCP_SERVER_TRANSPORT") == "" {
36+
McpServerTransport = "sse"
37+
} else {
38+
McpServerTransport = os.Getenv("MCP_SERVER_TRANSPORT")
39+
}
40+
}

docs/cursor.png

33.6 KB
Loading

go.mod

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module github.com/shaxiaozz/prometheus-mcp-server
2+
3+
go 1.24.2
4+
5+
require github.com/mark3labs/mcp-go v0.23.0
6+
7+
require (
8+
github.com/google/uuid v1.6.0 // indirect
9+
github.com/spf13/cast v1.7.1 // indirect
10+
github.com/wonderivan/logger v1.0.0 // indirect
11+
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
12+
)

go.sum

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
4+
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
5+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
6+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
7+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
8+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
9+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
10+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
11+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
12+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
13+
github.com/mark3labs/mcp-go v0.23.0 h1:NmtoPx4jf7if7bfAynocpVdpXqX5U8X/18c1gddK/QA=
14+
github.com/mark3labs/mcp-go v0.23.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4=
15+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
16+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
17+
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
18+
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
19+
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
20+
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
21+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
22+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
23+
github.com/wonderivan/logger v1.0.0 h1:Z6Nz+3SNcizolx3ARH11axdD4DXjFpb2J+ziGUVlv/U=
24+
github.com/wonderivan/logger v1.0.0/go.mod h1:NObMfQ3WOLKfYEZuGeZQfuQfSPE5+QNgRddVMzsAT/k=
25+
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
26+
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
27+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
28+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/mark3labs/mcp-go/server"
6+
"github.com/shaxiaozz/prometheus-mcp-server/config"
7+
"github.com/shaxiaozz/prometheus-mcp-server/prometheus"
8+
"github.com/shaxiaozz/prometheus-mcp-server/utils"
9+
"github.com/wonderivan/logger"
10+
"log"
11+
)
12+
13+
func init() {
14+
config.Config.InitConfig()
15+
}
16+
17+
var (
18+
Version = utils.Version
19+
)
20+
21+
func newMCPServer() *server.MCPServer {
22+
return server.NewMCPServer(
23+
"github.com/shaxiaozz/prometheus-mcp-server",
24+
Version,
25+
server.WithToolCapabilities(true),
26+
server.WithResourceCapabilities(true, true),
27+
server.WithLogging(),
28+
server.WithRecovery(),
29+
)
30+
}
31+
32+
func addTools(s *server.MCPServer) {
33+
s.AddTool(prometheus.HelloWorldTool, prometheus.HelloWorldToolHandle) // Say hello to someone
34+
s.AddTool(prometheus.ListMetricsTool, prometheus.ListMetricsToolHandle) // List all available metrics in Prometheus
35+
s.AddTool(prometheus.GetTargetsTool, prometheus.GetTargetsToolHandle) // Get information about all scrape targets
36+
s.AddTool(prometheus.GetMetricMetadataTool, prometheus.GetMetricMetadataToolHandle) // Get metadata for a specific metric
37+
s.AddTool(prometheus.ExecuteQueryTool, prometheus.ExecuteQueryToolHandle) // Execute a PromQL instant query against Prometheus
38+
s.AddTool(prometheus.ExecuteRangeQueryTool, prometheus.ExecuteRangeQueryToolHandle) // Execute a PromQL range query with start time, end time, and step interval.
39+
s.AddTool(prometheus.ExecuteLastQueryTool, prometheus.ExecuteLastQueryToolHandle) // Executes a PromQL range query with a recent time and a step interval. The recent time is in minutes
40+
}
41+
42+
func runServer(transport string) error {
43+
mcpServer := newMCPServer()
44+
addTools(mcpServer)
45+
ipAddr := utils.GetIPAddr()
46+
address := ipAddr + ":8000"
47+
48+
if transport == "sse" {
49+
logger.Info("SSE server listening on http://" + address)
50+
sseServer := server.NewSSEServer(mcpServer, server.WithBaseURL("http://"+address))
51+
if err := sseServer.Start(address); err != nil {
52+
log.Fatalf("Server error: %v", err)
53+
}
54+
} else {
55+
logger.Info("Run Stdio server")
56+
if err := server.ServeStdio(mcpServer); err != nil {
57+
log.Fatalf("Server error: %v", err)
58+
}
59+
}
60+
return nil
61+
}
62+
63+
func main() {
64+
if err := runServer(config.McpServerTransport); err != nil {
65+
fmt.Printf("server run error: %v\n", err)
66+
panic(err)
67+
}
68+
}

prometheus/hello_world.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package prometheus
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
"github.com/mark3labs/mcp-go/mcp"
8+
"github.com/wonderivan/logger"
9+
)
10+
11+
const (
12+
HelloWorld = "hello_world"
13+
)
14+
15+
var HelloWorldTool = mcp.NewTool(HelloWorld, mcp.WithDescription(
16+
"Say hello to someone"))
17+
18+
func HelloWorldToolHandle(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
19+
logger.Info("Call HelloWorldToolHandle")
20+
name, ok := request.Params.Arguments["name"].(string)
21+
if !ok {
22+
return nil, errors.New("name must be a string")
23+
}
24+
25+
return mcp.NewToolResultText(fmt.Sprintf("Hello, %s!", name)), nil
26+
}

0 commit comments

Comments
 (0)