Initial commit: omnichannel-mcp — MCP-сервер управления платформой Omnichannel
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"omnichannel-mcp/internal/configserver"
|
||||
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
// overview.go — сводные read-only инструменты для эксплуатации. Они не
|
||||
// изменяют состояние, а собирают картину несколькими GET-вызовами (best-effort:
|
||||
// сбой одного источника не рушит остальные, а попадает в поле errors).
|
||||
|
||||
func registerOverviewTools(s *mcp.Server) {
|
||||
addTool(s, &mcp.Tool{
|
||||
Name: "overview",
|
||||
Description: "Сводка состояния стенда одним вызовом: health, статистика, карта сервисов, приложения не в OK, последние failed-задачи. Read-only.",
|
||||
InputSchema: schema(map[string]any{"server": serverProp()}, nil),
|
||||
}, handleOverview)
|
||||
|
||||
addTool(s, &mcp.Tool{
|
||||
Name: "release_status",
|
||||
Description: "Состояние развёртывания релиза: release_job, release-задачи, приложения, сопоставление IP. Read-only.",
|
||||
InputSchema: schema(map[string]any{"server": serverProp()}, nil),
|
||||
}, handleReleaseStatus)
|
||||
}
|
||||
|
||||
func handleOverview(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
return observeCall(ctx, req, func(api *configserver.API) (any, error) {
|
||||
out := map[string]any{"server": api.Alias(), "read_only": api.Config.ReadOnly}
|
||||
var errs []string
|
||||
|
||||
if status, body, err := api.Health(ctx); err != nil {
|
||||
errs = append(errs, "health: "+err.Error())
|
||||
} else {
|
||||
out["health"] = map[string]any{"http_status": status, "body": body}
|
||||
}
|
||||
if st, err := api.Stats(ctx); err != nil {
|
||||
errs = append(errs, "stats: "+err.Error())
|
||||
} else {
|
||||
out["stats"] = st
|
||||
}
|
||||
if sm, err := api.ServiceMap(ctx); err != nil {
|
||||
errs = append(errs, "service_map: "+err.Error())
|
||||
} else {
|
||||
out["service_map"] = sm
|
||||
}
|
||||
if apps, err := api.ListApplications(ctx, false); err != nil {
|
||||
errs = append(errs, "applications: "+err.Error())
|
||||
} else {
|
||||
out["unhealthy_applications"] = unhealthy(apps)
|
||||
}
|
||||
if tasks, err := api.ListTasks(ctx, configserver.TaskFilter{Status: "failed", Limit: 10}); err != nil {
|
||||
errs = append(errs, "failed_tasks: "+err.Error())
|
||||
} else {
|
||||
out["recent_failed_tasks"] = tasks
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
out["errors"] = errs
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
func handleReleaseStatus(ctx context.Context, req *mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
return observeCall(ctx, req, func(api *configserver.API) (any, error) {
|
||||
out := map[string]any{"server": api.Alias()}
|
||||
var errs []string
|
||||
|
||||
if job, err := api.ReleaseJob(ctx); err != nil {
|
||||
errs = append(errs, "release_job: "+err.Error())
|
||||
} else {
|
||||
out["release_job"] = job
|
||||
}
|
||||
if tasks, err := api.DeploymentTasks(ctx); err != nil {
|
||||
errs = append(errs, "deployment_tasks: "+err.Error())
|
||||
} else {
|
||||
out["deployment_tasks"] = tasks
|
||||
}
|
||||
if apps, err := api.ListApplications(ctx, false); err != nil {
|
||||
errs = append(errs, "applications: "+err.Error())
|
||||
} else {
|
||||
out["applications"] = apps
|
||||
}
|
||||
if ipm, err := api.IPMatch(ctx); err != nil {
|
||||
errs = append(errs, "ip_match: "+err.Error())
|
||||
} else {
|
||||
out["ip_match"] = ipm
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
out["errors"] = errs
|
||||
}
|
||||
return out, nil
|
||||
})
|
||||
}
|
||||
|
||||
// unhealthy возвращает приложения со статусом, отличным от OK.
|
||||
func unhealthy(apps []configserver.Application) []configserver.Application {
|
||||
out := []configserver.Application{}
|
||||
for _, app := range apps {
|
||||
if app.Status != "OK" {
|
||||
out = append(out, app)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user