From 020b5f39843f137eff50895a6723a4f81c2adfdc Mon Sep 17 00:00:00 2001 From: EricaLiu <30773688+Erica177@users.noreply.github.com> Date: Mon, 1 Sep 2025 15:23:04 +0800 Subject: [PATCH] Add security schema for nacos mcp (#2847) --- registry/mcp_model.go | 48 ++++++++++++++++++++--------- registry/nacos/mcpserver/watcher.go | 41 ++++++++++++++++++++++-- 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/registry/mcp_model.go b/registry/mcp_model.go index 3afdfa6c9..f6bab0768 100644 --- a/registry/mcp_model.go +++ b/registry/mcp_model.go @@ -47,17 +47,25 @@ type McpServerRule struct { } type ServerConfig struct { - Name string `json:"name,omitempty"` - Config map[string]interface{} `json:"config,omitempty"` + Name string `json:"name,omitempty"` + Config map[string]interface{} `json:"config,omitempty"` + SecuritySchemes []*SecuritySchemes `json:"securitySchemes,omitempty"` } type McpTool struct { - Name string `json:"name,omitempty"` - Description string `json:"description,omitempty"` - Args []*ToolArgs `json:"args,omitempty"` - RequestTemplate *RequestTemplate `json:"requestTemplate"` - ResponseTemplate *ResponseTemplate `json:"responseTemplate"` - ErrorResponseTemplate string `json:"errorResponseTemplate,omitempty"` + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + Args []*ToolArgs `json:"args,omitempty"` + RequestTemplate *RequestTemplate `json:"requestTemplate"` + ResponseTemplate *ResponseTemplate `json:"responseTemplate"` + ErrorResponseTemplate string `json:"errorResponseTemplate,omitempty"` + Security *ToolSecurity `json:"security"` +} + +type ToolSecurity struct { + Id string `json:"type,omitempty"` + PassThrough bool `json:"passthrough,omitempty"` + Credential string `json:"credential"` } type ToolArgs struct { @@ -80,6 +88,7 @@ type RequestTemplate struct { ArgsToJsonBody bool `json:"argsToJsonBody,omitempty"` ArgsToUrlParam bool `json:"argsToUrlParam,omitempty"` ArgsToFormBody bool `json:"argsToFormBody,omitempty"` + Security *ToolSecurity `json:"security,omitempty"` } type RequestTemplateHeaders struct { @@ -125,8 +134,18 @@ type ServiceRef struct { // McpToolConfig Struct for mcp tool json unmarshal type McpToolConfig struct { - Tools []*ToolDescription `json:"tools,omitempty"` - ToolsMeta map[string]*ToolsMeta `json:"toolsMeta,omitempty"` + Tools []*ToolDescription `json:"tools,omitempty"` + ToolsMeta map[string]*ToolsMeta `json:"toolsMeta,omitempty"` + SecuritySchemes []*SecuritySchemes `json:"securitySchemes,omitempty"` +} + +type SecuritySchemes struct { + Id string `json:"id,omitempty"` + Type string `json:"type,omitempty"` + Scheme string `json:"scheme,omitempty"` + In string `json:"in,omitempty"` + Name string `json:"name,omitempty"` + DefaultCredential string `json:"defaultCredential,omitempty"` } type ToolDescription struct { @@ -148,8 +167,9 @@ type ToolsMeta struct { } type JsonGoTemplate struct { - RequestTemplate RequestTemplate `json:"requestTemplate,omitempty"` - ResponseTemplate ResponseTemplate `json:"responseTemplate,omitempty"` - ArgsPosition map[string]string `json:"argsPosition,omitempty"` - ErrorResponseTemplate string `json:"errorResponseTemplate,omitempty"` + RequestTemplate RequestTemplate `json:"requestTemplate,omitempty"` + ResponseTemplate ResponseTemplate `json:"responseTemplate,omitempty"` + ArgsPosition map[string]string `json:"argsPosition,omitempty"` + ErrorResponseTemplate string `json:"errorResponseTemplate,omitempty"` + Security *ToolSecurity `json:"security,omitempty"` } diff --git a/registry/nacos/mcpserver/watcher.go b/registry/nacos/mcpserver/watcher.go index a49894e51..16fe02075 100644 --- a/registry/nacos/mcpserver/watcher.go +++ b/registry/nacos/mcpserver/watcher.go @@ -129,8 +129,8 @@ func NewWatcher(cache memory.Cache, opts ...WatcherOption) (provider.Watcher, er constant.WithCacheDir(DefaultNacosCacheDir), constant.WithNotLoadCacheAtStart(DefaultNacosNotLoadCache), constant.WithLogRollingConfig(&constant.ClientLogRollingConfig{ - MaxAge: DefaultNacosLogMaxAge, - MaxSize: DefaultNacosLogMaxSize, + MaxAge: DefaultNacosLogMaxAge, + MaxSize: DefaultNacosLogMaxSize, MaxBackups: DefaultNacosLogMaxBackups, }), constant.WithUpdateCacheWhenEmpty(w.updateCacheWhenEmpty), @@ -429,6 +429,10 @@ func (w *watcher) processToolConfig(dataId, data string, credentials map[string] }, } rule.Server.Config["credentials"] = credentials + // process security schemas + if len(toolsDescription.SecuritySchemes) > 0 { + rule.Server.SecuritySchemes = toolsDescription.SecuritySchemes + } var allowTools []string for _, t := range toolsDescription.Tools { @@ -479,6 +483,15 @@ func (w *watcher) processToolConfig(dataId, data string, credentials map[string] convertTool.ResponseTemplate = responseTemplate convertTool.ErrorResponseTemplate = errorResponseTemplate } + + security, err := getSecurityFromToolMeta(toolMeta) + if err != nil { + mcpServerLog.Errorf("get security from tool meta error:%v, tool name %v", err, t.Name) + continue + } else { + convertTool.Security = security + } + rule.Tools = append(rule.Tools, convertTool) } @@ -740,6 +753,30 @@ func getResponseTemplateFromToolMeta(toolMeta *provider.ToolsMeta) (*provider.Re return nil, "", nil } +func getSecurityFromToolMeta(toolMeta *provider.ToolsMeta) (*provider.ToolSecurity, error) { + if toolMeta == nil { + return nil, nil + } + toolTemplate := toolMeta.Templates + for kind, meta := range toolTemplate { + switch kind { + case provider.JsonGoTemplateType: + templateData, err := json.Marshal(meta) + if err != nil { + return nil, err + } + template := &provider.JsonGoTemplate{} + if err = json.Unmarshal(templateData, template); err != nil { + return nil, err + } + return template.Security, nil + default: + return nil, fmt.Errorf("unsupported tool meta type: %s", kind) + } + } + return nil, nil +} + func mergeMaps(maps ...map[string]string) map[string]string { if len(maps) == 0 { return nil