fix(generate): preserve exact tool names in generated calls - #353
Conversation
…ames toProxyMethodName camelCases a tool name without checking that the result can start an identifier, and lowercasing a digit is a no-op. Both codegen sites splice that name into bare dot access, so a server advertising a tool such as 1password_get_item makes generate-cli and emit-ts --mode client emit `proxy.1passwordGetItem`, and the generated module does not parse. Guard the identifier start the way emit-ts-templates.ts already guards the interface member name with SAFE_IDENTIFIER, prefixing an underscore when the camelCased name cannot begin one. buildToolMetadataList already throws on a methodName collision, so the prefix cannot silently merge two tools.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. Reviewed September 11, 2026, 5:36 PM ET / 21:36 UTC (Revision 4). ClawSweeper reviewWhat this changesPreserves advertised MCP tool names in generated CLIs and TypeScript clients, with exact-name proxy dispatch and regression coverage for unusual names and alias collisions. Merge readiness✅ Ready for maintainer review This remains a useful, mergeable repair: current main and v0.13.11 still contain the generation defect. The earlier metadata-collision finding is resolved, and the maintainer’s real stdio verification supports the repaired behavior. No blocking introduced defect was found. Priority: P2 Review scores
Verification
How this fits togetherMCPorter generates command-line tools and TypeScript clients from MCP server metadata. Their calls pass through a runtime proxy that resolves tool names, applies schema defaults, and invokes the server. flowchart LR
A[MCP tool names and schemas] --> B[CLI and client generators]
B --> C[Quoted tool access]
C --> D[Runtime proxy]
D --> E[Exact name or loose alias]
E --> F[Schema defaults and validation]
F --> G[MCP server call]
Before mergeNone. Agent review detailsSecurityNone. Review metrics
Technical reviewBest possible solution: Keep metadata identities stable while generating valid access syntax and resolving each advertised name to its own tool and schema. Do we have a high-confidence way to reproduce the issue? Yes: current main interpolates a digit-leading metadata name into dot access, producing invalid generated syntax. Source inspection establishes the path; the supplied maintainer report independently describes failing main regressions. Is this the best way to solve the issue? Yes: quoting advertised names at generation sites avoids changing shared metadata, and exact-name resolution prevents loose aliases from redirecting those calls. Existing direct-call APIs do not by themselves repair generated artifacts. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against c66549857341. LabelsLabel changes:
Label justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (3 earlier review cycles)
|
Keep shared metadata stable, quote generated access, and preserve exact proxy names and schemas across alias collisions. Co-authored-by: Mohammed Alkindi <alkndymhmd692@gmail.com>
|
Maintainer live proof for the repaired branch: Used the built
The initial bracket-only repair exposed a second issue during this live run: loose proxy aliases sent the underscore-prefixed tool to the unprefixed one. The final repair uses exact advertised names and gives those precedence over loose aliases. Regression coverage exercises both cold discovery and preloaded schemas, while retaining ordinary camelCase aliases and custom mapper behavior.
A separate real runtime/proxy integration advertised both |
Generated CLIs and typed clients fail to parse when a tool name starts with a digit. Changing the shared metadata name to add a leading underscore also makes previously distinct tools collide and disappear from discovery or types-only output.
This repair preserves metadata names and quotes the exact advertised tool name in both generators. The default runtime proxy prefers exact advertised names before its loose aliases, including after cold schema discovery, so tools such as
1password_get_itemand__1password_get_itemreach distinct MCP methods. Inherited JavaScript properties no longer hide advertised tools. Schemas are stored under exact names, so aliases cannot overwrite another tool’s defaults. Custom property mappers retain their existing behavior. The schema-default test uses the advertised dashed names and disables disk caching so its alias assertion is independent of earlier cache writes.Validation:
pnpm checkandpnpm test --maxWorkers=4pass: 220 files, 1,941 tests, 26 existing opt-in/skipped cases.1password_get_item,__1password_get_item,tools.search,__proto__, and__defineGetter__. Discovery and emitted declarations retain all five.generate-cli --bundleandemit-ts --mode clientproduce runnable artifacts; all ten generated calls reach the exact requested MCP method.900fc62fe08b47bab447531219d46fdf31ba035a: https://github.com/openclaw/mcporter/actions/runs/34649451208.Thanks @MohammedAlkindi for identifying the generation defect and supplying the original regression. Changelog credit is carried in the final consolidated notes PR so this branch remains independent.