发布时间:2026/7/29 8:14:37
数据服务器+MCP服务器部署MCP供Workbuddy调用 需求分析公司希望用Workbuddy连接即有的数据供用户通过对话模式得到报表等数据。即有资源分析Workbuddy购买了企业版安全性有一定保障且能得到官方的支持。源头系统的数据服务器不对外全部部署在内网环境且数据需要严格控制不能让AI工具随意获取数据。现有服务器有空余资源可以在不新购服务器的情况下部署MCP服务。内部人力众所周知ALL IN 1系统架构架构图数据服务器新增用户、密码赋予查询某个表的权限MCP服务器服务器配置白名单加入MCP服务的对外端口选择自己的技术栈部署MCP服务这里举例用python来进行MCP服务部署python安装mcp包以及其他依赖包pycharm同时安装AI工具通过AI进行初步的代码生成历经超过30次的调试MCP服务调通最终的示例代码如下#codingutf-8importasyncioimportloggingimportoracledbfromtypingimportAny,Dict,Listfrommcp.serverimportServerfrommcp.typesimportTool,TextContentfromstarlette.applicationsimportStarlettefromstarlette.routingimportRoutefromstarlette.requestsimportRequestfromstarlette.responsesimportResponsefrommcp.server.sseimportSseServerTransportimportuvicornimportos# 配置日志logging.basicConfig(levellogging.INFO)loggerlogging.getLogger(MCP-Oracle-Server)# 环境变量读取注意这里配置环境变量更安全hostos.environ.get(host,localhost)portint(os.environ.get(port,))oracleuseros.environ.get(oracleuser,)oraclepasswordos.environ.get(oraclepassword,)service_nameos.environ.get(service_name,)# 启动前校验避免带空配置运行ifnotall([oracleuser,oraclepassword,service_name]):logger.warning(⚠️ Missing required environment variables (oracleuser, oraclepassword, service_name). Server may fail to connect.)# 数据库配置DB_CONFIG{host:host,port:port,service_name:service_name,user:oracleuser,password:oraclepassword}# 初始化 MCP ServerappServer(oracle-data-connector)# 白名单ALLOWED_TABLES{实例.表名:[X,XX,XXX,XXXX]}# 全局连接池poolNonedefinit_oracle_client():初始化 Oracle Thick 模式try:# 使用客户端路径client_dirr有效路径oracledb.init_oracle_client(lib_dirclient_dir)logger.info(f✅ Oracle Thick mode initialized successfully using client:{client_dir})exceptExceptionase:logger.error(f❌ Failed to initialize Oracle Thick mode:{e})raisedefinit_connection_pool():初始化 Oracle 连接池提升查询性能globalpoolifpoolisNone:try:dsnf{DB_CONFIG[host]}:{DB_CONFIG[port]}/{DB_CONFIG[service_name]}pooloracledb.create_pool(userDB_CONFIG[user],passwordDB_CONFIG[password],dsndsn,min1,max4,increment1,getmodeoracledb.POOL_GETMODE_WAIT)logger.info(✅ Oracle Connection Pool initialized successfully.)exceptExceptionase:logger.error(f❌ Failed to initialize Oracle Connection Pool:{e})raisedefget_db_connection():从连接池获取连接ifpoolisNone:init_connection_pool()returnpool.acquire()app.list_tools()asyncdeflist_tools()-List[Tool]:return[Tool(namelist_allowed_tables,description列出当前 MCP 服务允许查询的所有表名,inputSchema{type:object,properties:{},required:[]}),Tool(namequery_oracle_table,description查询指定 Oracle 表的数据。仅支持预定义白名单中的表和列。,inputSchema{type:object,properties:{table_name:{type:string,description:要查询的表名必须在大写白名单中},columns:{type:array,items:{type:string},description:要查询的列名列表。如果为空或包含*则返回所有允许列。},limit:{type:integer,description:限制返回行数默认 10最大 100,default:10},filter_column:{type:string,description:可选用于过滤的列名},filter_value:{type:string,description:可选过滤值}},required:[table_name]})]app.call_tool()asyncdefcall_tool(name:str,arguments:Dict[str,Any])-List[TextContent]:try:ifnamelist_allowed_tables:tableslist(ALLOWED_TABLES.keys())return[TextContent(typetext,textfAllowed tables:{, .join(tables)})]elifnamequery_oracle_table:table_namearguments.get(table_name,).upper()requested_columnsarguments.get(columns,[])limitmin(arguments.get(limit,10),100)filter_colarguments.get(filter_column)filter_valarguments.get(filter_value)iftable_namenotinALLOWED_TABLES:return[TextContent(typetext,textfError: Table {table_name} is not allowed.)]allowed_colsALLOWED_TABLES[table_name]ifnotrequested_columnsor*inrequested_columns:select_colsallowed_colselse:invalid_cols[colforcolinrequested_columnsifcol.upper()notinallowed_cols]ifinvalid_cols:return[TextContent(typetext,textfError: Columns{invalid_cols}are not allowed.)]select_cols[col.upper()forcolinrequested_columns]col_str, .join(select_cols)# 修复使用字典传参更安全可靠params{}base_sqlfSELECT{col_str}FROM{table_name}iffilter_colandfilter_valisnotNone:iffilter_col.upper()notinallowed_cols:return[TextContent(typetext,textfError: Filter column {filter_col} is not allowed.)]base_sqlf WHERE{filter_col.upper()} :bind_valparams[:bind_val]filter_val# Oracle 11g 兼容写法sqlfSELECT * FROM ({base_sql}) WHERE ROWNUM {limit}connget_db_connection()cursorconn.cursor()try:cursor.execute(sql,params)columns[desc[0]fordescincursor.description]rowscursor.fetchall()result_textfQuery Result for{table_name}:\nresult_text| | .join(columns) |\nresult_text||.join([---for_incolumns])|\nforrowinrows:formatted_row[str(item)ifitemisnotNoneelseNULLforiteminrow]result_text| | .join(formatted_row) |\nreturn[TextContent(typetext,textresult_text)]finally:# 无论是否报错必须关闭游标并将连接归还连接池cursor.close()conn.close()else:return[TextContent(typetext,textfUnknown tool:{name})]exceptExceptionase:logger.error(fError executing tool{name}:{e})return[TextContent(typetext,textfError:{str(e)})]defmain():# 1. 强制启用 Thick 模式并指定路径init_oracle_client()# 2. 初始化连接池try:init_connection_pool()exceptException:logger.error(❌ Database connection pool failed to initialize. MCP Server will not start.)returnsseSseServerTransport(/messages/)asyncdefhandle_sse(request:Request):asyncwithsse.connect_sse(request.scope,request.receive,request._send)as(read_stream,write_stream):awaitapp.run(read_stream,write_stream,app.create_initialization_options())asyncdefhandle_messages(request:Request):awaitsse.handle_post_message(request.scope,request.receive,request._send)returnResponse(status_code200)starlette_appStarlette(debugTrue,routes[Route(/sse,endpointhandle_sse),Route(/messages/,endpointhandle_messages,methods[POST]),Route(/messages,endpointhandle_messages,methods[POST]),],)logger.info( Starting Oracle MCP Server on port 白名单端口号...)uvicorn.run(starlette_app,host0.0.0.0,port白名单端口号)if__name____main__:main()Workbuddy端操作路径截图MCP配置代码{mcpServers:{Oracle-Connector:{transport:sse,url:http://地址:端口/sse,disabled:false}}}结论通过上述案例可以将系统的数据放在内网通过物理网络数据库单独账号控制权限同时MCP服务器单独部署也进一步杜绝了网络安全问题以及AI查数据不可控的情况。

