Skip to content

Commit 7e0099e

Browse files
committed
add schemas.py
1 parent 8e0fe66 commit 7e0099e

File tree

4 files changed

+140
-120
lines changed

4 files changed

+140
-120
lines changed

src/asktable_mcp_server/tools.py renamed to src/asktable_mcp_server/at_apis.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from asktable import Asktable
2-
2+
import logging
33

44
async def get_asktable_answer(
55
api_key, datasource_id, question, base_url=None, role_id: str=None, role_variables: dict = None
@@ -16,6 +16,8 @@ async def get_asktable_answer(
1616
"""
1717

1818
asktable_client = Asktable(api_key=api_key, base_url=base_url)
19+
logging.info(f"api_key: {api_key}")
20+
logging.info(f"base_url: {base_url}")
1921
answer_response = asktable_client.answers.create(
2022
datasource_id=datasource_id,
2123
question=question,

src/asktable_mcp_server/schemas.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from typing import Annotated, Dict, Any, Optional
2+
from pydantic import Field
3+
4+
# 共享的参数类型定义
5+
QuestionParam = Annotated[str, Field(description="用户的自然语言查询描述。示例:生成查询昨天订单总金额的SQL、写一个SQL查询销售额前10的产品、帮我写一个统计各部门员工数量的SQL")]
6+
7+
RoleIdParam = Annotated[Optional[str], Field(description="角色ID,精确控制用户对数据的访问权限,支持库/表/字段/行四级控制。示例:'role_123456',可以为空(使用默认权限)。详见:https://docs.asktable.com/docs/role-and-permission-management/introduction")]
8+
9+
RoleVariablesParam = Annotated[Optional[Dict[str, Any]], Field(description="角色变量,用于角色访问控制时的变量传递。示例:{'employee_id': 2}(限定员工可见范围)或{'department_id': 'dept_001'}(限定部门可见范围),可以为空(不使用变量限制)")]
10+
11+
# 共享的工具描述
12+
GEN_SQL_DESCRIPTION = """
13+
将自然语言查询转换为标准SQL语句。
14+
这是一个智能SQL生成工具,可以理解用户的自然语言描述,并生成相应的SQL查询语句。
15+
该工具仅返回SQL文本,不会执行查询操作。
16+
17+
适用场景:
18+
- 需要将业务需求快速转换为SQL查询语句
19+
- 在执行查询前想要检查和验证SQL语句
20+
- 需要获取SQL语句用于其他系统或工具
21+
- 学习或理解如何编写特定查询的SQL语句
22+
"""
23+
24+
QUERY_DESCRIPTION = """
25+
将自然语言查询转换为实际数据结果。
26+
这是一个智能数据查询工具,可以理解用户的自然语言描述,并返回相应的查询结果。
27+
28+
适用场景:
29+
- 需要快速获取业务数据的查询结果
30+
- 直接获取数据分析结果和洞察
31+
- 需要以自然语言方式查询数据库
32+
- 获取实时数据报表和统计信息
33+
- 通过角色访问控制实现数据安全访问
34+
"""
35+
36+
# HTML 模板
37+
def get_home_page_html(version: str, base_url: str, path_prefix: str) -> str:
38+
"""生成首页 HTML 内容"""
39+
return f"""
40+
<!DOCTYPE html>
41+
<html>
42+
<head>
43+
<meta charset="utf-8">
44+
<title>AskTable MCP 服务(SSE)</title>
45+
<style>
46+
body {{
47+
max-width: 800px;
48+
margin: 0 auto;
49+
padding: 20px;
50+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
51+
line-height: 1.6;
52+
}}
53+
pre {{
54+
background: #f5f5f5;
55+
padding: 15px;
56+
border-radius: 5px;
57+
overflow-x: auto;
58+
}}
59+
code {{
60+
white-space: pre-wrap;
61+
}}
62+
h1, h2 {{
63+
border-bottom: 1px solid #eee;
64+
padding-bottom: 10px;
65+
}}
66+
ul {{
67+
padding-left: 20px;
68+
}}
69+
</style>
70+
</head>
71+
<body>
72+
<h1>欢迎访问 AskTable MCP 服务(SSE)!</h1>
73+
<p>当前版本: v{version}</p>
74+
75+
<h2>配置示例</h2>
76+
<p>在您的 Agent 配置文件中,添加以下配置:</p>
77+
<pre><code>{{
78+
"mcpServers": {{
79+
"asktable": {{
80+
"type": "sse",
81+
"url": "{base_url}{path_prefix}/sse/?apikey=YOUR_API_KEY&datasource_id=YOUR_DATASOURCE_ID",
82+
"headers": {{}},
83+
"timeout": 300,
84+
"sse_read_timeout": 300
85+
}}
86+
}}
87+
}}</code></pre>
88+
89+
<h2>工具</h2>
90+
<ul>
91+
<li>使用 AskTable 生成 SQL</li>
92+
<li>使用 AskTable 查询数据</li>
93+
<li>列出 AskTable 中的所有数据</li>
94+
</ul>
95+
<h2>帮助文档</h2>
96+
<p>更多详细信息,请访问 <a href="https://docs.asktable.com/docs/integration/mcp/use-asktable-mcp">使用 MCP 访问 AskTable</a></p>
97+
</body>
98+
</html>
99+
"""

src/asktable_mcp_server/server.py

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,32 @@
11
import argparse
22
import os
3-
from typing import Annotated, Dict, Any, Optional
4-
from pydantic import Field
53
from fastmcp import FastMCP
64

7-
from asktable_mcp_server.tools import (
5+
from asktable_mcp_server.at_apis import (
86
get_asktable_answer,
97
get_asktable_sql,
108
)
119
from asktable_mcp_server.sse_server import main as sse_main
10+
from asktable_mcp_server.schemas import (
11+
QuestionParam,
12+
RoleIdParam,
13+
RoleVariablesParam,
14+
GEN_SQL_DESCRIPTION,
15+
QUERY_DESCRIPTION,
16+
)
1217

1318
mcp = FastMCP(name="Asktable stdio mcp server running...")
1419

1520

1621
@mcp.tool(name='使用 AskTable 生成 SQL')
1722
async def gen_sql(
18-
question: Annotated[str, Field(description="用户的自然语言查询描述。示例:生成查询昨天订单总金额的SQL、写一个SQL查询销售额前10的产品、帮我写一个统计各部门员工数量的SQL")],
19-
role_id: Annotated[Optional[str], Field(description="角色ID,用于访问控制,当需要进行精细化的数据访问控制时使用。示例:'role_123456',可以为空(使用默认权限)。详见:https://docs.asktable.com/docs/role-and-permission-management/introduction")] = None,
20-
role_variables: Annotated[Optional[Dict[str, Any]], Field(description="角色变量,用于角色访问控制时的变量传递。示例:{'employee_id': 2}(限定员工可见范围)或{'department_id': 'dept_001'}(限定部门可见范围),可以为空(不使用变量限制)")] = None
23+
question: QuestionParam,
24+
role_id: RoleIdParam = None,
25+
role_variables: RoleVariablesParam = None
2126
) -> dict:
2227
"""
23-
将自然语言查询转换为标准SQL语句。
24-
这是一个智能SQL生成工具,可以理解用户的自然语言描述,并生成相应的SQL查询语句。
25-
该工具仅返回SQL文本,不会执行查询操作。
26-
27-
适用场景:
28-
- 需要将业务需求快速转换为SQL查询语句
29-
- 在执行查询前想要检查和验证SQL语句
30-
- 需要获取SQL语句用于其他系统或工具
31-
- 学习或理解如何编写特定查询的SQL语句
32-
"""
28+
{description}
29+
""".format(description=GEN_SQL_DESCRIPTION)
3330
# 构建基本参数
3431
params = {
3532
"api_key": os.getenv("API_KEY"),
@@ -47,21 +44,13 @@ async def gen_sql(
4744

4845
@mcp.tool(name='使用 AskTable 查询数据')
4946
async def query(
50-
question: Annotated[str, Field(description="用户的自然语言查询描述。示例:查询昨天订单总金额、查询销售额前10的产品、统计各部门员工数量")],
51-
role_id: Annotated[Optional[str], Field(description="角色ID,用于访问控制,当需要进行精细化的数据访问控制时使用。示例:'role_123456',可以为空(使用默认权限)。详见:https://docs.asktable.com/docs/role-and-permission-management/introduction")] = None,
52-
role_variables: Annotated[Optional[Dict[str, Any]], Field(description="角色变量,用于角色访问控制时的变量传递。示例:{'employee_id': 2}(限定员工可见范围)或{'department_id': 'dept_001'}(限定部门可见范围),可以为空(不使用变量限制)")] = None
47+
question: QuestionParam,
48+
role_id: RoleIdParam = None,
49+
role_variables: RoleVariablesParam = None
5350
) -> dict:
5451
"""
55-
将自然语言查询转换为实际数据结果。
56-
这是一个智能数据查询工具,可以理解用户的自然语言描述,并返回相应的查询结果。
57-
58-
适用场景:
59-
- 需要快速获取业务数据的查询结果
60-
- 直接获取数据分析结果和洞察
61-
- 需要以自然语言方式查询数据库
62-
- 获取实时数据报表和统计信息
63-
- 通过角色访问控制实现数据安全访问
64-
"""
52+
{description}
53+
""".format(description=QUERY_DESCRIPTION)
6554
# 构建基本参数
6655
params = {
6756
"api_key": os.getenv("API_KEY"),

src/asktable_mcp_server/sse_server.py

Lines changed: 20 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,26 @@
22
import asyncio
33
import logging
44
from contextlib import asynccontextmanager
5-
from typing import Annotated, Dict, Any, Optional
65

76
from fastmcp import FastMCP
87
from fastmcp.server.dependencies import get_http_request
98
from starlette.requests import Request
109
from starlette.responses import JSONResponse, HTMLResponse
1110
import fastmcp
12-
from pydantic import Field
1311

14-
from asktable_mcp_server.tools import (
12+
from asktable_mcp_server.at_apis import (
1513
get_asktable_answer,
1614
get_asktable_sql,
1715
)
1816
from asktable_mcp_server.version import __version__
17+
from asktable_mcp_server.schemas import (
18+
QuestionParam,
19+
RoleIdParam,
20+
RoleVariablesParam,
21+
GEN_SQL_DESCRIPTION,
22+
QUERY_DESCRIPTION,
23+
get_home_page_html,
24+
)
1925

2026
# 配置日志
2127
logging.basicConfig(
@@ -74,86 +80,18 @@ async def home(request: Request):
7480
scheme = request.url.scheme
7581
base_url = f"{scheme}://{host}"
7682

77-
content = f"""
78-
<!DOCTYPE html>
79-
<html>
80-
<head>
81-
<meta charset="utf-8">
82-
<title>AskTable MCP 服务(SSE)</title>
83-
<style>
84-
body {{
85-
max-width: 800px;
86-
margin: 0 auto;
87-
padding: 20px;
88-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
89-
line-height: 1.6;
90-
}}
91-
pre {{
92-
background: #f5f5f5;
93-
padding: 15px;
94-
border-radius: 5px;
95-
overflow-x: auto;
96-
}}
97-
code {{
98-
white-space: pre-wrap;
99-
}}
100-
h1, h2 {{
101-
border-bottom: 1px solid #eee;
102-
padding-bottom: 10px;
103-
}}
104-
ul {{
105-
padding-left: 20px;
106-
}}
107-
</style>
108-
</head>
109-
<body>
110-
<h1>欢迎访问 AskTable MCP 服务(SSE)!</h1>
111-
<p>当前版本: v{__version__}</p>
112-
113-
<h2>配置示例</h2>
114-
<p>在您的 Agent 配置文件中,添加以下配置:</p>
115-
<pre><code>{{
116-
"mcpServers": {{
117-
"asktable": {{
118-
"type": "sse",
119-
"url": "{base_url}{path_prefix}/sse/?apikey=YOUR_API_KEY&datasource_id=YOUR_DATASOURCE_ID",
120-
"headers": {{}},
121-
"timeout": 300,
122-
"sse_read_timeout": 300
123-
}}
124-
}}
125-
}}</code></pre>
126-
127-
<h2>工具</h2>
128-
<ul>
129-
<li>使用 AskTable 生成 SQL</li>
130-
<li>使用 AskTable 查询数据</li>
131-
<li>列出 AskTable 中的所有数据</li>
132-
</ul>
133-
<h2>帮助文档</h2>
134-
<p>更多详细信息,请访问 <a href="https://docs.asktable.com/docs/integration/mcp/use-asktable-mcp">使用 MCP 访问 AskTable</a></p>
135-
</body>
136-
</html>
137-
"""
83+
content = get_home_page_html(__version__, base_url, path_prefix)
13884
return HTMLResponse(content=content)
13985

14086
@mcp.tool(name="使用 AskTable 生成 SQL")
14187
async def gen_sql(
142-
question: Annotated[str, Field(description="用户的自然语言查询描述。示例:生成查询昨天订单总金额的SQL、写一个SQL查询销售额前10的产品、帮我写一个统计各部门员工数量的SQL")],
143-
role_id: Annotated[Optional[str], Field(description="角色ID,用于访问控制,当需要进行精细化的数据访问控制时使用。示例:'role_123456',可以为空(使用默认权限)。详见:https://docs.asktable.com/docs/role-and-permission-management/introduction")] = None,
144-
role_variables: Annotated[Optional[Dict[str, Any]], Field(description="角色变量,用于角色访问控制时的变量传递。示例:{'employee_id': 2}(限定员工可见范围)或{'department_id': 'dept_001'}(限定部门可见范围),可以为空(不使用变量限制)")] = None
88+
question: QuestionParam,
89+
role_id: RoleIdParam = None,
90+
role_variables: RoleVariablesParam = None
14591
) -> dict:
14692
"""
147-
将自然语言查询转换为标准SQL语句。
148-
这是一个智能SQL生成工具,可以理解用户的自然语言描述,并生成相应的SQL查询语句。
149-
该工具仅返回SQL文本,不会执行查询操作。
150-
151-
适用场景:
152-
- 需要将业务需求快速转换为SQL查询语句
153-
- 在执行查询前想要检查和验证SQL语句
154-
- 需要获取SQL语句用于其他系统或工具
155-
- 学习或理解如何编写特定查询的SQL语句
156-
"""
93+
{description}
94+
""".format(description=GEN_SQL_DESCRIPTION)
15795
global server_ready
15896

15997
if not server_ready:
@@ -182,21 +120,13 @@ async def gen_sql(
182120

183121
@mcp.tool(name="使用 AskTable 查询数据")
184122
async def query(
185-
question: Annotated[str, Field(description="用户的自然语言查询描述。示例:查询昨天订单总金额、查询销售额前10的产品、统计各部门员工数量")],
186-
role_id: Annotated[Optional[str], Field(description="角色ID,用于访问控制,当需要进行精细化的数据访问控制时使用。示例:'role_123456',可以为空(使用默认权限)。详见:https://docs.asktable.com/docs/role-and-permission-management/introduction")] = None,
187-
role_variables: Annotated[Optional[Dict[str, Any]], Field(description="角色变量,用于角色访问控制时的变量传递。示例:{'employee_id': 2}(限定员工可见范围)或{'department_id': 'dept_001'}(限定部门可见范围),可以为空(不使用变量限制)")] = None
123+
question: QuestionParam,
124+
role_id: RoleIdParam = None,
125+
role_variables: RoleVariablesParam = None
188126
) -> dict:
189127
"""
190-
将自然语言查询转换为实际数据结果。
191-
这是一个智能数据查询工具,可以理解用户的自然语言描述,并返回相应的查询结果。
192-
193-
适用场景:
194-
- 需要快速获取业务数据的查询结果
195-
- 直接获取数据分析结果和洞察
196-
- 需要以自然语言方式查询数据库
197-
- 获取实时数据报表和统计信息
198-
- 通过角色访问控制实现数据安全访问
199-
"""
128+
{description}
129+
""".format(description=QUERY_DESCRIPTION)
200130
global server_ready
201131

202132
if not server_ready:

0 commit comments

Comments
 (0)