使用 Python 項目管理工具 uv 快速創建 MCP 服務(Cherry Studio、Trae 添加 MCP 服務)

文章目錄

  • 下載Trae
  • uv 工具教程參考我的這篇文章
  • 創建 uv 項目
  • main.py
  • Cherry Studio 添加 MCP 服務
    • 申請 DeepSeek API
    • 配置 DeepSeek API
    • 調用 MCP 服務
  • Trae 添加 MCP 服務
    • 添加 MCP
    • 創建智能體
  • 使用智能體
    • 調用 MCP 創建 demo 表
    • 查詢 demo 表結構信息
    • demo 表插入 2 條測試數據
    • 查詢 demo 表中的數據

下載Trae

  • https://www.trae.com.cn/
    在這里插入圖片描述

uv 工具教程參考我的這篇文章

  • 讓 Python 項目管理變簡單(uv 工具快速上手指南)

創建 uv 項目

uv init demo
cd demo
  • 添加依賴項
uv add 'mcp[cli]'

在這里插入圖片描述

main.py

import asyncio
import argparse
import sqlite3
import logging
from contextlib import closing
from pathlib import Path
from pydantic import AnyUrl
from typing import Anyfrom mcp.server import InitializationOptions
from mcp.server.lowlevel import Server, NotificationOptions
from mcp.server.stdio import stdio_server
import mcp.types as typeslogger = logging.getLogger('mcp_sqlite_server')
logger.info("Starting MCP SQLite Server")class SqliteDatabase:def __init__(self, db_path: str):self.db_path = str(Path(db_path).expanduser())Path(self.db_path).parent.mkdir(parents=True, exist_ok=True)self._init_database()self.insights: list[str] = []def _init_database(self):"""Initialize connection to the SQLite database"""logger.debug("Initializing database connection")with closing(sqlite3.connect(self.db_path)) as conn:conn.row_factory = sqlite3.Rowconn.close()def _synthesize_memo(self) -> str:"""Synthesizes business insights into a formatted memo"""logger.debug(f"Synthesizing memo with {len(self.insights)} insights")if not self.insights:return "No business insights have been discovered yet."insights = "\n".join(f"- {insight}" for insight in self.insights)memo = "📊 Business Intelligence Memo 📊\n\n"memo += "Key Insights Discovered:\n\n"memo += insightsif len(self.insights) > 1:memo += "\nSummary:\n"memo += f"Analysis has revealed {len(self.insights)} key business insights that suggest opportunities for strategic optimization and growth."logger.debug("Generated basic memo format")return memodef _execute_query(self, query: str, params: dict[str, Any] | None = None) -> list[dict[str, Any]]:"""Execute a SQL query and return results as a list of dictionaries"""logger.debug(f"Executing query: {query}")try:with closing(sqlite3.connect(self.db_path)) as conn:conn.row_factory = sqlite3.Rowwith closing(conn.cursor()) as cursor:if params:cursor.execute(query, params)else:cursor.execute(query)if query.strip().upper().startswith(('INSERT', 'UPDATE', 'DELETE', 'CREATE', 'DROP', 'ALTER')):conn.commit()affected = cursor.rowcountlogger.debug(f"Write query affected {affected} rows")return [{"affected_rows": affected}]results = [dict(row) for row in cursor.fetchall()]logger.debug(f"Read query returned {len(results)} rows")return resultsexcept Exception as e:logger.error(f"Database error executing query: {e}")raiseasync def main(db_path: str):logger.info(f"Starting SQLite MCP Server with DB path: {db_path}")db = SqliteDatabase(db_path)server = Server("sqlite-manager")logger.debug("Registering handlers")@server.list_resources()async def handle_list_resources() -> list[types.Resource]:logger.debug("Handling list_resources request")return [types.Resource(uri=AnyUrl("memo://insights"),name="Business Insights Memo",description="A living document of discovered business insights",mimeType="text/plain",)]@server.read_resource()async def handle_read_resource(uri: AnyUrl) -> str:logger.debug(f"Handling read_resource request for URI: {uri}")if uri.scheme != "memo":logger.error(f"Unsupported URI scheme: {uri.scheme}")raise ValueError(f"Unsupported URI scheme: {uri.scheme}")path = str(uri).replace("memo://", "")if not path or path != "insights":logger.error(f"Unknown resource path: {path}")raise ValueError(f"Unknown resource path: {path}")return db._synthesize_memo()@server.list_tools()async def handle_list_tools() -> list[types.Tool]:"""List available tools"""return [types.Tool(name="read_query",description="Execute a SELECT query on the SQLite database",inputSchema={"type": "object","properties": {"query": {"type": "string", "description": "SELECT SQL query to execute"},},"required": ["query"],},),types.Tool(name="write_query",description="Execute an INSERT, UPDATE, or DELETE query on the SQLite database",inputSchema={"type": "object","properties": {"query": {"type": "string", "description": "SQL query to execute"},},"required": ["query"],},),types.Tool(name="create_table",description="Create a new table in the SQLite database",inputSchema={"type": "object","properties": {"query": {"type": "string", "description": "CREATE TABLE SQL statement"},},"required": ["query"],},),types.Tool(name="list_tables",description="List all tables in the SQLite database",inputSchema={"type": "object","properties": {},},),types.Tool(name="describe_table",description="Get the schema information for a specific table",inputSchema={"type": "object","properties": {"table_name": {"type": "string", "description": "Name of the table to describe"},},"required": ["table_name"],},),types.Tool(name="append_insight",description="Add a business insight to the memo",inputSchema={"type": "object","properties": {"insight": {"type": "string", "description": "Business insight discovered from data analysis"},},"required": ["insight"],},),]@server.call_tool()async def handle_call_tool(name: str, arguments: dict[str, Any] | None) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:"""Handle tool execution requests"""try:if name == "list_tables":results = db._execute_query("SELECT name FROM sqlite_master WHERE type='table'")return [types.TextContent(type="text", text=str(results))]elif name == "describe_table":if not arguments or "table_name" not in arguments:raise ValueError("Missing table_name argument")results = db._execute_query(f"PRAGMA table_info({arguments['table_name']})")return [types.TextContent(type="text", text=str(results))]elif name == "append_insight":if not arguments or "insight" not in arguments:raise ValueError("Missing insight argument")db.insights.append(arguments["insight"])_ = db._synthesize_memo()# Notify clients that the memo resource has changedawait server.request_context.session.send_resource_updated(AnyUrl("memo://insights"))return [types.TextContent(type="text", text="Insight added to memo")]if not arguments:raise ValueError("Missing arguments")if name == "read_query":if not arguments["query"].strip().upper().startswith("SELECT"):raise ValueError("Only SELECT queries are allowed for read_query")results = db._execute_query(arguments["query"])return [types.TextContent(type="text", text=str(results))]elif name == "write_query":if arguments["query"].strip().upper().startswith("SELECT"):raise ValueError("SELECT queries are not allowed for write_query")results = db._execute_query(arguments["query"])return [types.TextContent(type="text", text=str(results))]elif name == "create_table":if not arguments["query"].strip().upper().startswith("CREATE TABLE"):raise ValueError("Only CREATE TABLE statements are allowed")db._execute_query(arguments["query"])return [types.TextContent(type="text", text="Table created successfully")]else:raise ValueError(f"Unknown tool: {name}")except sqlite3.Error as e:return [types.TextContent(type="text", text=f"Database error: {str(e)}")]except Exception as e:return [types.TextContent(type="text", text=f"Error: {str(e)}")]async with stdio_server() as (read_stream, write_stream):logger.info("Server running with stdio transport")await server.run(read_stream,write_stream,InitializationOptions(server_name="sqlite",server_version="0.1.0",capabilities=server.get_capabilities(notification_options=NotificationOptions(),experimental_capabilities={},),),)if __name__ == "__main__":parser = argparse.ArgumentParser(description='SQLite MCP Server')parser.add_argument('--db-path', default="./sqlite_mcp_server.db", help='Path to SQLite database file')args = parser.parse_args()asyncio.run(main(args.db_path))

