func()

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
}