关于 Symbol (XYM)
Symbol (XYM) 是用于查询 Symbol 区块链节点的只读 MCP 服务。其面向任务的工具服务于账户持有人和节点运营者,涵盖投票密钥到期估算及收获信息。
主要功能
- 01查询账户和交易
- 02余额显示别名并换算小数位
- 03检查节点健康与同步状态
- 04查询收获状态和收入
- 05估算投票密钥到期时间
适用场景
- 01查看账户余额和交易记录
- 02检查节点是否健康并已同步
- 03根据到期估算安排投票密钥续期
MCP 相关
服务连接到配置的 Symbol REST 节点,通过 MCP stdio 提供 20 个只读工具。工具返回经架构验证的结构化内容及文本摘要。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y symbol-mcp-serverSYMBOL_NODE_URLREST URL of the Symbol node to query, e.g. https://<node-host>:3001; https:// is required (http:// only for localhost / 127.0.0.1 / [::1]) and the port is used exactly as given.SYMBOL_NETWORKmainnet or testnet; when set, start-up fails if the node reports a different network.SYMBOL_TIMEZONEIANA zone such as Asia/Tokyo that adds a local time next to every UTC timestamp.SYMBOL_REFERENCE_NODESComma-separated https:// node URLs that symbol_network_compare and symbol_version_drift check against; no other host is ever contacted.SYMBOL_REQUEST_TIMEOUT_MSPer-request timeout in milliseconds, 100 to 600000 (default 10000).SYMBOL_STATE_DIRAbsolute directory where symbol_harvesting_status keeps one snapshot file per node (unlocked harvester public keys, heights and times; no secrets) when it is asked to compare or save, created on first save with mode 0700; when unset, the tool reports the current list without a comparison.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
symbol-mcp-server
仅支持 Symbol。 此服务与 Symbol(catapult)节点通信,不支持 NEM NIS1(XEM);后者是具有不同 API 的独立链。 非官方项目。 这是一个独立项目,与 NEM 或 Symbol 核心团队均无关联。
只读 MCP 服务,可将 Symbol REST API 转换为 20 个任务级工具。它不是将 REST 端点逐一照搬,而是让每个工具回答人们实际会提出的问题:
- 账户持有人: 应用别名和小数位后的余额、包含解码消息的交易历史记录和详情、mosaic 与命名空间查询、手续费估算、地址验证、高度/epoch/时间转换。
- 节点运营者: 节点健康状况和同步状态、委托收割状态、与参考节点的比较,尤其是投票密钥到期信息:剩余 epoch、区块和天数、预计到期日期以及建议的续期窗口。
每个工具都会返回 structuredContent(根据已发布的 outputSchema 验证),并在文本中附上相同的 JSON(只有 symbol_harvesting_income 使用 output: "csv" 时,文本中才会返回 CSV),同时在开头提供简短的 summary:第一行直接回答问题,后续行补充详情,例如每个月的数据或每项未通过的检查。金额会同时以应用小数位后的数值和原始整数返回;时间戳为 ISO 8601 UTC 格式,设置 SYMBOL_TIMEZONE 后还会附上当地时间。
效果示例
下面展示两次调用及其返回内容摘录。数值来自测试夹具(合成的节点主机和账户),并非实时节点。
“我的节点运行正常吗?是否已同步?” → symbol_node_status {}
{
"summary": "node.test:3001 (friendlyName \"fixture-node\", host \"mainnet-node.example\") on mainnet is healthy and synced.\nSymbol 1.0.3.9, roles Peer/API/Voting; height 5,763,675, finalized 5,763,656 (epoch 4004); 6 peers; latest block 201 s old (not synced above 300 s).",
"verdict": "healthy",
"sync": {
"synced": true,
"latestBlockTime": { "utc": "2026-09-10T03:01:38.808Z" },
"ageSeconds": 201,
"thresholdSeconds": 300,
"checkedAt": { "utc": "2026-09-10T03:05:00.000Z" }
},
"checks": [
{ "id": "api_node", "status": "ok", "detail": "API node service is up.", "hint": null },
{ "id": "db", "status": "ok", "detail": "Database service is up.", "hint": null },
{
"id": "clock_skew",
"status": "ok",
"detail": "Node clock is 1,000 ms behind this machine's clock (warn at 15,000 ms, fail at 30,000 ms).",
"hint": null
},
{
"id": "chain_tip_age",
"status": "ok",
"detail": "Latest block (height 5,763,675) is 201 s old (about 3.4 min; warn above 300 s, fail above 900 s).",
"hint": null
}
// … and storage_consistent, finalization_lag and roles
]
// … then node, network, chain, storage, peers, time and notes
}
verdict 将七项检查汇总为一个词,sync.synced 则表示节点是否跟随链(无法判断时为 null)。未达到 ok 的检查会附带一个 hint,说明下一步操作,摘要也会将其单独列出。请求失败时,相应检查会变为 unknown,其字段设为 null;调用仍会返回结果。
“我每个月通过收割赚了多少?”
→ symbol_harvesting_income { "account": "NCV5HR…", "fromDate": "2026-09-01", "toDate": "2026-09-11", "granularity": "monthly" }
NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY on mainnet, 2026-09-01 to 2026-09-11 (Asia/Tokyo; heights 5,736,305-5,767,984, 31,680 blocks): 20 harvest receipts totalling 662.574177 symbol.xym from 11 blocks (harvester share 461.240390 in 9 receipts, beneficiary share 201.333787 in 11 receipts).
Blocks: 9 harvested by this account, 2 harvested by others that paid it only the beneficiary share (typically delegators on its node). 9 of the 11 beneficiary receipts come from blocks it harvested itself, as its own node's beneficiary.
2026-09: 20 receipts, 662.574177 symbol.xym; 11 blocks: 9 harvested by this account, 2 by others (receipts 9 harvester / 11 beneficiary)
以上即为 summary;相同的数字也会出现在 totals 和 monthly[] 中,每笔金额都同时以十进制字符串("662.574177")和原始整数("662574177")表示,并由服务端汇总。收据是区块奖励的份额,因此,使用自有节点作为受益节点的运营者,每收割一个区块会获得两份收据;blocksHarvested 和 blocksBeneficiaryOnly 统计的是区块数。
要求
- Node.js 22 或更高版本。
- 可通过
https://访问的 Symbol REST 节点(大多数公共节点使用端口 3001)。公共节点列表见 https://nodewatch.symbol.tools/。
安装
Claude Desktop:一键安装包(.mcpb)
- 从 Releases 下载最新的
symbol-mcp-server-<version>.mcpb。 - 双击该文件,或打开 Claude Desktop 的 Settings → Extensions,然后在其中安装。
- 在设置表单中输入 Symbol 节点 URL,例如
https://<node-host>:3001(最好使用你自己的节点,参见选择节点)。此项为必填项:未设置时扩展不会启动。你也可以选择设置时区和状态目录,symbol_harvesting_status会在其中保存快照;其他字段可以留空。 - 启用扩展。
之后如果更改了这些设置,请在新对话中试用。
此安装包包含从已发布的 npm 软件包构建的服务及其生产依赖,并运行在 Claude Desktop 自带的 Node.js 上。请使用安装包或下方的 npx 配置,不能两者同时使用,否则每个工具都会出现两次。Claude Desktop 可能会将此扩展显示为未经验证,因为该安装包未使用 mcpb sign 签名;可以通过发布工作流附带的构建来源证明来检查其来源:
gh attestation verify symbol-mcp-server-<version>.mcpb --repo inotakeh/symbol-mcp-server
npm 和源代码
从 npm 安装(推荐用于其他所有 MCP 宿主):
npx -y symbol-mcp-server --help
该项目也以 io.github.inotakeh/symbol 的名称列在 MCP Registry 中。
从源代码构建:
git clone https://github.com/inotakeh/symbol-mcp-server.git
cd symbol-mcp-server
npm ci
npm run build
SYMBOL_NODE_URL=https://<node-host>:3001 node dist/index.js
运行 node dist/index.js --help 会将环境变量打印到 stderr 并退出;--version 会打印版本。除了这两个选项和 check 子命令(参见CLI:通过 cron 进行监控)外,该二进制程序不接受任何参数:所有配置都通过环境变量完成,因此模型无法将其指向其他主机。
配置 MCP 宿主
此服务通过 stdio 使用 MCP 通信。启动时,它会获取 /node/info,根据生成哈希种子检测主网或测试网,并向 stderr 输出一行日志:
symbol-mcp-server <version>: mainnet via <node-host>:3001, timezone Asia/Tokyo
Claude Desktop
将以下内容添加到 claude_desktop_config.json。使用 npm 软件包时:
{
"mcpServers": {
"symbol": {
"command": "npx",
"args": ["-y", "symbol-mcp-server"],
"env": {
"SYMBOL_NODE_URL": "https://<node-host>:3001",
"SYMBOL_TIMEZONE": "Asia/Tokyo"
}
}
}
}
从源代码检出目录运行时:
{
"mcpServers": {
"symbol": {
"command": "node",
"args": ["/path/to/symbol-mcp-server/dist/index.js"],
"env": {
"SYMBOL_NODE_URL": "https://<node-host>:3001"
}
}
}
}
Claude Code
claude mcp add symbol -s user -e SYMBOL_NODE_URL=https://<node-host>:3001 -e SYMBOL_TIMEZONE=Asia/Tokyo -- npx -y symbol-mcp-server
# or, from a source checkout:
claude mcp add symbol -s user -e SYMBOL_NODE_URL=https://<node-host>:3001 -- node /path/to/symbol-mcp-server/dist/index.js
或者提交项目级 .mcp.json:
{
"mcpServers": {
"symbol": {
"command": "npx",
"args": ["-y", "symbol-mcp-server"],
"env": { "SYMBOL_NODE_URL": "https://<node-host>:3001" }
}
}
}
其他客户端
相同的 npx 命令可用于任何能启动 stdio 服务的 MCP 宿主。以下文件位置和格式遵循各客户端自身的文档。
Cursor: 所有项目共用的 ~/.cursor/mcp.json,或单个项目中的 .cursor/mcp.json。
{
"mcpServers": {
"symbol": {
"command": "npx",
"args": ["-y", "symbol-mcp-server"],
"env": { "SYMBOL_NODE_URL": "https://<node-host>:3001" }
}
}
}
VS Code: 工作区中的 .vscode/mcp.json,或通过命令 MCP: Open User Configuration 打开的用户级文件。顶层键为 servers,而非 mcpServers。
{
"servers": {
"symbol": {
"type": "stdio",
"command": "npx",
"args": ["-y", "symbol-mcp-server"],
"env": { "SYMBOL_NODE_URL": "https://<node-host>:3001" }
}
}
}
Cline: 在 Cline 面板中,打开 MCP Servers → Configure → Configure MCP Servers,并在 mcpServers 下添加该服务(Cline CLI 从 ~/.cline/mcp.json 读取相同格式)。
{
"mcpServers": {
"symbol": {
"command": "npx",
"args": ["-y", "symbol-mcp-server"],
"env": { "SYMBOL_NODE_URL": "https://<node-host>:3001" },
"disabled": false,
"autoApprove": []
}
}
}
在 Windows 上,无法启动 npx 的客户端可能需要将 "command": "npx.cmd" 作为命令。
环境变量
| 变量 | 必填 | 含义 |
|---|---|---|
SYMBOL_NODE_URL | 是 | 要查询的节点 REST URL,例如 https://<node-host>:3001。必须使用 https://(仅 localhost / 127.0.0.1 / [::1] 可使用 http://)。端口将按给定值原样使用。 |
SYMBOL_NETWORK | 否 | mainnet 或 testnet。设置后,如果节点报告的网络不同,启动将失败。 |
SYMBOL_TIMEZONE | 否 | IANA 时区,例如 Asia/Tokyo。在每个 UTC 时间戳旁添加当地时间。 |
SYMBOL_REFERENCE_NODES | 否 | 以逗号分隔的 https:// 节点 URL,供 symbol_network_compare 和 symbol_version_drift 进行比对。不会联系任何其他主机。 |
SYMBOL_REQUEST_TIMEOUT_MS | 否 | 每个请求的超时时间,范围为 100 到 600000。默认值为 10000。 |
SYMBOL_STATE_DIR | 否 | 绝对目录,symbol_harvesting_status 在进行比较或保存时,会在其中为每个节点保存一个快照文件(未锁定的收割者公钥、高度和时间;不含机密信息)。首次保存时会以 0700 权限创建。未设置时:该工具会报告当前列表,但不进行比较。 |
选择节点
- 自己的节点是最佳选择。
SYMBOL_NODE_URL会接收您查询的内容:地址、交易哈希,以及命名空间和 mosaic 的 ID(完整列表请参阅隐私政策)。 参考节点只会收到/node/info和/chain/info请求,不会收到您的标识符。 - 公共节点也能使用,但其运营者可以看到您查询的内容。 其访问日志可能会显示查询了哪些账户、交易和命名空间、查询时间以及来源 IP 地址。请使用您信任的节点;若查询内容希望保密,则使用自己的节点。
- 必须使用 API 节点的 REST API。 大多数工具会读取
/network/properties、账户、交易或区块。Light REST(端点有所精简的 REST)并不够用:Symbol 仓库中的 README(symbol/symbol 内的client/rest/README_LIGHT.md)仅列出/chain/info、/node/info、/node/peers、/node/unlockedaccount和/node/server。如果工具返回does not provide the endpoint … (no such route),请参阅故障排除。 - 查找节点: https://nodewatch.symbol.tools/ 列出了主网和测试网节点及其区块高度和版本。请选择区块高度为当前高度、运行多数版本且通过
https://响应的 API 节点(通常使用端口 3001)。设置SYMBOL_NETWORK,这样如果节点最终位于另一个网络,启动就会失败;然后使用SYMBOL_NODE_URL=https://<node-host>:3001 npx -y symbol-mcp-server check进行测试。
工具
全部 20 个工具均为只读(readOnlyHint: true),并按固定顺序列出。参数仅为标识符,不会是 URL。每个 account 参数(以及 symbol_transaction_search 的 address)可接受 base32 地址、48 个字符的十六进制地址、十六进制公钥,或带有地址别名的命名空间名称,例如 alice 或 alice.pay;名称解析结果会显示在 accountResolution 中以及摘要开头。
| 工具 | 参数 | 返回内容 |
|---|---|---|
symbol_network_info | 无 | 网络名称/标识符和生成哈希种子、当前及最终确认高度、最终确认纪元、区块目标时间、投票集分组、纪元调整、XYM mosaic ID/别名/可分割性,以及当前手续费乘数。 |
symbol_node_status | format | 配置的节点当前是否同步、其服务是否健康,以及具体状态。根据按固定顺序执行的七项检查给出一个结论:healthy、degraded(存在警告或无法执行的检查)或 unhealthy。每项检查均为 ok/warn/fail/unknown,并附带提示:API 节点和数据库状态(会读取 503 /node/health 响应,但不会将其视为失败)、数据库区块数与链高度的对比、节点时钟与此机器时钟的对比、最终确认滞后区块数和分钟数、角色,以及最新区块相对于此机器时钟的时间(用于发现节点停止跟进区块链的情况;超过 10 个区块目标时间为 warn,超过 30 个为 fail)。当最新区块的时间不超过 10 个区块目标时间(主网为 5 分钟)时,sync.synced 为 true;超过时为 false;无法判断时为 null。还包括友好名称、主机、角色(Peer/API/Voting)、解码后的版本、网络、高度、对等节点数、数据库计数和节点时钟。请求失败时,对应检查会标记为 unknown,其字段为 null,而不会导致调用失败。阈值根据网络属性确定。 |
symbol_account_get | account(地址、公钥或命名空间名称)、format | Base32 和十六进制格式的地址、公钥、每种 mosaic 余额及其别名和小数位数、重要性、已关联/VRF/节点/投票密钥、是否已设置委托收割、多签设置(作为多签账户或共同签署者)。 |
symbol_voting_key_status | account | 每个投票密钥的状态(已过期/有效/未来)、剩余纪元/区块/天数、预计过期日期、建议的续期时间窗口(过期前 7 至 3 天)、包括过期密钥在内的槽位使用情况、相对于 minVoterBalance 的投票者资格,以及警告。 |
symbol_transaction_get | transactionHash | 在已确认、未确认和部分交易组中查找并报告状态;交易类型名称、签名者和收款人、带别名的 mosaics、解码后的纯文本消息或“已加密”标记、手续费、高度和时间,以及聚合交易的内部交易。节点拒绝的交易会报告为失败,并附上节点代码及其含义;节点不认识的哈希会报告为 not_found。 |
symbol_transaction_search | address、type、pageSize、pageNumber、order、format | 涉及某账户的已确认交易,默认按时间从新到旧排序;可选按名称(transfer)或代码(16724)筛选类型,每页 10 至 100 条。 |
symbol_mosaic_get | mosaic(十六进制 ID 或别名,例如 symbol.xym) | 供应量、可分割性、标志(供应量可变、可转让、可限制、可撤销)、所有者、起始高度、持续时间和预计到期时间。 |
symbol_namespace_get | namespace(名称或十六进制 ID) | 所有者、根命名空间或子命名空间、各级名称、别名目标(地址或 mosaic)、起始和结束高度、预计到期日期。 |
symbol_fee_estimate | transactionSizeBytes(可选) | 根据节点当前乘数计算的 XYM 慢速/平均/中位数/快速手续费档位,适用于指定大小的交易;若未指定,则按包含 1 个 mosaic 和 20 个 ASCII 字符消息的转账估算(197 字节)。转账按 160 字节计算,每个 mosaic 增加 16 字节,纯文本消息按其 UTF-8 字节数加 1 个类型字节计算(每个日文字符通常为 3 字节;加密消息更大);此计算不适用于聚合交易。不会签名或发送任何内容。 |
symbol_address_parse | value(地址、公钥或命名空间名称) | 离线验证:校验和、网络字节、Base32/十六进制/带连字符格式,以及从公钥派生的地址。命名空间名称会通过节点解析为其地址别名。 |
symbol_time_convert | height、epoch、timestamp 中的一项 | 高度、最终确认纪元、网络时间戳和墙上时钟时间。过去的时间精确,未来的时间为估算值(并会标记)。 |
symbol_harvesting_status | mode(current、compare、compare_and_save、save_only)、format | 节点上已解锁的委托收割者:当前数量,以及收割限制和受益人百分比。current(默认值)仅读取节点;密钥本身需通过 format: detailed 返回。其他模式会回答自上次存储的快照以来收割者数量是增加还是减少:新增和移除的远程密钥、数量变化,以及最近 30 天快照的最小/最大/平均值。快照按每个节点分别保存在 SYMBOL_STATE_DIR 下的一个文件中;未设置该变量时,只报告当前列表,无法进行比较。compare 仅读取,compare_and_save 还会保存当前列表,save_only 则只保存。若要检查单个账户(其已关联密钥是否在此处解锁、余额是否在限制范围内),请使用 symbol_delegation_diagnose。 |
symbol_network_compare | 无 | 对比节点与 SYMBOL_REFERENCE_NODES 中节点的高度和最终确认情况,给出落后于最佳节点的区块数及 lagging 标记。说明未配置参考节点时应如何处理;若所有参考节点都无法比较,也会明确说明。 |
symbol_harvesting_income | account、fromDate + toDate 或 fromHeight + toHeight、granularity、format、output | 指定时段内收到的收割奖励:收据数量和精确 XYM 总额(由服务器以整数求和)、收割者/受益人/未知类别明细、区块数(blocksHarvested:该账户收割的区块;blocksBeneficiaryOnly:由其他人收割、仅向该账户支付受益人份额的区块)、按 SYMBOL_TIMEZONE 或 UTC 划分的每日数据,或收据列表。日期根据区块时间戳解析为高度。granularity: monthly 会按日历月份生成一行(适用于按年查询);output: csv 会将行作为 CSV 文本返回,供电子表格使用,同时仍提供 JSON。一次调用可查询一年或更长时间的范围:数据会按约 90 天的区块读取(fetch 会报告区块、重试次数和分页情况)。 |
symbol_transaction_status | transactionHashes(数组,1 至 20 个) | 每笔交易当前所处状态:已确认(含高度)、未确认、部分交易(等待共同签署者签名)、失败(含节点代码及其含义)或 not_found。整批只需发送一次请求。 |
symbol_finality_participation | account、epoch(可选,默认为最新的最终确认纪元)、epochs(1 至 20,默认为 1)、format | 账户的投票密钥是否确实签署了各纪元的最终确认证明:已参与(prevote 和 precommit 均已签署)、未参与(注明未签署的阶段)、no_active_key 或 unavailable,并给出各阶段的签名数(若某阶段的证明拆分成多个消息组,仍计为一个阶段;任一组中有签名即视为已签署),以及当前纪元没有密钥覆盖或当前纪元未参与时的警告(历史纪元不会触发警告)。 |
symbol_delegation_diagnose | account、recentDays(1 至 30,默认为 7)、format | 委托收割是否处于活跃状态;若否,则说明问题出在哪里:账户是否存在、余额是否在收割限制范围内、重要性是否大于零(或距离下次重新计算还剩多少区块)、已关联/VRF/节点密钥、节点密钥是否与配置节点的 nodePublicKey 相同、远程密钥是否已在该节点解锁、账户类型、过去 N 天收割的区块,以及发送给节点的持久委托请求转账。结论为 active、not_active 或 cannot_verify(无法从此处检查委托到其他节点的情况)。 |
symbol_version_drift | format | 节点的软件版本是否落后于网络多数:将节点已知对等节点及参考节点的版本分布列出,并给出多数版本和运行较新版本的占比。结论为 ok、behind(版本低于多数版本,或较新版本占样本至少一半)、far_behind(较新版本占 75% 或以上;对等节点可能会拒绝连接)或 unknown(没有可用的对等节点,或节点未报告自身版本)。尚未报告版本的对等节点(0.0.0.0)会单独计数(sample.unknownVersion),不会计入某个版本。绝不报告对等节点主机或密钥。 |
symbol_account_rank | account(可选)、mosaic(可选;十六进制 ID 或别名,默认为 XYM)、top(1 至 100,默认为 20)、maxRank(100 至 5000,默认为 1000)、format | 显示账户在某种 mosaic 持有者中的排名及持有量最高的账户,类似区块链浏览器的富豪榜:账户余额、供应量占比(保留 4 位小数,使用整数运算)和排名,排名前 N 的持有者及其余额和占比,以及前 N 名的合计占比。持有者通过每次 100 条的 GET /accounts?orderBy=balance 请求读取,每次只发出一个请求,直到找到该账户或达到 maxRank(此时 rankBeyond 会说明这一点)。省略 account 时只返回榜单。并列排名由节点排序;不会附加标签(交易所、基金会)。 |
symbol_holdings_value | account、unitPrice(十进制字符串,例如 "12.34")、currency(3 至 6 个大写字母)、priceSource(可选)、priceAsOf(可选)、mosaic(可选,默认为 XYM)、decimals(可选,0 至 12)、format | 按调用者提供的单价计算账户持有的某种 mosaic 的价值:余额、标准化后的价格、精确乘积和按四舍五入规则取整后的乘积,全部使用整数运算。取整时会保留 Intl(Unicode CLDR)为该货币指定的位数(JPY 为 0 位、USD 为 2 位、KWD 为 3 位、CLF 为 4 位);对于少数代码,CLDR 与 ISO 4217 不同(CLDR 中 HUF、IDR、IQD 和 IRR 均为 0 位;ISO 4217 对 IQD 规定 3 位,对其他代码规定 2 位)。位数取自运行服务器的 Node.js,因此可传入 decimals 固定位数。Intl 不认识的代码(BTC、USDT)不会取整,取整后会变为 0 的非零值也不会取整;value.decimalsSource 会说明所用规则。服务器绝不会获取或验证价格;priceSource 和 priceAsOf 会原样返回,以说明价格来源。此功能不用于计算税费:不包括手续费、价差或税款。 |
示例问题
“NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY 的投票密钥何时过期,我应该何时续期?”
→ symbol_voting_key_status { "account": "NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY" }
返回每个密钥的 startEpoch/endEpoch、过期高度 (endEpoch - 1) × votingSetGrouping、剩余轮次、区块数和天数、根据测得的平均出块时间估算的过期日期、续期窗口、空闲名额(已过期的密钥仍占用名额),以及余额是否达到 minVoterBalance。
“显示 alice 的账户。”
→ symbol_account_get { "account": "alice" }
命名空间 alice 会通过节点解析为其地址别名(不存在、已过期、别名指向马赛克或没有别名的命名空间会报错并附带提示);答案以 alice → NCV5… 开头,并在 accountResolution 中包含解析结果。适用于每个账户参数。
“NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY 持有多少 XYM?”
→ symbol_account_get { "account": "NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY" }
返回每种马赛克及其 alias(symbol.xym)、amount(已应用小数位)和 rawAmount。
“显示涉及该账户的最近 20 笔转账,然后显示最新一笔的详情。”
→ symbol_transaction_search { "address": "NCV5HR…", "type": "transfer", "pageSize": 20 }
→ symbol_transaction_get { "transactionHash": "<hash from the list>" }
列表会提供哈希、日期、交易对手和消息预览;第二次调用会补充费用、完整解码后的消息和内部交易。
“我的节点落后了吗?”
→ symbol_node_status {} 会检查已配置节点上最新区块的时间;
→ symbol_network_compare {} 会报告其落后于 SYMBOL_REFERENCE_NODES 多少个区块。
“NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY 在 2026 年 8 月通过收割赚了多少?”
→ symbol_harvesting_income { "account": "NCV5HR…", "fromDate": "2026-08-01", "toDate": "2026-08-31" }
将日期解析为区块高度,读取所有支付给该账户的 HarvestFee 收据,并以精确整数求和:XYM 总额、收割者与受益者各自所得,以及每天一行的明细。无需模型再进行求和。
“我刚刚发布了投票密钥链接交易。交易 <hash> 成功了吗?”
→ symbol_transaction_status { "transactionHashes": ["<hash>"] }
返回已确认(包含高度)、未确认、部分完成(聚合绑定交易正在等待共同签名)、失败(包含节点错误代码,例如 Failure_Core_Insufficient_Balance 及其含义)或 not_found。始终返回数组,每次调用最多处理 20 个哈希。
“我的投票节点 NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY 上周真的能投票吗?”
→ symbol_finality_participation { "account": "NCV5HR…", "epochs": 14 }
读取最新已最终确定轮次及其之前 13 个轮次的最终性证明(一个轮次包含 votingSetGrouping 个区块,在主网上约为 12 小时),并逐轮报告该账户的某个投票密钥是否同时出现在两个阶段的签名者中、签名的投票者数量,以及当前轮次未参与或没有密钥覆盖该轮次时发出的警告。
“我觉得我的委托收割没有正常工作。检查一下 NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY。”
→ symbol_delegation_diagnose { "account": "NCV5HR…" }
按固定顺序执行 11 项检查(账户是否存在、余额限制、重要性、三个密钥链接、节点密钥与已配置节点是否匹配、是否在该节点上解锁、账户类型、最近收割的区块、委托请求转账),并返回 active、not_active(附失败步骤和提示)或 cannot_verify(账户委托给了 SYMBOL_NODE_URL 以外的节点,因此无法检查节点端)。
“我的节点运行正常吗?版本是否落后了?”
→ symbol_node_status {} 会检查已配置节点的 API 节点、数据库、存储、时钟、最终确认延迟和最新区块的时间,指出未通过的检查,并回答节点状态是健康、降级还是不健康,以及节点是否已同步;
→ symbol_version_drift {} 会将节点版本与其对等节点和参考节点进行比较,并回答状态是正常、落后还是严重落后。这两项是节点操作系统迁移后首先要检查的内容。
“迁移后,我的委托人回来了吗?”
→ symbol_harvesting_status { "mode": "compare_and_save" } 会将节点当前解锁的收割者与上次存储的快照进行比较(新增和移除的密钥、数量变化、30 天最低值 / 最高值 / 平均值),并存储今天的列表,供下次检查;"mode": "compare" 只进行比较,不存储。
需要设置 SYMBOL_STATE_DIR;如果未设置,该工具会报告当前数量,并说明无法进行比较。未指定模式时,该工具会回答“当前有多少委托人?”,且不会访问快照。
“NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY 持有的 XYM 排名第几?前 10 名是谁?”
→ symbol_account_rank { "account": "NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY", "top": 10 }
该工具会按余额排序,每次读取 100 个账户的持有者列表,直到找到该账户(或达到 maxRank,默认值为 1000),并返回其余额、占总供应量的比例和排名,以及前 10 名持有者及其合计占比。所有占比均由服务端使用整数运算计算;列表前列通常是交易所和基金会,该工具不会为任何人贴标签。
“如果 XYM 的价格是 12.34 日元,我的持仓值多少钱?NCV5HRBSFEGTPNBIUPBVAGWXWXZ43C4TNOQUYUY”
→ symbol_holdings_value { "account": "NCV5HR…", "unitPrice": "12.34", "currency": "JPY" }
该工具会读取余额,并使用整数运算乘以价格:4,321,000 XYM 的结果为 53,321,140 JPY,同时也会提供精确乘积。**价格由调用方提供。*此服务端绝不会联系价格 API(它只与 SYMBOL_NODE_URL 通信),因此,当你询问“我现在的持仓值多少钱?”*时,Claude Desktop 中的流程是:模型先查询价格(通过网页搜索、提供价格的其他 MCP 服务,或由你输入),然后使用 unitPrice、currency,最好还包括 priceSource / priceAsOf 调用此工具,这样回答就会说明价格的来源和查询时间。模型会被告知不要自行将余额乘以价格。
更多案例及其对应的确切参数见 evals/cases.json。
提示词
两个 MCP 提示词(prompts/list)封装了节点运营者会重复执行的工具调用。两者都接受一个参数 account:投票/收获账户的 39 字符 base32 地址。提示词文本本身不包含地址、主机、密钥或日期。
| 提示词 | 引导完成的步骤 |
|---|---|
voting_key_renewal_checklist | symbol_voting_key_status(到期时间、续期窗口、空闲槽位及其原样给出的警告)、symbol_node_status(如果未同步,或无法判断同步状态,则停止;其结论和未通过的检查列入待处理事项)、symbol_network_compare(无法比较时,将同步状态报告为未确认);然后,运营者在本服务之外宣布 VotingKeyLink 后,对哈希调用 symbol_transaction_status,再次调用 symbol_voting_key_status 以确认新密钥,并在新密钥的起始 epoch 达到最终确定状态后调用 symbol_finality_participation。最后给出四行摘要。 |
monthly_health_check | symbol_node_status(结论、同步状态、版本和对等节点数;不健康项优先)、symbol_version_drift(落后或严重落后的情况优先)、symbol_network_compare(无法比较时,将同步状态报告为未确认)、以 compare_and_save 模式调用 symbol_harvesting_status(与之前快照相比的差异)、symbol_voting_key_status(剩余天数和到期时间;警告按原样优先列出)、symbol_account_get(余额与 minVoterBalance 的比较)以及针对上一个日历月的 symbol_harvesting_income(先列收入,再将账户自身收获的区块和委托者或其他人收获的区块分别列为单独项目)。在一个屏幕上按“需要处理”/“注意”/“正常”报告。 |
服务器还会在初始化时发送简短的 instructions(只读、账户格式,以及容易混淆的问题分别由哪个工具回答:收获收入、投票密钥、节点健康状况与同步状态和版本的区别、交易是否成功;使用返回的数字,不作改动)。回答相关问题的工具会在其描述中互相指引。
CLI:通过 cron 进行监控
同一个二进制文件提供无需 MCP 客户端的一次性 check 子命令。它会使用上述工具判断节点状态,输出一份报告,并在发现问题时以非零状态码退出:
symbol-mcp-server check [--account <address|publicKey|namespace>] [--warn-days <n>]
[--cert <path>]... [--cert-warn-days <n>]
[--format text|json] [--quiet]
它读取与服务器相同的环境变量(必须设置 SYMBOL_NODE_URL;SYMBOL_TIMEZONE、SYMBOL_REFERENCE_NODES 和 SYMBOL_STATE_DIR 为可选项),并且需要 Node.js 22 或更高版本。不带参数启动时,该二进制文件仍会作为 MCP 服务运行,行为不变。
| # | 项目 | 正常 / 警告 / 失败 |
|---|---|---|
| 1 | node_health | symbol_node_status 的判定:健康 / 性能下降 / 不健康。最新区块超过 10 个目标出块时间(主网上为 5 分钟)的节点性能下降;超过 30 个则不健康 |
| 2 | version_drift | symbol_version_drift:正常 / 落后或未知 / 严重落后 |
| 3 | harvester_watch | symbol_harvesting_status 在 compare_and_save 模式下:解锁的收割者少于上次运行时,或无法保存快照时发出警告。未设置 SYMBOL_STATE_DIR 时跳过 |
| 4 | voting_key_status | 使用 --account 时:当前投票密钥将在 --warn-days(默认值为 14,范围为 1 到 120)指定的天数内到期时发出警告;将在 3 天内到期或没有当前密钥时失败;如果已注册后继密钥且密钥衔接无间隙,则正常。余额低于 minVoterBalance(该账户无法投票)时也会失败,无论是否有后继密钥。密钥槽位已满不会改变状态,但此时警告或失败的提示会附加该工具关于槽位的警告,除非已注册后继密钥。未使用 --account 时跳过 |
| 5 | finality_participation | 使用 --account 时,检查最近已最终确定的 epoch:已参与 / 未参与或节点上没有证明 / 没有密钥覆盖该 epoch。未使用 --account 时跳过 |
| 6 | certificate | 使用 --cert <path> 时,对每份节点证书副本分别检查:证书已过期或剩余有效期不足 7 天时失败;剩余有效期少于 --cert-warn-days(默认值为 30 天),或文件并非同一证书的副本时发出警告。文件无法读取或不是证书时,会说明原因并判定为失败。未使用 --cert 时跳过。请参阅节点证书文件 |
对于项目 1 到 5,判定由工具自身作出;检查程序只读取工具的输出,警告或失败行下方打印的提示也是工具提供的文本。工具调用失败(例如发生 HTTP 错误)时,该项目判定为失败,其他项目仍会继续运行。项目 6 是例外:REST 端点不会显示节点的证书文件,因此检查程序会自行读取文件,不依赖 MCP 工具。
| 退出代码 | 含义 |
|---|---|
| 0 | 所有项目均正常或已跳过 |
| 1 | 至少有一项警告,且没有失败 |
| 2 | 至少有一项失败 |
| 3 | 无法运行检查:配置错误、节点无法访问或参数错误(标准错误输出会用一两行说明原因)。使用 --cert 时,如果无法读取的是节点,仍会检查并报告证书文件;请参阅节点证书文件 |
文本输出(默认格式;示例值):
symbol check: WARN (node.example:3001, mainnet, 2026-01-15T07:00:03+09:00)
[ok] node_health: healthy (finalization lag 12 blocks)
[ok] version_drift: ok. node.example:3001 runs 1.0.3.9; majority of 24 sampled nodes runs 1.0.3.9; 0% run something newer.
[ok] harvester_watch: 18 unlocked harvesters on node.example:3001, unchanged since 2026-01-14T07:00:02+09:00 (2026-01-13T22:00:02.000Z). Snapshot saved (31 stored).
[warn] voting_key_status: active key 0A1B2C3D… expires in about 12.4 days (epoch 4321, estimated 2026-01-27T16:40:00+09:00 (2026-01-27T07:40:00.000Z))
hint: Active voting key 0A1B2C3D… expires at epoch 4321 in about 12.4 days (...) and no successor key is registered.
[ok] finality_participation: epoch 4290: participated (signed prevote and precommit)
[skip] certificate: no --cert given; pass --cert <path> for each copy of the node certificate to check its expiry
--format json 会将相同报告以一个 JSON 文档输出:{ verdict, exitCode, node: { host, network }, checkedAt, checks: [{ id, status, detail, hint }], warnDays, account },其中 verdict
为 ok、warn、fail、error(退出代码为 3),account 为解析后的地址。如果启动时无法读取
/node/info,且指定了 --cert,则 network 为 unknown,需要查询节点的五个项目状态为 skip,
certificate 状态为 ok、warn 或 fail,而 account 为原样传入的参数(长度超过 16 个字符时会截取前 8 个字符并加上 …);请根据 verdict(error)和 exitCode(3)读取总体结果,而非项目状态。--quiet 在退出代码为 0 时不输出任何内容,因此 cron 仅会在有内容可读时发送邮件:
[email protected]
0 7 * * * SYMBOL_NODE_URL=https://node.example:3001 SYMBOL_STATE_DIR=/var/lib/symbol-mcp-server \
npx --yes symbol-mcp-server check --account NXXX... --warn-days 14 --quiet \
--cert /path/to/target/nodes/node/cert/node.crt.pem \
--cert /path/to/target/gateways/rest-gateway/api-node-config/cert/node.crt.pem
此处为适应页面宽度而将条目拆成多行:cron 不支持续行,因此请在 crontab 中将其写成一行。
- 此项检查不会发送通知。 它会向 stdout 和 stderr 写入内容并设置退出代码;邮件由 cron 负责处理(
MAILTO)。它只会联系SYMBOL_NODE_URL和SYMBOL_REFERENCE_NODES,不会联系其他对象,且与服务一样只读。设置SYMBOL_STATE_DIR后,每次运行都会向symbol_harvesting_status使用的文件追加一个快照(保留最新的 60 个)。使用--cert时,它会读取运行所在机器上的指定文件;这些文件不会被发送到任何地方。 - 整次运行的时限为 120 秒。达到时限后会跳过剩余项目,将原因写入 stderr,结果至多为 WARN,即使使用
--quiet也会打印。若启动时无法读取/node/info(参见节点证书文件),则不适用此时限:此时不会再发出其他请求,且--cert文件只会被读取,每个文件最多 1 MiB。 - 子命令名称拼写错误时,服务会将其视为未知参数,并像之前一样以 2 退出。
节点证书文件(--cert)
使用 symbol-bootstrap 设置的节点会在两个位置保存证书:节点本身使用
target/nodes/node/cert/node.crt.pem,REST 网关则在
target/gateways/rest-gateway/api-node-config/cert/node.crt.pem 保存自己的副本。symbol-bootstrap renewCertificates 会更新第一份,不会修改第二份。如果只有 REST 网关的
副本过期,网关便无法再与节点通信,/node/health 会报告
apiNode: down。同时传入两个文件,check 就会在问题发生前告知你:
symbol-mcp-server check --cert target/nodes/node/cert/node.crt.pem \
--cert target/gateways/rest-gateway/api-node-config/cert/node.crt.pem
[warn] certificate: warn (copies differ: target/nodes/node/cert/node.crt.pem vs target/gateways/rest-gateway/api-node-config/cert/node.crt.pem)
target/nodes/node/cert/node.crt.pem: ok, expires 2027-01-20T02:11:09.000Z, 370 days left, sha256 0A:1B:2C:…
target/gateways/rest-gateway/api-node-config/cert/node.crt.pem: ok, expires 2026-03-01T02:11:09.000Z, 45 days left, sha256 3D:4E:5F:…
- 每个文件:证书已过期或剩余有效期不足 7 天时为
fail(固定值,不是 选项);剩余有效期不足--cert-warn-days天时为warn(默认 30,必须是大于等于 1 的整数;与--warn-days相互独立);其他情况为ok。剩余天数是从现在到证书 notAfter 的整天数,向下取整,因此最后一天计为 0。包含多个证书的文件(node.full.crt.pem)以第一个证书为准。 - 副本:传入两个或更多文件时,它们的 SHA-256 指纹必须全部相同;否则该项至少为
warn,并会列出不一致的文件。若续期只替换了一个副本,这里会在当天就显示出来,远早于旧副本过期。重复提供同一路径会被拒绝并作为用法错误处理,因为这会导致文件与自身比较(路径按输入形式比较,但会先解析.和..;指向同一文件的链接,或在不区分大小写的文件系统上以另一种形式写出的路径,不会被识别)。 - 该项的判定结果为所有文件和比较结果中最差的状态。无法读取或不是证书的文件会判定为失败,并注明原因(
cannot be read (ENOENT)、not a certificate …);其他文件和其他项目仍会继续检查。 - 请在节点所在的服务器上运行。 文件从本地磁盘读取;MCP 工具无法完成此操作,因为 REST API 不会显示这些文件。相对路径会以当前目录为基准解析;cron 会从主目录启动命令,因此应在其中提供绝对路径。
- 绝不要传入密钥。 内容包含
PRIVATE KEY(所有 PEM 私钥的标签)的文件不会被解析,并会判定为失败,原因是a private key was passed; pass the certificate (.crt.pem)。其他任何非证书文件也会判定为失败,原因是not a certificate。无论哪种情况,报告只包含你提供的路径、判定结果、notAfter(ISO 8601,UTC)、剩余天数、SHA-256 指纹,以及 JSON 中的主题通用名称;不会打印文件中的其他内容。 - 运行时,
--format json会在certificate项中添加files: [{ path, status, notAfter, daysLeft, fingerprint256, commonName, reason }](reason说明文件无法使用的原因,否则为 null;过期后daysLeft为负数)。 - 如果运行期间节点停止响应,且所有依赖节点的项目都因此失败,退出码仍为 3,无论文件检查结果如何;
certificate行仍会打印。启动时无法读取/node/info(节点无响应或返回错误)时也一样:文件仍会照常读取并判定,报告仍会打印,即使使用了--quiet也是如此。首行会显示ERROR,并将网络标记为unknown;需要查询节点的五个项目会跳过,并注明原因/node/info could not be read at start-up, so this check did not run;随后会输出certificate项和每个文件对应的一行,stderr 则会说明无法读取/node/info的原因。未使用--cert时,只会打印 stderr 中的行。配置错误(缺少或无效的环境变量,或节点网络不符)会在读取任何文件之前终止检查。
安全
- 只读。 没有工具会签署、构建或广播交易。没有参数接受私钥、助记词或令牌。64 位十六进制账户参数会被视为公钥,并在此机器上转换为地址,然后向节点查询该地址:误粘贴的私钥永远不会到达节点,错误信息最多只显示其前 8 个字符。调用之间不会存储任何内容;但在会保存数据的模式(
compare_and_save、save_only)中,symbol_harvesting_status会在设置了SYMBOL_STATE_DIR时,将每个节点的未锁定收割者公钥、区块高度和时间快照保存在该目录下(不含机密;删除文件即可重新开始)。 - 仅在请求时读取证书文件。 MCP 服务不会读取任何证书或密钥。只有
check --cert <path>会读取,且只读取运行该命令的机器上指定的文件。它不会自行打开任何密钥文件;如果误传了 PEM 私钥(文件内容包含PRIVATE KEY),则会在解析前拒绝。文件内容不会被打印,例外仅限证书到期日期、SHA-256 指纹和通用名称;也不会向任何地方发送任何内容。 - 目标地址固定。 服务只会联系
SYMBOL_NODE_URL,以及symbol_network_compare和symbol_version_drift使用的SYMBOL_REFERENCE_NODES中列出的主机。工具不会将 URL 作为参数,因此模型无法重定向请求。没有遥测。 - 链上数据不可信。 转账消息、元数据值、别名名称,以及节点对自身的报告(友好名称、主机名、状态和版本字符串)均由第三方写入。它们会以明确表明其性质的名称(
messageText)公开,并转换为单行:制表符和换行符会变为空格,以保留单词间距;连续空格会合并为一个。其他所有控制字符和不可见格式字符都会被剔除(零宽字符、双向文本字符、软连字符,以及人眼不可见但模型可读取的 U+E0000 至 U+E007F 标签字符),并会限制长度,且不会截断字符。变体选择符会保留,因此表情符号和表意文字变体仍会显示;通过零宽连接符连接的表情符号会拆分为独立表情符号。显示此类文本的 16 个工具会在invisibleCharactersRemoved中报告从文本中移除的字符数;如果有任何字符被移除,摘要末尾会添加一行说明。在summary中,此类文本也会带标签并置于双引号内,且引号和反斜杠会像 JSON 中那样转义(untrusted message: "…",friendlyName "…"),因此它无法闭合引号并伪装成服务自己的话语;符合命名空间语法的别名和命名空间名称会保持原样。所有此类内容都应视为数据,而非指令。 - 出错时明确报错。 网络不匹配(
SYMBOL_NETWORK与节点不一致)、节点无法访问或响应结构异常,都会报错并提供恢复提示,绝不会静默回退到另一个网络。堆栈跟踪和原始 HTTP 响应正文绝不会返回给模型。 - 请求安全措施。 每个请求均设有超时、
User-Agent和 5 MB 响应上限(在响应正文流式传输时应用;若声明的Content-Length更大,则会在读取前拒绝);每个节点最多同时处理 4 个请求,并对每个响应进行架构验证。绝不跟随重定向:如果节点返回 HTTP 3xx,则会报错,且不会联系其指向的地址。请求路径只包含普通标识符。 - 仓库设置。 已启用 CodeQL 代码扫描、带推送保护的机密扫描、Dependabot(安全更新和按月分组的版本更新)、
main分支保护(所有更改都通过拉取请求合并,并保持线性历史记录)以及私密漏洞报告。
漏洞报告:请参阅 SECURITY.md。
隐私政策
MCP 服务及其 check 命令会发送什么、谁会收到,以及哪些内容会留在你的设备上。
- 本项目。 维护者不会收到任何信息:服务没有遥测、分析功能或更新检查。它建立的网络连接仅会连到你在
SYMBOL_NODE_URL和SYMBOL_REFERENCE_NODES中设置的节点。 SYMBOL_NODE_URL中的节点。 它会收到你查询的内容:地址、交易哈希、命名空间和马赛克 ID、高度和纪元,以及搜索的分页、排序方式和筛选选项。节点运营者可以看到这些内容,以及请求时间和来源 IP 地址。- 名称和公钥。 命名空间名称会以你设备上根据该名称计算出的 ID 发送(这并不会隐藏名称:该 ID 可由名称推导得出);若账户以公钥形式提供,则会通过从该公钥推导出的地址查询该账户。有一个工具会发送公钥:
symbol_delegation_diagnose会将节点报告的账户公钥发回同一节点,以查找该账户的委托请求。 SYMBOL_REFERENCE_NODES中的节点。 它们只会收到/node/info和/chain/info请求,因此其运营者能看到请求时间和你的 IP 地址,但看不到你查询的内容。发送给这些节点和SYMBOL_NODE_URL的每个请求都包含以下标头:User-Agent: symbol-mcp-server/<version>- 你的磁盘。 仅当你设置了
SYMBOL_STATE_DIR时:每份保存的快照(symbol_harvesting_status处于compare_and_save或save_only模式时,以及每次运行check时)都会写入该目录中对应每个节点的一个文件。文件中包含节点的nodePublicKey,以及最新 60 份快照的时间、高度和已解锁收割账户的公钥。文件名以harvesters-开头,会一直保留,直到你将其删除;删除文件会移除服务保留的所有快照。 - 日志。 服务和
check会向 stderr 记录少量内容:服务启动行(版本、网络、节点主机,以及设置时的时区、参考节点数量和状态目录)、启动失败、参数错误、与 MCP 主机连接出错、意外错误、无法显示为日期的节点时间,以及check的诊断信息。它们不会写入日志文件;除上述快照外,也不会保留任何工具调用记录。stderr 的后续处理取决于启动它们的程序(参见故障排除)。 check --cert。 指定的证书文件会在命令运行的设备上读取,不会存储或发送其中的任何内容。报告会显示你提供的路径、证书到期日期和 SHA-256 指纹(使用--format json时还会显示通用名称),并输出到 stdout;之后内容会去向何处(例如 cron 的邮件或日志文件),由你自行设置。- 本服务之外。 服务返回给 MCP 主机的答复包含链数据和你自己的设置值:节点 URL、参考节点 URL、时区、请求超时,以及在快照模式下的快照文件路径。主机和模型提供方如何处理你的问题及其答复,以及获取软件包时 npm 和 GitHub 能看到什么(上述
npx配置会在每次启动时运行 npx),或下载软件包时它们能看到什么,均由各自的政策决定。 - 问题反馈。 请使用问题跟踪器中的一种方式;问题是公开的,因此请勿包含你不愿公开的内容。请通过
SECURITY.md中说明的私密报告方式,报告漏洞或隐私问题。
发布完整性
-
由 CI 发布,并附带来源证明。 每个 npm 版本均由 GitHub Actions 工作流
release.yml通过 npm 可信发布 (OIDC)构建并发布。维护者的机器和仓库机密中都没有 npm 令牌。 每个版本都附带来源证明声明,将其与源代码提交和构建该版本的工作流运行关联起来。 -
自行验证。
- npmjs.com 上的包页面会显示一个 来源证明部分,其中包含提交和工作流运行信息。
npm view symbol-mcp-server dist.attestations会打印最新版本的声明 URL 和来源证明谓词类型。- 在安装了该包的项目中,
npm audit signatures会验证已安装包的注册表签名和 来源证明声明。
-
GitHub Releases 附带相同的包。 从 0.8.0 开始,每个 GitHub Release 都附带三个文件 (更早的版本附带前两个):
symbol-mcp-server-<version>.tgz,与 npm 提供的 tarball 逐字节一致(其 SHA-512 会与注册表的dist.integrity核对);symbol-mcp-server-<version>.tgz.sigstore.json,npm 为该 tarball 提供的 SLSA 来源证明 Sigstore bundle(其 subject 会与 tarball 的 SHA-512 核对);以及 Claude Desktop bundlesymbol-mcp-server-<version>.mcpb(见下一条)。前两个文件由scripts/release-assets.sh收集。要使用 GitHub CLI 验证下载的这两个文件:gh attestation verify symbol-mcp-server-<version>.tgz \ --bundle symbol-mcp-server-<version>.tgz.sigstore.json \ --repo inotakeh/symbol-mcp-server --digest-alg sha512由于 npm 的来源证明使用 tarball 的 SHA-512 标识它,因此需要
--digest-alg sha512。 -
Claude Desktop bundle 由同一个 tarball 构建。
symbol-mcp-server-<version>.mcpb由scripts/build-mcpb.sh使用上文经过核验的 npm tarball,以及 根据该版本锁文件通过npm ci --omit=dev安装的生产依赖构建; 不会编译或下载其他内容。发布工作流会为其附加 GitHub 构建来源证明声明 (gh attestation verify … --repo inotakeh/symbol-mcp-server,参见 安装)。 -
谁可以发布。 只有维护者可以创建发布标签(
v1.2.3)。工作流会先在npm-publishGitHub Environment 中等待维护者批准运行;获批后才会检查标签是否与package.json及其他发布文件匹配,运行 lint、类型检查和测试,然后发布。 完整流程见docs/RELEASING.md。
支持的网络
| 网络 | 标识符 | 通过生成哈希种子检测 |
|---|---|---|
| Symbol 主网 | 104 | 57F7DA20…72B2D6 |
| Symbol 测试网(sai) | 152 | 49D6E1CE…FC665A4 |
启动时会从节点检测网络。其他任何生成哈希种子(私有网络、NEM NIS1)都会被拒绝。 两个网络的节点均列于 https://nodewatch.symbol.tools/;参见[选择节点](#choosing-a-node)。
限制
- 节点历史记录和限制。 结果来自已配置的节点。会修剪交易历史记录的节点只会返回其仍保留的内容,因此
symbol_transaction_search可能会遗漏此类节点上的旧交易。公共节点也可能限制其接受的请求数量。请求量最大的调用是symbol_account_rank(最多 50 页)和长时间段的symbol_harvesting_income(最多 200 页);请为这些调用使用自己的节点。 - 未来日期为估算值。 投票密钥、命名空间和 mosaic 的到期日期,以及任何未来的高度或 epoch,都是根据最近 10,000 个区块测得的平均出块时间推算的(主网约为 30 s),并标记为估算值。
- 加密消息不会解密,会标记为已加密。
- 页面大小为 10 到 100,因为 catapult-rest 会将较小的页面大小强制设为 10。
- 搜索仅包含已确认的交易。 未确认和部分交易可通过哈希使用
symbol_transaction_get查看。 - 收获状态仅反映已配置的节点(
/node/unlockedaccount),不代表整个网络。 - 不提供价格。
symbol_holdings_value会将余额乘以调用方传入的单价;它不会获取、核实或记住价格,结果的准确性完全取决于输入值。请先查询价格(通过网页搜索、价格 MCP 服务或询问用户),并通过priceSource和priceAsOf传入。该值是直接相乘所得:不含费用、价差或税款,也不进行税务批次核算。 - 持有者排名通过扫描获得,而非索引查询。
symbol_account_rank每次请求读取 100 个账户的持有者列表,直到maxRank(最多 5,000,即 50 次请求);排名低于该范围的账户会获得rank: null和rankBeyond。余额相同的账户由节点排序,不同调用之间顺序可能变化。 - 收获者历史记录仅保存在本地。
symbol_harvesting_status会与其在SYMBOL_STATE_DIR下自行写入的快照进行比较;换用另一台机器、删除文件或更改节点密钥(迁移后生成新的 node.key.pem)都会建立新的基线。同一天重复调用会添加多个快照;只保留最新的 60 个。 - 每次调用最多读取 20,000 条收获收入记录(200 页,每页 100 条)。更长的时间段会返回
truncated;请使用fromHeight/toHeight拆分查询。奖励根据 HarvestFee 回执求和,因此会修剪回执的节点报告的金额会少于链上实际金额。 - 按年读取收获收入时会分段处理。 catapult-rest 对较大的高度范围响应较慢,因此会将范围拆分为约 90 天的区间并依次读取;如果某个区间的第一页超时,就会将其减半(最短约 7 天)后重试。总额与单次查询相同,
fetch字段会说明范围的读取方式;只有当节点无法在SYMBOL_REQUEST_TIMEOUT_MS时间内响应约 7 天的查询时,调用才会失败。 - 最终性参与情况根据节点持有的证明读取。
unavailable表示节点没有该 epoch 的证明(尚未最终确定,或超出其保留的历史记录范围),并不表示账户没有投票。服务端不知道已注册的投票者人数,因此signatureCount只能与 nodewatch 等外部名单进行比较。 - 版本偏差根据抽样得出,并非全面调查。
symbol_version_drift会检查已配置节点当前已知的对等节点以及参考节点,而非整个网络;完整情况请查看 nodewatch。symbol_node_status中的时钟偏差和最新区块的时间则是相对于运行此服务的机器时钟测量的,而该时钟本身也可能不准。 - 仅支持主网和测试网。 按设计,不构建、签署或广播交易。
- 按给定 URL 使用。 服务端不会自行切换端口或协议;如果节点仅通过 http 在端口 3000 提供服务,除非它位于 localhost,否则无法使用。
故障排除
启动错误会以一行文本写入 stderr,行首为 symbol-mcp-server failed to start:。MCP 主机会将 stderr 保存在日志中(Claude Desktop:macOS 上为 ~/Library/Logs/Claude/mcp*.log,Windows 上为 %APPDATA%\Claude\logs);在终端中运行相同命令也会显示错误。
| 你看到的内容 | 原因和解决方法 |
|---|---|
SYMBOL_NODE_URL is required | 该变量没有传递给服务进程。将它放在主机配置的 env 区块中;在 shell 中执行 export 无法传递给由桌面应用启动的服务。 |
SYMBOL_NODE_URL must use https:// 或 SYMBOL_NODE_URL must start with https:// | 使用节点的 https:// URL(通常为端口 3001)。只有在 localhost / 127.0.0.1 / [::1] 上才接受 http://。 |
SYMBOL_NETWORK=mainnet but node <host> is on testnet | 节点位于另一个网络。将 SYMBOL_NODE_URL 指向你需要的网络中的节点,或更正 SYMBOL_NETWORK。 |
Node <host> reports an unknown network | 节点的生成哈希种子既不是 Symbol 主网,也不是测试网(可能是私有网络或 NEM NIS1 节点)。请使用 Symbol 主网或测试网节点。 |
启动时出现 <host> did not answer /node/info within 10000 ms 或 could not reach <host> for /node/info;工具返回 Node <host> did not answer … within … ms 或 Could not connect to node <host> | 节点已停止、过载或端口错误(https 使用 3001)。请尝试 nodewatch 中的其他节点,或通过 SYMBOL_REQUEST_TIMEOUT_MS 为响应较慢的节点延长等待时间(最多 600000)。 |
启动时出现 <host> answered /node/info with a redirect (HTTP 301), which is not followed;工具返回 Node <host> answered … with a redirect | URL 指向了会重定向的地址:http 到 https、代理或已移动的路径。系统不会跟随重定向,也不会访问重定向中的地址。请将 SYMBOL_NODE_URL 设置为节点本身的 REST API URL,通常为 https://<node-host>:3001。 |
工具返回 Node <host> does not provide the endpoint … (no such route)(check 会将其打印为 hint: 行) | 节点响应称该路径没有对应路由。此服务需要 API 节点的 REST API。可能的原因:节点只提供 Light REST,该服务仅支持少量 /node 和 /chain 端点(参见选择节点);或者节点运行的 catapult-rest 版本不包含该端点。请将 SYMBOL_NODE_URL 设置为最新 API 节点的 REST URL,例如 nodewatch 中的节点。如果最新 API 节点也出现此响应,则这是此服务中的错误:请报告问题并注明工具名称。 |
工具返回 Node <host> answered HTTP 429 for …(或 503) | 节点限制了接受的请求数量,或节点过载。请稍后重试。对于会读取许多页的调用(例如 symbol_account_rank 使用较大的 maxRank,或 symbol_harvesting_income 查询较长时间段),请使用自己的节点或 nodewatch 中的其他节点。 |
Claude Desktop 没有列出任何 symbol_* 工具 | 使用捆绑包(.mcpb)时:打开扩展的设置;Symbol node URL 为空时不会启动。使用 JSON 配置时:Claude Desktop 只会在启动时读取配置。请完全退出并重新打开(仅关闭窗口不够)。如果仍未显示这些工具,请在上方日志中查找 failed to start 行,并检查 JSON 是否有效。 |
npm 打印 npm warn EBADENGINE Unsupported engine | Node.js 版本低于 22。请检查 node --version 并安装 22 或更高版本(例如 nvm install 22)。桌面应用的 PATH 中可能包含与 shell 不同的 node / npx;如有需要,请在 command 中提供完整路径。 |
| 发布后仍在运行旧版本 | npx 会重用缓存。请运行 npx -y symbol-mcp-server@latest --version,或在 args 中添加 symbol-mcp-server@latest。 |
开发
npm ci
npm run lint && npm run typecheck && npm test
npm run build
SYMBOL_NODE_URL=https://<node-host>:3001 node dist/index.js
npx @modelcontextprotocol/inspector -e SYMBOL_NODE_URL=https://<node-host>:3001 node dist/index.js
SYMBOL_INTEGRATION=1 SYMBOL_NODE_URL=https://<testnet-node>:3001 npm test # live-node tests
SYMBOL_INTEGRATION=1 SYMBOL_NODE_URL=https://<node-host>:3001 SYMBOL_INTEGRATION_ACCOUNT=<address> npm test # account tools against a specific account
SYMBOL_INTEGRATION=1 SYMBOL_NODE_URL=https://<node-host>:3001 SYMBOL_INTEGRATION_MULTISIG_ACCOUNT=<address> npm test # symbol_account_get against a multisig account and its first cosignatory
node scripts/capture-fixtures.mjs https://<node-host>:3001 # refresh test/fixtures/<network>/ from a node
MCP Inspector 启动服务时,只会传递少数几个自身的环境变量(PATH、HOME 等,这是 MCP SDK 的默认设置)以及显式提供给它的变量,因此在 npx 前设置的变量不会传递给服务。像上面那样使用 -e KEY=VALUE 逐个传递,或在 Inspector 的表单中输入;在 macOS 和 Linux 上,也可以用 env 包装服务命令。
设计说明:docs/DESIGN-BRIEF.md。变更记录:CHANGELOG.md。
发布说明:docs/RELEASING.md。
贡献
欢迎提交错误报告、功能请求和拉取请求。开发环境设置、如何添加工具以及设计规则,请参阅 CONTRIBUTING.md;安全问题请通过 SECURITY.md 反馈。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。