mcp-server-gamenumerics 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,74 @@
1
+ # MCP 宿主真机验证记档
2
+
3
+ > 验证日期:2026-09-12 | 验证人:AI 全程代办(用户裁决 ZCode 宿主优先)
4
+ > 宿主环境:**ZCode 0.16.5**(Windows 11,stdio,会话级隔离)+ 宿主 LLM GLM-5.3
5
+ > 被测:`mcp-server-gamenumerics` 0.1.0(PR #215 set_fs 修复 + PR #216 依赖显式化之后的构建)
6
+ > 性质:W2 Spec 遗留「宿主真机验证(用户侧动作)」的交付物——**npm 发布决策的输入**
7
+
8
+ ## 一、验证金字塔定位
9
+
10
+ | 层 | 手段 | 结论 |
11
+ |---|------|------|
12
+ | 单测(CI) | 映射器 34 round-trip / 工具面 17 三向闭合 / import 装配(43 用例) | 逻辑正确 |
13
+ | 冒烟 | SDK Client 子进程全链(握手→tools/list 17→七步断言) | 参考客户端可正常工作 |
14
+ | **宿主真机(本记档)** | ZCode 宿主 + 宿主 LLM 语义路由自然语言任务 | **可用性成立,3 项发现** |
15
+
16
+ ## 二、剧本结果(全部通过)
17
+
18
+ | # | 剧本项 | 结果 |
19
+ |---|--------|------|
20
+ | 1 | 会话启动自动连接(用户级 config) | ✓ `mcp.server.connected`:connectDurationMs 636-1090 / listTools **toolCount=17** / 协议 2026-07-28(modern era) |
21
+ | 2 | `list_workspaces` 空状态 | ✓ 空列表(GND_WORKSPACES_DIR 隔离生效) |
22
+ | 3 | `import_xlsx` 真实外包表(441KB / 20 sheet) | ✓ 20 表装配、双行表头启发式命中(`设定` headerRows=2 复合键)、列模式识别(等差序号) |
23
+ | 4 | `read_table` 读回 + 分页 | ✓ 61 行表 limit=5 正常(含 xlsx 公式注释行原样返回) |
24
+ | 5 | `infer_column_rule` ×2 | ✓ 「属性」列 100% 命中 `95+5×i`;「经验消耗」诚实判定「无单一规则」(真实表为查表设计) |
25
+ | 6 | `audit_column` 对账(推断产物→expression 复核) | ✓ 60 行全符合公式 |
26
+ | 7 | `power_curve` 无标准属性列边角 | ✓ isError + 引导显式 columns 指定 |
27
+ | 8 | `compute_power` 真实表面板 | ✓ EDPS/EHP/边际价值 + assumptions 诚实声明 |
28
+ | 9 | `read_table` 不存在表名边角 | ✓ isError + 引导 list_tables |
29
+ | — | 宿主 LLM 编排观察 | ✓ 语义路由正确(自然语言→正确工具+参数,read/infer 并行独立调用自然发生) |
30
+
31
+ ## 三、发现与处置
32
+
33
+ | # | 发现 | 定性 | 处置 |
34
+ |---|------|------|------|
35
+ | F1 | **W3 SheetJS 换源涟漪**:重建 bundle 后 `import_xlsx` 全链死(esbuild ESM 解析 `xlsx.mjs` 无 fs,`readFile` 报 Cannot access file);W2 旧 dist 解析 0.18.5 CJS 故冒烟一直假 PASS | server bug(生产面) | ✓ **PR #215 已修**:显式 `XLSX.set_fs(node:fs)`;冒烟 RED→GREEN 实证 |
36
+ | F2 | **中文文件名首体验摩擦**:`import_xlsx` 以文件名推断工作区名,中文名直接被拒(sanitize 白名单 fail-closed 正确+引导文案),但中文用户外包表大概率中文名 | 产品体验改进候选 | 记 Backlog:自动转写(拼音/时间戳)兜底而非要求显式传 `workspaceName` |
37
+ | F3 | **ZCode 宿主单工具丢失(17→16)**:宿主连接层三次连接 `toolCount=17`(schema 正常、协议协商正常),但模型工具面仅注入 16 个——恰好缺 `infer_foreign_keys` | **宿主侧**(ZCode 连接层→模型注入层),server 无罪 | 观察项:ZCode 宿主下外键悬挂审计不可达(/agent 工作台与其他宿主不受影响);**Claude Code / Cursor 交叉验证时确认**——彼处 17/17 则 ZCode 专属,彼处也 16 则重开 server 端排查 |
38
+ | F4 | stdio 进程树清理偶发失败(`taskkill failed`,Windows) | 宿主侧观察级 | 僵尸 node 进程风险,留意即可 |
39
+ | F5 | 用户级配置 = 所有工作区会话均拉起本 server(Resume / FinancialCounseler 会话日志实证) | 预期行为(用户级语义) | 若不想全局常驻,可改 workspace 级配置(`<repo>/.zcode/config.json`) |
40
+
41
+ ## 四、结论
42
+
43
+ - **ZCode 宿主可用性成立**:自然语言→正确工具编排链(导入→查→读→推断→对账→算)全通,错误路径引导文案符合设计,连接/协议/性能(冷启动 ~1s)全部健康。
44
+ - **发布前置就绪**:依赖显式化(PR #216,xlsx tarball + esbuild + lock 入库)后,`npm publish` 的工程条件已齐;发布动作本身仍待用户确认(W2 Spec 裁决维持)。
45
+ - ~~遗留:跨宿主交叉验证~~ → **Claude Code 已完成(见 §六),Cursor 经用户裁决跳过(2026-09-12)**;F2 中文名兜底 + F6 守卫细分留 Backlog。
46
+
47
+ ## 五、性能基线与优化记账(2026-09-12)
48
+
49
+ **1. 基准面(性能回归护栏)**:冷启动 ~146ms(spawn → initialize → tools/list 全链)/ 空闲 RSS ~78.7MB(握手完成后,Windows WorkingSetSize 口径)/ stdin EOF 干净退出 3/3。固化于 `scripts/mcp-benchmark.ts`(仓库根 `npx tsx scripts/mcp-benchmark.ts`,3 轮独立子进程取中位)——后续加工具/加依赖时对照此基线,防性能回归无声滑落。
50
+
51
+ **2. xlsx lazy import 探针结论(已 revert,只记结论)**:把 SheetJS 从启动加载改为首次 `import_xlsx` 调用时动态加载,**技术上成立**——esbuild 对动态 import 以 init 包装内联、启动链不触及(首次调用实测耗时 ~42ms 含一次性模块加载、调用后进程 +9.9MB,证明启动时确实未加载);但空闲 RSS 仅降 ~0.3MB,远低于 5MB 门槛:xlsx **模块体**的驻留成本本就低,+9.9MB 是**调用期解析工作内存**(readFile 缓冲/工作簿对象,eager 模式同样只在调用时产生)。按门槛裁决 revert,结论沉淀:单进程内存被 Node.js 基线(空进程 ~48MB)锁死,server 侧内存优化优先级让位于 TTFC。
52
+
53
+ **3. Theil-Sen 性能债(跨域记账,本域不排期)**:`infer_column_rule` 全链 ~7.2s,瓶颈在 `lib/table/pattern.ts` 的 Theil-Sen 稳健拟合;消费方三方(agent 工具 / mcp-server / `/checkup` 体检页);`lib/table` 为共享文件跨域,归 **lib/agent 域**排期——用户感知最强的性能优化项。
54
+
55
+ ## 六、跨宿主验证:Claude Code(2026-09-12,第二宿主)
56
+
57
+ > 宿主:**Claude Code CLI 2.1.212**(Windows 11,`claude -p` 非交互剧本);配置:`claude mcp add gamenumerics --env GND_WORKSPACES_DIR=D:/mcp-workspaces -- node <dist>`(local 级,验后已清理);被测与 ZCode 验证同一 dist(PR #215 后零源码改动)。
58
+
59
+ | # | 剧本项 | 结果 |
60
+ |---|--------|------|
61
+ | 1 | 连接 + **F3 对照(LLM 报工具名单)** | ✓ **17/17 全注册,`infer_foreign_keys` 在列——F3 判定落定:ZCode 注入层专属问题,server 普遍缺陷排除** |
62
+ | 2 | import_xlsx 中文文件名(F2 对照) | ✓ F2 复现(sanitize 是 server 端规则,与宿主无关)且 **LLM 读错误文案一次重试自愈**(自起名 `core-loop-0118`,20 表装配 + 双行表头 + 列模式与 ZCode 一致)——两宿主错误恢复行为一致 |
63
+ | 3 | infer_column_rule + audit_column 链 | ✓ LLM 交叉验证:fitPct 0.0944 与对账吻合行 17/180 精确一致;对查表结构列诚实判定「单一曲线审计前提不成立」而非乱报手调 |
64
+ | 4 | compute_power | ✓ LLM 算术复核 √(1200×256.25)=554.5268… 逐位吻合;assumptions 数组原文返回 |
65
+ | 5 | 错误路径 ×2 | ✓ 「表不存在 / 工作区不存在」文案自包含引导 |
66
+
67
+ **新发现**:
68
+
69
+ | # | 发现 | 定性 | 处置 |
70
+ |---|------|------|------|
71
+ | F6 | `compute_power` 等不依赖工作区数据的纯计算工具也被「未设工作区」会话守卫拦截 | 统一保守卫的代价——ZCode 长会话形态不暴露;Claude Code 每次 `-p` 拉起独立无状态会话暴露(工具说明与守卫矛盾:read/算工具声称可先算后导) | Backlog:guard 按工具是否需工作区细分(session.ts 单点) |
72
+ | F7 | 宿主进程模型差异:Claude Code 每次 `-p` 独立 server 子进程(无状态),ZCode 长会话常驻 | 预期行为(宿主语义),两种形态 server 均健康(EOF 干净退出 3/3 已验) | 记档即可 |
73
+
74
+ **验证金字塔收官判定**:两宿主(ZCode + Claude Code)真机全绿 + 用户裁决跳过 Cursor——**发布决策输入齐备,npm publish 解禁**。
package/README.md ADDED
@@ -0,0 +1,223 @@
1
+ # mcp-server-gamenumerics
2
+
3
+ 游戏数值设计 Agent 工作站的 MCP(Model Context Protocol)形态——**read/算/审计面**的 stdio server。
4
+
5
+ 把本项目 agent harness 的 20+ 个零依赖纯函数数值引擎,以 **14 个只读数值工具 + 3 个会话 meta 工具**(共 17 个)带给任意 MCP 宿主(Claude Code / Cursor / ZCode 等):在开发者自己的 AI 编辑器里直接说「检查这份 HeroGrowth.xlsx 的数值曲线」,宿主 LLM 即可完成导入 → 查表 → 曲线审计的完整链路。
6
+
7
+ 核心叙事一句话:**LLM 负责理解、编排、解释;确定性引擎负责数值正确性**——所有数值结论都出自确定性纯函数,不依赖 LLM 心算。
8
+
9
+ ## 安装与启动
10
+
11
+ 前置:Node.js 18+。
12
+
13
+ **方式一:npx 免安装直跑(推荐,宿主配置推荐写法)**
14
+
15
+ ```bash
16
+ npx -y mcp-server-gamenumerics
17
+ ```
18
+
19
+ **方式二:全局安装**
20
+
21
+ ```bash
22
+ npm install -g mcp-server-gamenumerics
23
+ gnd-mcp # 本包配置了 bin: gnd-mcp,全局安装后直接以该命令启动
24
+ ```
25
+
26
+ **方式三:从源码运行(开发者路径)**
27
+
28
+ ```bash
29
+ # 在 mcp-server/ 目录内
30
+ npm install # 安装 @modelcontextprotocol/server
31
+ npm run build # esbuild bundle 出单文件 dist/index.js
32
+ node dist/index.js # 即 stdio server(stdin/stdout 通信,直接运行会等待输入,属正常)
33
+ ```
34
+
35
+ `npx .`(在 mcp-server/ 目录内)与 `node dist/index.js` 等价可用。
36
+
37
+ ## 环境变量
38
+
39
+ | 变量 | 说明 | 缺省 |
40
+ |------|------|------|
41
+ | `GND_WORKSPACES_DIR` | 工作区根目录(**建议绝对路径**;相对值按用户主目录解析,不依赖进程 cwd)——import_xlsx 装配产物落于此,写侧严格限于该目录内 | `~/.gamenumerics/workspaces` |
42
+
43
+ MCP 用户机器上无本仓库源码,工作区绝不落到仓库 `workspaces/` 目录。`import_xlsx` 只接受本地磁盘路径(UNC/网络路径 `//server/...` 前置拒绝——网络解析可能长时间阻塞进程)。
44
+
45
+ ## 宿主配置
46
+
47
+ 以下配置提供两种接入形态:`npx` 形式直接使用 npm 包(推荐,无需本仓库源码);本地路径形式供源码开发者使用,其中的 `<仓库绝对路径>` 替换为本仓库实际路径(Windows 路径正反斜杠均可)。
48
+
49
+ ### Claude Code
50
+
51
+ npx 形式(推荐):
52
+
53
+ ```bash
54
+ claude mcp add gamenumerics --env GND_WORKSPACES_DIR=D:/mcp-workspaces -- npx -y mcp-server-gamenumerics
55
+ ```
56
+
57
+ 本地路径形式(源码开发者用):
58
+
59
+ ```bash
60
+ claude mcp add gamenumerics -- node <仓库绝对路径>/mcp-server/dist/index.js
61
+ ```
62
+
63
+ 可选指定工作区根(本地路径形式;npx 形式同样加 `--env` 即可):
64
+
65
+ ```bash
66
+ claude mcp add gamenumerics --env GND_WORKSPACES_DIR=D:/mcp-workspaces -- node <仓库绝对路径>/mcp-server/dist/index.js
67
+ ```
68
+
69
+ ### Cursor
70
+
71
+ 项目级 `.cursor/mcp.json`(或用户级全局配置)。
72
+
73
+ npx 形式(推荐):
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "gamenumerics": {
79
+ "command": "npx",
80
+ "args": ["-y", "mcp-server-gamenumerics"],
81
+ "env": { "GND_WORKSPACES_DIR": "D:/mcp-workspaces" }
82
+ }
83
+ }
84
+ }
85
+ ```
86
+
87
+ 本地路径形式(源码开发者用):
88
+
89
+ ```json
90
+ {
91
+ "mcpServers": {
92
+ "gamenumerics": {
93
+ "command": "node",
94
+ "args": ["<仓库绝对路径>/mcp-server/dist/index.js"],
95
+ "env": { "GND_WORKSPACES_DIR": "D:/mcp-workspaces" }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### ZCode
102
+
103
+ 在 ZCode 的 MCP 配置(项目级 `.zcode/mcp.json` 或用户级配置文件,以所用版本文档为准)中加入同形态的 `mcpServers` 条目——`npx` 形式与本地 `node` 路径形式皆可。
104
+
105
+ npx 形式(推荐):
106
+
107
+ ```json
108
+ {
109
+ "mcpServers": {
110
+ "gamenumerics": {
111
+ "command": "npx",
112
+ "args": ["-y", "mcp-server-gamenumerics"],
113
+ "env": { "GND_WORKSPACES_DIR": "D:/mcp-workspaces" }
114
+ }
115
+ }
116
+ }
117
+ ```
118
+
119
+ 本地路径形式(源码开发者用):
120
+
121
+ ```json
122
+ {
123
+ "mcpServers": {
124
+ "gamenumerics": {
125
+ "command": "node",
126
+ "args": ["<仓库绝对路径>/mcp-server/dist/index.js"],
127
+ "env": { "GND_WORKSPACES_DIR": "D:/mcp-workspaces" }
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ 配置后重启宿主,工具列表中出现 `import_xlsx` / `list_tables` 等 17 个工具即接入成功。
134
+
135
+ ## 性能基线
136
+
137
+ | 指标 | 数值 |
138
+ |------|------|
139
+ | 冷启动(spawn → initialize → tools/list 全链) | ~150ms |
140
+ | 空闲内存(握手完成后单进程) | ~79MB |
141
+ | 工具面 | 17 个(14 映射 + 3 meta) |
142
+ | stdin 关闭 | 干净退出,无残留进程 |
143
+
144
+ 测量条件:Windows 11 / Node v24 / 单进程空闲态——数字随环境浮动。复现命令(仓库根目录):`npx tsx scripts/mcp-benchmark.ts`(3 轮独立子进程取中位)。
145
+
146
+ 内存大头是 Node.js 运行时基线(空进程 ~48MB),本包从 34 工具 registry 到 17 工具面的全链业务增量克制在 ~30MB——在「MCP server 动辄 100-200MB」是社区普遍抱怨的背景下,这是选型上的差异点。
147
+
148
+ ## 工具面清单(17 = 14 映射 + 3 meta)
149
+
150
+ ### 会话 meta 工具(3)
151
+
152
+ | 工具 | 职责 |
153
+ |------|------|
154
+ | `import_xlsx` | 从本地 xlsx(绝对路径)导入并创建工作区:双行表头合并「父.子」列名、数值列自动识别等差/等比/常数模式,成功后设为当前工作区 |
155
+ | `list_workspaces` | 列出工作区根下全部可用工作区 |
156
+ | `set_workspace` | 按名切换当前工作区(后续全部数值工具作用于它) |
157
+
158
+ ### 工作区读取(2)
159
+
160
+ | 工具 | 职责 |
161
+ |------|------|
162
+ | `list_tables` | 列出当前工作区全部数值表清单(表名/模块/行数/列名) |
163
+ | `read_table` | 读取指定表的数据行(支持列选择/条件过滤/分页) |
164
+
165
+ ### 数值计算与审计(8)
166
+
167
+ | 工具 | 职责 |
168
+ |------|------|
169
+ | `battle_simulate` | 战斗模拟(属性/伤害数值计算) |
170
+ | `simulate_gacha` | 抽卡概率计算 + Monte Carlo 模拟 |
171
+ | `compute_power` | 属性 → 战力(EHP×EDPS 解析式单源计算) |
172
+ | `power_curve` | 批量战力曲线(多属性组对比) |
173
+ | `eval_formula` | 求值数值公式表达式 |
174
+ | `audit_column` | 列对账:实际值 vs 生成规则期望值的偏离点审计 |
175
+ | `infer_column_rule` | 列规则逆向推断(Theil-Sen 稳健拟合等差/等比/幂律) |
176
+ | `infer_table_relation` | 列间派生关系推断(还原「各列 = 基准 × 系数」生成结构) |
177
+
178
+ ### 结构分析(3)
179
+
180
+ | 工具 | 职责 |
181
+ |------|------|
182
+ | `grade_workspace` | 工作区数值质量评分 |
183
+ | `profile_table` | 单表结构画像 |
184
+ | `infer_foreign_keys` | 表间外键关系推断 |
185
+
186
+ ### 记忆(1)
187
+
188
+ | 工具 | 职责 |
189
+ |------|------|
190
+ | `read_memory` | 读工作区记忆文件(PROFILE/facts,缺省回落公共 facts) |
191
+
192
+ > 面边界说明:本 MCP 形态只暴露只读面——写表/规划/问卷/交付导出等依赖人在回路确认面板、登录身份或前端 UI 载荷的工具不在 stdio 面提供。
193
+
194
+ ## 使用示例
195
+
196
+ 对话示例(任意 MCP 宿主中):
197
+
198
+ > **用户**:检查这份 D:/data/HeroGrowth.xlsx 的数值曲线
199
+
200
+ 宿主 LLM 的典型编排(工具调用链):
201
+
202
+ 1. `import_xlsx` `{ "xlsxPath": "D:/data/HeroGrowth.xlsx" }`
203
+ → 返回摘要:工作区 `HeroGrowth`、1 张表 `import/HeroGrowth`(3 行,双行表头探测 headerRows=2,`成长` 列为等比 1.1)
204
+ 2. `read_table` `{ "table": "import/HeroGrowth" }` → 读回行数据确认口径
205
+ 3. `infer_column_rule` 对 `成长` 列逆向拟合生成规则
206
+ 4. `audit_column` `{ "table": "import/HeroGrowth", "column": "成长", "rule": "<上一步推断的表达式>" }` → 对账偏离点(疑似手调值)
207
+
208
+ 若 headerRows 启发式探测失误(摘要回显可疑列名),在 `import_xlsx` 显式传 `"sheets": [{ "sheet": "HeroGrowth", "headerRows": 1 }]` 重试即可。
209
+
210
+ ## 开发
211
+
212
+ ```bash
213
+ # 类型检查(mcp-server 自带独立 tsconfig,根 tsc exclude 本目录)
214
+ npm run check
215
+
216
+ # 单测(经根仓库 vitest 收集:npm test,文件级 @vitest-environment node)
217
+ cd .. && npx vitest run mcp-server/__tests__/
218
+
219
+ # 真机冒烟(stdio 子进程拉起 dist/index.js 全链路,不进 CI;上一行 cd .. 后即处于仓库根目录)
220
+ npx tsx scripts/mcp-smoke.ts
221
+ ```
222
+
223
+ 架构一页纸见仓库 `docs/agent-harness-architecture.md`;本包 Spec 见 `docs/specs/v9-w2-mcp-server-spec.md`。
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "mcp-server-gamenumerics",
3
+ "version": "0.1.0",
4
+ "description": "游戏数值设计 MCP server——17 个确定性数值工具(查表/算力/审计/导入)接入任意 MCP 宿主(Claude Code / Cursor / ZCode 等)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/26048608982lp-ai/aigamedesign.git",
10
+ "directory": "mcp-server"
11
+ },
12
+ "keywords": [
13
+ "mcp",
14
+ "model-context-protocol",
15
+ "game-design",
16
+ "game-numerics",
17
+ "roguelike",
18
+ "balance",
19
+ "spreadsheet",
20
+ "xlsx"
21
+ ],
22
+ "bin": {
23
+ "gnd-mcp": "dist/index.js"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "HOST-VERIFICATION.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "node -e \"require('esbuild').buildSync({entryPoints:['src/index.ts'],bundle:true,platform:'node',format:'esm',outfile:'dist/index.js',banner:{js:`#!/usr/bin/env node\\nimport { createRequire } from 'module'; const require = createRequire(import.meta.url);`}})\"",
32
+ "prepublishOnly": "npm run build",
33
+ "check": "tsc --noEmit"
34
+ },
35
+ "dependencies": {
36
+ "@modelcontextprotocol/server": "^2.0.0",
37
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
38
+ },
39
+ "devDependencies": {
40
+ "esbuild": "^0.28.2"
41
+ }
42
+ }