Token导航 LogoToken导航TokenDH.com
MCP LLM server logo
AI代理未说明官方级别未说明来源级核验

MCP LLM server

MCP Server

通过LlmServer和mcp_server集成,提供AI能力作为服务,支持多种客户端应用。

工具数

4

提示词数

0

GitHub Stars

0

资源数

0
ClaudeAI代理工作流自动化Claude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

MCP-Dev-Studio

提供方

MCP-Dev-Studio

最后核验

2026/5/17 20:23

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

详细介绍

将AI与Flutter集成:使用LlmServer和mcp_server创建AI服务

Flutter and AI Integration

引言

在我们正在进行的关于将AI与Flutter应用程序集成的系列中,我们之前探讨了客户端与Flutter的集成 LlmClientmcp_client现在,是时候深入了解服务器端集成了 LlmServermcp_server这种强大的组合使您能够将人工智能功能作为服务提供给多个客户端。

本文是我们的模型上下文协议(MCP)系列中的第五篇,第三篇主要关注 mcp_llm--探索如何构建利用标准化MCP协议的强大AI服务,使您的AI功能可供各种客户端应用程序访问。

目录

  1. 了解LlmServer和mcp_server
  2. 服务器端集成架构
  3. 设置集成
  4. 将LLM函数注册为MCP工具
  5. 核心LLM插件
  6. 基于人工智能的工具生成
  7. 服务器监控和管理
  8. 后续步骤

了解LlmServer和mcp_server

在我们深入探讨集成之前,让我们澄清一下这两个关键组件的作用:

LlmServer的作用

LlmServer 是来自 mcp_llm 作为AI功能的服务器端实现的包。它负责:

  • 与大型语言模型(LLMs)如Claude、GPT等进行交流。
  • 注册和管理AI驱动的工具
  • 处理查询并生成响应
  • 管理插件和扩展
  • 监控性能和请求

它本质上是将人工智能功能作为服务公开,而不是将其直接嵌入到您的客户端应用程序中。

mcp_server的作用

mcp_server 在服务器端实现模型上下文协议(MCP),允许:

  • 向客户注册和公开工具
  • 资源管理(数据库、API、文件)
  • 提供标准化的提示模板
  • 客户端连接和会话管理
  • 基于协议的通信

整合的价值

集成后,这些组件可以实现:

  1. 将LLM功能作为标准化的MCP工具进行展示
  2. 为多个客户端集中AI功能
  3. 在一个地方安全地管理API密钥和凭据
  4. 基于自然语言描述动态生成新工具
  5. 独立于客户端应用程序扩展AI功能

这种集成通过在客户端界面和后端AI处理之间创建明确的分离来改变AI开发,从而实现了更好的可扩展性、安全性和资源管理。

服务器端集成架构

了解这种集成的架构对于实施至关重要:

集成模型

[Client Apps] ← HTTP/SSE → [mcp_server] ↔ [LlmServer] ← HTTP → [LLM API]
                                ↓              ↓
                        [Tools/Resources]  [Plugin Management]

通信流

组件之间的通信流遵循以下模式:

  1. mcp_server 接收来自客户端(Flutter应用程序、web客户端等)的请求
  2. 如果请求涉及LLM工具,则会转发给 LlmServer
  3. LlmServer 处理请求并与LLM提供者通信
  4. LLM的响应返回给 LlmServer
  5. LlmServer 处理响应并将结果返回给 mcp_server
  6. mcp_server 将最终结果发送回客户端

这种分层架构创建了清晰的关注点分离,并实现了高效的扩展。

设置集成

让我们来了解一下使用以下工具设置集成AI服务器的过程 LlmServermcp_server:

import 'dart:async';
import 'dart:io';
import 'package:mcp_llm/mcp_llm.dart';
import 'package:mcp_server/mcp_server.dart' as mcp;
import 'package:dotenv/dotenv.dart';

