Skip to content

Commit 8b2d253

Browse files
feat(config): 采用 YAML 配置文件替代环境变量
- 新增 config_demo.yml 示例配置文件- 修改 README.md,更新环境变量设置说明 - 更新 requirements.txt,添加 yaml 库依赖 -重构 server.py,使用 YAML 配置替代环境变量获取
1 parent 87b6690 commit 8b2d253

File tree

4 files changed

+54
-64
lines changed

4 files changed

+54
-64
lines changed

README.md

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

22
# XiYan MCP Server
33

4-
A Model Context Protocol (MCP) server that enables secure interaction with MySQL databases. This server allows AI assistants to list tables, read data, and execute SQL queries through a controlled interface, making database exploration and analysis safer and more structured.
4+
A Model Context Protocol (MCP) server that enables natural language queries to MySQL databases, power by XiYanSQL as text-to-sql technique.
5+
56

67
## Features
78
- Fetch data by natural language throught XiYanSQL (https://github.com/XGenerationLab/XiYan-SQL)
@@ -19,16 +20,16 @@ pip install xiyan-mcp-server
1920
Set the following environment variables:
2021

2122
```bash
22-
MYSQL_HOST= # Database host
23-
MYSQL_PORT= # Optional: Database port (defaults to 3306 if not specified)
24-
MYSQL_USER=
25-
MYSQL_PASSWORD=
26-
MYSQL_DATABASE=
27-
MODEL_NAME=
28-
MODEL_KEY=
29-
MODEL_URL=
23+
YML= # yml config file path
3024
```
3125

26+
see config_demo.yml for example
27+
28+
## Models
29+
30+
Any LLMs are supported as long as they support the `chat` API.
31+
We recommend using xiyansql-qwencoder-32b (https://github.com/XGenerationLab/XiYanSQL-QwenCoder) for best performance.
32+
3233
## Usage
3334

3435
### With Claude Desktop
@@ -47,14 +48,7 @@ Add this to your `claude_desktop_config.json`:
4748
"xiyan_mcp_server"
4849
],
4950
"env": {
50-
"MYSQL_HOST": "localhost",
51-
"MYSQL_PORT": "3306",
52-
"MYSQL_USER": "your_username",
53-
"MYSQL_PASSWORD": "your_password",
54-
"MYSQL_DATABASE": "your_database",
55-
"MODEL_NAME": "your_model_name",
56-
"MODEL_URL": "your_model enpoint",
57-
"MODEL_KEY": "your_model_key"
51+
"YML": "path/to/yml"
5852
}
5953
}
6054
}

config_demo.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
model:
2+
name: "pre-xiyan_multi_dialect_v3"
3+
key: ""
4+
url: "https://poc-dashscope.aliyuncs.com/compatible-mode/v1"
5+
6+
database:
7+
host: "localhost"
8+
port: 3306
9+
user: "root"
10+
password: ""
11+
database: ""

requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mcp>=1.0.0
22
mysql-connector-python>=9.1.0
33
sqlalchemy
4-
llama_index
4+
llama_index
5+
yaml

src/xiyan_mcp_server/server.py

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import os
3-
3+
import yaml # 添加yaml库导入
44

55
from mysql.connector import connect, Error
66
from mcp.server import FastMCP
@@ -22,47 +22,32 @@
2222
)
2323
logger = logging.getLogger("xiyan_mcp_server")
2424

25-
def get_model_config():
26-
model_config ={
27-
"name":os.getenv("MODEL_NAME","qwen-max-0125"),
28-
"key":os.getenv("MODEL_KEY",""),
29-
"url":os.getenv("MODEL_URL","https://dashscope.aliyuncs.com/compatible-mode/v1")
30-
}
31-
if not all([model_config["name"], model_config["key"]]):
32-
logger.error("Missing required model configuration. Please check environment variables:")
33-
logger.error("MODEL_NAME and MODEL_KEY are required")
34-
raise ValueError("Missing required model configuration")
35-
36-
return model_config
37-
38-
def get_db_config():
39-
40-
"""Get database configuration from environment variables."""
41-
config = {
42-
"host": os.getenv("MYSQL_HOST", ""),
43-
"port": int(os.getenv("MYSQL_PORT", "3306")),
44-
"user": os.getenv("MYSQL_USER",''),
45-
"password": os.getenv("MYSQL_PASSWORD",""),
46-
"database": os.getenv("MYSQL_DATABASE",'')
47-
}
48-
49-
if not all([config["user"], config["password"], config["database"]]):
50-
logger.error("Missing required database configuration. Please check environment variables:")
51-
logger.error("MYSQL_USER, MYSQL_PASSWORD, and MYSQL_DATABASE are required")
52-
raise ValueError("Missing required database configuration")
53-
54-
return config
25+
def get_yml_config():
26+
config_path = os.getenv("YML","")
27+
try:
28+
with open(config_path, 'r') as file:
29+
config = yaml.safe_load(file)
30+
return config
31+
except FileNotFoundError:
32+
logger.error(f"Configuration file {config_path} not found.")
33+
raise
34+
except yaml.YAMLError as exc:
35+
logger.error(f"Error parsing configuration file {config_path}: {exc}")
36+
raise
37+
38+
5539

