使用说明
MCP实验室
MCP(模型上下文协议)生态系统的实验功能和增强功能。
延迟工具加载
渐进式工具披露模式的灵感来自Claude Code的“技能”系统。它不会在每次请求时向LLM发送完整的工具模式,而是只发送轻量级元数据(名称+描述),从而大大减少了令牌的使用。
主要优势
| 特性 | 描述 |
|---|---|
| 令牌减少 | 工具定义的令牌减少60-80% |
| 零中断更改 | 100%向后兼容 |
| 仅选择加入 | 默认禁用 |
| 自动 | 只需设置一个标志,无需手动设置 |
运作原理
Normal Flow:
User Request → [Full Tool Schemas] → LLM → Execute Tools
↑
Many tokens
Deferred Loading Flow:
User Request → [Metadata Only] → LLM → Validate → Execute Tools
↑ ↓
Few tokens If invalid: Retry with full schema
用法
基本用法(mcp_llm)
import 'package:mcp_llm/mcp_llm.dart';
// Enable deferred loading when creating LlmClient
final client = LlmClient(
llmProvider: provider,
mcpClient: mcpClient,
useDeferredLoading: true, // Enable token optimization
);
// Use normally - deferred loading is handled automatically
final response = await client.chat('Search for Flutter tutorials');
使用MCPLlm工厂
final mcpLlm = MCPLlm();
mcpLlm.registerProvider('claude', ClaudeProviderFactory());
final client = await mcpLlm.createClient(
providerName: 'claude',
config: LlmConfiguration(apiKey: 'your-api-key'),
mcpClient: mcpClient,
useDeferredLoading: true, // Enable here
);
独立mcp_client使用情况(无mcp_llm)
import 'package:mcp_client/mcp_client.dart';
final registry = ToolRegistry();
// Fetch and cache tools
final tools = await mcpClient.listTools();
registry.cacheFromTools(tools);
// Get lightweight metadata for your LLM integration
final metadata = registry.getAllMetadata();
final toolsForLlm = metadata.map((m) => m.toJson()).toList();
// Later, get full schema when needed for validation/execution
final fullSchema = registry.getSchema('search');
使用客户端扩展
final registry = ToolRegistry();
final metadata = await client.listToolsMetadata(registry);
// metadata: lightweight for LLM context
// registry: contains full schemas for later lookup
api参考
mcp_client类
工具元数据
轻量级工具表示(仅名称+描述)。
// Create from Tool object
final metadata = ToolMetadata.fromTool(tool);
// Create from Map
final metadata = ToolMetadata.fromMap({'name': 'search', 'description': 'Search the web'});
// Serialize (no inputSchema - token efficient)
final json = metadata.toJson();
工具注册表
工具定义的缓存层。
final registry = ToolRegistry();
// Cache tools
registry.cacheFromTools(tools); // From Tool list
registry.cacheFromMaps(toolMaps); // From Map list
// Get metadata (lightweight)
registry.getAllMetadata(); // All metadata
registry.getMetadata('search'); // Specific tool
// Get full schema (for validation/execution)
registry.getSchema('search');
// Status
registry.isInitialized; // true/false
registry.count; // Number of cached tools
registry.toolNames; // ['search', 'calculator', ...]
registry.hasTool('search'); // true/false
// Invalidate on tools/list_changed notification
registry.invalidateAll();
mcp_llm类
验证结果
工具调用验证结果。
final valid = ValidationResult.valid();
final invalid = ValidationResult.invalid('Missing required parameter: query');
_logger.debug('isValid: ${result.isValid}'); // true/false
_logger.debug('error: ${result.error}'); // null or error message
LlmToolMetadata
LLM特定的轻量级元数据。
const metadata = LlmToolMetadata(name: 'search', description: 'Search for information');
final json = metadata.toJson(); // Excludes inputSchema
DeferredToolManager
编排层(当useDeferredLoading=true时,由LlmClient自动创建)。
// Usually handled internally by LlmClient
// For advanced use:
final manager = DeferredToolManager();
await manager.initialize(mcpClientManager);
manager.getMetadataForLlm(); // For LLM context
manager.getFullSchema('search'); // For validation
manager.validateToolCall('search', args); // Returns ValidationResult
manager.invalidate(); // On tools/list_changed
项目
mcp_client_defer_loading
增强 mcp_client 支持延迟工具加载的软件包。
ToolMetadata-轻量级工具表示ToolRegistry-具有元数据提取功能的缓存层ClientToolMetadataExtension-方便的扩展
mcp_llm_defer_loading
增强 mcp_llm 带有延迟工具加载编排的包。
ValidationResult-工具调用验证结果LlmToolMetadata-LLM特定的轻量级元数据DeferredToolManager-编排层useDeferredLoading参数在LlmClient
建筑
+------------------+ +------------------+
| mcp_client | | mcp_llm |
+------------------+ +------------------+
| ToolMetadata | | LlmToolMetadata |
| ToolRegistry | | ValidationResult |
| | | DeferredToolMgr |
+------------------+ +------------------+
Data Layer Orchestration Layer
资源工具桥
MCP资源在系统提示中可见,但LLM无法调用。合成工具(mcp_read_resource, mcp_list_resources)弥合这一差距。
final client = LlmClient(
llmProvider: provider,
mcpClient: mcpClient,
);
// Resources are automatically available as callable tools
final response = await client.chat('Read the config resource');
多轮刀具调用
使LLM能够进行多次连续的工具调用,直到它有足够的信息来应答。
final client = LlmClient(
llmProvider: provider,
mcpClient: mcpClient,
maxToolRounds: 5, // Allow up to 5 rounds (default: 1, max: 10)
);
final response = await client.chat('Compare weather in Seoul and Tokyo');
// Round 1: LLM calls get_weather(Seoul)
// Round 2: LLM calls get_weather(Tokyo)
// Round 3: LLM returns comparison
运行测试
# All packages
cd mcp_llm_resource_tools && dart test
cd mcp_client_defer_loading && dart test
cd mcp_llm_defer_loading && dart test
设计原则
- 零突破性变化:所有现有API工作不变
- 仅限选择加入:默认情况下禁用(
useDeferredLoading: false) - 自动配置:只需设置标志,无需手动设置
- 短暂重试:重试上下文不会污染聊天历史记录
- 分层:mcp_client用于数据,mcp_llm用于编排
许可证
请参阅单个软件包许可证。
