addTool method

  1. @override
void addTool({
  1. required String name,
  2. required String description,
  3. required Map<String, dynamic> inputSchema,
  4. required ToolHandler handler,
  5. String? title,
  6. Map<String, dynamic>? outputSchema,
  7. List<Map<String, dynamic>>? icons,
  8. Map<String, dynamic>? meta,
  9. ToolAnnotations? annotations,
  10. ToolExecution? execution,
})
override

Add a tool to the server

Implementation

@override
void addTool({
  required String name,
  required String description,
  required Map<String, dynamic> inputSchema,
  required ToolHandler handler,
  String? title,
  Map<String, dynamic>? outputSchema,
  List<Map<String, dynamic>>? icons,
  Map<String, dynamic>? meta,
  ToolAnnotations? annotations,
  ToolExecution? execution,
}) {
  _logger.debug('Adding tool: $name');

  if (_tools.containsKey(name)) {
    _logger.debug('Tool with name "$name" already exists');
    throw McpError('Tool with name "$name" already exists');
  }
  if (!_toolNamePattern.hasMatch(name)) {
    _logger.warning(
      'Tool name "$name" is outside the recommended form '
      '(1-128 of A-Z a-z 0-9 _ - .)',
    );
  }
  if (!capabilities.hasTools) {
    _logger.warning(
      'Tool "$name" added but the tools capability is not declared; '
      'clients cannot call it',
    );
  }
  // Schemas are checked once, here: a schema the server cannot evaluate
  // must not be advertised.
  final inputValidator = _toolSchemaValidator(
    name,
    'inputSchema',
    inputSchema,
  );
  if (inputSchema['type'] != 'object') {
    throw ArgumentError.value(
      inputSchema,
      'inputSchema',
      'Tool "$name": the root type must be "object"',
    );
  }
  final headerProblem = mcpParamHeaders(inputSchema).problem;
  if (headerProblem != null) {
    throw ArgumentError.value(
      inputSchema,
      'inputSchema',
      'Tool "$name": $headerProblem',
    );
  }
  final outputValidator =
      outputSchema == null
          ? null
          : _toolSchemaValidator(name, 'outputSchema', outputSchema);

  final tool = Tool(
    name: name,
    title: title,
    description: description,
    inputSchema: inputSchema,
    outputSchema: outputSchema,
    icons: icons?.map(McpIcon.fromJson).toList(),
    annotations: annotations,
    execution: execution,
    meta: meta,
  );

  _tools[name] = tool;
  _toolHandlers[name] = handler;
  _toolInputValidators[name] = inputValidator;
  if (outputValidator != null) _toolOutputValidators[name] = outputValidator;

  _logger.debug('Tool added successfully: $name');
  _logger.debug('Total tools: ${_tools.length}');

  // Notify clients about tool changes if connected and supported
  if (isConnected && capabilities.hasTools && capabilities.toolsListChanged) {
    _broadcastNotification('notifications/tools/list_changed', {});
  }

  // Emit change event
  _toolsChangedController.add(null);

  // Update metrics
  _updateResourceMetrics();
}