优化mcp配置
This commit is contained in:
parent
4939a70209
commit
9f12a633bc
@ -88,9 +88,8 @@ skill-name/
|
||||
|
||||
## Skill 加载优先级
|
||||
|
||||
1. Skill MCP 配置(最高)
|
||||
2. 默认 MCP 配置 (`mcp/mcp_settings.json`)
|
||||
3. 用户传入参数(覆盖所有)
|
||||
1. Skill MCP 配置
|
||||
2. 用户传入参数(覆盖已有同名配置)
|
||||
|
||||
## 安全措施
|
||||
|
||||
|
||||
@ -396,7 +396,6 @@ dataset_name/
|
||||
│ ├── document.txt # 原始文本内容
|
||||
│ ├── serialization.txt # 结构化数据
|
||||
│ └── schema.json # 字段定义和元数据
|
||||
├── mcp_settings.json # MCP 工具配置
|
||||
└── system_prompt.md # 系统提示词(可选)
|
||||
```
|
||||
|
||||
@ -405,7 +404,6 @@ dataset_name/
|
||||
- **document.txt**: 原始 Markdown 文本,提供完整上下文
|
||||
- **serialization.txt**: 格式化结构数据,每行 `字段1:值1;字段2:值2`
|
||||
- **schema.json**: 字段定义、枚举值映射和文件关联关系
|
||||
- **mcp_settings.json**: MCP 工具配置,定义可用的数据处理工具
|
||||
|
||||
---
|
||||
|
||||
@ -565,8 +563,7 @@ qwen-agent/
|
||||
│ ├── multi_keyword_search_server.py # 多关键词搜索服务
|
||||
│ ├── excel_csv_operator_server.py # Excel/CSV 操作服务
|
||||
│ ├── json_reader_server.py # JSON 读取服务
|
||||
│ ├── mcp_settings.json # MCP 配置文件
|
||||
│ └── tools/ # 工具定义文件
|
||||
│ └── tools/ # 工具定义文件
|
||||
├── models/ # 模型文件
|
||||
├── projects/ # 项目目录
|
||||
│ └── queue_data/ # 队列数据
|
||||
|
||||
@ -117,13 +117,6 @@ def read_system_prompt():
|
||||
return f.read().strip()
|
||||
|
||||
|
||||
def read_mcp_settings():
|
||||
"""读取MCP工具配置"""
|
||||
with open("./mcp/mcp_settings.json", "r") as f:
|
||||
mcp_settings_json = json.load(f)
|
||||
return mcp_settings_json
|
||||
|
||||
|
||||
async def get_tools_from_mcp(mcp):
|
||||
"""从MCP配置中提取工具(带缓存)"""
|
||||
start_time = time.time()
|
||||
@ -195,8 +188,7 @@ async def init_agent(config: AgentConfig):
|
||||
final_system_prompt = await load_system_prompt_async(config)
|
||||
final_mcp_settings = await load_mcp_settings_async(config)
|
||||
|
||||
# 如果没有提供mcp,使用config中的mcp_settings
|
||||
mcp_settings = final_mcp_settings if final_mcp_settings else read_mcp_settings()
|
||||
mcp_settings = final_mcp_settings if final_mcp_settings else []
|
||||
system_prompt = final_system_prompt if final_system_prompt else read_system_prompt()
|
||||
|
||||
config.system_prompt = mcp_settings
|
||||
|
||||
@ -5,6 +5,7 @@ Claude Plugins 模式的 Hook 加载器
|
||||
"""
|
||||
import os
|
||||
import json
|
||||
import copy
|
||||
import logging
|
||||
import asyncio
|
||||
import subprocess
|
||||
@ -116,7 +117,8 @@ async def merge_skill_mcp_configs(bot_id: str) -> List[Dict]:
|
||||
plugin_config = json.load(f)
|
||||
servers = plugin_config.get('mcpServers', {})
|
||||
if servers:
|
||||
merged_servers.update(servers)
|
||||
normalized_servers = _normalize_skill_mcp_servers(servers, skill_path)
|
||||
merged_servers.update(normalized_servers)
|
||||
logger.info(f"Loaded MCP config from skill: {skill_name}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load mcpServers from {skill_name}: {e}")
|
||||
@ -127,6 +129,47 @@ async def merge_skill_mcp_configs(bot_id: str) -> List[Dict]:
|
||||
return []
|
||||
|
||||
|
||||
def _normalize_skill_mcp_servers(servers: Dict[str, Any], skill_path: str) -> Dict[str, Any]:
|
||||
"""将 skill plugin 中 stdio MCP server 的相对路径归一化为基于 skill 目录的绝对路径。"""
|
||||
normalized_servers = copy.deepcopy(servers)
|
||||
|
||||
for server_name, server_config in normalized_servers.items():
|
||||
if not isinstance(server_config, dict):
|
||||
continue
|
||||
|
||||
transport = server_config.get('transport')
|
||||
if not transport:
|
||||
transport = 'http' if 'url' in server_config else 'stdio'
|
||||
if transport != 'stdio':
|
||||
continue
|
||||
|
||||
command = server_config.get('command')
|
||||
if isinstance(command, str):
|
||||
server_config['command'] = _resolve_skill_relative_path(command, skill_path)
|
||||
|
||||
args = server_config.get('args')
|
||||
if isinstance(args, list):
|
||||
server_config['args'] = [
|
||||
_resolve_skill_relative_path(arg, skill_path) if isinstance(arg, str) else arg
|
||||
for arg in args
|
||||
]
|
||||
|
||||
return normalized_servers
|
||||
|
||||
|
||||
def _resolve_skill_relative_path(value: str, skill_path: str) -> str:
|
||||
"""将 ./ 或 ../ 开头且不含占位符的路径转为基于 skill 目录的绝对路径。"""
|
||||
if '{' in value or '}' in value:
|
||||
return value
|
||||
|
||||
if not value.startswith(('./', '../')):
|
||||
return value
|
||||
|
||||
normalized_path = os.path.abspath(os.path.join(skill_path, value))
|
||||
logger.debug(f"Resolved skill MCP path: {value} -> {normalized_path}")
|
||||
return normalized_path
|
||||
|
||||
|
||||
def _load_plugin_config(plugin_json_path: str) -> Dict:
|
||||
"""加载 plugin.json 配置"""
|
||||
try:
|
||||
|
||||
@ -203,10 +203,9 @@ async def load_mcp_settings_async(config) -> List[Dict]:
|
||||
List[Dict]: 合并后的MCP设置列表
|
||||
|
||||
Note:
|
||||
支持在 mcp_settings.json 的 args 中使用 {dataset_dir} 占位符,
|
||||
支持在传入或合并后的 mcp_settings 的 args 中使用 {dataset_dir} 占位符,
|
||||
会在 init_modified_agent_service_with_files 中被替换为实际的路径。
|
||||
"""
|
||||
from agent.config_cache import config_cache
|
||||
|
||||
# 从config中获取参数
|
||||
project_dir = getattr(config, 'project_dir', None)
|
||||
@ -222,33 +221,6 @@ async def load_mcp_settings_async(config) -> List[Dict]:
|
||||
skill_mcp_servers = skill_mcp_settings[0].get('mcpServers', {})
|
||||
logger.info(f"Loaded {len(skill_mcp_servers)} MCP servers from skills")
|
||||
# ===========================================================================================
|
||||
|
||||
# 2. 读取默认MCP设置(使用缓存)
|
||||
default_mcp_settings = []
|
||||
try:
|
||||
default_mcp_file = os.path.join("mcp", f"mcp_settings.json")
|
||||
default_mcp_settings = await config_cache.get_json_file(default_mcp_file) or []
|
||||
if default_mcp_settings:
|
||||
logger.info(f"Using cached default mcp_settings from mcp folder")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load default mcp_settings: {str(e)}")
|
||||
default_mcp_settings = []
|
||||
|
||||
# 3. 合并默认设置到merged_settings(默认设置被skill覆盖)
|
||||
if default_mcp_settings and len(default_mcp_settings) > 0:
|
||||
default_mcp_servers = default_mcp_settings[0].get('mcpServers', {})
|
||||
if merged_settings and len(merged_settings) > 0:
|
||||
# skill配置已存在,将默认配置合并进去(skill优先)
|
||||
skill_mcp_servers = merged_settings[0].get('mcpServers', {})
|
||||
# 默认配置中不存在的才添加
|
||||
for server_name, server_config in default_mcp_servers.items():
|
||||
if server_name not in skill_mcp_servers:
|
||||
skill_mcp_servers[server_name] = server_config
|
||||
else:
|
||||
# 没有skill配置,直接使用默认配置
|
||||
merged_settings = default_mcp_settings.copy()
|
||||
|
||||
# 遍历mcpServers工具,给每个工具增加env参数
|
||||
if merged_settings and len(merged_settings) > 0:
|
||||
mcp_servers = merged_settings[0].get('mcpServers', {})
|
||||
for server_name, server_config in mcp_servers.items():
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
[
|
||||
{
|
||||
"mcpServers": {}
|
||||
}
|
||||
]
|
||||
@ -14,7 +14,7 @@
|
||||
"transport": "stdio",
|
||||
"command": "python",
|
||||
"args": [
|
||||
"./skills/rag-retrieve-only/rag_retrieve_server.py",
|
||||
"./rag_retrieve_server.py",
|
||||
"{bot_id}"
|
||||
]
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
"transport": "stdio",
|
||||
"command": "python",
|
||||
"args": [
|
||||
"./skills_autoload/rag-retrieve/rag_retrieve_server.py",
|
||||
"./rag_retrieve_server.py",
|
||||
"{bot_id}"
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user