news 2026/9/14 8:17:41

WrenAI 语义层接入 MCP:用 `wren serve mcp` 让 AI 客户端直接查询你的项目

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WrenAI 语义层接入 MCP:用 `wren serve mcp` 让 AI 客户端直接查询你的项目

WrenAI 语义层接入 MCP:用wren serve mcp让 AI 客户端直接查询你的项目

【免费下载链接】WrenAIGenBI (Generative BI) for AI agents, an open-source, governed text-to-SQL through an open context layer that turns natural-language questions into trusted dashboards, charts, and SQL across 20+ data sources, such as BigQuery, Snowflake, PostgreSQL, ClickHouse, Amazon Redshift, Databricks and more.项目地址: https://gitcode.com/GitHub_Trending/wr/WrenAI

导读

WrenAI 通过开放的上下文层(Open Context Layer)把自然语言问题转译为可信的 SQL 与图表,而 MCP(Model Context Protocol)是 AI Agent 与外部工具之间的标准桥梁。本篇指南围绕 docs/core/guides/mcp.md 展开,完整讲解wren serve mcp的启动方式、客户端接入配置、可用的查询/模式/知识工具集,并结合 serve_cli.py 与 mcp_server.py 的源码实现,说明能力门控、行数截断、降级策略与安全边界。读完你将能在 Claude Desktop、Claude Code、Cursor 等任意 MCP 客户端中,让 Agent 通过语义模型(MDL)直接查询数据库,并在对话中复用项目沉淀的业务知识与 NL→SQL 记忆。

一、前置准备:一个可服务的 Wren 项目

wren serve mcp将 Wren 项目的查询(query)、模式(schema)与业务知识(business-knowledge)工具暴露给任何 MCP 客户端。它在进程内基于已编译的 MDL 与当前绑定的连接 profile 运行——不需要独立的 ibis-server,也不需要额外后端,只需你已安装好的 CLI 本身。启动前需要满足三个条件:

  1. 已构建的 MDL 产物:项目根目录下存在target/mdl.json,由wren context build生成;
  2. 已绑定的连接 profile:通过wren profile add/wren context set-profile绑定(如果只需要 schema / 转译类工具,可用--no-connect跳过数据库连接);
  3. 已安装mcp可选依赖
pip install 'wrenai[mcp]'

若在core/wren源码检出目录下工作,则使用:

just install-extra mcp

关于项目的标准初始化流程,可参考 manage_project.md:wren context init脚手架出 v5 项目布局(models/views/cubes/knowledge/),wren context validate校验 YAML,wren context build编译到target/mdl.jsonwren context set-profile把连接 profile 写入wren_project.yml。仓库中的 v5-jaffle 示例项目 就是一个典型的最小可服务项目:data_source: postgres,其knowledge/下包含业务规则、NL→SQL 对与知识索引等全部可供 MCP 读取的内容。

二、启动服务器:从 stdio 到 Streamable HTTP

2.1 默认 stdio 模式

cd my-project wren serve mcp

stdio是默认传输方式——这是"客户端把wren作为子进程拉起"这一模式所期望的形态:MCP 客户端负责 spawn 进程,通过标准输入输出与服务器通信。

2.2 HTTP 模式

如果需要让其他工具连接到一台本地常驻服务器,改用 Streamable HTTP:

wren serve mcp --transport http --host 127.0.0.1 --port 8080

2.3 能力开关

  • --allow-write:开启store_query写入工具。默认关闭——不加该参数时服务器只读
  • --no-connect:纯转译(transpile-only)模式,服务器完全不触碰数据库,run_sql/dry_run/query_cube三个工具会被禁用,仅保留 schema 与dry_plan等能力。

2.4 启动横幅(banner)

启动时服务器会打印与本次实际调用完全匹配的、可直接复制的客户端注册命令——HTTP 模式下是claude mcp add/codex mcp add两行;stdio 模式下除这两行外还会附带一段 JSON 格式的mcpServers配置块。传--quiet(等价-q)可静默横幅。

