in registry/nacos/mcpserver/watcher.go [503:604]
func (w *watcher) multiCallback(server *provider.McpServer, routeName, configKey string) func(map[string]string) {
callback := func(configs map[string]string) {
defer w.UpdateService()
mcpServerLog.Infof("callback, ref config changed: %s", configKey)
rule := &provider.McpServerRule{
MatchRoute: []string{routeName},
Server: &provider.ServerConfig{
Name: server.Name,
Config: map[string]interface{}{},
},
}
// process mcp credential
credentialConfig := map[string]interface{}{}
for key, data := range configs {
if strings.HasPrefix(key, provider.DefaultMcpToolsGroup) {
// skip mcp tool description
continue
}
var cred interface{}
if err := json.Unmarshal([]byte(data), &cred); err != nil {
mcpServerLog.Errorf("unmarshal credential data %v to map error:%v", key, err)
}
w.callbackMutex.Lock()
name := w.credentialKeyToName[configKey][key]
w.callbackMutex.Unlock()
credentialConfig[name] = cred
}
rule.Server.Config["credentials"] = credentialConfig
// process mcp tool description
var allowTools []string
for key, toolData := range configs {
if strings.HasPrefix(key, provider.DefaultMcpCredentialsGroup) {
// skip mcp credentials
continue
}
toolsDescription := &provider.McpToolConfig{}
if err := json.Unmarshal([]byte(toolData), toolsDescription); err != nil {
mcpServerLog.Errorf("unmarshal toolsDescriptionRef to mcp tool config error:%v", err)
}
for _, t := range toolsDescription.Tools {
convertTool := &provider.McpTool{Name: t.Name, Description: t.Description}
toolMeta := toolsDescription.ToolsMeta[t.Name]
if toolMeta != nil && toolMeta.Enabled {
allowTools = append(allowTools, t.Name)
}
argsPosition, err := getArgsPositionFromToolMeta(toolMeta)
if err != nil {
mcpServerLog.Errorf("get args position from tool meta error:%v, tool name %v", err, t.Name)
}
requiredMap := sets.Set[string]{}
for _, s := range t.InputSchema.Required {
requiredMap.Insert(s)
}
for argsName, args := range t.InputSchema.Properties {
convertArgs, err := parseMcpArgs(args)
if err != nil {
mcpServerLog.Errorf("parse mcp args error:%v, tool name %v, args name %v", err, t.Name, argsName)
continue
}
convertArgs.Name = argsName
convertArgs.Required = requiredMap.Contains(argsName)
if pos, exist := argsPosition[argsName]; exist {
convertArgs.Position = pos
}
convertTool.Args = append(convertTool.Args, convertArgs)
mcpServerLog.Debugf("parseMcpArgs, toolArgs:%v", convertArgs)
}
requestTemplate, err := getRequestTemplateFromToolMeta(toolMeta)
if err != nil {
mcpServerLog.Errorf("get request template from tool meta error:%v, tool name %v", err, t.Name)
} else {
convertTool.RequestTemplate = requestTemplate
}
responseTemplate, err := getResponseTemplateFromToolMeta(toolMeta)
if err != nil {
mcpServerLog.Errorf("get response template from tool meta error:%v, tool name %v", err, t.Name)
} else {
convertTool.ResponseTemplate = responseTemplate
}
rule.Tools = append(rule.Tools, convertTool)
}
}
rule.Server.AllowTools = allowTools
wasmPluginConfig := &config.Config{
Meta: config.Meta{
GroupVersionKind: gvk.WasmPlugin,
Namespace: w.namespace,
},
Spec: rule,
}
w.cache.UpdateConfigCache(gvk.WasmPlugin, configKey, wasmPluginConfig, false)
}
return callback
}