模型元数据提取工具包

一个Dart包,利用注解从模型中提取元数据,用于模型上下文协议(MCP)工具,简化工具定义和输入模式生成。

  • by JasperEssien2
  • Dart
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 JasperEssien2/mcp_toolkit

使用说明

dart_mcp_toolkit

一个Dart包,它利用注释从模型上下文协议(MCP)工具的模型中提取元数据。

这个包裹是关于什么的

dart_mcp_toolkit 是一个Dart包,旨在简化表示MCP服务器工具及其输入模式的模型的定义。它利用了Dart的反射能力(dart:mirrors)以及自定义注释(@MCPToolInput, @MCPToolProperty)允许开发人员直接在Dart类中声明工具输入及其属性。这种方法消除了手动创建和维护模式的需要,促进了一种更具声明性、更不易出错的工具定义方式。

包装用例

此软件包非常适合您需要以下操作的场景:

  • 以声明方式定义可调用工具: 您可以定义一个Dart模型类,使用注释表示工具的输入,而不是使用输入模式手动构建工具定义。

    之前 dart_mcp_toolkit (硬编码工具定义):

    Tool(
        name: 'readFile',
        description: 'Reads a file from the file system.',
        inputSchema: Schema.object(
          properties: {
            'path': Schema.string(description: 'The path to the file to read.'),
          },
        ),
      )
    

    随着 dart_mcp_toolkit (基于模型的定义):

    @MCPToolInput(
      toolName: 'readFile',
      toolDescription: 'Reads a file from the file system.',
    )
    class ReadFileTool {
      const ReadFileTool({required this.path});
    
      @MCPToolProperty(description: 'The path to the file to read.', isRequired: true)
      final String path;
    }
    
  • 结构工具参数: 直接在Dart模型中明确定义这些工具的输入参数,包括它们的名称、描述以及是否需要它们。

  • 自动生成工具模式: 从Dart模型中自动提取结构化模式(类似于JSON模式)。然后,外部系统(如MCP服务器)可以使用此模式来理解您定义的工具并与之交互,从而促进动态工具调用。

  • 将架构序列化为JSON: 所有生成的模式都支持通过JSON序列化 toJson() 方法,使其易于与JSON-RPC或其他基于JSON的协议集成。

如何使用/示例

  1. 添加依赖关系:

    dependencies:
      dart_mcp_toolkit: ^0.1.0 # Use the latest version
    
  2. 定义您的工具输入和属性 使用 @MCPToolInput 和 @MCPToolProperty 注释:

    import 'package:dart_mcp_toolkit/mcp_toolkit.dart';
    
    @MCPToolInput(
      toolName: 'getCurrentWeather',
      toolDescription: 'Get the current weather in a given location',
    )
    class GetCurrentWeatherTool {
      const GetCurrentWeatherTool({required this.location, this.unit});
    
      @MCPToolProperty(description: 'The location to get the weather for', isRequired: true)
      final Location location;
    
      @MCPToolProperty(description: 'The unit of temperature to return')
      final TemperatureUnit? unit;
    }
    
    @MCPToolInput(
      toolName: 'getSpecialWeather',
      toolDescription: 'Get special weather for a given location',
    )
    class GetSpecialWeatherTool {
      const GetSpecialWeatherTool({required this.location, required this.date});
    
      @MCPToolProperty(description: 'The location to get the weather for', isRequired: true)
      final Location location;
    
      @MCPToolProperty(description: 'The date to get the special weather for', isRequired: true)
      final String date;
    }
    
    
    class Location {
      const Location({required this.city, this.country});
    
      @MCPToolProperty(description: 'The city name', isRequired: true)
      final String city;
    
      @MCPToolProperty(description: 'The country name')
      final String? country;
    }
    
    enum TemperatureUnit {
      celsius,
      fahrenheit,
    }
    

    注: 嵌套类,如 Location 不需要 @MCPToolInput 注释-只有顶级工具输入类需要它。当使用注释时,嵌套类中的属性会自动提取 @MCPToolProperty.

  3. 初始化 MCPModelToolMapper 并检索您的可调用工具:

    void main() {
      // Initialize the mapper with your tool input classes
      final mapper = MCPModelToolMapper(
        toolInput: [
          GetCurrentWeatherTool,
          GetSpecialWeatherTool,
        ],
      )..initialize();
    
      // Retrieve a specific tool by name
      final getWeatherTool = mapper.callableToolByName('getCurrentWeather');
      if (getWeatherTool != null) {
        print('Tool Name: ${getWeatherTool.toolName}');
        print('Description: ${getWeatherTool.toolDescription}');
        
        // Access the input schema
        final schema = getWeatherTool.inputSchema;
        print('Properties: ${schema?.properties?.length}');
        
        // Serialize to JSON for MCP server integration
        final jsonSchema = schema?.toJson();
        print('JSON Schema: $jsonSchema');
      }
    
      // Or get all callable tools
      final allTools = mapper.callableTools;
      print('Total tools: ${allTools.length}');
      
      // Each tool can be serialized to JSON
      for (final tool in allTools) {
        final toolJson = {
          'name': tool.toolName,
          'description': tool.toolDescription,
          'inputSchema': tool.inputSchema?.toJson(),
        };
        print(toolJson);
      }
    }
    

