- internal/rm/client.go: YARN RM 客户端 - ListApps / GetApp / KillApp / GetLogs - GetLogs 降级链数据驱动 (amContainerLogs → aggregated-logs → logs) - 跨主机 redirect 保留 Authorization (URLAllowlist 兜底) - 4 Tool: list_applications / get_application_status / get_application_logs / kill_application - mcp.WithEnum(state) 约束 YARN app 状态 - tool handler 永远 (result, nil), 业务错误用 NewToolResultError - deps.go: +HTTPClient + MaxResponseBytes - main.go: 注入 httpclient.Client - 端到端实测: mock RM 验证 4 Tool + 降级链 + 错误路径 Co-Authored-By: Claude <noreply@anthropic.com>
61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
package tools
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/mark3labs/mcp-go/mcp"
|
|
|
|
"spark-mcp-go/internal/rm"
|
|
)
|
|
|
|
const GetApplicationStatusName = "get_application_status"
|
|
|
|
// NewGetApplicationStatusTool returns the schema for the get_application_status MCP Tool.
|
|
func NewGetApplicationStatusTool() mcp.Tool {
|
|
return mcp.NewTool(GetApplicationStatusName,
|
|
mcp.WithDescription("Get the detailed status of a single YARN application from the ResourceManager. Returns the raw RM JSON for the app."),
|
|
mcp.WithString("cluster_id",
|
|
mcp.Required(),
|
|
mcp.Description("ID of the configured cluster (from list_clusters)"),
|
|
),
|
|
mcp.WithString("app_id",
|
|
mcp.Required(),
|
|
mcp.Description("YARN application ID, e.g. application_1234567890_0001"),
|
|
),
|
|
)
|
|
}
|
|
|
|
// GetApplicationStatusHandler fetches a single application's details.
|
|
func (d *Deps) GetApplicationStatusHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
|
clusterID, err := req.RequireString("cluster_id")
|
|
if err != nil {
|
|
return errResult("get_application_status: " + err.Error()), nil
|
|
}
|
|
appID, err := req.RequireString("app_id")
|
|
if err != nil {
|
|
return errResult("get_application_status: " + err.Error()), nil
|
|
}
|
|
|
|
callLog := startToolCall(ctx, d.Logger, GetApplicationStatusName, map[string]any{
|
|
"cluster_id": clusterID,
|
|
"app_id": appID,
|
|
})
|
|
defer callLog.End()
|
|
|
|
cl, err := d.ClusterRepo.Get(ctx, clusterID)
|
|
if err != nil {
|
|
callLog.WithError(err)
|
|
return errResult("get_application_status: cluster " + clusterID + ": " + err.Error()), nil
|
|
}
|
|
|
|
rmc := rm.New(d.HTTPClient, cl)
|
|
raw, err := rmc.GetApp(ctx, appID)
|
|
if err != nil {
|
|
callLog.WithError(err)
|
|
return errResult("get_application_status: " + err.Error()), nil
|
|
}
|
|
|
|
callLog.WithResult(map[string]any{"bytes": len(raw)})
|
|
return textResult(string(raw)), nil
|
|
}
|