5640
def get_xiyan_config(db_config):
5741
xiyan_db_config = DBConfig(dialect='mysql',db_name=db_config['database'], user_name=db_config['user'], db_pwd=db_config['password'], db_host=db_config['host'], port=db_config['port'])
5842
return xiyan_db_config
5943

60-
global_db_config = get_db_config()
44+
45+
global_config = get_yml_config()
46+
#print(global_config)
47+
model_config = global_config['model']
48+
global_db_config = global_config['database']
6149
global_xiyan_db_config = get_xiyan_config(global_db_config)
62-
model_config = get_model_config()
63-
model_name= model_config['name']
64-
model_key=model_config['key']
65-
model_url = model_config['url']
50+
6651

6752

6853
@mcp.resource('mysql://'+global_db_config['database'])
@@ -75,7 +60,7 @@ async def read_resource() -> str:
7560
@mcp.resource("mysql://{table_name}")
7661
async def read_resource(table_name) -> str:
7762
"""Read table contents."""
78-
config = get_db_config()
63+
config = global_db_config
7964
try:
8065
with connect(**config) as conn:
8166
with conn.cursor() as cursor:
@@ -110,7 +95,7 @@ def sql_gen_and_execute(db_env, query: str):
11095
{"role": "system", "content": prompt},
11196
{"role": "user", "content": f"用户的问题是: {query}"}
11297
]
113-
param = {"model": model_config['name'], "messages": messages,"key":model_key,"url":model_config['url']}
98+
param = {"model": model_config['name'], "messages": messages,"key":model_config['key'],"url":model_config['url']}
11499

115100
try:
116101
response = call_dashscope(**param)
@@ -126,8 +111,8 @@ def sql_gen_and_execute(db_env, query: str):
126111

127112
sql_res = db_env.database.fetch_truncated(sql_query,max_rows=100)
128113
markdown_res = db_env.database.trunc_result_to_markdown(sql_res)
129-
logger.info(f"SQL query: {sql_query}\nSQL result: {markdown_res}")
130-
return markdown_res
114+
logger.info(f"SQL query: {sql_query}\nSQL result: {sql_res}")
115+
return markdown_res.strip()
131116

132117
except Exception as e:
133118
return str(e)
@@ -151,12 +136,11 @@ def sql_fix(dialect: str, mschema: str, query: str, sql_query: str, error_info:
151136
【错误信息】
152137
{sql_res}'''.format(question=query, sql=sql_query, sql_res=error_info)
153138

154-
model = model_name
155139
messages = [
156140
{"role": "system", "content": system_prompt},
157141
{"role": "user", "content": user_prompt}
158142
]
159-
param = {"model": model, "messages": messages,"key":model_key,'url':model_config['url']}
143+
param = {"model": model_config['name'], "messages": messages,"key":model_config['key'],'url':model_config['url']}
160144

161145
response = call_dashscope(**param)
162146
content = response.choices[0].message.content
@@ -170,12 +154,12 @@ def call_xiyan(query: str)-> str:
170154
Args:
171155
query: The query in natual language
172156
"""
173-
db_config = get_db_config()
174-
xiyan_config = get_xiyan_config(db_config)
157+
#db_config = global_db_config
158+
#xiyan_config = get_xiyan_config(db_config)
175159

176160
logger.info(f"Calling tool with arguments: {query}")
177161
try:
178-
db_engine = init_db_conn(xiyan_config)
162+
db_engine = init_db_conn(global_xiyan_db_config)
179163
db_source = HITLSQLDatabase(db_engine)
180164
except Exception as e:
181165

@@ -186,7 +170,7 @@ def call_xiyan(query: str)-> str:
186170

187171
return str(res)
188172
@mcp.tool()
189-
def get_data_via_natual_language(query: str)-> list[TextContent]:
173+
def get_data_via_natural_language(query: str)-> list[TextContent]:
190174
"""Fetch the data from database through a natural language query
191175
192176
Args:

0 commit comments

Comments
 (0)