Files
ops-mcp/internal/tool/docker.go
T
yangzhaohan 093511bbdd 精简项目:只保留 docker_logs + health + info 三个工具
- 移除 database/middleware 等复杂模块,先聚焦核心功能
- docker_logs:封装 docker logs --tail N <container>
- 修复 go.mod 版本为 1.24 匹配 Docker 构建镜像
- Dockerfile 改用 alpine + docker-cli,避免 scratch 无 shell 问题
- docker-compose.yml 简化为单服务定义

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-06 10:42:23 +08:00

89 lines
2.1 KiB
Go

package tool
import (
"bytes"
"context"
"fmt"
"log/slog"
"os/exec"
"strconv"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
// DockerTool 提供 docker logs 查询。
type DockerTool struct{}
func NewDockerTool() *DockerTool {
return &DockerTool{}
}
func (d *DockerTool) Name() string { return "docker" }
func (d *DockerTool) Description() string { return "Docker 容器日志查询" }
func (d *DockerTool) Initialize(_ context.Context) error {
if _, err := exec.LookPath("docker"); err != nil {
return fmt.Errorf("docker CLI not found: %w", err)
}
slog.Info("docker CLI ready")
return nil
}
func (d *DockerTool) Shutdown(_ context.Context) error { return nil }
func (d *DockerTool) HealthCheck(ctx context.Context) error {
return exec.CommandContext(ctx, "docker", "version").Run()
}
func (d *DockerTool) Register(mcpServer *server.MCPServer) error {
mcpServer.AddTool(mcp.NewTool("docker_logs",
mcp.WithDescription("获取 Docker 容器日志,等价于 docker logs --tail N <container>"),
mcp.WithString("container",
mcp.Required(),
mcp.Description("容器名称或 ID"),
),
mcp.WithNumber("tail",
mcp.Description("返回最后 N 行日志,默认 100"),
),
), d.handleLogs)
return nil
}
func (d *DockerTool) handleLogs(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
args := getArgs(req)
container, _ := args["container"].(string)
if container == "" {
return mcp.NewToolResultError("container 参数必填"), nil
}
tail := 100
if t, ok := args["tail"].(float64); ok && t > 0 {
tail = int(t)
}
cmd := exec.CommandContext(ctx, "docker", "logs",
"--tail", strconv.Itoa(tail),
"--timestamps",
container,
)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return mcp.NewToolResultError(
fmt.Sprintf("docker logs 失败: %v\n%s", err, stderr.String()),
), nil
}
output := stdout.String()
if output == "" {
output = "(容器没有日志输出)"
}
return mcp.NewToolResultText(output), nil
}