MCP让你的传统应用焕发AI新活力

80 阅读7分钟

MCP让你的传统应用焕发AI新活力

最近 MCP (Model Context Protocol) 异常爆火,借助 IoTGateway项目 ,和大家做一下实战分享 ## 抛出一个问题 “ 大模型都是别人预训练好的数据,如何才获取到我的应用或系统中的实时数据呢? ” 这个问题背后实际是在问 “ 大语言模型如何感知现实世界、影响现实世界? ” 通过下面的教程,你一定会找到答案。 ## 实现效果 就让我们从 IoTGateway项目 入手,快速了解并 掌握 MCP 的基本原理和用法 目标 是使用 自然语言提问 ,自动 调用IoTGateway 的MCPServer 回答相关问题 ## 什么是Function Calling(函数调用) 大语言模型本身相当于一个被关在铁笼子里的专家,无法了解外部信息也无法和外部交互,OpenAI 在2023年6月份时给出了Function Calling(函数调用)方案。Function Calling相当于提供了一个跑腿小哥给这个专家,由他代劳信息搜集和数据交互的工作,详细的知识图解见下: ## 什么是 MCP(模型上下文协议) MCP 是 Anthropic(Claude 的母公司)在2024年12月份提出来的 Agent开发过程中的规范,它是连接 API 和大模型的桥梁。通过 MCP,大模型可以调用和操作第三方工具,从而扩展大模型的能力边界。 MCP 让大模型不再局限于预训练的知识,而是能够实时地与外部世界互动。 MCP 主要做了两件事: 1. 统一命名,把大模型的运行环境叫做MCP Client,Function叫做MCP Server; 2. 统一开发规范,把大模型与Function之间的交互规范统一为一个范式。

Function Calling与MCP通俗类比

  • Function Calling(函数调用) Function Calling 像是一家专门店,当你只需要某个特定产品时,你直接走进这家店,一对一地享受专业服务。这里没有购物中心那种多样化和统一标准,只是针对某个具体需求进行快速解决。这正好类似于函数调用,它专注于完成单一任务,过程简单直接,适合处理特定功能需求。

  • MCP(模型上下文协议) 像是一个大型购物中心,这里所有店铺都遵循统一的设计风格和支付系统,无论你要买什么(比如服装、食品或电子产品),你都可以通过同一个入口、使用同一种支付方式快速找到并购买。这种统一性让你在不同店铺之间切换非常顺畅。类似地,MCP 提供了一个标准化的接口,让各种数据源和工具像不同的店铺一样整合在一起,方便 AI 模型以一致的方式获取和处理信息。 总结来说: MCP 提供的是一个广泛、标准化的生态系统,适合多样化和复杂的场景; 而函数调用则更像是专门化、针对性强的服务。 ## MCP的两种模式

  • stdio(标准输入输出) 这种方式常用于本地开发和调试阶段。MCP 服务器可以作为子进程,通过标准输入输出流直接与主程序通信。它实现简单、延迟低,非常适合快速开发和问题排查,但不适用于分布式环境或需要长连接实时更新的场景。

  • sse (Server-Sent Events) SSE 基于 HTTP 协议,是一种单向实时数据推送机制。它允许服务器持续向客户端发送更新信息,非常适合云端或分布式系统中需要实时数据流的应用场景。通过 SSE,MCP 客户端可以保持一个长连接,及时接收来自服务器的事件和数据更新,从而满足实时性要求较高的应用需求。

什么是IoTGateway

我想你一定知道, IoTGateway 是基于.NET8的 开源 跨平台架构 工业物联网网关 。 通过可视化配置(B/S),轻松的连接到你的任何设备和系统(如PLC、扫码枪、CNC、数据库、串口设备、上位机、OPC Server、OPC UA Server、Mqtt Server等),从而与 物联网平台、MES、SCADA、进行双向数据通讯 。 提供简单 的驱动二次开发 接口,当然也可以进行 边缘计算 。 项目文档: iotgateway.net/ ## 环境准备

visual studio v2022
node v18.20.4
npx v10.7.0
vscode v1.99.0

IoTGateway中编写MCP Server

```
  • AddMcpServer WithTools ``` services.AddMcpServer().WithTools();

* UseEndpoints MapMcp ```
app.UseEndpoints(endpoints =>
 {
     endpoints.MapMcp();
 });
  • 添加DeviceTool.cs,用来返回网关内当前子设备清单、子设备状态和当前变量值 ``` using ModelContextProtocol.Server; using Plugin; using System.ComponentModel; using System.Linq; using System.Collections.Generic; using JetBrains.Annotations;

namespace IoTGateway.MCP { [McpServerToolType] public sealed class DeviceTool { private readonly DeviceService _deviceService; public DeviceTool(DeviceService deviceService) { _deviceService = deviceService; } ///

/// Get the list of sub-devices. /// /// [McpServerTool(Name = "DevicesList"), Description("Get the list of sub-devices.")] public IEnumerable DevicesList() { return _deviceService.DeviceThreads.Select(x => x.Device.DeviceName); }

