Skip to content

Commit b1ac254

Browse files
committed
📝 Update app version and format the memorial wall
1 parent 3036b14 commit b1ac254

File tree

1 file changed

+80
-5
lines changed

1 file changed

+80
-5
lines changed
Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,87 @@
11
from fastmcp import FastMCP
2+
import psycopg2
3+
from psycopg2.extras import RealDictCursor
4+
import json
25

3-
# Create MCP server
6+
# 创建 MCP 服务
47
local_mcp_service = FastMCP("local")
58

6-
@local_mcp_service.tool(name="test_tool_name",
7-
description="test_tool_description")
9+
# 数据库连接字符串
10+
DATABASE_URL = "postgresql://postgres.vcfrtyjaokoklaebnfuh:[email protected]:6543/postgres?sslmode=require"
11+
12+
def get_connection():
13+
"""获取 psycopg2 数据库连接"""
14+
return psycopg2.connect(DATABASE_URL, cursor_factory=RealDictCursor)
15+
16+
def format_table(rows):
17+
"""将查询结果格式化为纯文本表格"""
18+
if not rows:
19+
return "⚠️ 查询返回为空"
20+
21+
headers = list(rows[0].keys())
22+
# 计算每列最大宽度
23+
col_widths = [len(h) for h in headers]
24+
for row in rows:
25+
for i, h in enumerate(headers):
26+
col_widths[i] = max(col_widths[i], len(str(row[h])))
27+
28+
# 构造分隔符
29+
sep = "+".join("-" * (w + 2) for w in col_widths)
30+
sep = f"+{sep}+"
31+
32+
# 构造表头
33+
header_row = "| " + " | ".join(h.ljust(w) for h, w in zip(headers, col_widths)) + " |"
34+
35+
# 构造数据行
36+
data_rows = []
37+
for row in rows:
38+
data_rows.append("| " + " | ".join(str(row[h]).ljust(w) for h, w in zip(headers, col_widths)) + " |")
39+
40+
# 拼接表格
41+
table = [sep, header_row, sep] + data_rows + [sep]
42+
return "\n".join(table)
43+
44+
# 异步数据库查询工具
45+
@local_mcp_service.tool(
46+
name="query_database",
47+
description="输入 SQL 查询数据库,返回查询结果"
48+
)
49+
async def query_database(sql: str, output_format: str = "table") -> str:
50+
"""
51+
sql: 查询语句
52+
output_format: 输出格式,可选 'table' 或 'json'
53+
"""
54+
conn = None
55+
try:
56+
conn = get_connection()
57+
with conn:
58+
with conn.cursor() as cur:
59+
cur.execute(sql)
60+
if cur.description: # 查询语句
61+
rows = cur.fetchall()
62+
if output_format.lower() == "json":
63+
return json.dumps(rows, indent=2, ensure_ascii=False)
64+
else:
65+
return format_table(rows)
66+
else: # 非查询语句
67+
return f"❌ 非查询语句,拒绝执行"
68+
except Exception as e:
69+
return f"❌ 执行出错: {e}"
70+
finally:
71+
if 'conn' in locals():
72+
conn.close()
73+
74+
# 示例测试工具
75+
@local_mcp_service.tool(
76+
name="demo_tool",
77+
description="测试工具示例"
78+
)
879
async def demo_tool(para_1: str, para_2: int) -> str:
9-
print("tool is called successfully")
10-
print(para_1, para_2)
80+
print("demo_tool 被调用")
81+
print("para_1:", para_1)
82+
print("para_2:", para_2)
1183
return "success"
1284

85+
# 启动 MCP 服务
86+
if __name__ == "__main__":
87+
local_mcp_service.run()

0 commit comments

Comments
 (0)