Future main() async {
  // Logger setup - utility for structured server logs
  final logger = Logger.getLogger('mcp_llm.server');

  try {
    // Load environment variables - server configuration settings
    final env = DotEnv()..load();
    final apiKey = env['OPENAI_API_KEY'] ?? '';
    final serverPort = int.tryParse(env['MCP_SERVER_PORT'] ?? '8999') ?? 8999;
    final authToken = env['MCP_AUTH_TOKEN'] ?? 'test_token';
    final logLevelStr = env['LOG_LEVEL'] ?? 'info';

    // Set log level - various levels of detail for logging
    final LogLevel logLevel;
    switch (logLevelStr.toLowerCase()) {
      case 'trace': logLevel = LogLevel.trace; break;
      case 'debug': logLevel = LogLevel.debug; break;
      case 'info': logLevel = LogLevel.info; break;
      case 'warning': logLevel = LogLevel.warning; break;
      case 'error': logLevel = LogLevel.error; break;
      default: logLevel = LogLevel.info;
    }
    logger.setLevel(logLevel);

    // Verify API key - required setting for server startup
    if (apiKey.isEmpty) {
      logger.error('OPENAI_API_KEY is not set.');
      exit(1);
    }

    logger.info('Starting AI service server...');

    // Create McpLlm instance - entry point for all LLM functionality
    final mcpLlm = McpLlm();

    // Register LLM provider - support for various AI models
    mcpLlm.registerProvider('openai', OpenAiProviderFactory());
    logger.debug('OpenAI provider registered.');

    // Create MCP server - Model Context Protocol server configuration
    final mcpServer = mcp.McpServer.createServer(
      name: 'ai_service',
      version: '1.0.0',
      capabilities: mcp.ServerCapabilities(
        tools: true,
        toolsListChanged: true,
        resources: true,
        resourcesListChanged: true,
        prompts: true,
        promptsListChanged: true,
        sampling: true,
      ),
    );

    // Register custom tools - add specific functionality tools
    final pluginManager = PluginManager();

    await pluginManager.registerPlugin(EchoToolPlugin());
    await pluginManager.registerPlugin(CalculatorToolPlugin());

    // Create LlmServer - server for providing AI functionality as a service
    final llmServer = await mcpLlm.createServer(
      providerName: 'openai',  // LLM provider to use
      config: LlmConfiguration(
        apiKey: apiKey,
        model: 'gpt-4o',  // Model to use
        options: {
          'temperature': 0.3,  // Control response randomness/creativity (0-1)
          'max_tokens': 2000,  // Maximum output token limit
        },
      ),
      storageManager: MemoryStorage(),
      pluginManager: pluginManager,
      mcpServer: mcpServer,  // MCP server integration
    );

    logger.info('LlmServer has been created.');

    // Register core LLM plugins - enable basic AI functionality
    await llmServer.registerCoreLlmPlugins(
      registerCompletionTool: true,  // Text generation tool
      registerStreamingTool: true,   // Streaming response tool
      registerEmbeddingTool: true,   // Embedding generation tool
      registerRetrievalTools: true,  // Retrieval-related tools
      registerWithServer: true,      // Auto-register with MCP server
    );
    logger.info('Core LLM plugins registered.');

    // Add auto-generated tool - LLM designs/implements tool automatically
    // Executing asynchronously to avoid delaying server startup
    _generateAutomaticTool(llmServer, logger);

    // Create SSE transport - communication channel between server and clients
    final transport = mcp.McpServer.createSseTransport(
      endpoint: '/sse',
      messagesEndpoint: '/message',
      port: serverPort,
      authToken: authToken,  // Token for client authentication
    );

    // Connect MCP server with transport
    mcpServer.connect(transport);
    logger.info('MCP server connected to transport.');

    // Output server information
    logger.info('AI service running on port $serverPort.');
    logger.info('Server URL: http://localhost:$serverPort/sse');

    // Verify auth token setting
    if (authToken.isNotEmpty) {
      logger.debug('Auth token set: $authToken');
    }

    // Output available tools
    final tools = mcpServer.getTools();
    logger.info('');
    logger.info('Available tools:');
    for (final tool in tools) {
      logger.info('- ${tool.name}: ${tool.description}');
    }

    // Handle server shutdown - for Ctrl+C or other termination
    ProcessSignal.sigint.watch().listen((_) async {
      logger.info('Shutting down server...');
      await mcpLlm.shutdown();
      exit(0);
    });

    // Maintain event loop - keep server running
    try {
      logger.info('Server ready to process requests. Press Ctrl+C to shut down.');
      await Future.delayed(Duration(days: 365));
    } catch (e) {
      logger.error('Error during server execution: $e');
    }

  } catch (e, stack) {
    logger.error('Error during server startup: $e');
    logger.debug('Stack trace: $stack');
    exit(1);
  }
}

