在本地部署mcp服務器實現自然語言操作mysql數據庫,輕松實現數據表的增~ 刪~ 改~ 查~

1.將寫好的mcp_server代碼放在本地任意盤!

import asyncio
import logging
import os
import sys
from mysql.connector import connect, Error
from mcp.server import Server
from mcp.types import Resource, Tool, TextContent
from pydantic import AnyUrl# Configure logging
logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("mysql_mcp_server")def get_db_config():"""Get database configuration from environment variables."""config = {"host": os.getenv("MYSQL_HOST", "localhost"),"port": int(os.getenv("MYSQL_PORT", "3306")),"user": os.getenv("MYSQL_USER"),"password": os.getenv("MYSQL_PASSWORD"),"database": os.getenv("MYSQL_DATABASE"),# Add charset and collation to avoid utf8mb4_0900_ai_ci issues with older MySQL versions# These can be overridden via environment variables for specific MySQL versions"charset": os.getenv("MYSQL_CHARSET", "utf8mb4"),"collation": os.getenv("MYSQL_COLLATION", "utf8mb4_unicode_ci"),# Disable autocommit for better transaction control"autocommit": True,# Set SQL mode for better compatibility - can be overridden"sql_mode": os.getenv("MYSQL_SQL_MODE", "TRADITIONAL")}# Remove None values to let MySQL connector use defaults if not specifiedconfig = {k: v for k, v in config.items() if v is not None}if not all([config.get("user"), config.get("password"), config.get("database")]):logger.error("Missing required database configuration. Please check environment variables:")logger.error("MYSQL_USER, MYSQL_PASSWORD, and MYSQL_DATABASE are required")raise ValueError("Missing required database configuration")return config# Initialize server
app = Server("mysql_mcp_server")@app.list_resources()
async def list_resources() -> list[Resource]:"""List MySQL tables as resources."""config = get_db_config()try:logger.info(f"Connecting to MySQL with charset: {config.get('charset')}, collation: {config.get('collation')}")with connect(**config) as conn:logger.info(f"Successfully connected to MySQL server version: {conn.get_server_info()}")with conn.cursor() as cursor:cursor.execute("SHOW TABLES")tables = cursor.fetchall()logger.info(f"Found tables: {tables}")resources = []for table in tables:resources.append(Resource(uri=f"mysql://{table[0]}/data",name=f"Table: {table[0]}",mimeType="text/plain",description=f"Data in table: {table[0]}"))return resourcesexcept Error as e:logger.error(f"Failed to list resources: {str(e)}")logger.error(f"Error code: {e.errno}, SQL state: {e.sqlstate}")return []@app.read_resource()
async def read_resource(uri: AnyUrl) -> str:"""Read table contents."""config = get_db_config()uri_str = str(uri)logger.info(f"Reading resource: {uri_str}")if not uri_str.startswith("mysql://"):raise ValueError(f"Invalid URI scheme: {uri_str}")parts = uri_str[8:].split('/')table = parts[0]try:logger.info(f"Connecting to MySQL with charset: {config.get('charset')}, collation: {config.get('collation')}")with connect(**config) as conn:logger.info(f"Successfully connected to MySQL server version: {conn.get_server_info()}")with conn.cursor() as cursor:cursor.execute(f"SELECT * FROM {table} LIMIT 100")columns = [desc[0] for desc in cursor.description]rows = cursor.fetchall()result = [",".join(map(str, row)) for row in rows]return "\n".join([",".join(columns)] + result)except Error as e:logger.error(f"Database error reading resource {uri}: {str(e)}")logger.error(f"Error code: {e.errno}, SQL state: {e.sqlstate}")raise RuntimeError(f"Database error: {str(e)}")@app.list_tools()
async def list_tools() -> list[Tool]:"""List available MySQL tools."""logger.info("Listing tools...")return [Tool(name="execute_sql",description="Execute an SQL query on the MySQL server",inputSchema={"type": "object","properties": {"query": {"type": "string","description": "The SQL query to execute"}},"required": ["query"]})]@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:"""Execute SQL commands."""config = get_db_config()logger.info(f"Calling tool: {name} with arguments: {arguments}")if name != "execute_sql":raise ValueError(f"Unknown tool: {name}")query = arguments.get("query")if not query:raise ValueError("Query is required")try:logger.info(f"Connecting to MySQL with charset: {config.get('charset')}, collation: {config.get('collation')}")with connect(**config) as conn:logger.info(f"Successfully connected to MySQL server version: {conn.get_server_info()}")with conn.cursor() as cursor:cursor.execute(query)# Special handling for SHOW TABLESif query.strip().upper().startswith("SHOW TABLES"):tables = cursor.fetchall()result = ["Tables_in_" + config["database"]]  # Headerresult.extend([table[0] for table in tables])return [TextContent(type="text", text="\n".join(result))]# Handle all other queries that return result sets (SELECT, SHOW, DESCRIBE etc.)elif cursor.description is not None:columns = [desc[0] for desc in cursor.description]try:rows = cursor.fetchall()result = [",".join(map(str, row)) for row in rows]return [TextContent(type="text", text="\n".join([",".join(columns)] + result))]except Error as e:logger.warning(f"Error fetching results: {str(e)}")return [TextContent(type="text", text=f"Query executed but error fetching results: {str(e)}")]# Non-SELECT querieselse:conn.commit()return [TextContent(type="text", text=f"Query executed successfully. Rows affected: {cursor.rowcount}")]except Error as e:logger.error(f"Error executing SQL '{query}': {e}")logger.error(f"Error code: {e.errno}, SQL state: {e.sqlstate}")return [TextContent(type="text", text=f"Error executing query: {str(e)}")]async def main():"""Main entry point to run the MCP server."""from mcp.server.stdio import stdio_server# Add additional debug outputprint("Starting MySQL MCP server with config:", file=sys.stderr)config = get_db_config()print(f"Host: {config['host']}", file=sys.stderr)print(f"Port: {config['port']}", file=sys.stderr)print(f"User: {config['user']}", file=sys.stderr)print(f"Database: {config['database']}", file=sys.stderr)logger.info("Starting MySQL MCP server...")logger.info(f"Database config: {config['host']}/{config['database']} as {config['user']}")async with stdio_server() as (read_stream, write_stream):try:await app.run(read_stream,write_stream,app.create_initialization_options())except Exception as e:logger.error(f"Server error: {str(e)}", exc_info=True)raiseif __name__ == "__main__":asyncio.run(main())

2.再cherry studio中導入json配置參數

{"mcpServers": {"mysql": {"command": "uv","args": ["--directory","path/to/mysql_mcp_server","run","mysql_mcp_server"],"env": {"MYSQL_HOST": "localhost","MYSQL_PORT": "3306","MYSQL_USER": "your_username","MYSQL_PASSWORD": "your_password","MYSQL_DATABASE": "your_database"}}}
}

其中args中的參數說明:~
“–directory”, # 目錄參數
“path/to/mysql_mcp_server.py”, # mcpserver端程序放置絕對路徑!
“run”, # uv啟動python腳本!
“mysql_mcp_server.py” # mcpserver代碼 !

其中env中為本地或者遠程數據庫配置參數:~
“MYSQL_HOST”: “localhost”, #mysql主機IP
“MYSQL_PORT”: “3306”, #mysql服務端口
“MYSQL_USER”: “your_username”, #數據庫用戶名
“MYSQL_PASSWORD”: “your_password”, #數據庫密碼
“MYSQL_DATABASE”: “your_database” #數據庫名

3.再cherry studio中新建會話,選擇mysql mcp服務器

在這里插入圖片描述

即可使用自然語言對數據表進行增刪改查!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88175.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88175.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88175.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025快手創作者中心發布視頻python實現

難度還行,只有一個__NS_sig3加密,流程麻煩點cookies_list cookie.split("; ")cookie_dict {}# 遍歷每個 Cookie,根據等號將鍵值對拆分并添加到字典中for cookie in cookies_list:key_value cookie.split("")if len(ke…

Android 組件內核

文章目錄什么是binder1. 什么是Binder?2. Binder架構組成3. 工作原理與通信流程1)服務注冊2)服務查詢3)通信過程4)核心數據結構4. 關鍵技術點5. 常見面試考點1)Binder與傳統IPC(Socket、管道、共…

java類加載機制:Tomcat的類加載機制

Tomcat類加載機制深度解析:打破雙親委派的Web容器實現 Tomcat作為Java Web容器,其類加載機制為滿足Web應用的隔離性、熱部署和兼容性需求,對標準Java類加載機制進行了定制化擴展,核心是打破雙親委派模型并引入多層級類加載器。以下…

【PTA數據結構 | C語言版】從順序表 list 中刪除第 i 個元素

本專欄持續輸出數據結構題目集,歡迎訂閱。 文章目錄題目代碼題目 請編寫程序,將 n 個整數存入順序表,對任一指定的第 i 個位置,將這個位置上的元素從順序表中刪除。注意:i 代表位序,從 1 開始,…

VS2022 C++ EasyX庫 掃雷游戲項目開發:打造經典游戲的詳細之旅

老樣子,先上效果 視頻演示 C經典掃雷-介紹一、引言 在這篇博客中,我將詳細介紹掃雷游戲項目的開發過程。掃雷作為一款經典的游戲,其規則簡單但富有挑戰性。通過開發這個項目,我不僅加深了對 C 編程的理解,還提升了自己…

Go語言網絡游戲服務器模塊化編程

本文以使用origin框架(一款使用Go語言寫的開源游戲服務器框架)為例進行說明,當然也可以使用其它的框架或者自己寫。 在框架中PBProcessor用來處理Protobuf消息,在使用之前,需要使用Register函數注冊網絡消息&#xff…

【機器人】Aether 多任務世界模型 | 4D動態重建 | 視頻預測 | 視覺規劃

Aether 是一個的世界模型,整合幾何重建與生成建模的統一框架,實現類人空間推理能力。 來自ICCV 2025,該框架具有三大核心功能: (1) 4D動態重建,(2) 動作條件視頻預測, (3) 目標條件視覺規劃。 代碼地址&…

MiniMind:3小時訓練26MB微型語言模型,開源項目助力AI初學者快速入門

開發|界面|引擎|交付|副駕——重寫全棧法則:AI原生的倍速造應用流來自全棧程序員 nine 的探索與實踐,持續迭代中。 歡迎關注評論私信交流~ 在大型語言模型(LLaMA、GPT等)日益流行的今天,一個名為…

相機Camera日志實例分析之五:相機Camx【萌拍閃光燈后置拍照】單幀流程日志詳解

【關注我,后續持續新增專題博文,謝謝!!!】 上一篇我們講了: 這一篇我們開始講: 目錄 一、場景操作步驟 二、日志基礎關鍵字分級如下 三、場景日志如下: 一、場景操作步驟 操作步…

[2-02-02].第03節:環境搭建 - Win10搭建ES集群環境

ElasticSearch學習大綱 基于ElasticSearch7.8版本 一、ElasticStack下載: 1.Elasticsearch 的官方地址 2.Elasticsearch 下載地址: 二、集群搭建: 第1步:創建es目錄: 1.創建 elasticsearch-cluster 文件夾,在內部…

操作系統核心技術剖析:從Android驅動模型到鴻蒙微內核的國產化實踐

目錄 一、移動端操作系統技術細節 1. Android 內核版本 核心模塊 驅動架構 國內定制案例 2. iOS XNU內核關鍵模塊 安全機制 3. HarmonyOS 多內核架構 驅動隔離 二、PC端操作系統技術細節 1. Windows NT內核 模塊分層 驅動模型 國內適配 2. macOS(X…

整合Spring、Spring MVC與MyBatis:構建高效Java Web應用

本文將詳細講解如何整合Spring、Spring MVC和MyBatis(SSM框架),通過一個人員信息查詢案例展示完整開發流程。所有代碼基于提供的文件實現。一、項目結構src/ ├── main/ │ ├── java/ │ │ └── com/ │ │ └── qcb…

視頻插幀技術:從流暢觀影到AI創作的革命

一、起源:為什么需要視頻插幀? 視頻的本質是連續播放的靜態幀序列,幀率(FPS) 決定了流暢度。早期電影受限于拍攝技術和存儲成本,普遍采用24FPS,而現代顯示設備(如120Hz屏幕&#xf…

【一起來學AI大模型】PyTorch 實戰示例:使用 BatchNorm 處理張量(Tensor)

PyTorch 實戰示例 演示如何在神經網絡中使用 BatchNorm 處理張量(Tensor),涵蓋關鍵實現細節和常見陷阱。示例包含數據準備、模型構建、訓練/推理模式切換及結果分析。示例場景:在 CIFAR-10 數據集上實現帶 BatchNorm 的 CNNimport…

第8章:應用層協議HTTP、SDN軟件定義網絡、組播技術、QoS

應用層協議HTTP 應用層協議概述 應用層協議非常多,我們重點熟悉以下常見協議功能即可。 Telnet:遠程登錄協議,基于TCP 23端口,用于遠程管理設備,采用明文傳輸。安全外殼協議 (SecureShell,SSH) ,基于TCP 22端口,用于…

uniapp頁面間通信

uniapp中通過eventChannel實現頁面間通信的方法,這是一種官方推薦的高效傳參方式。我來解釋下這種方式的完整實現和注意事項:?發送頁面(父頁面)?:uni.navigateTo({url: /pages/detail/detail,success: (res) > {/…

Android ViewModel機制與底層原理詳解

Android 的 ViewModel 是 Jetpack 架構組件庫的核心部分,旨在以生命周期感知的方式存儲和管理與 UI 相關的數據。它的核心目標是解決兩大痛點: 數據持久化: 在配置變更(如屏幕旋轉、語言切換、多窗口模式切換)時保留數…

雙倍硬件=雙倍性能?TDengine線性擴展能力深度實測驗證!

軟件擴展能力是軟件架構設計中的一個關鍵要素,具有良好擴展能力的軟件能夠充分利用新增的硬件資源。當軟件性能與硬件增加保持同步比例增長時,我們稱這種現象為軟件具有線性擴展能力。要實現這種線性擴展并不簡單,它要求軟件架構精心設計&…

頻繁迭代下完成iOS App應用上架App Store:一次快速交付項目的完整回顧

在一次面向商戶的會員系統App開發中,客戶要求每周至少更新一次版本,涉及功能迭代、UI微調和部分支付方案的更新。團隊使用Flutter進行跨平臺開發,但大部分成員日常都在Windows或Linux環境,只有一臺云Mac用于打包。如何在高頻率發布…

springsecurity03--異常攔截處理(認證異常、權限異常)

目錄 Spingsecurity異常攔截處理 認證異常攔截 權限異常攔截 注冊異常攔截器 設置跨域訪問 Spingsecurity異常攔截處理 認證異常攔截 /*自定義認證異常處理器類*/ Component public class MyAuthenticationExceptionHandler implements AuthenticationEntryPoint {Overr…