Doris MCP Server on AWS AgentCore
Deploys 25 MCP tools for Apache Doris, enabling SQL execution, metadata queries, monitoring, and data governance over HTTPS via AWS Bedrock AgentCore Runtime.
README
Doris MCP Server on AWS AgentCore Runtime
将 Apache Doris MCP Server 的全部 25 个工具部署到 AWS Bedrock AgentCore Runtime,通过 HTTPS endpoint 对外提供 MCP 协议服务。
架构
MCP Client (Quick Suite / Cursor / 其他)
│
▼ HTTPS + JWT/SigV4
AgentCore Runtime (MCP 协议, ap-northeast-2)
│ VPC 内网
▼
Apache Doris (EC2 i-0180e08a5cf11e596, 172.31.48.206:9030)
AgentCore Runtime 与 Doris 部署在同一个 VPC 内,通过内网 IP 直接通信,无需公网暴露数据库端口。
可用工具 (25 个)
| 类别 | 工具 |
|---|---|
| SQL 执行 | exec_query, exec_adbc_query |
| 元数据查询 | get_db_list, get_db_table_list, get_table_schema, get_table_comment, get_table_column_comments, get_table_indexes, get_catalog_list |
| 查询分析 | get_sql_explain, get_sql_profile, get_table_data_size, get_recent_audit_logs |
| 监控 | get_monitoring_metrics_info, get_monitoring_metrics_data, get_realtime_memory_stats, get_historical_memory_stats, get_adbc_connection_info |
| 数据治理 | analyze_data_quality, trace_column_lineage, monitor_data_freshness, analyze_data_access_patterns, analyze_data_flow_dependencies, analyze_slow_queries_topn, analyze_resource_growth_curves |
前置条件
- Python 3.12+
- AWS CLI 已配置凭证,且有 AgentCore 相关权限
- Doris EC2 所在安全组允许来自 AgentCore 子网的 9030 端口入站流量
快速开始
1. 创建虚拟环境并安装依赖
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
2. 编辑部署配置
vim deploy.conf
需要填写的关键字段:
AWS_REGION="ap-northeast-2" # 首尔
SUBNET_IDS="subnet-xxx,subnet-yyy" # Doris 同 VPC 的子网 (至少 2 个不同 AZ)
SECURITY_GROUP_IDS="sg-zzz" # 允许访问 Doris 9030 的安全组
DORIS_HOST="172.31.48.206" # Doris 内网 IP
DORIS_PORT="9030"
DORIS_USER="root"
DORIS_PASSWORD="your_password"
3. 部署
source .venv/bin/activate
./deploy.sh
脚本会自动执行 agentcore configure 和 agentcore deploy,采用 Direct Code Deploy 方式(代码直传 S3,无需 Docker)。
4. 验证
agentcore status
agentcore invoke '{"prompt": "列出所有数据库"}'
安全组配置
AgentCore Runtime 以 VPC 模式部署时,会在指定子网中创建 ENI(弹性网络接口)。需要确保:
- AgentCore 的安全组出站规则允许访问
172.31.48.206:9030 - Doris EC2 的安全组入站规则允许来自 AgentCore 安全组(或子网 CIDR)的 TCP 9030 流量
如果 AgentCore 和 Doris 使用同一个安全组,且该安全组允许组内互访,则无需额外配置。
文件说明
├── mcp_server.py # MCP Server 入口 (FastMCP + doris-mcp-server 工具)
├── requirements.txt # Python 依赖
├── deploy.conf # 部署配置 (区域/VPC/Doris 连接信息)
├── deploy.sh # 一键部署脚本
├── setup_cognito.sh # 一键创建 Cognito OAuth 资源 (Quick Suite 接入用)
├── test_mcp.py # 端到端测试 (OAuth 认证)
└── README.md
部署后配置 MCP 客户端
部署完成后,运行 agentcore status 获取 Agent Runtime ARN,格式如下:
arn:aws:bedrock-agentcore:ap-northeast-2:123456789012:runtime/mcp_server-xxxxxx
获取 MCP Endpoint URL
将 ARN 中的 : 替换为 %3A,/ 替换为 %2F,拼接成 endpoint URL:
https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/<URL编码的ARN>/invocations?qualifier=DEFAULT
可以用以下命令自动生成:
AGENT_ARN="你的Agent Runtime ARN"
ENCODED_ARN=$(echo -n "$AGENT_ARN" | python3 -c "import sys,urllib.parse; print(urllib.parse.quote(sys.stdin.read(), safe=''))")
echo "https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/${ENCODED_ARN}/invocations?qualifier=DEFAULT"
认证方式
AgentCore Runtime 支持两种认证方式:
| 认证方式 | 适用场景 | 客户端要求 |
|---|---|---|
| IAM SigV4(默认) | AWS 内部调用、开发测试 | 需要 AWS 凭证,客户端需实现 SigV4 签名 |
| OAuth 2.0 / JWT | 外部客户端集成(Quick Suite、Kiro、Cursor 等) | 只需 Bearer Token,标准 HTTP 认证 |
默认部署使用 IAM SigV4 认证。如需接入 Amazon Quick Suite 等外部 MCP 客户端,需要配置 OAuth 认证。详见下方 Cognito OAuth 认证 章节。
在 Kiro 中配置
创建或编辑 .kiro/settings/mcp.json:
{
"mcpServers": {
"doris": {
"url": "https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/<URL编码的ARN>/invocations?qualifier=DEFAULT",
"headers": {
"Authorization": "Bearer <你的JWT Token>"
}
}
}
}
如果使用 IAM SigV4 认证,Kiro 目前不直接支持 SigV4 签名的 Streamable HTTP,建议配置 OAuth/JWT 认证方式。
在 Cursor 中配置
编辑 ~/.cursor/mcp.json:
{
"mcpServers": {
"doris": {
"url": "https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/<URL编码的ARN>/invocations?qualifier=DEFAULT",
"headers": {
"Authorization": "Bearer <你的JWT Token>"
}
}
}
}
使用 Python MCP SDK 连接
import asyncio
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client
async def main():
agent_arn = "arn:aws:bedrock-agentcore:ap-northeast-2:123456789012:runtime/mcp_server-xxxxxx"
encoded_arn = agent_arn.replace(':', '%3A').replace('/', '%2F')
mcp_url = f"https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/{encoded_arn}/invocations?qualifier=DEFAULT"
headers = {
"Authorization": "Bearer <你的JWT Token>",
"Content-Type": "application/json",
}
async with streamablehttp_client(mcp_url, headers, timeout=120, terminate_on_close=False) as (
read_stream, write_stream, _,
):
async with ClientSession(read_stream, write_stream) as session:
await session.initialize()
# 列出所有工具
tools = await session.list_tools()
print(f"可用工具: {len(tools.tools)} 个")
for tool in tools.tools:
print(f" - {tool.name}: {tool.description[:60]}...")
# 调用工具示例: 查询数据库列表
result = await session.call_tool("get_db_list", {})
print(result)
asyncio.run(main())
使用 MCP Inspector 测试
npx @modelcontextprotocol/inspector
在浏览器中打开 Inspector(默认 http://localhost:6274),选择 Streamable HTTP 传输方式,填入 endpoint URL 和 Bearer Token 即可交互测试所有 25 个工具。
Cognito OAuth 认证详解
为什么需要 Cognito?
AgentCore Runtime 默认使用 IAM SigV4 认证,这要求客户端拥有 AWS 凭证并实现 SigV4 签名算法。但很多 MCP 客户端(如 Amazon Quick Suite、Kiro、Cursor、MCP Inspector)只支持标准的 OAuth 2.0 Bearer Token 认证。
Amazon Cognito 在这里充当 OAuth 2.0 身份提供者(Identity Provider),为 AgentCore Runtime 提供标准的 JWT Token 签发和验证能力。
Cognito 与 AgentCore Runtime 的协作流程
┌─────────────┐ ① client_credentials grant ┌──────────────────┐
│ MCP Client │ ──────────────────────────────────▶ │ Cognito User │
│ (Quick │ (Client ID + Client Secret) │ Pool │
│ Suite等) │ ◀────────────────────────────────── │ │
│ │ ② 返回 Access Token (JWT) │ Token Endpoint: │
│ │ │ /oauth2/token │
│ │ └──────────────────┘
│ │ │
│ │ ③ MCP 请求 + Bearer Token │
│ │ ──────────────────────────────────▶ ┌───────┴──────────┐
│ │ │ AgentCore │
│ │ ⑤ MCP 响应 (JSON-RPC) │ Runtime │
│ │ ◀────────────────────────────────── │ │
└─────────────┘ │ ④ 验证 JWT: │
│ - 签名有效? │
│ - Client ID │
│ 在白名单中? │
│ - Token 未过期? │
└──────────────────┘
详细步骤:
- MCP 客户端用 Client ID + Client Secret 向 Cognito Token Endpoint 发起
client_credentialsgrant 请求 - Cognito 验证凭证后签发一个 JWT 格式的 Access Token(默认有效期 1 小时)
- MCP 客户端在后续每个 MCP 请求的
Authorizationheader 中携带Bearer <token> - AgentCore Runtime 收到请求后,通过 Cognito 的 OIDC Discovery URL 获取公钥,验证 JWT 的签名、有效期,并检查 Client ID 是否在
allowedClients白名单中 - 验证通过后,AgentCore Runtime 正常处理 MCP 请求并返回响应
Cognito 中各组件的作用
| Cognito 组件 | 作用 | 说明 |
|---|---|---|
| User Pool | 身份目录和 Token 签发服务 | 管理用户/客户端身份,签发 JWT Token |
| Resource Server | 定义 OAuth scope | 定义 doris-mcp/invoke scope,限定 Token 的权限范围 |
| User Pool Domain | 提供 OAuth 2.0 端点 | 暴露 /oauth2/token 等标准 OAuth 端点 |
| App Client | 代表一个接入方 | 每个 MCP 客户端(Quick Suite、Kiro 等)可以有独立的 App Client |
| OIDC Discovery URL | 公钥发现端点 | AgentCore 通过此 URL 获取 JWT 签名公钥,无需手动配置证书 |
两种 OAuth 认证模式对比
| client_credentials (2LO) | USER_PASSWORD_AUTH (3LO) | |
|---|---|---|
| 适用场景 | 服务间调用(Machine-to-Machine) | 有具体用户身份的场景 |
| 需要用户名密码 | 否,只需 Client ID + Secret | 是 |
| 需要 Client Secret | 是 | 可选 |
| 需要 Resource Server | 是(必须定义 scope) | 否 |
| 需要 User Pool Domain | 是(提供 token endpoint) | 否(通过 API 直接调用) |
| Quick Suite 支持 | ✅ Service authentication | ✅ 但需要用户交互 |
| 推荐用于 | Quick Suite、服务端集成 | 个人开发者测试 |
一键创建 Cognito 资源(2LO 模式)
项目提供了 setup_cognito.sh 脚本,自动创建所有 Cognito 资源:
source .venv/bin/activate
./setup_cognito.sh
脚本会依次创建 User Pool → Resource Server → User Pool Domain → App Client,并输出 Quick Suite 接入所需的三个值:
- Client ID — App Client 的唯一标识
- Client Secret — App Client 的密钥,用于 client_credentials 认证
- Token URL — Cognito 的 OAuth 2.0 Token 端点
同时输出 AgentCore 重新部署所需的 Discovery URL。
将 OAuth 配置绑定到 AgentCore Runtime
创建 Cognito 资源后,需要重新部署 AgentCore Runtime,通过 --authorizer-config 参数告诉 Runtime 如何验证 JWT:
agentcore configure \
--entrypoint mcp_server.py \
--protocol MCP \
--runtime PYTHON_3_12 \
--disable-memory \
--region ap-northeast-2 \
--vpc \
--subnets "subnet-xxx,subnet-yyy" \
--security-groups "sg-zzz" \
--authorizer-config '{
"customJWTAuthorizer": {
"discoveryUrl": "https://cognito-idp.ap-northeast-2.amazonaws.com/<POOL_ID>/.well-known/openid-configuration",
"allowedClients": ["<CLIENT_ID>"]
}
}' \
--non-interactive
agentcore deploy \
--env DORIS_HOST=172.31.48.206 \
--env DORIS_PORT=9030 \
--env DORIS_USER=root \
--env DORIS_PASSWORD=your_password \
--env DORIS_DATABASE=ecommerce_demo
authorizer-config 中的两个关键字段:
discoveryUrl— Cognito 的 OIDC Discovery 端点,AgentCore 通过它自动获取 JWT 签名公钥(JWKS)、签发者(issuer)等信息,无需手动配置allowedClients— 允许访问的 Client ID 白名单,只有在此列表中的 App Client 签发的 Token 才会被接受
部署完成后,AgentCore Runtime 同时支持 IAM SigV4 和 OAuth Bearer Token 两种认证方式。
在 Amazon Quick Suite 中接入
- 登录 Amazon Quick Suite(需要 Author Pro 订阅)
- 左侧导航 → Integrations → Actions 标签
- 点击 Model Context Protocol 的 "+" 号创建新集成
- 填写配置:
| 配置项 | 值 |
|---|---|
| Name | Doris MCP Server |
| Description | Apache Doris 数据库查询和管理,支持 SQL 执行、元数据查询、性能分析、数据治理等 25 个工具 |
| MCP server endpoint | https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/<URL编码的ARN>/invocations?qualifier=DEFAULT |
| Authentication | Service authentication (2LO) |
| Client ID | setup_cognito.sh 输出的 Client ID |
| Client Secret | setup_cognito.sh 输出的 Client Secret |
| Token URL | setup_cognito.sh 输出的 Token URL |
- Quick Suite 会自动通过
client_credentialsgrant 获取 Token,发现全部 25 个 Doris 工具 - 可选:将此集成共享给其他用户和组
Token 有效期与刷新
- Cognito
client_credentialsgrant 签发的 Access Token 默认有效期为 1 小时 - Quick Suite 等成熟的 MCP 客户端会自动在 Token 过期前刷新
- 如需手动获取 Token(用于测试),可以用以下命令:
CLIENT_ID="你的Client ID"
CLIENT_SECRET="你的Client Secret"
TOKEN_URL="你的Token URL"
# 获取 Access Token
curl -s -X POST "$TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-u "${CLIENT_ID}:${CLIENT_SECRET}" \
-d "grant_type=client_credentials&scope=doris-mcp/invoke" \
| python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])"
添加更多接入方
如果需要让多个客户端(如同时接入 Quick Suite 和 Kiro)使用独立的凭证,可以在同一个 Cognito User Pool 中创建多个 App Client,并将它们的 Client ID 都加入 allowedClients 列表:
# 创建新的 App Client
NEW_CLIENT_ID=$(aws cognito-idp create-user-pool-client \
--user-pool-id "$POOL_ID" \
--client-name "doris-mcp-kiro" \
--generate-secret \
--explicit-auth-flows "ALLOW_USER_PASSWORD_AUTH" "ALLOW_REFRESH_TOKEN_AUTH" \
--allowed-o-auth-flows "client_credentials" \
--allowed-o-auth-scopes "doris-mcp/invoke" \
--allowed-o-auth-flows-user-pool-client \
--region ap-northeast-2 \
--query 'UserPoolClient.ClientId' --output text)
# 重新部署,allowedClients 中加入新的 Client ID
agentcore configure \
... \
--authorizer-config '{
"customJWTAuthorizer": {
"discoveryUrl": "https://cognito-idp.ap-northeast-2.amazonaws.com/<POOL_ID>/.well-known/openid-configuration",
"allowedClients": ["<原CLIENT_ID>", "'$NEW_CLIENT_ID'"]
}
}' \
--non-interactive
这样每个接入方有独立的 Client ID 和 Secret,可以独立吊销,互不影响。
部署踩坑记录
问题 1: 子网所在可用区不被 AgentCore 支持
现象
❌ Launch failed: Agent endpoint create failed: The following subnets are in
unsupported availability zones in region ap-northeast-2:
subnet-07580033567fa2ebe in ap-northeast-2d (ID: apne2-az4).
Supported availability zones are: apne2-az3, apne2-az2, apne2-az1
原因
AgentCore Runtime 在每个区域只支持部分可用区。首尔区域(ap-northeast-2)支持的 AZ 为 apne2-az1、apne2-az2、apne2-az3,不支持 apne2-az4(即 ap-northeast-2d)。
解决
在 deploy.conf 中将子网换成位于支持 AZ 的子网。可以用以下命令查询子网的 AZ ID:
aws ec2 describe-subnets --region ap-northeast-2 \
--filters "Name=vpc-id,Values=vpc-0afafebf14225f0f4" \
--query 'Subnets[*].{SubnetId:SubnetId, AZ:AvailabilityZone, AZID:AvailabilityZoneId}' \
--output table
各区域支持的 AZ 列表见 AgentCore VPC 文档。
问题 2: MCP 协议的 Runtime 不能用 InvokeAgentRuntime API 调用
现象
使用 boto3 的 invoke_agent_runtime() 调用 MCP 协议的 Runtime 时返回 HTTP 406 错误。
原因
InvokeAgentRuntime API 是为 HTTP 协议的 Agent 设计的。MCP 协议的 Runtime 需要通过 Streamable HTTP 传输方式直接发送 MCP JSON-RPC 消息到 endpoint URL,而不是通过 AWS SDK 的封装 API。
解决
使用 SigV4 签名的 HTTP POST 请求直接调用 MCP endpoint:
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
from botocore.session import Session as BotocoreSession
import httpx
url = "https://bedrock-agentcore.ap-northeast-2.amazonaws.com/runtimes/<编码ARN>/invocations?qualifier=DEFAULT"
body = '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
headers = {"Content-Type": "application/json", "Accept": "application/json, text/event-stream"}
# SigV4 签名
session = BotocoreSession()
creds = session.get_credentials().get_frozen_credentials()
req = AWSRequest(method="POST", url=url, data=body, headers=headers)
SigV4Auth(creds, "bedrock-agentcore", "ap-northeast-2").add_auth(req)
async with httpx.AsyncClient(timeout=120) as client:
resp = await client.post(url, content=body, headers=dict(req.headers))
问题 3: 调用 get_db_list 等数据库工具时无限挂起
现象
MCP Initialize 和 tools/list 正常返回,但调用任何需要数据库连接的工具(如 get_db_list、exec_query)时请求永远不返回,直到超时。
原因
doris-mcp-server 0.6.0 的 DorisConnectionManager 存在一个连接池死锁 bug。在 __init__ 中设置了:
self._recovery_lock = asyncio.Lock()
self.pool_recovery_lock = self._recovery_lock # 别名,指向同一把锁
当首次调用需要创建连接池时,调用链为:
get_connection()
→ _recover_pool_with_lock()
→ async with self._recovery_lock: # 第一次获取锁
→ _recover_pool()
→ async with self.pool_recovery_lock: # 同一把锁,死锁!
asyncio.Lock 不可重入,同一个协程对同一把锁做两次 acquire 会永远阻塞。
解决
在 mcp_server.py 的初始化逻辑中,绕过 _recover_pool 路径,直接用 aiomysql.create_pool() 预创建连接池并赋值给 connection_manager.pool:
import aiomysql
connection_manager.pool = await asyncio.wait_for(
aiomysql.create_pool(
host=connection_manager.host,
port=connection_manager.port,
user=connection_manager.user,
password=connection_manager.password,
db=connection_manager.database,
charset=connection_manager.charset,
minsize=0,
maxsize=connection_manager.maxsize,
pool_recycle=connection_manager.pool_recycle,
connect_timeout=connection_manager.connect_timeout,
autocommit=True,
),
timeout=15.0,
)
这样 get_connection() 发现 self.pool 已经存在,就不会走 _recover_pool 的死锁路径。
清理资源
source .venv/bin/activate
agentcore destroy
手动部署 (不使用 deploy.sh)
source .venv/bin/activate
# 配置
agentcore configure \
--entrypoint mcp_server.py \
--protocol MCP \
--runtime PYTHON_3_12 \
--disable-memory \
--region ap-northeast-2 \
--vpc \
--subnets subnet-xxx,subnet-yyy \
--security-groups sg-zzz \
--non-interactive
# 部署
agentcore deploy \
--env DORIS_HOST=172.31.48.206 \
--env DORIS_PORT=9030 \
--env DORIS_USER=root \
--env DORIS_PASSWORD=your_password \
--env DORIS_DATABASE=information_schema
# 测试
agentcore invoke '{"prompt": "show databases"}'
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.