// AI-based tool generation function - LLM designs and implements tools automatically
void _generateAutomaticTool(LlmServer server, Logger logger) async {
  try {
    logger.info('Generating sentiment analysis tool...');

    // Tool description - LLM uses this description to generate the tool
    final toolDescription = """
      Create a tool that analyzes the sentiment of text. This tool should provide:
      
      1. Sentiment analysis of input text (positive, negative, neutral)
      2. Sentiment score (-1.0 to 1.0, where -1 is most negative, 1 is most positive)
      3. Extraction of key sentiment words
      4. Analysis confidence (0.0 to 1.0)
      
      It should support text in multiple languages and provide results in either text or JSON format.
      
      The tool name must be sentiment_analyzer.
      """;

    // Attempt LLM-based tool generation
    try {
      logger.info('Attempting LLM-based tool generation...');

      // Generate tool
      final success = await server.generateAndRegisterTool(
        toolDescription,
        registerWithServer: true,  // Auto-register with server
      );

      logger.info('Automatic tool generation result: ${success ? "Success" : "Failed"}');

      if (!success) {
        logger.info('Automatic generation failed...');
      }
    } catch (e) {
      logger.error('Error during tool generation: $e');

      // Handle error if direct registration is needed
      logger.info('Error...');
    }
  } catch (e) {
    logger.error('Error during sentiment analyzer tool setup: $e');
  }
}

class EchoToolPlugin extends BaseToolPlugin {
  EchoToolPlugin() : super(
    name: 'echo',
    version: '1.0.0',
    description: 'Echoes back the input message with optional transformation',
    inputSchema: {
      'type': 'object',
      'properties': {
        'message': {
          'type': 'string',
          'description': 'Message to echo back'
        },
        'uppercase': {
          'type': 'boolean',
          'description': 'Whether to convert to uppercase',
          'default': false
        }
      },
      'required': ['message']
    },
  );

  @override
  Future onExecute(Map arguments) async {
    final message = arguments['message'] as String;
    final uppercase = arguments['uppercase'] as bool? ?? false;

    final result = uppercase ? message.toUpperCase() : message;

    Logger.getLogger('LlmServerDemo').debug(message);
    return LlmCallToolResult([
      LlmTextContent(text: result),
    ]);
  }
}

class CalculatorToolPlugin extends BaseToolPlugin {
  CalculatorToolPlugin() : super(
    name: 'calculator',
    version: '1.0.0',
    description: 'Performs basic arithmetic operations',
    inputSchema: {
      'type': 'object',
      'properties': {
        'operation': {
          'type': 'string',
          'description': 'The operation to perform (add, subtract, multiply, divide)',
          'enum': ['add', 'subtract', 'multiply', 'divide']
        },
        'a': {
          'type': 'number',
          'description': 'First number'
        },
        'b': {
          'type': 'number',
          'description': 'Second number'
        }
      },
      'required': ['operation', 'a', 'b']
    },
  );

  @override
  Future onExecute(Map arguments) async {
    final operation = arguments['operation'] as String;
    final a = (arguments['a'] as num).toDouble();
    final b = (arguments['b'] as num).toDouble();

    double result;
    switch (operation) {
      case 'add':
        result = a + b;
        break;
      case 'subtract':
        result = a - b;
        break;
      case 'multiply':
        result = a * b;
        break;
      case 'divide':
        if (b == 0) {
          throw Exception('Division by zero');
        }
        result = a / b;
        break;
      default:
        throw Exception('Unknown operation: $operation');
    }

    Logger.getLogger('LlmServerDemo').debug('$result');
    return LlmCallToolResult([
      LlmTextContent(text: result.toString()),
    ]);
  }
}