从 serve_cli.py 的实现可以看到,该横幅总是输出到 stderr——因为在 stdio 传输下,stdout 是 MCP 协议通道,绝不能污染;同时它会用shlex.quote对每个 token 做 shell 转义,保证含空格的路径也能直接复制粘贴,并在设置了WREN_HOME环境变量时把-e WREN_HOME=...一并拼进注册命令。

2.5 完整的命令行参数

wren serve mcp的全部参数见 CLI 参考文档:

Flag默认值说明
--transportstdio传输方式,stdiohttp
--host127.0.0.1绑定地址,仅--transport http生效
--port8080绑定端口,仅--transport http生效
--project自动发现覆盖项目根目录
--profile当前激活 profile连接 profile 名称
--allow-write关闭启用store_query写入工具
--no-connect关闭转译模式:禁用run_sqldry_runquery_cube
--quiet/-q关闭抑制客户端注册帮助横幅

2.6 启动流程的源码视角

serve_cli.py 中serve_mcp的启动顺序可以拆解为五步,理解它对排错很有帮助:

  1. 校验传输方式:非stdio/http直接报错退出;
  2. 校验依赖:尝试import mcp,失败时提示pip install 'wrenai[mcp]'。这也解释了为什么mcp_server.py选择模块文件而非mcp/包命名——避免遮蔽顶层 MCP SDK 包(见 mcp_server.py 模块注释);
  3. 发现项目并校验 MDLdiscover_project_path定位项目根,若target/mdl.json不存在则报错并提示"Hint: runwren context buildfirst";
  4. MDL 新鲜度检查_mdl_is_stale会比较wren_project.ymlrelationships.ymlmodels/views/cubes/下所有源文件的 mtime 与target/mdl.json,发现更新即打印"MDL may be stale"警告,但仍继续服务旧 manifest(从不自动重建);
  5. 解析 profile 并构建引擎:读取~/.wren/profiles.yml中指定 profile,展开${ENV_VAR}密文占位符(缺失时给出明确的MissingSecretError),把{"datasource": ..., ...}序列化为connection_info交给_build_engine,最后注册atexit关闭引擎。

run_server内部(mcp_server.py)则按 transport 分派:stdiomcp.run(transport="stdio")httpstreamable-http并写入 host/port 设置。

三、接入客户端:JSON 配置与注册命令

3.1 stdio:让客户端 spawn 服务器进程

启动横幅已经为你填好了下面的命令;本节解释其含义。大多数桌面 / IDE MCP 客户端接受一段 JSON 配置,通过 stdio spawn 服务器进程:

{ "mcpServers": { "wren": { "command": "wren", "args": ["serve", "mcp"], "cwd": "/path/to/your/project" } } }

要点:

  • cwd必须位于项目内部;或者在args中传--project /path/to/project代替;
  • 添加配置后需要重启客户端才会生效;
  • 若设置了WREN_HOME,横幅给出的配置块还会附带"env": {"WREN_HOME": ...},确保子进程找到全局 CLI 状态。

3.2 HTTP:指向 Streamable HTTP 端点

对于需要被其他机器 / 进程连接的场景,运行:

wren serve mcp --transport http --port 8080

客户端不再 spawn 进程,而是直连该 host/port 上的 Streamable HTTP 端点。注意两点安全约束:HTTP 默认只绑定127.0.0.1(本机回环),且当前版本不提供 bearer-token 鉴权——因此务必保持其本地运行,不要暴露到公网。

3.3 一键注册命令

服务启动横幅直接给出形如以下的注册命令(stdio 与 http 略有差异):

claude mcp add wren -- serve mcp --project /path/to/your/project codex mcp add wren -- serve mcp --project /path/to/your/project # HTTP 模式: claude mcp add --transport http wren http://127.0.0.1:8080/mcp codex mcp add wren --url http://127.0.0.1:8080/mcp