Cherry Studio 添加 MCP 服務

  • 下載地址:https://cherry-ai.com/

  • MCP 參數

--directory
~/TraeProjects/demo
run
main.py
--db-path
~/TraeProjects/demo/test.db

在這里插入圖片描述
在這里插入圖片描述

申請 DeepSeek API

  • 申請 API_KEY:https://platform.deepseek.com/usage

在這里插入圖片描述

配置 DeepSeek API

在這里插入圖片描述

調用 MCP 服務

在這里插入圖片描述
在這里插入圖片描述

Trae 添加 MCP 服務

  • 下載Trae:https://www.trae.com.cn/

添加 MCP

{"mcpServers": {"sqlite-server": {"command": "uv","args": ["--directory","~/TraeProjects/demo","run","main.py","--db-path","~/TraeProjects/demo/test.db"]}}
}

在這里插入圖片描述
在這里插入圖片描述

創建智能體

在這里插入圖片描述

使用智能體

調用 MCP 創建 demo 表

在這里插入圖片描述

查詢 demo 表結構信息

在這里插入圖片描述

demo 表插入 2 條測試數據

在這里插入圖片描述

查詢 demo 表中的數據

在這里插入圖片描述

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

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

相關文章

為什么要學習《金剛經》

《金剛經》作為佛教般若經典的核心,以"緣起性空"為思想根基,通過佛陀與須菩提的對話,揭示了破除執著、見真實相的智慧。 以下從核心要義、精髓段落和現實應用三個維度進行解讀: 一、核心思想精髓 1. "凡所有相&am…

