MCPcopy
hub / github.com/googleapis/mcp-toolbox / toolsCallHandler

Function toolsCallHandler

internal/server/mcp/v20250326/method.go:136–399  ·  view source on GitHub ↗

toolsCallHandler generate a response for tools call.

(ctx context.Context, id jsonrpc.RequestId, toolset tools.Toolset, resourceMgr *resources.ResourceManager, body []byte, header http.Header)

Source from the content-addressed store, hash-verified

134
135// toolsCallHandler generate a response for tools call.
136func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolset tools.Toolset, resourceMgr *resources.ResourceManager, body []byte, header http.Header) (any, error) {
137 if header != nil {
138 if clientIP := util.ExtractClientIP(header); clientIP != "" {
139 ctx = util.WithClientIP(ctx, clientIP)
140 }
141 }
142
143 authServices := resourceMgr.GetAuthServiceMap()
144
145 // retrieve logger from context
146 logger, err := util.LoggerFromContext(ctx)
147 if err != nil {
148 return jsonrpc.NewError(id, jsonrpc.INTERNAL_ERROR, err.Error(), nil), err
149 }
150
151 var req CallToolRequest
152 if err = json.Unmarshal(body, &req); err != nil {
153 err = fmt.Errorf("invalid mcp tools call request: %w", err)
154 return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err
155 }
156
157 toolName := req.Params.Name
158 toolArgument := req.Params.Arguments
159 logger.DebugContext(ctx, fmt.Sprintf("tool name: %s", toolName))
160
161 // Update span name and set gen_ai attributes
162 span := trace.SpanFromContext(ctx)
163 span.SetName(fmt.Sprintf("%s %s", TOOLS_CALL, toolName))
164 span.SetAttributes(
165 attribute.String("gen_ai.tool.name", toolName),
166 attribute.String("gen_ai.operation.name", "execute_tool"),
167 )
168
169 // Verify tool belongs to the current toolset before resolving globally.
170 if !toolset.ContainsTool(toolName) {
171 err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
172 return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
173 }
174
175 tool, ok := resourceMgr.GetTool(toolName)
176 if !ok {
177 err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
178 return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
179 }
180
181 // Populate gen_ai attributes for operation duration metric
182 if genAIAttrs := util.GenAIMetricAttrsFromContext(ctx); genAIAttrs != nil {
183 genAIAttrs.OperationName = "execute_tool"
184 genAIAttrs.ToolName = toolName
185 }
186
187 // Get access token
188 authTokenHeadername, err := tool.GetAuthTokenHeaderName(resourceMgr)
189 if err != nil {
190 errMsg := fmt.Errorf("error during invocation: %w", err)
191 return jsonrpc.NewError(id, jsonrpc.INTERNAL_ERROR, errMsg.Error(), nil), errMsg
192 }
193 var accessToken tools.AccessToken

Callers 2

ProcessMethodFunction · 0.70
TestToolsCallHandlerFunction · 0.70

Calls 15

CategoryMethod · 0.95
ExtractClientIPFunction · 0.92
WithClientIPFunction · 0.92
LoggerFromContextFunction · 0.92
NewErrorFunction · 0.92
AccessTokenTypeAlias · 0.92
NewClientServerErrorFunction · 0.92
DecodeJSONFunction · 0.92
ParseParamsFunction · 0.92

Tested by 1

TestToolsCallHandlerFunction · 0.56