相关新闻

2026/7/29 8:14:37

【单片机毕业设计推荐】基于 STM32 单片机的智能鱼缸环境监控与自动控制系统设计,基于 STM32 的水族箱多参数监测与自动化养护系统设计(012304)

文章目录20 个相关毕业设计备选题目项目研究背景摘要总体方案核心功能技术路线项目演示关于我们项目案例源码获取温馨提示:本人主页置顶文章(点我)有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)有 CSDN 平台官…

2026/7/29 8:14:37

Postman Mock Server实战:契约驱动开发与前后端高效协作

1. 项目概述:为什么我们需要一个“假”后端? 在前后端分离的开发模式下,一个经典的矛盾总是反复上演:前端页面已经画好了,交互逻辑也写得差不多了,但后端接口文档还躺在产品经理的脑子里,或者后…

2026/7/29 8:09:37

C++编程实战:从快递费计算项目掌握输入验证与模块化设计

1. 项目概述:从“Hello World”到解决实际问题很多朋友学C,卡在了一个尴尬的阶段:语法书看完了,cout、if-else、for循环都认识了,甚至能写个小程序算算斐波那契数列。但一遇到稍微具体点的需求,比如“根据快…

2026/7/29 9:09:40

C#调用Windows API实现桌面图标隐藏与显示:原理、代码与实战