【MQ篇】RabbitMQ之消費失敗重試!

目錄 引言:消息不丟是底線,失敗了優雅重試是修養!消費失敗了,為啥不能老是原地復活?🤔智能重試策略一:本地重試(Spring Retry 的魔法)🏠?智能重試策略二&…

制作一款打飛機游戲33:碰撞體編輯

我們設置系統的方式使得編輯碰撞檢測框(即碰撞盒)并不容易。所以,我們的下一步是擴展我們的編輯器,尤其是精靈編輯器,以便我們能夠在編輯器中直接編輯碰撞盒。 編輯碰撞盒 讓我們加載Sprite編輯器。例如,這…

Kotlin和JavaScript的對比

Kotlin和JavaScript有一些相似之處,但也存在顯著的差異,下面從多個方面為你詳細分析: 相似點 1. 語法靈活性 變量聲明:二者在變量聲明上都較為靈活。在JavaScript里,借助var、let和const可以聲明變量。其中&#xf…

生活需要一些思考

總分總 寫文章、做事情、寫郵件、寫信,都是要【總分總】。 先總【因為沒人有耐心一上來就看細節,先總結,別人感興趣才會看分】 然后分【分中包括多個子部分,或子章節、子目標,他們之間層層遞進,最終引出最…

JAVA設計模式——(九)工廠模式

JAVA設計模式——(九)工廠模式 介紹理解實現ProductFactory測試泛型擴展 應用 介紹 定義一個工廠類的接口,幫助一個實際對象 創建實例,并讓其工廠類的子類決定實例化哪個類。 理解 工廠模式中,必定分為了兩部分&…

Java后端接口調用攔截處理:注解與攔截器的實現

在Java開發中,對后端接口調用進行攔截處理是一種常見的需求,通常用于權限驗證、Token校驗、狀態更新等操作。本文將圍繞 Spring框架的攔截器(Interceptor)、Spring AOP(面向切面編程) 和 Spring Security 三…

第14講:科研圖表的導出與排版藝術——高質量 PDF、TIFF 輸出與投稿規范全攻略!

目錄 ?? 前言:導出,不只是“保存”! ?? 一、你需要掌握的導出目標 ??? 二、TIFF / PNG 導出規范(適用于投稿) ?? 三、PDF 矢量圖導出(排版首選) ?? 四、強烈推薦組合:showtext + Cairo ?? 五、多個圖的組合導出技巧 ?? 六、特殊投稿需求處理 ?…

對 FormCalc 語言支持較好的 PDF 編輯軟件綜述

FormCalc是一種專為PDF表單計算設計的腳本語言,主要應用于Adobe生態及SAP相關工具。以下是對FormCalc支持較好的主流軟件及其特點: 1. Adobe LiveCycle Designer 作為FormCalc的原生開發環境,LiveCycle Designer提供最佳支持: …

第二階段:基礎加強階段總體介紹

Java語法的學習筆記 下面放復習的文檔鏈接,如果有需要可以前往下載獲取,這個倉庫還有關于mysql、hadoop、python等的復習部分,并且每個文檔有著對應的代碼部分。文章作為復習使用,更多代碼內容見鏈接如下: https://gitee.com/zha…

