自定义 MCP Server,在 cursor 中连接本地 MySQL 实现了统计分析

前言

在上一篇cursor 如何调用 MCP server 实现天气查询文章中,我通过在网上找到的天气查询 MCP Server,直接通过复制mcp.json直接实现了cursor天气查询的调用。那么,如果我们自己开发的 MCP Server 该如何在cursor中调用呢?

所以本篇文章就通过实现一个 MySQL 数据库查询的 MCP Server,探索在cursor中如何配置并调用自己的 MCP Server,以此来实现 MySQL 数据库的查询。

MCP Server 开发

之前说过用 uv 进行管理 MCP 项目,这里为了简化开发,直接使用 pip 进行开发,要求 Python 版本在3.10及以上。

数据准备

首先在 MySQL 中创建要使用的数据库和表,并插入测试数据。

create database mcp;
use mcp;
CREATE TABLE user (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    age INT NOT NULL
);

-- 插入 10 条数据
INSERT INTO user (name, age) VALUES 
('Alice', 23),
('Bob', 30),
('Charlie', 27),
('David', 35),
('Eve', 22),
('Frank', 28),
('Grace', 31),
('Heidi', 26),
('Ivan', 29),
('Judy', 24);

程序开发

python 开发连接数据库的 MCP Server 只需要安装两个依赖,mcpcli 和 pymysql,执行下面命令即可完成安装。

pip install "mcp[cli]" 
pip install pymysql

然后就是使用 python 开发 MCP server。整体程序设计分为两个部分:

  1. MCP Server 的定义,这里可以参考之前写的一篇博客什么是MCP?本地如何开发MCP Server
  2. pymysql 连接 MySQL 查询数据库

新建一个 mysql_mcp.py 文件,其中代码实现如下:

from mcp.server.fastmcp import FastMCP
import pymysql

mcp = FastMCP("MySQLMCP")

@mcp.tool()
def analysis_data(age: int) -> int:
    conn = pymysql.connect(
        host="152.136.xx.xxx",
        port=3306,
        user="root",
        password="1234567",
        database="mcp"
    )
    cursor = conn.cursor()
    cursor.execute(f"SELECT COUNT(*) FROM user where age > {age}")
    result = cursor.fetchone()[0]
    cursor.close()
    conn.close()
    return result

if __name__ == "__main__":
    mcp.run()

在上面代码中定义了函数 analysis_data,在里面实现了 MySQL 的连接以及对 user 表的查询,通过传入的参数 age 作为限定条件统计用户个数。使用 @mcp.tool() 注解将 analysis_data 变成了 MCP Server 的“工具”。

调试

还是通过 mcp dev 启动 MCP Insepctor 进行调试我们的 MCP Server 是否可用。

在浏览器中访问6274端口即可访问,点击 Connect 连接到 MCP Server。在 Tools 标签页下可以看到我们定义的 analysis_data。

点击 Run Tool,输入参数 age 即可获取查询数据库的统计结果。

如上图说,查询到数据库并成功返回。接下来就是将这个 MCP Server 配置到 cursor 中。

cursor 配置 MCP Server

首先我们需要编写 MCP Server 的 json 信息,这个还是超简单的,如下所示:

{
    "mcpServers": {
      "mysql_mcp": {
        "command": "python3.10",
        "args": [
          "/Users/aqi/mcp-demo/server/mysql_mcp.py"
        ]
      }
    }
  }
  1. mcpServers 是固定的,是 MCP Server 的顶级节点。
  2. mysql_mcp 是自定义的节点名称。
  3. commandargs 分别是运行命令和参数。

在 Cursor Settings 中找到 MCP,点击右侧上方的 Add new global MCP server 按钮,
会自动打开 mcp.json 文件,将上面 json 内容粘贴进去保存,回到 MCP 页面即可看到我们的 MCP Server 信息。

在 cursor 的 chat 聊天框中,输入我们的查询需求运行,cursor 就会调用 MCP Server 的 analysis_data 工具进行查询。

运行成功之后将结果返回。

结语

本篇文章通过自定义 MCP Server,在 cursor 中调用 tool 对 MySQL 的数据查询,从程序开发来看,MCP Server 连接数据库的实现,和普通 Python 程序连接 MySQL 基本上没什么区别。这也进一步说明了 MCP 给 LLM 工具的开发带来了很大的提升,也从侧面说明了有了 MCP 万物可连。

### Python MCP ServerCursor 的用法 在 Python MCP (Message Communication Protocol) 服务器中,`cursor` 是用于管理数据库查询结果的一个重要对象。它允许开发者通过编程方式执行 SQL 查询并处理返回的数据集[^1]。 以下是 `cursor` 在 Python MCP Server 连接中的典型用法: #### 建立连接与创建游标 首先需要建立到数据库的连接,并从中获取一个 `cursor` 对象。这通常涉及以下几个步骤: - 使用合适的库(如 psycopg2 或 pymysql)来初始化数据库连接。 - 调用连接对象上的 `.cursor()` 方法以获得一个新的游标实例。 ```python import mcp.db as db_module # 假设这是自定义模块或者标准库的一部分 connection = db_module.connect( host="localhost", user="your_username", password="your_password", database="mcp_database" ) cursor = connection.cursor() ``` 上述代码展示了如何设置基本的数据库连接以及创建游标的过程[^3]。 #### 执行查询操作 一旦获得了游标对象,就可以调用其方法来执行各种类型的 SQL 操作,比如 SELECT、INSERT 和 UPDATE 等语句。 对于简单的读取数据场景可以这样实现: ```python query = "SELECT id, name FROM users WHERE active = %s" try: cursor.execute(query, ("true",)) # 参数化查询防止SQL注入攻击 except Exception as e: print(f"An error occurred while executing the query: {e}") else: results = cursor.fetchall() # 获取所有匹配记录 for row in results: print(row) finally: cursor.close() # 关闭游标释放资源 ``` 这里需要注意的是,在实际应用过程中应当始终考虑异常情况的发生,并采取适当措施加以应对[^2]。 #### 更新或删除数据 除了检索之外,还可以利用游标的 execute 函数来进行修改型的操作,例如更新某条特定用户的邮箱地址如下所示: ```python update_query = """UPDATE users SET email=%(email)s WHERE username=%(username)s""" data_to_update = { 'email': '[email protected]', 'username': 'johndoe' } affected_rows_count = None try: affected_rows_count = cursor.execute(update_query, data_to_update) connection.commit() # 提交更改至永久存储介质上 except Exception as err_msg: connection.rollback() # 如果失败则回滚事务状态回到之前的状态 raise RuntimeError('Database update failed') from err_msg print(f"{affected_rows_count} rows were updated.") ``` 此片段说明了当尝试改变表内字段值时应遵循的最佳实践之一——即先测试再确认提交;如果出现问题,则立即撤销所做的任何潜在破坏性的变动。 最后别忘了断开已不再使用的链接以免浪费系统资源! ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值