MCP-SERVER

MCP-SERVER

A TypeScript + Express skeleton for MCP services, currently only providing a health check endpoint, with planned MySQL metadata and Alibaba Cloud log MCP services.

Category
访问服务器

README

aliyun-sls-mcp-server

这是一个 TypeScript + Express 项目,用来承载阿里云 SLS MCP 服务。

当前已经包含健康检查、阿里云日志 HTTP 调试接口,以及 Streamable HTTP MCP 服务。

服务规划

  • MySQL 元数据 MCP 服务:后续用于告诉大模型某个 MySQL 实例有哪些表、表结构是什么、字段含义是什么,以及是否需要补充索引等建议。
  • 阿里云日志 MCP 服务:后续用于封装阿里云日志相关能力。

本地启动

npm install
npm run dev

默认端口是 3000,可以通过 .env 修改:

cp .env.example .env

健康检查

curl http://localhost:3000/health

预期返回:

{
  "status": "ok",
  "service": "aliyun-sls-mcp-server"
}

阿里云日志调试接口

这里是阿里云日志服务 ListProject API 的 HTTP 调试入口,方便本地直接用浏览器或 curl 验证。

先复制本地环境变量文件:

cp .env.example .env.local

然后填写:

ALIYUN_LOG_ACCESS_KEY_ID=
ALIYUN_LOG_ACCESS_KEY_SECRET=
ALIYUN_LOG_REGION=cn-hangzhou
ALIYUN_LOG_DEFAULT_ENVIRONMENT=test
ALIYUN_LOG_ENVIRONMENTS={"test":{"projectName":"k8s-dev","logstoreName":"test"},"staging":{"projectName":"k8s-staging","logstoreName":"staging"}}
ALIYUN_LOG_DEFAULT_QUERY_MINUTES=15
ALIYUN_LOG_MAX_QUERY_MINUTES=30
ALIYUN_LOG_EMPTY_QUERY_MAX_MINUTES=5
ALIYUN_LOG_TRACE_DEFAULT_QUERY_MINUTES=10080
ALIYUN_LOG_TRACE_MAX_QUERY_MINUTES=10080
ALIYUN_LOG_TRACE_MIN_LENGTH=16
ALIYUN_LOG_DEFAULT_PAGE_SIZE=50
ALIYUN_LOG_MAX_PAGE_SIZE=100
ALIYUN_LOG_RETURN_FIELDS=time,level,_container_name_,_pod_name_,_namespace_,content

.env.example 是提交到 Git 的模板,不放真实密钥。.env.local 是本机真实配置,已经被 .gitignore 忽略,不会上传到 GitHub。

ALIYUN_LOG_RETURN_FIELDS 用来控制每条日志返回哪些字段,不配置时返回阿里云原始日志的全部字段。配置时填写阿里云原始字段名,例如:

time,level,_container_name_,_pod_name_,_namespace_,content

字段名要和阿里云返回保持一致,例如服务名字段是 _container_name_,不是 containerName。如果要调试字段,可以先不配置 ALIYUN_LOG_RETURN_FIELDS,这样会返回原始日志的全部字段。

ALIYUN_LOG_RETURN_FIELDS=time,level,_container_name_,_pod_name_,_namespace_,content,__time__

启动服务:

npm run dev

查询当前账号在指定区域下能访问的 Project:

curl "http://localhost:3000/aliyun-log/projects"

如果请求里不传 projectName,接口会查询当前区域下全部 Project。

按 Project 名称模糊过滤:

curl "http://localhost:3000/aliyun-log/projects?projectName=k8s"

查询某个 Project 下的 Logstore:

curl "http://localhost:3000/aliyun-log/projects/k8s-dev/logstores"

按 Logstore 名称模糊过滤:

curl "http://localhost:3000/aliyun-log/projects/k8s-dev/logstores?logstoreName=test"

查询某个 Project + Logstore 最近 5 分钟日志:

curl "http://localhost:3000/aliyun-log/projects/k8s-dev/logstores/test/logs"

按环境查询最近 5 分钟日志。environment 不传时默认使用 ALIYUN_LOG_DEFAULT_ENVIRONMENT,当前默认是 test

curl "http://localhost:3000/aliyun-log/logs"

指定环境查询:

curl "http://localhost:3000/aliyun-log/logs?environment=staging"

查询最近 5 分钟 ERROR 日志:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "level=error" \
  --data-urlencode "minutes=5" \
  --data-urlencode "pageNumber=1" \
  --data-urlencode "pageSize=50"

查询两个服务的日志:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "containerNames=order-service,pay-service" \
  --data-urlencode "minutes=5"

查询两个服务的 ERROR 日志:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "containerNames=order-service,pay-service" \
  --data-urlencode "level=error" \
  --data-urlencode "minutes=5"

查询 traceId 链路:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "traceId=b03a2133ebe048ccae56cb40125bb53d.574.17827209165150053"

traceId 且不传 from/to/minutes 时,默认查最近 7 天,也就是 ALIYUN_LOG_TRACE_DEFAULT_QUERY_MINUTES=10080

查询 traceId 的某个日志级别:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "traceId=b03a2133ebe048ccae56cb40125bb53d.574.17827209165150053" \
  --data-urlencode "level=info"

query 可以和结构化参数混用,服务端会用 and 拼成最终查询语句。例如:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "query=TimeoutException" \
  --data-urlencode "containerNames=order-service,pay-service" \
  --data-urlencode "level=error" \
  --data-urlencode "keywords=database,slow sql" \
  --data-urlencode "minutes=5"