大前端開發——前端知識漸變分層講解 利用金字塔原理簡化前端知識體系

Web開發基礎 核心概念 HTML、CSS和JavaScript:Web開發的三大基石,分別負責結構、樣式和行為。 代碼管理:隨著項目規模擴大,需要將代碼拆分成小塊,便于維護。 作用域污染:早期所有代碼共享全局作用域&…

Mixture-of-Experts(MoE)原理與在DeepSeek中的應用

MoE機制簡介 Mixture-of-Experts(MoE,混合專家)是一種“分而治之”的神經網絡架構思想。在MoE模型中,存在多個并行的子網絡,被稱為“專家”。每個專家通常擅長處理特定類型的輸入特征或知識片段。而在模型前向計算時,并非激活所有專家參與運算,而是通過一個專門的門控網…

SpringCloud學習筆記

個人學習進度:視頻跟敲筆記(12天) 學習視頻:尚硅谷微服務速通(7小時左右課程) 資源: 1.pdf:微服務pdf(課程):https://pan.baidu.com/s/1g_TAuBjQ…

【大模型】Coze AI 智能體工作流從配置到使用實戰詳解

目錄 一、前言 二、工作流介紹 2.1 什么是工作流 2.2 工作流與對話流 2.2.1 兩者區別 2.3 工作流節點介紹 2.3.1 工作流節點說明 2.3.2 開始節點與結束節點 2.4 工作流入口 2.4.1 自定義智能體入口 2.4.2 從資源庫新增工作流 2.5 工作流使用限制 三、工作流配置與使…

Discord多賬號注冊登錄:如何同時管理多個賬戶?

Discord是許多人、特別是游戲玩家和社區管理者的重要溝通工具。隨著用戶需求的增長,越來越多的人開始在Discord上注冊多個賬號進行管理。例如,個人和工作賬號的區分,多個游戲社區的參與,或者通過不同的身份進行更靈活的社交互動。…

前端如何使用Mock模擬數據實現前后端并行開發,提升項目整體效率

1. 安裝 Mock.js npm install mockjs --save-dev # 或使用 CDN <script src"https://cdn.bootcdn.net/ajax/libs/Mock.js/1.0.0/mock-min.js"></script>2. 創建 Mock 數據文件 在項目中新建 mock 目錄&#xff0c;創建 mock.js 文件&#xff1a; // m…

AimRT 從零到一:官方示例精講 —— 二、HelloWorld示例.md

HelloWorld示例 官方倉庫&#xff1a;helloworld 配置文件&#xff08;configuration_helloworld.yaml? &#xff09; 依據官方示例項目結構自行編寫YAML配置文件 # 基礎信息 base_info:project_name: helloworld # 項目名稱build_mode_tags: ["EXAMPLE", &quo…

Tauri 跨平臺開發指南及實戰:用前端技術征服桌面應用(合集-萬字長文)

厭倦了笨重的Electron應用&#xff1f;想要構建體積小、性能高、安全可靠的跨平臺桌面應用&#xff1f;Tauri將是你的不二之選&#xff01;本教程帶你從入門到精通&#xff0c;掌握這個下一代桌面應用開發框架&#xff0c;并通過實戰APK分析工具項目&#xff0c;將理論知識轉化…

【LeetCode 熱題 100】矩陣置零 / 螺旋矩陣 / 旋轉圖像 / 搜索二維矩陣 II

??個人主頁&#xff1a;小羊 ??所屬專欄&#xff1a;LeetCode 熱題 100 很榮幸您能閱讀我的文章&#xff0c;誠請評論指點&#xff0c;歡迎歡迎 ~ 目錄 矩陣矩陣置零螺旋矩陣旋轉圖像搜索二維矩陣 II 矩陣 矩陣置零 矩陣置零 用兩個數組分別標記行和列&#xff0c;判斷…

JavaScript進階(三十一): === 與 == 比較運算符

文章目錄 一、前言二、嚴格相等運算符 ()三、寬松相等運算符 ()四、推薦做法五、特殊情況 一、前言 在 JavaScript 中&#xff0c; 和 都是比較運算符&#xff0c;但它們在比較時有重要區別&#xff1a; 二、嚴格相等運算符 () 不進行類型轉換只有當兩個操作數的值和類型都…