附加功能

自定义属性名称

您可以使用以下命令为属性指定自定义名称 name 参数在 @MCPToolProperty:

@MCPToolInput(toolName: 'customNaming', toolDescription: 'Example of custom naming')
class CustomNamingTool {
  const CustomNamingTool({required this.internalName});

  @MCPToolProperty(
    name: 'external_name',  // This will be used in the schema
    description: 'Custom named property',
    isRequired: true,
  )
  final String internalName;
}

嵌套对象和列表

该工具包支持复杂的嵌套结构,包括对象内的对象和对象列表:

@MCPToolInput(toolName: 'complexData', toolDescription: 'Handle complex nested data')
class ComplexDataTool {
  const ComplexDataTool({required this.items});

  @MCPToolProperty(description: 'List of data objects', isRequired: true)
  final List<DataObject> items;
}

class DataObject {
  const DataObject({required this.id, this.metadata});

  @MCPToolProperty(description: 'Unique identifier', isRequired: true)
  final String id;

  @MCPToolProperty(description: 'Optional metadata')
  final Map<String, dynamic>? metadata;
}

枚举支持

该工具包处理Dart枚举,包括那些带有方法和变量的枚举:

enum Priority {
  low,
  medium,
  high;
  
  String get displayName => name.toUpperCase();
}

@MCPToolInput(toolName: 'taskTool')
class TaskTool {
  const TaskTool({required this.priority});

  @MCPToolProperty(description: 'Task priority', isRequired: true)
  final Priority priority;
}

JSON模式序列化

所有模式类型都实现了 toJson() 易于序列化的方法:

final mapper = MCPModelToolMapper(toolInput: [GetCurrentWeatherTool])..initialize();
final tool = mapper.callableToolByName('getCurrentWeather');

// Serialize the entire input schema
final schemaJson = tool?.inputSchema?.toJson();
// Returns:
// {
//   'type': 'object',
//   'properties': {
//     'location': { /* location schema */ },
//     'unit': { /* unit schema */ }
//   },
//   'required': ['location']
// }

支持的架构类型

这 dart_mcp_toolkit 生成与JSON Schema兼容的模式,JSON Schema通常与JSON-RPC 2.0和MCP一起用于描述参数。

dart_mcp_toolkit 模式类型 对应的JSON模式类型 描述 Dart类型示例
StringPropertySchema string 表示字符串值 String
BooleanPropertySchema boolean 表示布尔值 bool
NumberPropertySchema number 表示数值(整数或浮点) num, double
IntPropertySchema integer 表示整数值 int
ListPropertySchema array 表示值的有序列表 List<T>
EnumPropertySchema string 随着 enum 表示预定义集合中的值 任意飞镖 enum
ObjectPropertySchema object 表示具有命名属性的结构化对象 自定义类
NullPropertySchema null 表示空值 -
InvalidPropertySchema - 表示不支持或无效的类型 不支持的类型

局限性

由于使用 dart:mirrors,该软件包有一些局限性:

  • 不支持记录类型: 该包目前不支持从Dart中提取元数据 Record 由于限制,类型 dart:mirrors。使用记录类型将导致 InvalidSchema.

    @MCPToolProperty()
    final ({String a, int b}) record;  // Not supported - will generate InvalidSchema
    
  • isRequired 对于命名参数: 由于已知的限制 dart:mirrors,the paramMirror.isOptional 财产总是会归还 true 对于命名参数。因此,您必须显式设置 isRequired 在 @MCPToolProperty 注释:

    @MCPToolProperty(isRequired: true)  // Must explicitly set this
    final String requiredParam;
    
  • 有限的动态类型处理: 包裹可能会退回 InvalidSchema 对于没有直接映射到支持的模式类型的复杂或未处理的Dart类型。

  • 反射依赖性: 该包需要 dart:mirrors,这在Flutter或web应用程序中不可用。它仅设计用于Dart服务器端应用程序。

API 参考

核心类

注释

  • @MCPToolInput -将类标记为工具输入定义

    • toolName (必填)-工具名称
    • toolDescription (可选)-工具功能说明
  • @MCPToolProperty -将字段标记为工具属性

    • description (可选)-属性描述
    • isRequired (可选)-是否需要此属性
    • name (可选)-模式中属性的自定义名称

贡献

欢迎投稿!请随时提交拉取请求。

许可证

此项目根据BSD-3-Clause许可证进行许可-有关详细信息,请参阅许可证文件。