上面的代码设置了一个集成的AI服务器,其中包含几个关键组件:

  1. 环境配置:从环境变量加载API密钥、端口设置和身份验证令牌
  2. McpLlm和提供商设置:创建主实例并注册LLM提供者
  3. MCP服务器创建:设置具有所需功能的MCP服务器
  4. 工具注册:注册Echo和Calculator等基本工具
  5. Llm服务器创建:创建LLM服务器并将其连接到MCP服务器
  6. 核心插件注册:将基本的人工智能功能注册为工具
  7. 基于AI的工具生成:使用LLM自动生成情绪分析工具
  8. 传输设置:为客户端通信设置SSE传输

将LLM函数注册为MCP工具

这种集成的一个关键方面是将LLM功能作为客户端可以访问的MCP工具公开。提供的代码演示了两种工具注册方法:

1.插件注册

示例代码展示了如何通过扩展来创建工具插件 BaseToolPlugin 类并通过注册 PluginManager:

// Register custom tools through PluginManager
final pluginManager = PluginManager();
await pluginManager.registerPlugin(EchoToolPlugin());
await pluginManager.registerPlugin(CalculatorToolPlugin());

EchoToolPluginCalculatorToolPlugin 类演示了如何通过以下方式实现自定义工具:

  • 定义工具名称、版本和描述
  • 将输入模式指定为JSON模式
  • 实施 onExecute 处理工具调用的方法

2.核心LLM插件

registerCoreLlmPlugins 该方法自动将一组核心LLM功能注册为工具:

// Register core LLM plugins
await llmServer.registerCoreLlmPlugins(
  registerCompletionTool: true,  // Text generation
  registerStreamingTool: true,   // Streaming responses
  registerEmbeddingTool: true,   // Embedding generation
  registerRetrievalTools: true,  // Retrieval-related tools
  registerWithServer: true,      // Auto-register with MCP server
);

这些核心插件将基本的LLM功能(文本生成、嵌入等)作为标准化工具公开,使其通过MCP协议可供客户端使用。

核心LLM插件

通过注册的核心LLM插件 registerCoreLlmPlugins 提供对以下功能的访问:

  • 完井工具:允许根据提示生成文本
  • 流媒体工具:为实时更新提供流式响应
  • 嵌入工具:为文本生成向量嵌入
  • 检索工具:提供检索增强生成功能

这些工具会自动向MCP服务器注册,使其可供所有连接的客户端使用。

基于人工智能的工具生成

代码中展示的最具创新性的功能之一是能够使用LLM本身自动生成新工具。这在 _generateAutomaticTool 功能:

void _generateAutomaticTool(LlmServer server, Logger logger) async {
  try {
    logger.info('Generating sentiment analysis tool...');

    // Tool description - LLM uses this description to generate the tool
    final toolDescription = """
      Create a tool that analyzes the sentiment of text. This tool should provide:
      
      1. Sentiment analysis of input text (positive, negative, neutral)
      2. Sentiment score (-1.0 to 1.0, where -1 is most negative, 1 is most positive)
      3. Extraction of key sentiment words
      4. Analysis confidence (0.0 to 1.0)
      
      It should support text in multiple languages and provide results in either text or JSON format.
      
      The tool name must be sentiment_analyzer.
      """;

    // Attempt LLM-based tool generation
    try {
      logger.info('Attempting LLM-based tool generation...');

      // Generate tool
      final success = await server.generateAndRegisterTool(
        toolDescription,
        registerWithServer: true,  // Auto-register with server
      );

      logger.info('Automatic tool generation result: ${success ? "Success" : "Failed"}');

      if (!success) {
        logger.info('Automatic generation failed...');
      }
    } catch (e) {
      logger.error('Error during tool generation: $e');
      logger.info('Error...');
    }
  } catch (e) {
    logger.error('Error during sentiment analyzer tool setup: $e');
  }
}

此函数使用 generateAndRegisterTool 方法:

  1. 向LLM发送自然语言工具描述
  2. 让LLM设计工具的输入模式和实现
  3. 为工具功能生成可执行代码
  4. 在服务器上注册生成的工具

