yd-mcp-server
v0.6.0
Published
元点 AI MCP — project-aware tools (framework detection, schema inspection, code scaffolding, patch application, self-checks) for 元点Admin / 元点SaaS AI code generation over stdio.
Maintainers
Readme
yd-mcp-server
面向 AI 编码助手(Claude Code / Cursor / Claude Desktop 等)的 MCP Server:把你本地的 ydadmin 框架项目(数据库结构、已有代码、代码生成引擎)暴露成一组标准 MCP 工具,让 AI 助手能"看懂"你的项目并生成符合框架分层架构(Controller → Service → Repository → Model)的代码。
与 yd:ai CLI 的关系:两者都是 YD-AI 代码生成引擎(ydsaas-ai-engine,POST /api/v1/generate)的客户端,功能等价、后端共用同一套引擎——区别只在接入方式。php think yd:ai "指令" 是框架内置的终端命令,适合你直接在终端里一次性生成代码;yd-mcp-server 则是把同样的能力(外加数据库读取、文件读取、写盘、语法自检)包装成 MCP 工具,交给 Claude Code / Cursor / Claude Desktop 里的 AI 助手在对话中自主编排调用,助手可以先看表结构、再生成、再预览、确认后才落盘,整个过程无需你手动敲命令。
快速开始(零配置,最佳努力)
包发布到 npm registry 后,多数客户端只需三行配置即可使用,无需手工填写项目路径或数据库账号:
{
"mcpServers": {
"yuandian": { "command": "npx", "args": ["-y", "yd-mcp-server"] }
}
}这是「最佳努力零配置」,不是对所有客户端的承诺——MCP 会依次尝试
YD_PROJECT_ROOT(显式配置,未设置时跳过)→ MCP Roots(客户端声明的工作区,3 秒超时)→ 进程当前工作目录,取第一个通过元点项目特征验证(含server/think且含server/app/adminapi或tenantapi)的目录作为项目根。三级都未命中时不会猜测,而是进入「未定位」态:本地文件与数据库工具全部禁用,get_project_info会给出诊断信息。定位成功后,MCP 自动读取项目server/.env的[DB]段建立只读数据库连接,同样无需手工配置YD_DB_*。
能否真正做到零配置取决于客户端是否支持 MCP Roots:
| 客户端 | 零配置可用性 |
|---|---|
| Claude Code | 支持,可真正零配置 |
| Cursor | 推荐项目级 ${workspaceFolder} 插值(实测不声明 Roots,且子进程 cwd 非工作区,零配置行不通) |
| Claude Desktop | 不支持,无工作区概念,需显式设置 YD_PROJECT_ROOT |
Cursor 推荐配置:项目内 .cursor/mcp.json 用 ${workspaceFolder} 模板插值,内容跨项目、跨机器一致,可直接提交入库:
{
"mcpServers": {
"yuandian": {
"command": "npx",
"args": ["-y", "yd-mcp-server"],
"env": { "YD_PROJECT_ROOT": "${workspaceFolder}" }
}
}
}旧版 Cursor(或其他不做模板插值的客户端)收到字面量 ${workspaceFolder} 时,MCP 不会把它当路径校验,而是视为未设置并给出 PROJECT_ROOT_TEMPLATE_UNRESOLVED 告警(不锁死),随后落入自动探测链;仍未定位时,助手可调用 set_project_root(见下方工具表)一次性兜底传入工作区路径。全局 ~/.cursor/mcp.json 下该模板能否解析视 Cursor 版本而定,需自行实测,这里不作承诺。
Claude Desktop 没有模板插值能力,最小可用配置仍是绝对路径:
{
"mcpServers": {
"yuandian": {
"command": "npx",
"args": ["-y", "yd-mcp-server"],
"env": { "YD_PROJECT_ROOT": "/absolute/path/to/your/ydadmin-project" }
}
}
}高级配置
以下都是可选项,仅在对应场景需要时添加到 env 块:
云增强生成(不设置时,generate_code 之外的九个工具仍可正常使用):
{ "YD_AI_TOKEN": "yd_live_your_token_here", "YD_AI_ENDPOINT": "https://your-yuandian-ai-endpoint" }数据库覆盖(逐项覆盖项目 server/.env 的 [DB] 段,即使覆盖成空字符串也算显式值):
{ "YD_DB_USER": "mcp_readonly", "YD_DB_PASS": "your_password" }项目跑在 Docker 里、.env 的 HOST 是容器内部域名(如 mysql)时,宿主机上的 MCP 进程需要覆盖:
{ "YD_DB_HOST": "127.0.0.1" }monorepo / 多项目根:仓库里有多个元点项目子目录时,用 YD_PROJECT_ROOT 显式指向目标子项目根目录,避免自动定位选错。
团队共享项目标识:零配置下 projectId 由项目根路径哈希派生(yd_ + 12 位十六进制),项目目录搬动路径后会变化。团队共享 RAG 索引或云端归因统计场景,必须显式设置:
{ "YD_PROJECT_ID": "team-shared-project-id" }从 0.3.0 升级
0.4.0 收紧了几处曾经"静默兜底"的行为,全部改为显式失败(fail closed),升级前请注意:
YD_PROJECT_ROOT设置了但验证失败时,不再静默继续用旧逻辑猜测目录,而是直接禁用本地文件/数据库工具(见上文「项目未定位」)。- 进程当前工作目录(cwd)不再被盲目当作项目根使用,必须先通过元点项目特征验证(含
server/think且含adminapi/tenantapi)才会采信。 - 数据库配置移除了隐式默认值(原
HOST=127.0.0.1、USER=root):现在默认读取项目server/.env的[DB]段;纯用环境变量配置数据库时,须显式给全YD_DB_HOST/YD_DB_USER/YD_DB_NAME,不再有兜底值。 - 零配置下的
projectId从固定的"default"改为项目根路径哈希派生,团队共享 RAG 索引等场景请显式设置YD_PROJECT_ID(见上文「团队共享项目标识」)。 - 已按旧文档写死绝对路径
YD_PROJECT_ROOT的配置无需任何改动:显式绝对路径的行为完全不变,${workspaceFolder}与set_project_root只是新增的可选姿势。
本地开发 / 内测(尚未发布到 npm 时)
先在 ydsaas-mcp-server 目录执行一次构建:
cd ydsaas-mcp-server
npm install
npm run build # 产出 dist/index.js之后有两种等价的接入方式,任选一种:
方式 a:直接用 node 运行编译产物(最简单,无需 npm pack):
{
"mcpServers": {
"yuandian": {
"command": "node",
"args": ["/absolute/path/to/ydsaas-mcp-server/dist/index.js"],
"env": { "YD_PROJECT_ROOT": "/absolute/path/to/your/ydadmin-project" }
}
}
}方式 b:用 npm pack 产出的本地 tgz 包,通过 npx 加载(更接近真实发布后的运行路径,适合发布前最后一轮验证):
cd ydsaas-mcp-server
npm pack # 产出 yd-mcp-server-<version>.tgz{
"mcpServers": {
"yuandian": {
"command": "npx",
"args": ["-y", "/absolute/path/to/ydsaas-mcp-server/yd-mcp-server-<version>.tgz"],
"env": { "YD_PROJECT_ROOT": "/absolute/path/to/your/ydadmin-project" }
}
}
}两种方式都可以叠加「高级配置」一节里的任意环境变量。
配置文件放在哪里
以上 JSON 都是同一份 mcpServers 结构,只是写入的文件不同:
| 客户端 | 配置文件路径 |
|---|---|
| Claude Code | 项目内 .mcp.json,或通过 claude mcp add 命令添加 |
| Cursor | 项目内 .cursor/mcp.json,或全局 ~/.cursor/mcp.json;也可在 Cursor Settings → MCP → Add new MCP Server 里通过界面添加,效果等价 |
| Claude Desktop | macOS: ~/Library/Application Support/Claude/claude_desktop_config.json;Windows: %APPDATA%\Claude\claude_desktop_config.json |
保存配置后需要重启客户端(或在 Cursor 里重新加载 MCP 连接)才会生效。连接成功后,客户端会列出 10 个可用工具(见下表)。
初始化客户端引导资产(推荐)
连接成功后,在对话里说「初始化元点 AI 配置」,助手会调用 init_client_assets 把三类引导资产写入项目(默认 dry_run 预览,确认后落盘):
AGENTS.md规约块:Cursor 全版本与 Kimi Code 常驻加载,约束助手必须走「查表结构 → 生成 → 预览 → 落盘 → run_check」标准流程;.claude/skills/yuandian-*:新增模块 / 修改存量代码两套标准流程(Cursor 2.4+、Kimi Code、Claude Code 三端自动发现);.cursor/rules/yuandian.mdc:Cursor 旧版本兜底垫片(内容与 AGENTS.md 块同源)。
这些资产可提交入库供团队共享;升级 MCP 后重跑一次即可同步到新版。
十个工具
| 工具 | 用途 | 关键参数 |
|---|---|---|
| get_project_info | 自动定位与识别诊断:项目根、workspace_state、root_candidates、数据库是否已配置、能力清单与告警 | 无参数 |
| list_tables | 列出当前项目数据库的所有表及注释、行数 | 无参数 |
| show_table_schema | 查看指定表的字段结构、类型、主键/索引/是否必填/默认值/注释 | table_name(string,必填,数据库表名) |
| read_file | 读取项目中已有的代码文件,供 AI 参考现有实现风格 | file_path(string,必填,相对于项目根的路径;不能超出项目根目录) |
| generate_code | 根据自然语言指令,调用 YD-AI Engine 为 ydadmin 框架生成完整分层代码 | instruction(string,必填,自然语言需求);tables(string[],可选,涉及的表名,会自动注入表结构作为上下文);layers(可选,controller/service/repository/model 的子集,默认全部四层);framework(可选,项目未定位时必填) |
| apply_patch | 把 generate_code 产出的文件写入项目磁盘 | files({path, code}[],必填,要写入的文件列表);dry_run(boolean,默认 true,即默认只预览"将写入哪些文件、新增还是覆盖",不真正落盘;确认无误后需再次调用并显式传 dry_run: false 才会真实写入) |
| run_check | 对刚写入的 PHP 文件做语法检查(php -l),若文件中包含路由文件(路径含 server/app/adminapi/route/)还会额外跑一次 php think optimize:route adminapi 校验路由注册 | files(string[],必填,要检查的文件相对路径,通常就是刚 apply_patch 写入的那批文件) |
| set_project_root | 项目未定位时的兜底:由助手传入当前工作区绝对路径完成定位 | path(string,必填,工作区/项目根的绝对路径,须通过元点项目特征验证) |
| get_conventions | 按主题返回元点框架编码规范全文(分层/路由/权限/验证器/前端),项目未定位也可用 | topic(string,可选,不传返回主题目录) |
| init_client_assets | 把 AI 引导资产写入项目:AGENTS.md 规约块、.claude/skills/ 标准流程(Cursor 2.4+/Kimi Code/Claude Code 三端共用)、.cursor/rules/yuandian.mdc 垫片 | dry_run(boolean,默认 true,预览后确认再传 false 写入) |
补充说明:
- 项目未定位时,
read_file/apply_patch/run_check/list_tables/show_table_schema全部拒绝执行;generate_code仍可用,但仅限 instruction-only(不能传tables)且必须显式传framework或设置YD_FRAMEWORK,不会静默假设框架;此时 MCP 返回的错误消息里已经引导助手调用set_project_root,通常无需你手动干预。 set_project_root是一次性生效(one-shot)的严格兜底:仅当项目处于「未定位」且未真正显式配置YD_PROJECT_ROOT时才允许调用;已ready、已进入workspace_changed_restart_required陈旧态、或已显式配置YD_PROJECT_ROOT时一律拒绝——避免工具中途覆盖用户的显式配置或误切换项目。传入路径须通过元点项目特征验证(含server/think及server/app/adminapi/tenantapi),未通过会明确报错。定位成功后get_project_info的project_root_source会显示为tool。apply_patch和run_check内部都会做路径安全校验(拒绝绝对路径、..穿越、Windows 盘符路径、空字节路径等),越界路径会被跳过并在返回文本里标出,不会写入项目根目录之外的位置。run_check的路由检查依赖项目根目录下存在server/think;如果项目根没有指向一个真正的 ydadmin 项目根目录,路由检查会自动跳过并给出提示,不会报错中断。- 切换客户端工作区(roots/list_changed)后,所有工具会报「请重启 MCP 进程」,这是预期的安全行为,防止误操作到旧项目。
init_client_assets幂等可重跑:AGENTS.md只维护<!-- yd:begin -->/<!-- yd:end -->标记块(块外用户内容不动,标记残缺时拒绝改动该文件);skills 与.mdc归 MCP 所有整文件覆盖。npm 包升级后get_project_info的client_assets字段会显示outdated,重跑一次 init 即可同步。
环境变量
| 变量 | 是否必填 | 默认值 | 说明 |
|---|---|---|---|
| YD_PROJECT_ROOT | 否(Claude Desktop 等无工作区概念的客户端建议显式设置) | 未设置时依次尝试 MCP Roots → 进程 cwd | 你的 ydadmin 项目根目录绝对路径。一旦显式设置,只信任这一个值,验证失败直接禁用本地工具(fail closed),不会降级去猜别的目录 |
| YD_FRAMEWORK | 否 | 自动识别 | 可显式指定 ydadmin_php 或 ydsaas_php;与自动检测结果冲突时 run_check 拒绝执行,设置 YD_FRAMEWORK_FORCE=1 可强制放行 |
| YD_PROJECT_ID | 否 | 项目根路径哈希派生(yd_ + 12 位十六进制) | 传给引擎的项目标识,用于多项目场景下的 RAG 检索隔离;团队共享项目须显式设置,因为自动派生的 ID 会随本机路径变化 |
| YD_AI_ENDPOINT | 否 | http://127.0.0.1:8000 | YD-AI Engine 的 API 地址(generate_code 请求 ${YD_AI_ENDPOINT}/api/v1/generate)。旧变量名 YD_API_BASE_URL 仍兼容支持,但仅在 YD_AI_ENDPOINT 未设置时作为回退使用 |
| YD_AI_TOKEN | 否 | 空 | 调用引擎时的鉴权 Token,以 Authorization: Bearer <token> 请求头发送;本地自建引擎且未启用鉴权时可不设置 |
| YD_DB_HOST / YD_DB_PORT / YD_DB_USER / YD_DB_PASS / YD_DB_NAME | 否 | 自动读取项目 server/.env 的 [DB] 段 | 逐项覆盖项目 .env 里的对应值——按「该环境变量是否存在」判断,覆盖成空字符串也算显式值。仅支持 TYPE=mysql;密码只用于 MCP 内部连接,绝不返回给 AI 模型、不写入任何日志 |
数据库连接信息只用于读取表结构(
list_tables、show_table_schema、generate_code的 Schema 注入),Server 本身不会对你的数据库执行任何写操作。
典型对话流程
以「给 brands 表生成品牌管理模块」为例,AI 助手在 Claude Code / Cursor / Claude Desktop 里通常会自主完成以下调用序列(你只需要在关键节点确认):
- AI 调用
get_project_info,确认项目已定位(workspace_state: "ready")、识别到的框架和数据库配置状态。(首次接入建议先完成上方「初始化客户端引导资产」) - 你说:「帮我给 brands 表生成品牌管理模块(列表/新增/修改/删除/状态切换)」
- AI 调用
show_table_schema(table_name: "brands"),看到id、name、logo、status、sort等字段的类型、主键、是否必填、注释,理解表结构。 - AI 调用
generate_code(instruction为你的需求描述,tables: ["brands"]),引擎结合上一步拿到的表结构,流式生成 Controller / Service / Repository / Model 四层代码(layers不传则默认四层全生成),并返回每个文件的路径和内容。 - AI 调用
apply_patch(files为上一步生成的文件列表,dry_run默认true),只做预览:告诉你会新增还是覆盖哪些文件、各多少行、最终会写到项目里的哪个绝对路径。 - 你在客户端里确认(Cursor 会弹出工具调用审批,你点击允许/拒绝)。
- AI 再次调用
apply_patch,这次显式传dry_run: false,文件被真正写入磁盘。 - AI 调用
run_check(files为刚写入的那批文件路径),逐个跑php -l语法检查;如果文件里包含路由文件,还会额外跑一次php think optimize:route adminapi确认路由能正常注册。 - 若
run_check全部 ✓:流程结束,代码已就绪。若有 ✗:AI 会把失败原因(语法错误位置、路由注册报错信息)作为上下文,重新生成或直接修正对应文件,再次apply_patch+run_check,直到全部通过。
故障排查
项目未定位(get_project_info 显示 workspace_state: "unlocated",或其他工具报错「未定位到元点项目」)
- 查看
get_project_info返回的root_candidates,逐一确认每个来源(env/mcp_roots/cwd)是否通过验证(accepted)。 - 若设置了
YD_PROJECT_ROOT,验证失败会 fail closed(不会自动降级去试 Roots 或 cwd),检查该路径是否正确,以及是否含server/think和server/app/adminapi(或tenantapi)。 - 若
warnings里出现PROJECT_ROOT_TEMPLATE_UNRESOLVED,说明客户端把${workspaceFolder}之类的模板变量原样传了过来、没有做插值;一般无需你手动处理,MCP 的错误消息已经引导助手自动调用set_project_root传入当前工作区绝对路径兜底。 - 若未设置
YD_PROJECT_ROOT且客户端不支持 MCP Roots(如 Claude Desktop),必须显式设置该变量。
引擎不可达(generate_code 报错 API error 或连接被拒绝/超时)
- 确认 YD-AI Engine 是否已在本地启动:
cd ydsaas-ai-engine uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload - 用
curl探活:curl http://127.0.0.1:8000/api/v1/health,正常应返回{"status":"ok","service":"ydsaas-ai-engine"}。 - 检查 MCP 配置里的
YD_AI_ENDPOINT(或仍在使用的旧变量名YD_API_BASE_URL)是否指向了正确的地址和端口;引擎跑在非默认端口、或跑在远程/容器里时,http://127.0.0.1:8000这个默认值不适用,必须显式设置。 - 若引擎开启了鉴权,确认
YD_AI_TOKEN是否正确设置;未设置 token 时请求不带Authorization头,鉴权开启的引擎会拒绝。
数据库连不上(list_tables / show_table_schema 报错,或 get_project_info 显示 database_configured: false)
- 默认情况下数据库配置自动从项目
server/.env的[DB]段读取,先确认该文件存在且[DB]段填写完整(TYPE=mysql、HOST/USER/NAME均不能为空)。 - 若通过
YD_DB_*显式覆盖,检查是否与项目实际数据库配置一致;项目跑在 Docker 里、.env的HOST是容器内部域名时,需要用YD_DB_HOST=127.0.0.1覆盖。 - 确认目标 MySQL 允许来自 Server 所在机器的连接(本地开发通常是
127.0.0.1,容器/远程数据库需检查网络和防火墙)。
生成后语法检查失败(run_check 输出里出现 ✗)
- 直接把
run_check的完整输出文本粘贴回给 AI 助手(对话里说「run_check 报错了,帮我修一下」),run_check的错误信息里已经包含php -l的具体报错行号或路由注册失败的堆栈片段,AI 可以据此定位并修正对应文件,无需你手动排查 PHP 语法问题。 - 路由注册检查(
optimize:route adminapi)失败通常意味着新生成的路由文件里有语法错误,或路由定义与已有路由冲突;同样把报错原文丢给 AI 即可。 - 路由检查被跳过(提示
server/think 缺失,非元点Admin 项目根)说明项目根没有指向正确的目录,检查YD_PROJECT_ROOT(或get_project_info里的project_root)是否写对。
切换工作区后工具报「请重启 MCP 进程」
- 这是预期行为,不是故障。客户端切换工作区触发
roots/list_changed通知后,MCP 不会动态切换项目根(避免误操作到旧项目),需要重启 MCP 进程重新定位。
License
MIT