调试阶段也可用 MCP Inspector(npx @modelcontextprotocol/inspector,Streamable HTTP 指向上述 URL)查看服务器暴露的工具与资源。

四、客户端获得的能力清单

4.1 查询工具(Query)

工具说明
run_sql通过 Wren 语义层执行 SQL 并返回行数据。SQL 面向MDL 模型名而非原始数据库表书写;未传limit时默认上限 1000 行,硬上限 10000 行,负数 limit 直接拒绝
dry_run校验 SQL 合法性但不返回结果行,是执行前的廉价预检,失败时携带引擎错误信息
dry_plan仅做 SQL 展开(transpile),返回目标方言的 SQL,完全不碰数据库
query_cube结构化 cube(指标)查询并返回聚合结果,镜像wren cube query的语义

query_cube的参数规格(见 mcp_server.py 工具 docstring)值得单独说明:

  • cubemeasures必填,缺一即抛ValueError
  • time_dimension使用 CLI 规格格式name:granularity[:start,end](支持粒度year/quarter/month/week/day/hour/minute);
  • filters使用dim:op[:value]格式,in/not_in操作用逗号分隔多个值(支持的算子:eqneqinnot_ingtgteltltecontainsstarts_withis_nullis_not_null,见 cli.md);
  • sql_only=True时只返回生成的 SQL 不执行。

4.2 模式工具(Schema)

get_mdl(完整编译 MDL JSON)、list_models(模型列表 + 列数)、describe_model(列、主键、ref_sql、关系)、get_data_source(项目数据源/方言)、list_cubesdescribe_cubelist_functions(当前数据源注册的 SQL 函数,无需数据库连接)。从源码看,describe_model会自动补充模型或列上properties.description中的描述,方便 Agent 理解字段语义;list_functions则在会话上下文构建时按数据源注册函数表(见 mcp_server.py)。

4.3 知识工具(Knowledge)