这种强大的功能允许开发人员通过用自然语言描述来创建复杂的工具,大大加快了开发速度。

服务器监控和管理

示例代码包括几个用于有效服务器监控和管理的功能:

1.测井系统

该代码建立了一个不同级别的综合日志系统:

final logger = Logger.getLogger('mcp_llm.server');

// Set log level based on environment
final LogLevel logLevel;
switch (logLevelStr.toLowerCase()) {
  case 'trace': logLevel = LogLevel.trace; break;
  case 'debug': logLevel = LogLevel.debug; break;
  case 'info': logLevel = LogLevel.info; break;
  case 'warning': logLevel = LogLevel.warning; break;
  case 'error': logLevel = LogLevel.error; break;
  default: logLevel = LogLevel.info;
}
logger.setLevel(logLevel);

此日志记录系统有助于跟踪服务器操作、错误和重要事件。

2.工具库存

代码列出了注册后所有可用的工具:

// Output available tools
final tools = mcpServer.getTools();
logger.info('');
logger.info('Available tools:');
for (final tool in tools) {
  logger.info('- ${tool.name}: ${tool.description}');
}

这提供了客户可用功能的清晰视图。

3.优雅关机

该代码实现了一个优雅的关闭机制,以确保正确的资源清理:

// Handle server shutdown - for Ctrl+C or other termination
ProcessSignal.sigint.watch().listen((_) async {
  logger.info('Shutting down server...');
  await mcpLlm.shutdown();
  exit(0);
});

这可确保在服务器终止时正确释放所有资源。

后续步骤

实施基本集成后 LlmServermcp_server,您可能想探索几个高级主题:

  1. 多LLM提供商集成:将不同的AI模型(Claude、GPT等)与MCP生态系统集成
  2. MCP插件系统开发:将自定义工具和资源构建为插件
  3. 分布式MCP环境:创建具有多个MCP客户端和服务器的复杂系统
  4. 使用MCP工具进行并行处理:使用MCP工具实现并行任务执行
  5. 构建基于MCP的RAG系统实施基于知识的文档检索系统

整合 LlmServer 随着 mcp_server 为构建可供各种客户端应用程序使用的人工智能服务开辟了许多可能性。

结论

在本文中,我们探讨了 LlmServermcp_server 创建强大的人工智能服务。这种服务器端集成提供了许多好处:

  1. API标准化:通过标准化协议展示人工智能能力
  2. 资源优化:在服务器上处理繁重的人工智能工作负载,保护客户端资源
  3. 集中管理:从中心位置管理所有AI功能和工具
  4. 可扩展性:无需客户端更改,即可轻松添加新的AI功能或工具
  5. 多客户端支持:使用单个服务器支持各种客户端平台
  6. 增强的安全性:在服务器上保留敏感的API密钥和凭据

使用LLM本身自动生成新工具的能力特别令人兴奋,因为它允许开发人员使用自然语言描述而不是编写代码来创建复杂的AI驱动工具。

通过将前面文章中讨论的客户端集成与这里介绍的服务器端集成相结合,您可以构建一个完整的、可扩展的AI生态系统,利用模型上下文协议的强大功能。

______________________________________________________________________

资源

______________________________________________________________________

支持开发者

如果你觉得这篇文章很有帮助,请考虑通过Patreon支持更多免费内容的开发。你的支持会带来很大的不同!

![Support on Patreon](https://www.patreon.com/mcpdevstudio)

标签:#Flutter#AI#MCP#LLM#Dart#OpenAI#模型上下文协议#AIIntegration#MCP_server#LlmServer

目录标签

目录标签

ClaudeAI代理工作流自动化Dart本地部署AI集成服务器端AI多客户端支持工具自动生成模型上下文协议

支持客户端

Claude

接入字段

传输方式(transport,传输协议)

未说明

鉴权方式(authType,认证方式)

api-key

工具数量(toolCount,工具数)

4

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

未说明api-key部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

仍需确认:installCommand

来源信息

继续浏览同类 MCP