2026-04-09 15:24:34 +08:00
|
|
|
package services
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"slices"
|
|
|
|
|
"strings"
|
|
|
|
|
|
2026-05-31 18:43:48 +08:00
|
|
|
"agent-desk/internal/ai/mcps"
|
|
|
|
|
"agent-desk/internal/pkg/config"
|
|
|
|
|
"agent-desk/internal/pkg/enums"
|
|
|
|
|
"agent-desk/internal/pkg/errorsx"
|
|
|
|
|
"agent-desk/internal/pkg/i18nx"
|
|
|
|
|
"agent-desk/internal/pkg/toolx"
|
2026-04-09 15:24:34 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var ToolCatalogService = newToolCatalogService()
|
|
|
|
|
|
|
|
|
|
func newToolCatalogService() *toolCatalogService {
|
|
|
|
|
return &toolCatalogService{}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type toolCatalogService struct{}
|
|
|
|
|
|
|
|
|
|
type MCPToolCatalogItem struct {
|
|
|
|
|
ToolCode string
|
|
|
|
|
ServerCode string
|
|
|
|
|
ToolName string
|
2026-04-14 15:05:38 +08:00
|
|
|
SourceType enums.ToolSourceType
|
2026-04-10 15:41:02 +08:00
|
|
|
AutoInjected bool
|
2026-04-09 15:24:34 +08:00
|
|
|
Title string
|
|
|
|
|
Description string
|
|
|
|
|
InputSchema any
|
|
|
|
|
OutputSchema any
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *toolCatalogService) ListMCPTools(ctx context.Context) ([]MCPToolCatalogItem, error) {
|
2026-05-31 20:06:44 +08:00
|
|
|
return s.ListMCPToolsWithLocale(ctx, i18nx.DefaultLocale)
|
2026-05-25 12:06:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *toolCatalogService) ListMCPToolsWithLocale(ctx context.Context, locale string) ([]MCPToolCatalogItem, error) {
|
2026-04-09 15:24:34 +08:00
|
|
|
cfg := config.Current()
|
2026-04-10 16:00:10 +08:00
|
|
|
ret := make([]MCPToolCatalogItem, 0, 3)
|
2026-04-12 22:30:00 +08:00
|
|
|
for _, spec := range toolx.ListAgentDirectToolSpecs() {
|
|
|
|
|
if spec.Code == toolx.BuiltinToolSearch.Code && !cfg.MCP.Enabled {
|
2026-04-12 22:27:09 +08:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
ret = append(ret, MCPToolCatalogItem{
|
|
|
|
|
ToolCode: spec.Code,
|
|
|
|
|
ServerCode: spec.ServerCode,
|
|
|
|
|
ToolName: spec.Name,
|
|
|
|
|
SourceType: spec.SourceType,
|
|
|
|
|
AutoInjected: spec.AutoInjected,
|
2026-05-25 12:06:15 +08:00
|
|
|
Title: toolx.GetRegisteredToolTitleLocale(spec.Code, locale),
|
|
|
|
|
Description: toolx.GetRegisteredToolDescriptionLocale(spec.Code, locale),
|
2026-04-12 22:27:09 +08:00
|
|
|
})
|
|
|
|
|
}
|
2026-04-09 15:24:34 +08:00
|
|
|
if !cfg.MCP.Enabled {
|
2026-04-10 14:57:46 +08:00
|
|
|
return ret, nil
|
2026-04-09 15:24:34 +08:00
|
|
|
}
|
|
|
|
|
serverCodes := make([]string, 0, len(cfg.MCP.Servers))
|
|
|
|
|
for serverCode, server := range cfg.MCP.Servers {
|
|
|
|
|
if !server.Enabled {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
serverCodes = append(serverCodes, serverCode)
|
|
|
|
|
}
|
|
|
|
|
slices.Sort(serverCodes)
|
|
|
|
|
for _, serverCode := range serverCodes {
|
|
|
|
|
tools, err := mcps.Runtime.ListTools(ctx, serverCode)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
for _, item := range tools {
|
|
|
|
|
ret = append(ret, MCPToolCatalogItem{
|
|
|
|
|
ToolCode: toolx.BuildMCPToolCode(serverCode, item.Name),
|
|
|
|
|
ServerCode: serverCode,
|
|
|
|
|
ToolName: strings.TrimSpace(item.Name),
|
2026-04-14 15:05:38 +08:00
|
|
|
SourceType: enums.ToolSourceTypeMCP,
|
2026-04-10 15:41:02 +08:00
|
|
|
AutoInjected: false,
|
2026-04-09 15:24:34 +08:00
|
|
|
Title: strings.TrimSpace(item.Title),
|
|
|
|
|
Description: strings.TrimSpace(item.Description),
|
|
|
|
|
InputSchema: item.InputSchema,
|
|
|
|
|
OutputSchema: item.OutputSchema,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return ret, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *toolCatalogService) ValidateMCPToolCode(toolCode string) error {
|
2026-04-10 14:43:57 +08:00
|
|
|
return s.ValidateToolCode(toolCode)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *toolCatalogService) ValidateToolCode(toolCode string) error {
|
2026-04-09 15:24:34 +08:00
|
|
|
cfg := config.Current()
|
2026-04-10 14:43:57 +08:00
|
|
|
toolCode = strings.TrimSpace(toolCode)
|
|
|
|
|
if toolCode == "" {
|
2026-06-02 20:51:13 +08:00
|
|
|
return errorsx.InvalidParamI18n("error.e0074")
|
2026-04-10 14:43:57 +08:00
|
|
|
}
|
2026-04-12 22:30:00 +08:00
|
|
|
if toolx.IsAgentDirectToolCode(toolCode) {
|
2026-04-10 14:43:57 +08:00
|
|
|
return nil
|
2026-04-09 15:24:34 +08:00
|
|
|
}
|
|
|
|
|
serverCode, toolName := toolx.SplitMCPToolCode(toolCode)
|
|
|
|
|
if serverCode == "" || toolName == "" {
|
2026-06-02 20:51:13 +08:00
|
|
|
return errorsx.InvalidParamI18n("error.e0075")
|
2026-04-09 15:24:34 +08:00
|
|
|
}
|
2026-04-10 14:43:57 +08:00
|
|
|
if !cfg.MCP.Enabled {
|
2026-06-02 20:51:13 +08:00
|
|
|
return errorsx.InvalidParamI18n("error.e0035")
|
2026-04-10 14:43:57 +08:00
|
|
|
}
|
2026-04-09 15:24:34 +08:00
|
|
|
server, ok := cfg.MCP.Servers[serverCode]
|
|
|
|
|
if !ok || !server.Enabled {
|
2026-06-02 20:51:13 +08:00
|
|
|
return errorsx.InvalidParamI18n("error.e0073")
|
2026-04-09 15:24:34 +08:00
|
|
|
}
|
|
|
|
|
return nil
|
|
|
|
|
}
|