最终会拼成类似:

(TimeoutException) and (_container_name_: order-service or _container_name_: pay-service) and level: error and content: "database" and content: "slow sql"

分页查询第二页时,不要重新传 minutes。如果上一页返回了 nextPage,直接复用里面的 from/to/query/pageSize/reverse,只使用它给出的下一页页码。

上一页返回示例:

{
  "page": {
    "pageNumber": 1,
    "pageSize": 50,
    "offset": 0,
    "hasMore": true
  },
  "nextPage": {
    "environment": "test",
    "query": "level: error",
    "from": 1719390000,
    "to": 1719390900,
    "pageNumber": 2,
    "pageSize": 50,
    "reverse": true
  }
}

然后按 nextPage 查询第二页:

curl --get "http://localhost:3000/aliyun-log/logs" \
  --data-urlencode "environment=test" \
  --data-urlencode "query=level: error" \
  --data-urlencode "from=1719390000" \
  --data-urlencode "to=1719390900" \
  --data-urlencode "pageNumber=2" \
  --data-urlencode "pageSize=50"

也可以用 Unix 秒级时间戳指定时间范围:

curl "http://localhost:3000/aliyun-log/projects/k8s-dev/logstores/test/logs?query=level:%20ERROR&from=1719390000&to=1719390900"

注意:query 里如果包含 |,阿里云会把它当分析语句处理,普通 line/offset 分页可能会被忽略。这种情况建议在 SQL 里自己写 limit/offset

MCP 服务

当前提供一个 Streamable HTTP MCP 服务,路径是:

POST /mcp

MCP 使用 stateful Streamable HTTP:

  • 初始化请求会返回 mcp-session-id
  • 后续 POST /mcp 需要带同一个 mcp-session-id
  • GET /mcp 使用同一个 mcp-session-id 建立 SSE 长连接,用于接收服务端通知。
  • DELETE /mcp 使用同一个 mcp-session-id 终止会话。

当前注册的工具:

aliyun_log_list_projects
aliyun_log_list_logstores
aliyun_log_query_logs

这些工具复用阿里云日志 API,用来查询当前账号在指定区域下可访问的 Project、Logstore,以及指定 Logstore 下的日志。

启动服务:

npm run dev

工具参数:

{
  "projectName": "k8s",
  "offset": 0,
  "size": 100
}

projectName 不传时,会查询当前区域下全部 Project。工具执行期间会发送开始和完成两条 logging notification,MCP 客户端建立 GET /mcp 长连接后可以收到这些服务端通知。

aliyun_log_list_logstores 工具参数:

{
  "projectName": "k8s-dev",
  "logstoreName": "test",
  "offset": 0,
  "size": 200
}

aliyun_log_query_logs 工具参数:

{
  "environment": "test",
  "query": "(_container_name_: order-service or _container_name_: pay-service) and level: error",
  "minutes": 5,
  "pageNumber": 1,
  "pageSize": 50,
  "reverse": true
}

environment 不传时默认查 test。如果要临时绕过环境映射,也可以同时传 projectNamelogstoreName,但不能和 environment 混用。

常用查询字段:

  • 服务名:_container_name_
  • 日志级别:level
  • 日志级别取值:infowarnerror
  • traceId:content

时间参数有两种写法:

  1. minutes,表示查询最近 N 分钟。
  2. 同时传 fromto,表示查询固定 Unix 秒级时间范围。

如果两种都不传,有 traceId 时默认查询最近 7 天;有普通 query 或结构化服务/level/keyword 条件时默认查询最近 15 分钟;空查询时默认查询最近 5 分钟。空查询最大只允许查 5 分钟,避免一次性扫太多日志。

常用命令

npm run typecheck
npm run build
npm start

代码结构

  • src/server.ts:进程入口,负责监听端口。
  • src/app.ts:Express 应用组装入口。
  • src/config/env.ts:环境变量读取和校验。
  • src/routes/health.ts:健康检查路由。
  • src/mcp-services/mysql-metadata:MySQL 元数据 MCP 服务预留目录。
  • src/mcp-services/aliyun-log:阿里云日志 API 接入模块,当前实现 ListProjectListLogStoresGetLogsV2

Review TS 代码的建议流程

你对 TypeScript 还不熟,所以每次看 AI 生成的 TS 代码,建议按下面顺序 review:

  1. 先看 package.json:确认新增依赖是不是必要,脚本命令是否清楚。
  2. 再看入口文件:本项目先看 src/server.ts,确认服务从哪里启动、监听哪个端口。
  3. 再看应用组装:看 src/app.ts,确认中间件、路由注册、返回结构是否符合预期。
  4. 再看配置读取:看 src/config/env.ts,确认环境变量有没有默认值、有没有基本校验。
  5. 再看具体路由:看 src/routes/health.tssrc/mcp-services/aliyun-log/routes.ts,确认接口路径、入参、返回 JSON。
  6. 再看 MCP 注册:看 src/mcp-server.ts,确认工具名、参数、调用的服务函数和返回内容。
  7. 跑一遍命令:npm run typechecknpm run build

如果你不确定某段 TS,可以重点问三个问题:

  • 这个文件对外暴露了什么?
  • 这个函数接收什么输入,返回什么输出?
  • 这里失败时会发生什么?

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选