get_instructions(来自knowledge/rules/*.md的业务规则)、recall_queries(按相似度召回已验证的 NL→SQL 范例)、get_context(按问题做语义化 schema 片段检索,是recall_queries的 schema 轴孪生)、describe_schema(纯文本 schema 描述,get_mdl的人类可读版本,适合直接粘进 LLM prompt)、list_stored_queries(枚举全部已存 NL→SQL 对,可按source标签过滤)、list_knowledge(列出可经wren://knowledge/{path}读取的文件)。加上仅在--allow-write下注册的store_query(持久化确认过的 NL→SQL 对,详见后文)。

4.4 资源(Resources)

  • wren://mdl— 编译后的 MDL JSON(application/json)
  • wren://instructionsknowledge/rules/*.md中的业务规则(text/markdown)
  • wren://project— 项目名 / catalog / schema / 数据源 / schema_version / knowledge_schema_version(application/json)
  • wren://agents— 项目根下的AGENTS.md(若存在)
  • wren://knowledge/{path}— 读取knowledge/下任意文件,如wren://knowledge/knowledge.ymlwren://knowledge/rules/general.md

值得注意的实现细节:MCP SDK 的{param}匹配单个路径段([^/]+),一个{path}占位符无法跨/,因此 mcp_server.py 用两个模板覆盖实际布局——wren://knowledge/{name}服务根级文件(如knowledge.yml),wren://knowledge/{subdir}/{name}服务一层子目录(rules/*.mdsql/*.md)。

4.5 提示词(Prompt):wren_workflow

wren_workflow是一份现成的 SOP(标准作业流程),引导 Agent 按"schema → instructions → recall → dry-run → run → store"的顺序回答数据问题。其步骤列表会根据启动参数动态裁剪(见 mcp_server.py 的_workflow_text):

  • 默认连接模式:读取wren://mdl/list_models/describe_model理解 schema →get_instructions获取业务规则 →recall_queries召回范例 →dry_run校验 →run_sql执行 → 命名指标优先query_cube
  • --no-connect模式下,dry_run/run_sql/query_cube步骤被替换为dry_plan(无数据库连接时的转译检查);
  • --allow-write模式下追加可选步骤store_query

步骤在门控后重新编号,保证始终是连续的 1..N。相关行为被 test_mcp_server.py 的test_workflow_text_*系列测试锁定。

五、源码级原理:能力门控、行数截断与降级

5.1 能力门控

build_server(mcp_server.py)按ServeContext状态决定注册哪些工具:

  • no_connect=True时跳过run_sqldry_runquery_cube_register_query_toolsif not ctx.no_connect:分支),但dry_plan始终注册;
  • allow_write=False时根本不调用_register_write_toolsstore_query不出现。

5.2 行数截断的 N+1 探测

run_sql_query_with_limit_probe(mcp_server.py):请求 limit 先被钳制在MAX_ROW_LIMIT(10000)内,随后以effective_limit + 1向引擎取数——多取一行用于判断是否截断,超限则切片到有效 limit 并在结果里标记"truncated": true。负数 limit 在执行前即被拒绝(对应测试 test_run_sql_negative_limit_rejected)。

query_cube的执行路径则不同:_query_cube_with_limit_probe把行数上限直接嵌进生成的 SQLLIMIT n+1),connector 收到的 limit 为None。这样既保持了生成 SQL 中LIMIT/OFFSET的合法顺序,又能约束先物化再切片型 connector 的行为(见 mcp_server.py 与测试 test_query_cube_execution_bakes_probe_into_sql_not_connector)。返回结构统一为{"columns": [...], "rows": [...], "row_count": N, "truncated": bool}datetime/Decimal/bytes/NaN 等类型会在_normalize_value中递归转换为 JSON 原生类型。

5.3 无 memory extra 时的优雅降级

知识工具设计为"可降级":

  • recall_queries优先走memoryextra 的语义(embedding)检索,未安装时退回对knowledge/sql/*.md零依赖 token 重叠检索
  • get_context在未安装memory时退回完整纯文本 schema 描述(与describe_schema同源),并在返回中附带提示"Installwrenai[memory]and runwren memory indexfor embedding-based schema search on large schemas";
  • describe_schema完全不需要额外依赖——它是get_mdl的纯文本对应物,专为粘贴进 LLM prompt 而设计;
  • list_stored_queriesMemoryStore出错(含未装 extra)时退回直接读取knowledge/sql/*.md,且同样施加行数上限——测试 test_list_stored_queries_fallback_applies_default_cap 明确锁定了这一行为。

store_query写入时以 Markdown 为源(写knowledge/sql/*.md),若装了memory再尽力索引到 LanceDB;索引失败仅记 warning、不阻断(见 mcp_server.py)。

5.4 查询引擎链路

所有查询最终落到 engine.py 的WrenEnginequerydry_plan转译,再交给按数据源分派的 connector 执行并返回 Arrow 表;dry_plan内部依次做 sqlglot 解析(目标方言)→ 模型解析(含大小写敏感/不敏感回退)→ 按引用表裁剪 manifest → 政策校验(validate_sql_policyvalidate_planned_sql)→ CTE 重写展开为完整目标方言 SQL。这意味着 Agent 写出的"模型级" SQL 在到达数据库前会经历语义层的完整校验与展开。

六、安全边界与运维注意

  1. 凭据不跨 MCP 边界:连接凭据在启动时从 profile 解析一次、常驻服务端,跨过 MCP 边界的只有 SQL 文本、查询结果与元数据(见 cli.md);
  2. 从不自动重建 MDL:若项目源文件比target/mdl.json新,服务器只打印 staleness 警告、继续服务旧 manifest。修改模型后请手动重跑wren context build
  3. wren://knowledge/{path}路径逃逸防护:资源处理器用resolve()归一化后校验目标必须位于项目knowledge/目录内且为文件,形如../wren_project.yml的逃逸路径会被拒绝(见 mcp_server.py);
  4. HTTP 仅限本地:默认绑定127.0.0.1,且此版本无 bearer-token 鉴权,切勿暴露到非本地网络;
  5. profile 缺失处理--profile指定的名字不存在、或缺datasource、或${VAR}密文解析失败时,服务器都会给出明确的错误提示后退出(见 serve_cli.py)。

七、端到端实战:从零接入 Claude Code

结合仓库内的 v5-jaffle 示例,完整流程如下:

# 1. 构建 MDL(示例项目已具备 models/、views/、knowledge/) cd examples/v5-jaffle wren context validate wren context build # 生成 target/mdl.json # 2. 绑定连接 profile(以 postgres 为例;仅 schema/转译可省略) wren profile add pg-dev --from-file dev.yml --activate wren context set-profile pg-dev # 3. 安装 MCP 依赖并启动 pip install 'wrenai[mcp]' wren serve mcp # 或 --transport http --port 8080

随后把启动横幅给出的 JSONmcpServers块(含cwd指向项目根)粘贴进客户端的 MCP 配置并重启。之后 Agent 即可:

  1. 读取wren://project/wren://mdl了解项目与数据模型;
  2. 通过list_modelsdescribe_modelget_context理解可用字段与语义;
  3. 调用get_instructions拿到业务规则(示例项目中的 business-rules.md 声明了"订单金额以 USD 记录"、"客户名可能为 NULL"等约束);
  4. recall_queries复用已验证的范例查询(如 total-revenue.md 中的SELECT SUM(amount) AS total_revenue FROM orders);
  5. dry_run校验后run_sql执行,确认无误后在--allow-write模式下用store_query沉淀新的 NL→SQL 对,形成持续增强的记忆闭环。

八、常见问题速查

现象原因与处理
启动报 "target/mdl.json missing"项目未构建,先wren context build
启动报 "Install the MCP extra"mcp依赖,执行pip install 'wrenai[mcp]'just install-extra mcp
启动报 "profile 'X' not found"--profile名不存在,wren profile list核对
启动报 "profile has no datasource"profile 缺少datasource字段
启动警告 "MDL may be stale"模型源文件比 manifest 新,重跑wren context build
客户端连不上 stdio 服务器确认cwd在项目内、已重启客户端;stdout 是协议通道,勿与日志混淆
run_sql返回truncated: true结果超过请求 limit(默认 1000、上限 10000),调大limit或细化查询

参见

  • CLI 参考 —wren serve—— 全部 flag 与工具签名
  • Manage project —— 项目布局与target/mdl.json生命周期
  • Connect your database —— 服务器查询所依赖的 profile 配置
  • Cube guide ——query_cube依赖的 cube YAML 结构与校验规则

【免费下载链接】WrenAIGenBI (Generative BI) for AI agents, an open-source, governed text-to-SQL through an open context layer that turns natural-language questions into trusted dashboards, charts, and SQL across 20+ data sources, such as BigQuery, Snowflake, PostgreSQL, ClickHouse, Amazon Redshift, Databricks and more.项目地址: https://gitcode.com/GitHub_Trending/wr/WrenAI

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 8:15:33

ollama+openclaw本地AI助手部署与优化指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 8:13:13

腾讯Agent Suite办公智能体套件:从架构到实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/14 8:11:49

Java学籍管理系统:从JDBC到事务设计的工程实践指南

简介:本资源是一套完整的基于Java开发的学籍管理系统实践项目,面向计算机专业本科生、Java初学者及教育信息化开发者,解决高校或教务场景中学生信息、成绩、课程等核心数据的结构化管理问题。压缩包共50个文件,含24个Java源码&…

作者头像 李华
网站建设 2026/9/14 8:10:45

集体好奇心如何提升团队协作与创新效率

1. 集体好奇心与团队合作的内在联系在团队协作中,集体好奇心往往被忽视,但它实际上是推动团队创新和高效合作的关键因素。集体好奇心指的是团队成员共同表现出的求知欲、探索精神和学习意愿。这种特质能够显著提升团队成员的合作意愿,形成良性…

作者头像 李华