feat(.kilo): 新增 AgileDB 数据库操作技能

新增 lzwcai-agile-db 技能文件,为 AI Agent 提供 AgileDB 数据库操作的场景化工作流指导。
该技能支持数据源浏览、表数据 CRUD、SQL 执行和 AI 生成表结构等功能,包含完整的工具列表和使用场景。
This commit is contained in:
2026-06-11 18:51:49 +08:00
parent 9c597c9b0d
commit 557361632c
21 changed files with 1807 additions and 97 deletions

View File

@@ -6,8 +6,8 @@
| 变量名 | 必填 | 说明 |
|--------|------|------|
| `AGILE_DB_API_KEY` | 是 | 数据库管理平台的 API 密钥 |
| `AGILE_DB_BASE_URL` | 否 | 数据库管理平台后端地址(默认 `http://localhost:8080` |
| `API_KEY` | 是 | 数据库管理平台的 API 密钥(格式: `Bearer <token>` |
| `backendBaseUrl` | 否 | 数据库管理平台后端地址(默认 `http://lzwcai-demp-corp-manager:8086` |
## 安装
@@ -19,8 +19,8 @@ pip install -e .
```bash
# 设置环境变量
export AGILE_DB_API_KEY="your-api-key"
export AGILE_DB_BASE_URL="http://localhost:8080" # 可选
export API_KEY="Bearer your-token"
export backendBaseUrl="https://dempdemo.lzwcai.com" # 可选
# 运行 MCP Server
lzwcai-mcp-agile-db

View File

@@ -1,6 +0,0 @@
def main():
print("Hello from lzwcai-mcp-agile-db!")
if __name__ == "__main__":
main()

View File

@@ -1,7 +0,0 @@
[project]
name = "lzwcai-mcp-agile-db"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

View File

@@ -26,7 +26,7 @@ def register_tool(name: str):
input_schema = {...}
async def execute(self, args):
return await self.client.get("/api/...", params=args)
return await self.client.get("/datasource/...", params=args)
Args:
name: 工具名称(唯一标识)

View File

@@ -22,7 +22,7 @@ class ListApiKeysTool(ToolDef):
async def execute(self, args: dict) -> dict:
args = dict(args)
params = {k: v for k, v in args.items() if v is not None}
return self.client.get("/api/datasource/api_key/list", params=params)
return await self.client.get("/datasource/api_key/list", params=params)
@register_tool("create_api_key")
@@ -38,7 +38,7 @@ class CreateApiKeyTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/api_key", json_data=args)
return await self.client.post("/datasource/api_key", json_data=args)
@register_tool("toggle_api_key_status")
@@ -55,7 +55,7 @@ class ToggleApiKeyStatusTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.put("/api/datasource/api_key", json_data=args)
return await self.client.put("/datasource/api_key", json_data=args)
@register_tool("delete_api_key")
@@ -71,7 +71,7 @@ class DeleteApiKeyTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.delete(f"/api/datasource/api_key/{args['id']}")
return await self.client.delete(f"/datasource/api_key/{args['id']}")
@register_tool("get_api_key_permissions")
@@ -87,7 +87,7 @@ class GetApiKeyPermissionsTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.get(f"/api/datasource/api_key/permission/{args['apiKeyId']}")
return await self.client.get(f"/datasource/api_key/permission/{args['apiKeyId']}")
@register_tool("grant_api_key_permissions")
@@ -118,4 +118,4 @@ class GrantApiKeyPermissionsTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/api_key/permission/grant_batch", json_data=args)
return await self.client.post("/datasource/api_key/permission/grant_batch", json_data=args)

View File

@@ -38,8 +38,8 @@ class PreviewImportDataTool(ToolDef):
"file": (file_name, io.BytesIO(file_content), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
}
return self.client.upload(
f"/api/datasource/connection/{connection_id}/import_document/preview",
return await self.client.upload(
f"/datasource/connection/{connection_id}/import_document/preview",
files=files,
params={"target": target},
)
@@ -65,8 +65,8 @@ class ConfirmImportDataTool(ToolDef):
target = args.pop("target", "test")
data = args.pop("data")
return self.client.post(
f"/api/datasource/connection/{connection_id}/import_document/confirm",
return await self.client.post(
f"/datasource/connection/{connection_id}/import_document/confirm",
json_data=data,
params={"target": target},
)

View File

@@ -22,7 +22,7 @@ class ListDatabasesTool(ToolDef):
async def execute(self, args: dict) -> dict:
params = {k: v for k, v in args.items() if v is not None}
return self.client.get("/api/datasource/config/list", params=params)
return await self.client.get("/datasource/config/list", params=params)
@register_tool("list_tables")
@@ -42,7 +42,7 @@ class ListTablesTool(ToolDef):
async def execute(self, args: dict) -> dict:
params = {k: v for k, v in args.items() if v is not None}
return self.client.get("/api/datasource/table/list", params=params)
return await self.client.get("/datasource/table/list", params=params)
@register_tool("get_table_detail")
@@ -59,7 +59,7 @@ class GetTableDetailTool(ToolDef):
async def execute(self, args: dict) -> dict:
table_id = args["tableId"]
return self.client.get(f"/api/datasource/table/{table_id}/detail")
return await self.client.get(f"/datasource/table/{table_id}/detail")
@register_tool("create_table")
@@ -98,7 +98,7 @@ class CreateTableTool(ToolDef):
async def execute(self, args: dict) -> dict:
args = dict(args)
connection_id = args.pop("connectionId")
return self.client.post(f"/api/datasource/connection/{connection_id}/create_table", json_data=args)
return await self.client.post(f"/datasource/connection/{connection_id}/create_table", json_data=args)
@register_tool("alter_table")
@@ -131,7 +131,7 @@ class AlterTableTool(ToolDef):
async def execute(self, args: dict) -> dict:
args = dict(args)
connection_id = args.pop("connectionId")
return self.client.put(f"/api/datasource/connection/{connection_id}/alter_table", json_data=args)
return await self.client.put(f"/datasource/connection/{connection_id}/alter_table", json_data=args)
@register_tool("generate_table_by_description")
@@ -148,4 +148,4 @@ class GenerateTableByDescriptionTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/connection/generate_table", json_data=args)
return await self.client.post("/datasource/connection/generate_table", json_data=args)

View File

@@ -27,7 +27,7 @@ class ListDatasourcesTool(ToolDef):
async def execute(self, args: dict) -> dict:
params = {k: v for k, v in args.items() if v is not None}
return self.client.get("/api/datasource/connection/list", params=params)
return await self.client.get("/datasource/connection/list", params=params)
@register_tool("get_datasource_detail")
@@ -47,17 +47,17 @@ class GetDatasourceDetailTool(ToolDef):
result = {}
# 获取基本信息
try:
result["detail"] = self.client.get(f"/api/datasource/connection/{ds_id}")
result["detail"] = await self.client.get(f"/datasource/connection/{ds_id}")
except Exception as e:
result["detail"] = {"error": str(e)}
# 获取配置
try:
result["config"] = self.client.get(f"/api/datasource/config/{ds_id}")
result["config"] = await self.client.get(f"/datasource/config/{ds_id}")
except Exception as e:
result["config"] = {"error": str(e)}
# 获取实时结构
try:
result["structure"] = self.client.get(f"/api/datasource/connection/realtime/structure/{ds_id}")
result["structure"] = await self.client.get(f"/datasource/connection/realtime/structure/{ds_id}")
except Exception as e:
result["structure"] = {"error": str(e)}
return result
@@ -100,12 +100,12 @@ class CreateDatasourceTool(ToolDef):
"password": args.get("password"),
"connectionType": args.get("connectionType", "user_password"),
}
test_result = self.client.post("/api/datasource/connection/test", json_data=test_data)
test_result = await self.client.post("/datasource/connection/test", json_data=test_data)
if test_result.get("code") != 200:
return {"success": False, "error": f"连接测试失败: {test_result.get('msg', '未知错误')}"}
# 创建数据源
return self.client.post("/api/datasource/connection", json_data=args)
return await self.client.post("/datasource/connection", json_data=args)
@register_tool("update_datasource")
@@ -128,7 +128,7 @@ class UpdateDatasourceTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.put("/api/datasource/connection", json_data=args)
return await self.client.put("/datasource/connection", json_data=args)
@register_tool("toggle_datasource_status")
@@ -145,7 +145,7 @@ class ToggleDatasourceStatusTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.put("/api/datasource/connection/changeStatus", json_data=args)
return await self.client.put("/datasource/connection/changeStatus", json_data=args)
@register_tool("delete_datasource")
@@ -164,10 +164,10 @@ class DeleteDatasourceTool(ToolDef):
ds_id = args["id"]
# 先尝试停用(仅忽略已停用等预期错误)
try:
self.client.put("/api/datasource/connection/changeStatus", json_data={"id": ds_id, "status": 1})
await self.client.put("/datasource/connection/changeStatus", json_data={"id": ds_id, "status": 1})
except Exception as e:
# 记录日志但继续删除
logger.debug(f"停用数据源失败(可能已停用): {e}")
# 删除数据源
return self.client.delete(f"/api/datasource/connection/{ds_id}")
return await self.client.delete(f"/datasource/connection/{ds_id}")

View File

@@ -20,7 +20,7 @@ class GetSkillByDatasourceTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.get(f"/api/datasource/skill/getByDatasource/{args['datasourceId']}")
return await self.client.get(f"/datasource/skill/getByDatasource/{args['datasourceId']}")
@register_tool("get_skill_tools")
@@ -36,7 +36,7 @@ class GetSkillToolsTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.get(f"/api/datasource/skill/getBySkillId/{args['skillId']}")
return await self.client.get(f"/datasource/skill/getBySkillId/{args['skillId']}")
@register_tool("create_skill")
@@ -54,7 +54,7 @@ class CreateSkillTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/skill/createOrGet", json_data=args)
return await self.client.post("/datasource/skill/createOrGet", json_data=args)
@register_tool("create_sql_tool")
@@ -97,7 +97,7 @@ class CreateSqlToolTool(ToolDef):
for suggestion in args["suggestions"]:
if "sqlParams" in suggestion and isinstance(suggestion["sqlParams"], dict):
suggestion["sqlParams"] = json.dumps(suggestion["sqlParams"])
return self.client.post("/api/datasource/skill/confirmTools", json_data=args)
return await self.client.post("/datasource/skill/confirmTools", json_data=args)
@register_tool("delete_skill_tool")
@@ -113,7 +113,7 @@ class DeleteSkillToolTool(ToolDef):
}
async def execute(self, args: dict) -> dict:
return self.client.delete(f"/api/datasource/skill/tskilltool/{args['skillToolId']}")
return await self.client.delete(f"/datasource/skill/tskilltool/{args['skillToolId']}")
@register_tool("update_skill_config")
@@ -134,4 +134,4 @@ class UpdateSkillConfigTool(ToolDef):
# 如果 configTemplate 是 dict转为 JSON 字符串
if "configTemplate" in args and isinstance(args["configTemplate"], dict):
args["configTemplate"] = json.dumps(args["configTemplate"])
return self.client.post("/api/datasource/skill/updateOrGet", json_data=args)
return await self.client.post("/datasource/skill/updateOrGet", json_data=args)

View File

@@ -13,13 +13,26 @@ class ExecuteSqlTool(ToolDef):
"type": "object",
"properties": {
"datasourceId": {"type": "string", "description": "数据源 ID"},
"executableSql": {"type": "string", "description": "SQL 语句"},
"sql": {"type": "string", "description": "SQL 语句"},
"target": {"type": "string", "enum": ["prod", "test"], "default": "prod", "description": "环境,默认 prod"},
"sqlTemplate": {"type": "string", "description": "SQL 模板(可选)"},
"businessName": {"type": "string", "description": "业务名称(可选)"},
"parameters": {"type": "object", "description": "参数定义(可选)"},
"params": {"type": "object", "description": "SQL 参数对象(可选)"},
},
"required": ["datasourceId", "executableSql"],
"required": ["datasourceId", "sql"],
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/sqlExecutionLog/testSqlWithSchema", json_data=args)
# 映射参数名为后端 API 期望的格式
body = {}
if "datasourceId" in args:
body["datasourceId"] = args["datasourceId"]
if "sql" in args:
body["executableSql"] = args["sql"]
if "sqlTemplate" in args:
body["sqlTemplate"] = args["sqlTemplate"]
if "businessName" in args:
body["businessName"] = args["businessName"]
if "params" in args:
body["parameters"] = args["params"]
return await self.client.post("/datasource/sqlExecutionLog/testSqlWithSchema", json_data=body)

View File

@@ -12,12 +12,18 @@ class ToggleTableSubscriptionTool(ToolDef):
input_schema = {
"type": "object",
"properties": {
"configId": {"type": "string", "description": "数据库配置 ID"},
"tableName": {"type": "string", "description": "表名"},
"isSubscribe": {"type": "boolean", "description": "true=订阅, false=取消订阅"},
"tableId": {"type": "string", "description": " ID"},
"datasourceId": {"type": "string", "description": "数据源 ID"},
"subscribe": {"type": "boolean", "description": "true=订阅, false=取消订阅"},
},
"required": ["configId", "tableName", "isSubscribe"],
"required": ["tableId", "datasourceId", "subscribe"],
}
async def execute(self, args: dict) -> dict:
return self.client.post("/api/datasource/subscription/toggle", json_data=args)
# 映射参数名为后端 API 期望的格式
body = {
"tableId": args["tableId"],
"datasourceId": args["datasourceId"],
"subscribe": args["subscribe"],
}
return await self.client.post("/datasource/subscription/toggle", json_data=body)

View File

@@ -26,7 +26,7 @@ class QueryTableDataTool(ToolDef):
args = dict(args)
table_id = args.pop("tableId")
params = {k: v for k, v in args.items() if v is not None}
return self.client.get(f"/api/datasource/connection/builtin/table/{table_id}", params=params)
return await self.client.get(f"/datasource/connection/builtin/table/{table_id}", params=params)
@register_tool("insert_table_row")
@@ -49,7 +49,7 @@ class InsertTableRowTool(ToolDef):
target = args.pop("target", "prod")
data = args.pop("data", {})
params = {"target": target} if target else {}
return self.client.post(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=data, params=params)
return await self.client.post(f"/datasource/connection/builtin/table/{table_id}/rows", json_data=data, params=params)
@register_tool("update_table_row")
@@ -75,7 +75,7 @@ class UpdateTableRowTool(ToolDef):
data = args.pop("data", {})
params = {"target": target} if target else {}
body = {"primaryKey": primary_key, "data": data}
return self.client.put(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params)
return await self.client.put(f"/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params)
@register_tool("delete_table_rows")
@@ -103,7 +103,7 @@ class DeleteTableRowsTool(ToolDef):
primary_keys = args.pop("primaryKeys")
params = {"target": target} if target else {}
body = {"primaryKeys": primary_keys}
return self.client.delete(f"/api/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params)
return await self.client.delete(f"/datasource/connection/builtin/table/{table_id}/rows", json_data=body, params=params)
@register_tool("export_table_excel")
@@ -124,7 +124,7 @@ class ExportTableExcelTool(ToolDef):
table_id = args.pop("tableId")
target = args.pop("target", "prod")
params = {"target": target} if target else {}
result = self.client.get(f"/api/datasource/connection/builtin/table/{table_id}/export/excel", params=params)
result = await self.client.get(f"/datasource/connection/builtin/table/{table_id}/export/excel", params=params)
# 处理二进制响应
if result.get("raw"):

View File

@@ -30,8 +30,8 @@ class AgileDBAPIClient:
初始化 API 客户端
Args:
base_url: API 基础 URL默认从环境变量 AGILE_DB_BASE_URL 读取)
api_key: API 密钥(默认从环境变量 AGILE_DB_API_KEY 读取)
base_url: API 基础 URL默认从环境变量 backendBaseUrl 读取)
api_key: API 密钥(默认从环境变量 API_KEY 读取)
default_timeout: 请求超时时间(秒),默认 30 秒
"""
if base_url is None:
@@ -43,15 +43,15 @@ class AgileDBAPIClient:
self.base_url = base_url.rstrip('/')
self.api_key = api_key
self.default_timeout = default_timeout
self._client: Optional[httpx.Client] = None
self._client: Optional[httpx.AsyncClient] = None
logger.info(f"[客户端初始化] base_url={self.base_url}")
@property
def client(self) -> httpx.Client:
def client(self) -> httpx.AsyncClient:
"""懒加载 HTTP 客户端"""
if self._client is None:
self._client = httpx.Client(timeout=self.default_timeout)
self._client = httpx.AsyncClient(timeout=self.default_timeout)
return self._client
def _get_headers(self, extra_headers: Optional[Dict[str, str]] = None) -> Dict[str, str]:
@@ -64,10 +64,14 @@ class AgileDBAPIClient:
return headers
def _build_url(self, path: str) -> str:
"""构建完整 URL"""
"""构建完整 URL,自动去掉路径中多余的 /api 前缀"""
if path.startswith('http://') or path.startswith('https://'):
return path
return f"{self.base_url}{path}"
# 去掉 /api 前缀,因为 base_url 已经包含完整地址
clean_path = path
if clean_path.startswith('/api'):
clean_path = clean_path[4:]
return f"{self.base_url}{clean_path}"
def _handle_response(self, response: httpx.Response, url: str) -> Dict[str, Any]:
"""统一处理 API 响应"""
@@ -93,12 +97,12 @@ class AgileDBAPIClient:
return data
def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
async def get(self, path: str, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""发送 GET 请求"""
url = self._build_url(path)
try:
logger.info(f"[API请求] GET {url}")
response = self.client.get(url, headers=self._get_headers(), params=params)
response = await self.client.get(url, headers=self._get_headers(), params=params)
return self._handle_response(response, url)
except httpx.TimeoutException:
raise Exception(f"API 请求超时: {url}")
@@ -107,13 +111,13 @@ class AgileDBAPIClient:
except httpx.RequestError as e:
raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")
def post(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
async def post(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""发送 POST 请求"""
url = self._build_url(path)
try:
logger.info(f"[API请求] POST {url}")
headers = self._get_headers({'Content-Type': 'application/json'})
response = self.client.post(url, headers=headers, json=json_data, params=params)
response = await self.client.post(url, headers=headers, json=json_data, params=params)
return self._handle_response(response, url)
except httpx.TimeoutException:
raise Exception(f"API 请求超时: {url}")
@@ -122,13 +126,13 @@ class AgileDBAPIClient:
except httpx.RequestError as e:
raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")
def put(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
async def put(self, path: str, json_data: Optional[Dict[str, Any]] = None, params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""发送 PUT 请求"""
url = self._build_url(path)
try:
logger.info(f"[API请求] PUT {url}")
headers = self._get_headers({'Content-Type': 'application/json'})
response = self.client.put(url, headers=headers, json=json_data, params=params)
response = await self.client.put(url, headers=headers, json=json_data, params=params)
return self._handle_response(response, url)
except httpx.TimeoutException:
raise Exception(f"API 请求超时: {url}")
@@ -137,7 +141,7 @@ class AgileDBAPIClient:
except httpx.RequestError as e:
raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")
def delete(self, path: str, params: Optional[Dict[str, Any]] = None, json_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
async def delete(self, path: str, params: Optional[Dict[str, Any]] = None, json_data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""发送 DELETE 请求"""
url = self._build_url(path)
try:
@@ -145,7 +149,7 @@ class AgileDBAPIClient:
headers = self._get_headers()
if json_data is not None:
headers['Content-Type'] = 'application/json'
response = self.client.delete(url, headers=headers, params=params, json=json_data)
response = await self.client.delete(url, headers=headers, params=params, json=json_data)
return self._handle_response(response, url)
except httpx.TimeoutException:
raise Exception(f"API 请求超时: {url}")
@@ -154,14 +158,14 @@ class AgileDBAPIClient:
except httpx.RequestError as e:
raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")
def upload(self, path: str, files: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
async def upload(self, path: str, files: Dict[str, Any], params: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
"""发送文件上传请求multipart/form-data"""
url = self._build_url(path)
try:
logger.info(f"[API请求] UPLOAD {url}")
# 文件上传不需要 Content-Typehttpx 会自动设置 multipart/form-data
headers = self._get_headers()
response = self.client.post(url, headers=headers, files=files, params=params)
response = await self.client.post(url, headers=headers, files=files, params=params)
return self._handle_response(response, url)
except httpx.TimeoutException:
raise Exception(f"API 请求超时: {url}")
@@ -170,17 +174,17 @@ class AgileDBAPIClient:
except httpx.RequestError as e:
raise Exception(f"API 请求异常: {url}, 错误: {str(e)}")
def close(self):
async def close(self):
"""关闭 HTTP 客户端"""
if self._client is not None:
self._client.close()
await self._client.aclose()
self._client = None
def __enter__(self):
async def __aenter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close()
return False

View File

@@ -6,7 +6,7 @@ from typing import Optional
def get_api_key(default: Optional[str] = None) -> str:
"""
获取数据库管理平台 API 密钥
获取 API 密钥
Args:
default: 默认值(可选)
@@ -15,25 +15,25 @@ def get_api_key(default: Optional[str] = None) -> str:
str: API 密钥
Raises:
ValueError: 当 AGILE_DB_API_KEY 未设置且无默认值时
ValueError: 当 API_KEY 未设置且无默认值时
"""
value = os.environ.get("AGILE_DB_API_KEY", default or "")
value = os.environ.get("API_KEY", default or "")
if not value:
raise ValueError("环境变量 AGILE_DB_API_KEY 未设置")
raise ValueError("环境变量 API_KEY 未设置")
return value
def get_base_url(default: str = "http://localhost:8080") -> str:
def get_base_url(default: str = "http://lzwcai-demp-corp-manager:8086") -> str:
"""
获取数据库管理平台后端地址
获取后端服务地址
Args:
default: 默认值(默认 http://localhost:8080
default: 默认值(默认 http://lzwcai-demp-corp-manager:8086
Returns:
str: 后端 API 基础 URL
"""
return os.environ.get("AGILE_DB_BASE_URL", default)
return os.environ.get("backendBaseUrl", default)
def get_env_config() -> dict:

View File

@@ -7,6 +7,6 @@ from lzwcai_mcp_agile_db.server import main
import os
if __name__ == "__main__":
os.environ["AGILE_DB_API_KEY"] = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiTE9HSU4iLCJsb2dpbl91c2VyX2tleSI6IjJiMDY0YzMzLTBiZWYtNDU0NC04NWY1LTRmNTFiOGMxMmI5NSJ9.Uv599TvlQvlTlwrnZGo3Tl2eLAvM0ldE9vpMI5jHxbTf4_tVSRA60rUNIV4LBiw6pt1r_xIi7aFcTRE2PeN5sg"
os.environ["AGILE_DB_BASE_URL"] = "https://dempdemo.lzwcai.com"
os.environ["API_KEY"] = "Bearer eyJhbGciOiJIUzUxMiJ9.eyJ0b2tlbl90eXBlIjoiTE9HSU4iLCJsb2dpbl91c2VyX2tleSI6IjJiMDY0YzMzLTBiZWYtNDU0NC04NWY1LTRmNTFiOGMxMmI5NSJ9.Uv599TvlQvlTlwrnZGo3Tl2eLAvM0ldE9vpMI5jHxbTf4_tVSRA60rUNIV4LBiw6pt1r_xIi7aFcTRE2PeN5sg"
os.environ["backendBaseUrl"] = "https://dempdemo.lzwcai.com"
main()

View File

@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "lzwcai-mcp-agile-db"
version = "0.1.0"
version = "0.1.3"
description = "MCP server for database management platform with 33 tools for datasource, table, data, API key, and skill management"
readme = "README.md"
requires-python = ">=3.10"