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

Function toolsCallHandler

internal/server/mcp/vdraft/method.go:202–468  ·  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

200
201// toolsCallHandler generate a response for tools call.
202func toolsCallHandler(ctx context.Context, id jsonrpc.RequestId, toolset tools.Toolset, resourceMgr *resources.ResourceManager, body []byte, header http.Header) (any, error) {
203 authServices := resourceMgr.GetAuthServiceMap()
204
205 // retrieve logger from context
206 logger, err := util.LoggerFromContext(ctx)
207 if err != nil {
208 return jsonrpc.NewError(id, jsonrpc.INTERNAL_ERROR, err.Error(), nil), err
209 }
210
211 var req CallToolRequest
212 if err = json.Unmarshal(body, &req); err != nil {
213 err = fmt.Errorf("invalid mcp tools call request: %w", err)
214 return jsonrpc.NewError(id, jsonrpc.INVALID_REQUEST, err.Error(), nil), err
215 }
216 validateHeaderErr, err := validateHeader(id, header, TOOLS_CALL, req.Params.Name)
217 if err != nil {
218 return validateHeaderErr, err
219 }
220 validateErr, err := validateMetadata(id, req.Params.RequestParams, header == nil)
221 if err != nil {
222 return validateErr, err
223 }
224
225 toolName := req.Params.Name
226 toolArgument := req.Params.Arguments
227 logger.DebugContext(ctx, fmt.Sprintf("tool name: %s", toolName))
228
229 // Update span name and set gen_ai attributes
230 span := trace.SpanFromContext(ctx)
231 span.SetName(fmt.Sprintf("%s %s", TOOLS_CALL, toolName))
232 span.SetAttributes(
233 attribute.String("gen_ai.tool.name", toolName),
234 attribute.String("gen_ai.operation.name", "execute_tool"),
235 )
236
237 // Verify tool belongs to the current toolset before resolving globally.
238 if !toolset.ContainsTool(toolName) {
239 err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
240 return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
241 }
242
243 tool, ok := resourceMgr.GetTool(toolName)
244 if !ok {
245 err = fmt.Errorf("invalid tool name: tool with name %q does not exist", toolName)
246 return jsonrpc.NewError(id, jsonrpc.INVALID_PARAMS, err.Error(), nil), err
247 }
248
249 // Populate gen_ai attributes for operation duration metric
250 if genAIAttrs := util.GenAIMetricAttrsFromContext(ctx); genAIAttrs != nil {
251 genAIAttrs.OperationName = "execute_tool"
252 genAIAttrs.ToolName = toolName
253 }
254
255 // Get access token
256 authTokenHeadername, err := tool.GetAuthTokenHeaderName(resourceMgr)
257 if err != nil {
258 errMsg := fmt.Errorf("error during invocation: %w", err)
259 return jsonrpc.NewError(id, jsonrpc.INTERNAL_ERROR, errMsg.Error(), nil), errMsg

Callers 2

ProcessMethodFunction · 0.70
TestToolsCallHandlerFunction · 0.70

Calls 15

CategoryMethod · 0.95
LoggerFromContextFunction · 0.92
NewErrorFunction · 0.92
AccessTokenTypeAlias · 0.92
NewClientServerErrorFunction · 0.92
DecodeJSONFunction · 0.92
ParseParamsFunction · 0.92
validateHeaderFunction · 0.85
validateMetadataFunction · 0.85

Tested by 1

TestToolsCallHandlerFunction · 0.56