1. 项目概述:为什么需要控制桌面图标? 在Windows桌面开发中,我们经常会遇到一些需要“清理”或“定制”桌面的场景。比如,在做屏幕录制或截图演示时,满屏的图标会分散观众的注意力;又或者,你开发…

2026/7/29 9:09:40

基于Arduino与LabVIEW的Makeblock小车PWM电机控制与无线通信系统设计

1. 项目概述:从遥控玩具到工程实践 几年前,我带着孩子玩Makeblock的套件,看着那些五颜六色的铝合金梁和电机,总觉得它们能做的远不止拼个会动的小车。后来因为一个实际需求——需要一台能在实验室和仓库之间自动搬运小型物料的小车…

2026/7/29 9:09:40

油猴脚本(Tampermonkey)安装使用教程

油猴脚本(Tampermonkey)安装使用教程1. 什么是油猴脚本?2. 如何安装油猴扩展?2.1 Chrome / Edge / 其他 Chromium 内核浏览器2.2 Firefox2.3 Safari3. 如何编写和使用脚本?3.1 编写脚本3.2 关键元数据说明3.3 创建与调…

2026/7/29 9:09:40

LLM、RAG与AI Agent:构建智能系统的三大核心技术解析

1. 从零理解AI智能系统的三大支柱 上周帮一家金融科技公司排查AI客服系统故障时,发现他们的技术团队对LLM、RAG和AI Agent的关系存在严重误解——用微调过的GPT-4直接处理用户隐私数据查询,既没做知识隔离又缺乏流程控制。这个价值百万的教训让我决定系统…

2026/7/29 9:09:40

EhCache三层架构与Spring Boot集成实战:本地缓存性能优化指南

1. 从“缓存”说起:为什么我们绕不开EhCache?做后端开发的朋友,对“缓存”这个词应该再熟悉不过了。数据库扛不住高并发查询?加缓存。接口响应慢,想提升用户体验?加缓存。计算密集型操作耗时太长&#xff1…

2026/7/29 9:04:39

Python 中 `request` 与 `requests` 的区别

Python 中 request 与 requests 的区别 1. 一句话结论 在 Python 后端开发中,request 和 requests 经常被混淆,但它们通常代表完全不同的方向。 request:别人请求我,我在后端接收这一次请求。 requests:我请求别人&…

2026/7/28 13:41:25

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

2026/7/29 0:02:56

商标注册找代理还是自己办?算清这笔“时间账”和“风险账

商标注册,找代理还是自己办?帮你算清这笔“时间账”和“风险账”“商标注册,找代理还是自己办?”这是深圳每个创业者都会遇到的灵魂拷问。有人说找代理是花冤枉钱,有人说自己办风险太高。到底哪种更划算?本…

2026/7/29 0:02:56

免费开源RPA工具OpenRPA:企业级自动化流程的终极解决方案

免费开源RPA工具OpenRPA:企业级自动化流程的终极解决方案 【免费下载链接】openrpa Free Open Source Enterprise Grade RPA 项目地址: https://gitcode.com/gh_mirrors/op/openrpa 你是否厌倦了每天重复枯燥的数据录入和报表整理工作?是否希望有…

2026/7/29 0:02:56

KMS智能激活工具:一站式解决Windows和Office激活难题

KMS智能激活工具:一站式解决Windows和Office激活难题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为系统弹出激活提示而烦恼吗?KMS智能激活工具能够帮你彻底告别W…

2026/7/28 4:38:09

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…