当前位置: 首页 > backend >正文

使用 uv 工具快速创建 MCP 服务(Trae 配置并调用 MCP 服务)

文章目录

  • 下载Trae
  • uv 工具教程参考我的这篇文章
  • 创建 uv 项目
  • main.py
  • 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))

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.xdnf.cn/news/1861.html

相关文章:

  • 晶振老化:不可忽视的隐患与预防策略
  • Linux的多进程开发与信号处理
  • Windows 10 上运行 Ollama 时遇到 llama runner process has terminated: exit status 2
  • 金仓数据库 KingbaseES 产品深度优化提案:迈向卓越的全面升级
  • GIS开发笔记(15)基于osg和osgearth实现三维地图上添加路网数据(矢量shp)
  • Node.js神器rimraf:10倍速删除node_modules的跨平台解决方案
  • 资源获取:项目成功的关键要素
  • Android WindowManagerService(WMS)框架深度解析
  • Python命名参数的使用
  • 从『玩意儿』代码综观『解决问题』的方案设计逻辑——开放/细致/『明理』(DeepSeek)
  • 基于javaweb的SSM+Maven红酒朔源管理系统设计与实现(源码+文档+部署讲解)
  • 3000年不识伪全等直线段使数学一直有将两异直线段误为同一线段的重大错误——百年病态集论的症结
  • DeepSeek回答过于笼统,提示词如何优化
  • 【金仓数据库征文】-数据库界新兴前列者,本篇带你速懂金仓数据库!
  • 深度学习之卷积神经网络入门
  • 使用idea打包maven项目的时候因为java文件多导致java.lang.OutOfMemoryError: Java heap space
  • 【金仓数据库征文】——选择金仓,选择胜利
  • 【论文推荐】人工智能在滑坡风险评估三大核心领域的应用:人工智能技术在滑坡风险评估中的方法学综述
  • 前端基础之《Vue(10)—过滤器》
  • Linux命令行基础入门详解
  • Python3(8) 字符串
  • fastjson使用parseObject转换成JSONObject出现将字符特殊字符解析解决
  • attention-transformer-test
  • Agent智能体应用详解:从理论到实践的技术探索
  • AD16批量修改PCB元件序号的高度和宽度
  • Python 学习路线与笔记跳转(持续更新笔记链接)
  • 接口测试和单元测试详解
  • 浔川代码编辑器v2.0(测试版)更新公告
  • 手搓实时操作系统实践:从零构建属于自己的系统世界
  • maven构建时报错:was cached in the local repository...