尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

SpacetimeDB MCP 指南:通过 Model Context Protocol 以工具调用方式操作运行中的数据库

SpacetimeDB MCP 指南:通过 Model Context Protocol 以工具调用方式操作运行中的数据库 SpacetimeDB MCP 指南通过 Model Context Protocol 以工具调用方式操作运行中的数据库【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDBSpacetimeDB 主机本身支持 MCPModel Context Protocol协议MCP 感知的客户端AI Agent、编辑器等可以直接通过工具调用tool call操作一个正在运行的数据库而无需在 Shell 中敲击命令。本文以仓库内的 MCP Skill 文档codex-plugin/plugins/spacetimedb/skills/mcp/SKILL.md为骨架结合 CLI 与 HTTP 层的源码实现完整讲解 MCP 工具的形态、host-wide 与 database-scoped 两种服务器模式、权限规则、常见错误排查以及它们与spacetimeCLI 的分工边界。读完本文你将掌握如何用spacetimedb.list_databases、spacetimedb.get_schema、spacetimedb.sql、spacetimedb.call、spacetimedb.ping五个工具安全地检查与变更线上数据。概览主机即 MCP 服务器SpacetimeDB 的主机host直接说 MCP 协议因此一个支持 MCP 的客户端可以用工具调用来操作一个正在运行的数据库而不是使用 Shell 命令。如果客户端暴露了spacetimedb工具那么凡是读取或修改一个运行中数据库的任务都应当优先使用这些工具。一个关键事实是这些工具是被动注册的——它们以spacetimedb.list_databases、spacetimedb.get_schema、spacetimedb.sql、spacetimedb.call和spacetimedb.ping的形式出现在客户端的工具列表中但没有任何主动的提示或广播来宣告它们的存在。因此在使用前务必先查看客户端暴露的工具列表tools/list确认工具确实存在而不是想当然地认为它们缺失。从源码看这一能力在服务端有两个落地位置HTTP 路由层crates/client-api/src/routes/mcp.rs实现了完整的 MCP JSON-RPC 处理逻辑initialize、ping、tools/list、tools/call四个方法并分别挂载在主机级路由POST /v1/mcp见 crates/client-api/src/routes/mod.rs和数据库级路由POST /database/:name_or_identity/mcp见 crates/client-api/src/routes/database.rs上CLI 桥接层spacetime mcp命令crates/cli/src/subcommands/mcp.rs在 stdio 上循环读取 MCP 客户端发出的 JSON-RPC 行转发给主机并把主机的 JSON 响应逐行写回 stdout从而把任意支持 stdio MCP 的客户端接驳到 SpacetimeDB 主机。何时使用 MCP 工具何时使用 CLIMCP 工具与spacetimeCLI 各司其职二者是互补关系而非替代关系任务使用列出数据库、读取 schema、运行 SQL、调用 reducerMCP 工具init、build、publish、generate、start、logsspacetimeCLI参见 codex-plugin/plugins/spacetimedb/skills/cli/SKILL.mdMCP 工具只能操作一个已经存在的数据库它们无法搭建项目骨架、编译模块、发布publish或生成绑定bindings。所以两者的边界非常清晰——脚手架与生命周期管理交给 CLI运行时数据检查与变更交给 MCP 工具。在两者都可用的场景下优先使用 MCP 工具原因有三类型化每个工具都有明确的参数 schemainputSchema返回 JSON结果结构化便于客户端解析与后续处理可门控客户端可以根据工具的annotations如readOnlyHint、destructiveHint对破坏性工具进行权限门控降低误操作风险。当然如果没有连接任何 MCP 客户端那么使用等价的 CLI 命令spacetime list、spacetime describe、spacetime sql、spacetime call等是完全正确的选择。五个工具的完整参考无论服务器处于哪种模式核心工具集都是同一套。下表汇总了工具、参数与返回内容工具参数返回list_databases无你自己拥有的数据库包含 identity 与名称get_schemadatabase表与 reducer 的 JSON 描述sqldatabase、sql、可选confirmed以 JSON 返回的行calldatabase、reducer、可选argsJSON 数组reducer 的执行结果ping可选message健康检查在服务端源码 crates/client-api/src/routes/mcp.rs 的tools_list函数中可以看到每个工具携带的annotationslist_databases、get_schema标记为readOnlyHint: true、destructiveHint: false只读sql与call标记为readOnlyHint: false、destructiveHint: true可能变更数据客户端应谨慎对待所有工具均设置openWorldHint: false。list_databases只列出你自己拥有的数据库因此对于匿名身份anonymous identity来说它返回的结果为空。当你不知道数据库名称时从这里开始排查是最稳妥的第一步——先用list_databases {}拿到身份与名称再用名称去查询 schema 或执行 SQL。两种服务器形态先读tools/list再决定参数一个 MCP 服务器要么是host-wide主机级要么是scoped绑定到单个数据库。不要假设是哪一种先读取工具列表来确认。源码 crates/client-api/src/routes/mcp.rs 中的host_wide scope.is_none()正是这一区分的核心逻辑它同时决定了tools_list与target_database的行为。Host-wide主机级形态通过spacetime mcp不带数据库参数启动或直接对POST /v1/mcp发起请求。此时每个数据工具都必须携带一个必填的database参数其值可以是数据库名称或 identity并且list_databases会被提供{ name: sql, arguments: { database: mydb, sql: SELECT * FROM message } }从源码的target_database逻辑crates/client-api/src/routes/mcp.rs可以看到host-wide 模式下如果database参数缺失会返回INVALID_PARAMS级别的协议错误database argument must be a string如果提供了参数则既可以是名称NameOrIdentity::Name也可以是 64 位十六进制的 identityNameOrIdentity::Identity。Scoped数据库级形态通过spacetime mcp database启动或对POST /v1/database/db/mcp发起请求。此时连接已经固定了目标数据库因此没有database参数也没有list_databases工具{ name: sql, arguments: { sql: SELECT * FROM message } }即使工具调用中多传了database参数target_database也会优先采用 URL 中已经解析好的数据库Target::Resolved忽略参数中的值——源码中的target_database_prefers_the_url_scope_then_the_argument测试用例明确验证了这一行为。如何启动这两种形态CLI 参考docs/docs/00300-resources/00200-reference/00100-cli-reference/00100-cli-reference.md与 MCP 参考文档docs/docs/00300-resources/00200-reference/00150-mcp.md给出了标准启动方式spacetime mcp --server local # host-wide每个工具需带 database 参数 spacetime mcp my-database --server local # scoped固定到 my-database省略数据库参数 → host-wide 模式传入数据库名称或 identity → scoped 模式数据库参数也可以来自SPACETIMEDB_DB_NAME环境变量见 crates/cli/src/subcommands/mcp.rs 中Arg::new(database).env(SPACETIMEDB_DB_NAME)命令使用你已保存的 SpacetimeDB 身份除非传入--anonymous--server参数接受服务器昵称、主机名或 URL。CLI 桥接的实现细节crates/cli/src/subcommands/mcp.rs是在 stdio 上逐行读取 JSON-RPC通过POST转发到主机的mcp端点若收到 HTTP 202 状态码表示这是一个无 id 的 notification无需应答则继续否则把 JSON 响应写回 stdout。对应的 HTTP 端点说明如下POST /v1/mcp # host-wide POST /v1/database/name-or-identity/mcp # database-scopedHTTP 方式使用与其他 SpacetimeDB HTTP API 相同的 bearer token 进行鉴权也可以省略授权头此时使用匿名身份。需要注意spacetime mcp目前标记为UNSTABLE命令行工具会打印WARNING: This command is UNSTABLE and subject to breaking changes.见 crates/cli/src/util.rs 的UNSTABLE_WARNING常量可能尚未出现在已发布的 CLI 中。因此如果客户端无法启动它就回退到cliskill 中的等价 CLI 命令。不变的四条规则无论使用哪种形态MCP 工具都以你的身份运行与 HTTP API 的行为完全一致。权限与数据模型遵循 codex-plugin/plugins/spacetimedb/skills/concepts/SKILL.md 中描述的 SpacetimeDB 核心概念具体到 MCP 场景有四点需要始终牢记Reducer 是写路径。用call来变更数据。reducer 在一个事务中运行要么整体提交Committed要么整体回滚Failed/BudgetExceeded。源码 crates/client-api/src/routes/mcp.rs 的tool_call_reducer会以你的 identity 建立连接上下文、调用 reducer、再断开连接最终把结果翻译为可读文本如reducer send_message committed失败时则返回带错误文本的 HTTP 错误。SQL 写入需要所有权。sql工具可以读取公开表public tables但通过 SQL 写入需要你拥有该数据库。通常应优先使用call——把授权与校验逻辑保留在模块的 reducer 中客户端无需直接面对写 SQL。私有表对客户端不可读。get_schema仍然会显示私有表private tables的声明因此当sql报出no such table时通常意味着该表是私有表而不是表不存在。可读性取决于你的身份不要假设某个私有表一定可读。工具错误是带内返回的。一个失败的 reducer 或一条错误的查询返回的是一个带isError: true的结果错误消息以文本形式出现在content里而不是传输层失败。重试之前务必先读取错误文本。源码中execution_error_to_tool_resultcrates/client-api/src/routes/mcp.rs正是把所有执行期错误转换为这种带内工具结果其测试用例failed_reducer_surfaces_in_band_with_message与execution_errors_become_in_band_tool_results都验证了isError: true与错误文本的传递。实战检查一个数据库的完整流程下面是针对一个名为mydb的数据库从发现到查询再到写入的完整工具调用序列host-wide 模式list_databases {} get_schema { database: mydb } sql { database: mydb, sql: SELECT * FROM message } call { database: mydb, reducer: send_message, args: [hello] }几点实操细节get_schema返回的 JSON 包含类型的 typespace、所有表含私有表的声明以及 reducer 列表。服务端实现tool_get_schema会等待数据库 leader 的模块就绪超时上限 10 秒见源码常量MODULE_WAIT_TIMEOUT再把模块定义序列化为 JSON。拿到 schema 后可以据此确定要查询的表名、可调用的 reducer 名及其参数顺序。sql的confirmed参数传入confirmed: true可以让读取等待持久化确认durably confirmed后再返回适用于对一致性要求较高的读取场景服务端SqlQueryParams { confirmed }会透传给sql_direct。call的args是位置参数按 reducer 声明的参数顺序传入 JSON 数组。无参时省略args或传空数组[]均可——源码reducer_args_json明确将None、null都规范化为[]而args必须是 JSON 数组传字符串或对象会被拒绝args must be a JSON array。scoped 模式下所有调用去掉database参数、list_databases不可用其余完全一致。常见错误排查速查表消息含义database argument must be a string服务器是 host-wide 形态而你省略了database参数或传了非字符串值unknown tool: list_databases服务器已 scoped 到某一个数据库list_databases不可用x not found此服务器上不存在名为x的数据库或调用时把名称用在了需要 identity 的位置no such table: x表是私有表当前身份不可读或你查询了错误的数据库完全没有spacetimedb工具没有连接 MCP 服务器。此时应改用 CLI 命令参见cliskill注意第一个错误在服务端表现为 JSON-RPC 协议错误INVALID_PARAMS错误码 -32602而非带内工具错误——因为它发生在参数解析阶段其余运行期错误则统一走带内isError: true返回。这点区别可以在排查时帮你快速定位问题出在参数形态还是数据库/表层面。与官方参考文档的关系本文对应的完整官方参考见 docs/docs/00300-resources/00200-reference/00150-mcp.md其中包含相同的工具表、权限说明与错误对照并额外给出了 HTTP 端点的鉴权细节bearer token 或匿名身份。CLI 命令的详细参数spacetime mcp [OPTIONS] [database]、--server、--anonymous、SPACETIMEDB_DB_NAME可在 docs/docs/00300-resources/00200-reference/00100-cli-reference/00100-cli-reference.md 中查阅。如果要在自己的 Agent 工作流中复用本文的能力可直接参考本文开篇引用的 Skill 文件 codex-plugin/plugins/spacetimedb/skills/mcp/SKILL.md。需要再次强调的是MCP 支持目前仍处于 unstable 阶段接口可能随版本变化在实际环境中操作前先通过tools/list确认工具形态再按本文的规则发起调用是稳妥的做法。【免费下载链接】SpacetimeDBDevelopment at the speed of light项目地址: https://gitcode.com/GitHub_Trending/sp/SpacetimeDB创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表