    /// <summary>
    /// Get the current connection status of the sub-device.
    /// </summary>
    /// <param name="deviceName"></param>
    /// <returns></returns>
    [McpServerTool, Description("Get the current connection status of the sub-device.")]
    public bool? GetDeviceStatus(
        [Description("name of device")] string deviceName
        )
    {
        return _deviceService.DeviceThreads.FirstOrDefault(x => x.Device.DeviceName == deviceName)?.Driver.IsConnected;
    }

    /// <summary>
    /// Get the current value of a variable of a sub-device.
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    [McpServerTool, Description("Get sub-device variables.")]
    [CanBeNull]
    public Dictionary<string, object> GetDeviceVariables(
        [Description("name of device")] string deviceName
        )
    {
        return _deviceService.DeviceThreads.FirstOrDefault(x => x.Device.DeviceName == deviceName)?.Device
            .DeviceVariables.ToDictionary(x => x.Name, x => x.CookedValue);
    }

    /// <summary>
    /// Get the current value of a variable of a sub-device.
    /// </summary>
    /// <param name="deviceName"></param>
    /// <param name="variableName"></param>
    /// <returns></returns>
    [McpServerTool, Description("Get the current value of a variable of a sub-device.")]
    public object GetDeviceVariable(
        [Description("name of device")] string deviceName,
        [Description("name of variable")] string variableName)
    {
        return _deviceService.DeviceThreads.FirstOrDefault(x => x.Device.DeviceName == deviceName)?.Device
            .DeviceVariables.FirstOrDefault(x => x.Name == variableName)?.CookedValue;
    }
}

}

 ## IoTGatway MCP Server调试

* 运行IoTGateway项目 访问http://localhost:518/Login/Login配置数据采集
* 运行inspector powershell 中执行 ```
npx @modelcontextprotocol/inspector

VSCode添加IoTGatway MCP Server

  • 安装Cline扩展并配置 API Provider使用 OpenRouter Model使用 deepseek/deepseek-chat:free
  • cline_mcp_settings.json 添加中添加 IoTGateway MCP Server ``` { "mcpServers": { "iotgateway": { "disabled": false, "timeout": 30, "url": "http://localhost:518/sse", "transportType": "sse", "autoApprove": [ "GetDeviceVariable", "GetDeviceStatus", "GetDeviceVariables", "DevicesList" ] } } }

* 查看IoTGateway提供的 4个Tool
 ## Task1:查询子设备某变量当前值
 Q1:"Modbus"子设备中,"temperature"变量当前值是多少? A1:The current value of the "temperature" variable in the "Modbus" sub-device is 29.32. ## Task2:查询子设备当前连接状态
 Q2:"网关中配置了几个子设备?他们的连接状态怎么样? A2:网关中配置了2个子设备: 1. 485总线 - 已连接
2. Modbus - 已连接
 ## 融合的价值
 * 实时数据驱动的智能决策
 将 IoTGateway 与 MCP 协议相结合,可以实现从工业现场到AI决策层的无缝数据传输。工业网关负责实时采集并预处理设备数据,而 MCP 协议则将这些数据以标准化的格式提供给 AI 模型,帮助企业构建基于实时数据的智能决策系统。例如,在设备预测维护、生产流程优化和异常报警中,AI 模型能够即时分析网关上传的数据,提前识别潜在故障或生产瓶颈,从而提高生产效率和安全性。 * 降低集成与开发成本
 传统上,不同系统之间的数据对接往往需要开发大量定制接口,导致开发成本高且维护难度大。通过采用 MCP 协议,企业可以利用现有的预构建模块实现不同数据源与 AI 系统之间的快速集成,降低了系统间集成的复杂度和成本。同时,开源的 IoTGateway 提供了灵活的扩展能力,二者的结合能够使开发者在不同场景下快速搭建原型,加速产品上市。 * 提升工业物联网系统的未来适应性
 工业现场的设备种类繁多、数据格式各异,而 MCP 协议的标准化特性使得系统具有更好的兼容性和扩展性。通过 IoTGateway 采集和传输的数据经过 MCP 协议统一处理,企业不仅能够在当前实现数据驱动的智能管理,更能够轻松对接未来的新型设备和服务,确保系统具备长远的适应性和竞争力。 ## 总结
 通过整合开源工业物联网网关 IoTGateway 与 MCP 协议,企业能够实现从现场数据采集、边缘预处理到AI智能决策的全链路数据闭环。两者的融合不仅提高了数据处理的实时性和准确性,还大幅降低了系统集成成本,提升了整个工业物联网系统的安全性和扩展性。随着技术不断发展,这种融合模式将为工业智能化转型提供更加坚实的数据和技术支撑,推动企业迈向更高效、更智能的未来。

> 原文链接: https://www.cnblogs.com/whdong/p/18811226