Skip to content

Conversation

@ericglau
Copy link
Member

Fixes #626

This allows consumers to import the functions as

import { registerSolidityTools } from "@openzeppelin/contracts-mcp";

rather than

import { registerSolidityTools } from "@openzeppelin/contracts-mcp/src/solidity/tools";

@ericglau ericglau requested a review from a team as a code owner August 13, 2025 21:36
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 13, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Removes import-time MCP server startup, adds a dedicated CLI entrypoint, re-exports language-specific MCP tool registration functions from the package entry, updates package.json packaging fields, and adds two changeset files for minor releases.

Changes

Cohort / File(s) Summary
Release metadata
/.changeset/famous-masks-cheat.md, /.changeset/loud-clowns-divide.md
Add two changeset files: one to bump @openzeppelin/contracts-mcp (note: "Export functions to register MCP tools") and one to bump @openzeppelin/wizard-common.
Packaging / manifest
/packages/mcp/package.json
Add top-level types field (dist/index.d.ts) and update bin.contracts-mcp to point to dist/cli.js.
CLI entrypoint
/packages/mcp/src/cli.ts
New CLI script with Node shebang that creates StdioServerTransport, constructs the MCP server via createServer, connects the server to the transport, and logs startup failures.
Library refactor and exports
/packages/mcp/src/index.ts
Remove import-time side effects and executable bootstrap; replace with pure re-exports: registerSolidityTools, registerCairoTools, registerStellarTools, registerStylusTools.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI
  participant StdioTransport
  participant ServerFactory

  User->>CLI: run contracts-mcp
  CLI->>StdioTransport: new StdioServerTransport()
  CLI->>ServerFactory: createServer()
  CLI->>ServerFactory: server.connect(transport)
  StdioTransport-->>ServerFactory: exchange messages
Loading
sequenceDiagram
  participant Consumer
  participant Library
  participant Server

  Consumer->>Library: import { register*Tools }
  Consumer->>Server: register*Tools(server)
  Note over Consumer,Library: import has no side effects
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Assessment against linked issues

Objective Addressed Explanation
Export MCP tool registration functions [#626]

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Add changeset for @openzeppelin/wizard-common (/.changeset/loud-clowns-divide.md) This changeset bumps a different package unrelated to exporting MCP registration functions in #626.
Add types and update bin in /packages/mcp/package.json Packaging metadata changes (types/bin) are ancillary to #626 and not required to expose the registration functions.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the "Integrations" page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02dd44b and 493da8f.

📒 Files selected for processing (1)
  • packages/mcp/src/cli.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/mcp/src/cli.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Redirect rules - openzeppelin-contracts-wizard
  • GitHub Check: build (stellar, compile)
  • GitHub Check: build (solidity, default)
  • GitHub Check: Header rules - openzeppelin-contracts-wizard
  • GitHub Check: Pages changed - openzeppelin-contracts-wizard
  • GitHub Check: semgrep-cloud-platform/scan
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@qodo-merge-pro
Copy link

User description

Fixes #626

This allows consumers to import the functions as

import { registerSolidityTools } from "@openzeppelin/contracts-mcp";

rather than

import { registerSolidityTools } from "@openzeppelin/contracts-mcp/src/solidity/tools";

PR Type

Enhancement


Description

  • Export MCP register tools functions from main package entry

  • Separate CLI functionality into dedicated file

  • Update package.json with proper exports configuration

  • Add TypeScript type definitions support


Diagram Walkthrough

flowchart LR
  A["CLI code"] --> B["Separate cli.ts file"]
  C["index.ts"] --> D["Export register functions"]
  E["package.json"] --> F["Update exports & bin config"]
Loading

File Walkthrough

Relevant files
Enhancement
cli.ts
Create dedicated CLI entry point                                                 

packages/mcp/src/cli.ts

  • Create new CLI entry point file
  • Move server startup logic from index.ts
  • Set up stdio transport for MCP server
+11/-0   
index.ts
Transform to library exports module                                           

packages/mcp/src/index.ts

  • Remove CLI startup code
  • Export registerSolidityTools function
  • Export registerCairoTools, registerStellarTools, registerStylusTools
    functions
+4/-11   
Miscellaneous
famous-masks-cheat.md
Add changeset for MCP package                                                       

.changeset/famous-masks-cheat.md

  • Add changeset for minor version bump
  • Document export of MCP tools registration functions
+5/-0     
loud-clowns-divide.md
Add changeset for common package                                                 

.changeset/loud-clowns-divide.md

  • Add changeset for wizard-common minor bump
  • Ensure semantic versioning stability
+5/-0     
Configuration changes
package.json
Update package configuration for library exports                 

packages/mcp/package.json

  • Update bin path to point to cli.js instead of index.js
  • Add types field and exports configuration
  • Configure proper module exports for library usage
+11/-2   

@qodo-merge-pro
Copy link

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

🎫 Ticket compliance analysis ✅

626 - Fully compliant

Compliant requirements:

  • Export language-specific MCP tool registration functions so downstream packages can consume them.
  • Provide a stable TypeScript API for other MCP servers (e.g., openzeppelin-mcp) to import these functions directly from the package root.
⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

API Surface

Ensure that the exported register functions have stable names and types across subpackages and that re-exports don't cause circular deps or unintended tree-shaking issues.

export { registerSolidityTools } from './solidity/tools';
export { registerCairoTools } from './cairo/tools';
export { registerStellarTools } from './stellar/tools';
export { registerStylusTools } from './stylus/tools';
Exports Config

Validate that the "exports" field aligns with consumers using ESM and CJS; consider adding "import" condition if ESM entry differs and ensure type definitions resolve correctly.

"exports": {
  ".": {
    "types": "./dist/index.d.ts",
    "require": "./dist/index.js",
    "default": "./dist/index.js"
  },
  "./package.json": "./package.json"
},
CLI Entry Move

Verify build outputs map CLI to dist/cli.js and that createServer is side-effect free when imported; ensure bin previously pointing to index is updated in all docs/scripts.

#!/usr/bin/env node

import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { createServer } from './server';

// Start receiving messages on stdin and sending messages on stdout
const transport = new StdioServerTransport();
(async () => {
  const server = createServer();
  await server.connect(transport);
})();

@socket-security
Copy link

socket-security bot commented Aug 13, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​openzeppelin/​hardhat-upgrades@​3.9.19910010089100
Added@​openzeppelin/​contracts-upgradeable@​5.4.010010010094100

View full report

@qodo-merge-pro
Copy link

qodo-merge-pro bot commented Aug 13, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Preserve CLI entry compatibility

Changing the bin from dist/index.js to dist/cli.js without a fallback may break
existing users invoking contracts-mcp directly or importing index for CLI
behavior. Consider keeping dist/index.js as a thin wrapper that re-exports types
and tools but also preserves the previous CLI entry (or provide a compatibility
shim and clear deprecation path) to avoid disruptive runtime breakage.

Examples:

packages/mcp/src/index.ts [1-5]
export { registerSolidityTools } from './solidity/tools';
export { registerCairoTools } from './cairo/tools';
export { registerStellarTools } from './stellar/tools';
export { registerStylusTools } from './stylus/tools';
packages/mcp/package.json [9-11]
"bin": {
  "contracts-mcp": "dist/cli.js"
},

Solution Walkthrough:

Before:

// packages/mcp/src/index.ts
// This file is the CLI entry point.
#!/usr/bin/env node
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { createServer } from './server';

(async () => {
  const server = createServer();
  await server.connect(new StdioServerTransport());
})();

After:

// packages/mcp/src/index.ts
// This file now serves as both a library and a CLI entry point.
export { registerSolidityTools } from './solidity/tools';
export { registerCairoTools } from './cairo/tools';
// ... other exports

// The CLI logic is imported and executed to maintain backward compatibility.
import './cli';
Suggestion importance[1-10]: 9

__

Why: This suggestion correctly identifies a significant breaking change where altering the bin entry in package.json and removing executable logic from index.ts can disrupt existing user workflows.

High
Possible issue
Add robust error handling
Suggestion Impact:The commit refactored startup into an async main() and added a .catch that logs an error and exits with code 1, addressing the request to fail fast on startup errors. It did not add a global unhandledRejection handler or an inner try/catch, but it implemented the core error handling intent.

code diff:

+async function main() {
+  const transport = new StdioServerTransport();
   const server = createServer();
   await server.connect(transport);
-})();
+  console.log("OpenZeppelin Contracts MCP Server is running...");
+}
+
+main().catch((error) => {
+  console.error("Failed to start OpenZeppelin Contracts MCP Server:", error);
+  process.exit(1);
+});

Ensure the process exits with a non-zero code if server connection fails to
avoid silent failures. Also handle unhandled rejections to prevent the process
from hanging without feedback.

packages/mcp/src/cli.ts [1-11]

 #!/usr/bin/env node
 
 import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
 import { createServer } from './server';
 
 // Start receiving messages on stdin and sending messages on stdout
 const transport = new StdioServerTransport();
 (async () => {
-  const server = createServer();
-  await server.connect(transport);
-})();
+  try {
+    const server = createServer();
+    await server.connect(transport);
+  } catch (err) {
+    console.error('Failed to start MCP server:', err);
+    process.exit(1);
+  }
+})().catch((err) => {
+  console.error('Unhandled error starting MCP server:', err);
+  process.exit(1);
+});
 
+process.on('unhandledRejection', (reason) => {
+  console.error('Unhandled promise rejection:', reason);
+  process.exit(1);
+});
+

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies that the new CLI script lacks error handling, and proposes adding try/catch and unhandledRejection handlers, which is a good practice for robust CLI tools.

Medium
General
Export CLI entry path

Ensure the CLI entry is marked as executable by including a proper build step or
file permission, and declare the CLI in exports for Node’s package exports
resolution. Without exporting the CLI path, some tooling might not resolve it
when using exports-only packages.

packages/mcp/package.json [1-23]

 {
   "name": "@openzeppelin/contracts-mcp",
   "version": "0.0.7",
   "description": "OpenZeppelin Contracts MCP Server",
   "license": "AGPL-3.0-only",
   "repository": "https://github.com/OpenZeppelin/contracts-wizard",
   "main": "dist/index.js",
   "types": "dist/index.d.ts",
   "bin": {
     "contracts-mcp": "dist/cli.js"
   },
   "exports": {
     ".": {
       "types": "./dist/index.d.ts",
       "require": "./dist/index.js",
       "default": "./dist/index.js"
     },
+    "./cli": {
+      "require": "./dist/cli.js",
+      "default": "./dist/cli.js"
+    },
     "./package.json": "./package.json"
   },
   "ts:main": "src/index.ts",
   "files": [
-    ...
+    "dist/",
+    "src/",
+    "package.json",
+    "README.md",
+    "LICENSE"
   ]
 }

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 2

__

Why: The suggestion to add the CLI path to the exports field is unnecessary, as the bin field is the standard and sufficient way to declare package executables for Node.js and package managers.

Low
  • Update

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
.changeset/loud-clowns-divide.md (1)

1-6: Clarify the rationale for the minor bump (nit).

If there’s no API change in wizard-common, consider adding a brief reason (e.g., alignment with MCP publishing cadence or dependency surface consistency) to aid future maintainers.

packages/mcp/package.json (1)

12-18: Consider adding an engines constraint.

The MCP SDK typically targets modern Node versions. Add an "engines" field (e.g., Node >= 18) to make failures explicit during install if a user is on an unsupported runtime.

Add outside the shown block:

"engines": {
  "node": ">=18"
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2bb2a16 and 4318128.

📒 Files selected for processing (5)
  • .changeset/famous-masks-cheat.md (1 hunks)
  • .changeset/loud-clowns-divide.md (1 hunks)
  • packages/mcp/package.json (2 hunks)
  • packages/mcp/src/cli.ts (1 hunks)
  • packages/mcp/src/index.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
packages/mcp/src/cli.ts (1)
packages/mcp/src/server.ts (1)
  • createServer (8-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Redirect rules - openzeppelin-contracts-wizard
  • GitHub Check: Header rules - openzeppelin-contracts-wizard
  • GitHub Check: Pages changed - openzeppelin-contracts-wizard
  • GitHub Check: build (solidity, default)
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
.changeset/famous-masks-cheat.md (1)

1-6: Release note is accurate and scoped.

This changeset clearly communicates the minor bump to export the MCP tools registration functions. Good alignment with the PR’s objective.

packages/mcp/src/cli.ts (2)

3-4: No change required — package is CommonJS so explicit “.js” is not needed

Summary: packages/mcp/tsconfig.json sets "module": "commonjs" and packages/mcp/package.json does not declare "type":"module" (it's null), so the current relative import without a ".js" extension is fine. If you later migrate this package to ESM/NodeNext, update the import to "./server.js" and adjust moduleResolution.

Files to note:

  • packages/mcp/src/cli.ts
    import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
    import { createServer } from './server';
    

1-1: Shebang preservation check — build not run; cannot verify dist/cli.js

The compiled file packages/mcp/dist/cli.js was not found when I ran the verification script, so I couldn't confirm the shebang is preserved in the build output.

  • packages/mcp/src/cli.ts — contains "#!/usr/bin/env node" (source).
  • packages/mcp/dist/cli.js — missing; run the build and re-check.

Run locally to verify:

pnpm -w -r build
if [ -f packages/mcp/dist/cli.js ]; then head -n 1 packages/mcp/dist/cli.js; else echo "dist/cli.js not found; build step likely not run."; fi
packages/mcp/src/index.ts (1)

1-4: LGTM: clean, side‑effect‑free re‑exports.

This meets the PR goal of exposing registration functions from the package root. Nice separation from the CLI bootstrap.

packages/mcp/package.json (1)

8-8: Top-level types exposure looks good.

The "types" field correctly points at the declaration entry for root exports and aligns with the re-exports in src/index.ts.

Comment on lines 12 to 18
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"default": "./dist/index.js"
},
"./package.json": "./package.json"
Copy link
Contributor

@coderabbitai coderabbitai bot Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

ESM named import compatibility: add an “import” export or ship an ESM build.

The PR’s usage example is import { registerSolidityTools } from "@openzeppelin/contracts-mcp". With the current exports map only specifying “require” and “default” (and likely emitting CJS), ESM consumers may not get named exports at runtime. Node ESM treats CJS as a default-only export.

Options:

  • Preferred: dual publish with ESM and CJS, and wire exports accordingly.
  • Minimal: add an "import" condition. This alone won’t enable named exports if the target is CJS, but it’s a step if you later emit ESM.

Apply at least this minimal change:

   "exports": {
     ".": {
       "types": "./dist/index.d.ts",
-      "require": "./dist/index.js",
-      "default": "./dist/index.js"
+      "import": "./dist/index.js",
+      "require": "./dist/index.js",
+      "default": "./dist/index.js"
     },
     "./package.json": "./package.json"
   },

If you can emit dual outputs, wire like this and update your build scripts:

   "exports": {
     ".": {
       "types": "./dist/index.d.ts",
-      "require": "./dist/index.js",
-      "default": "./dist/index.js"
+      "import": "./dist/index.js",
+      "require": "./dist/index.cjs"
     },
     "./package.json": "./package.json"
   },

Verification script to check module targets across the repo:


🏁 Script executed:

#!/bin/bash
# Show package type, exports, and bin for MCP
echo "packages/mcp/package.json:"
cat packages/mcp/package.json | jq '{ name, type, main, exports, bin }'

# Inspect TS configs to determine module target
fd -a --hidden --exclude node_modules 'tsconfig*.json' \
  | while read -r f; do echo "==> $f"; cat "$f"; echo; done

# Find any relative imports without .js that would need updates for ESM NodeNext
rg -n "from '\\./[^']+'|from \\"\\./[^\\"]+\\"" packages/mcp/src | sed 's/^/RELATIVE IMPORT: /'

Length of output: 4847


ESM named-imports will break for ESM consumers — emit ESM or add an import export

Verified: packages/mcp/package.json only exposes "require" and "default" and packages/mcp/tsconfig.json sets "module": "commonjs". The package is being built as CommonJS, so Node ESM consumers doing import { ... } from "@openzeppelin/contracts-mcp" will not get named exports at runtime.

Files to change:

  • packages/mcp/package.json — exports map (currently missing "import")
  • packages/mcp/tsconfig.json / build pipeline — currently emits CommonJS

Minimal change (adds an "import" condition; note: pointing it at a CJS file does NOT enable true named ESM exports at runtime, it's only preparatory):

"exports": {
".": {
"types": "./dist/index.d.ts",

  • "require": "./dist/index.js",
    
  • "default": "./dist/index.js"
    
  • "import": "./dist/index.js",
    
  • "require": "./dist/index.js",
    
  • "default": "./dist/index.js"
    
    },
    "./package.json": "./package.json"
    },

Preferred fix (publish dual outputs: ESM + CJS, update build to emit ESM and CJS and wire exports accordingly):

"exports": {
".": {
"types": "./dist/index.d.ts",

  • "require": "./dist/index.js",
    
  • "default": "./dist/index.js"
    
  • "import": "./dist/index.js",     # ESM build
    
  • "require": "./dist/index.cjs"    # CJS build
    
    },
    "./package.json": "./package.json"
    },

Action required: produce an actual ESM build (or dual builds) and update exports as above; adding "import" to point at a CJS artifact alone will not fix named-export behavior for ESM consumers.

🤖 Prompt for AI Agents
packages/mcp/package.json lines 12-18: the exports map only exposes "require"
and "default" while the package is built as CommonJS, which breaks named ESM
imports; to fix, add an "import" condition and produce real ESM output
(preferred: dual ESM+CJS). Change the exports to include an "import" entry
pointing at the ESM build and keep "require" pointing at the CJS build, update
package "type" or file extensions accordingly, then update the build
pipeline/tsconfig to emit both module formats (e.g., add an ES module target in
tsconfig or add a separate rollup/tsc step to emit dist/index.mjs (or .js under
"module":"ESNext") and dist/index.cjs), adjust package.json build scripts to
produce both artifacts, and finally update exports to map
"import"->dist/index.mjs (ESM) and "require"->dist/index.cjs (CJS).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the exports section instead. assess.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ask

removed the exports section instead. assess.

Answer:

Assessment:

  • The PR did not remove exports; it refactored index.ts to export the MCP tool registration functions at the package root:
    • Added named exports: registerSolidityTools, registerCairoTools, registerStellarTools, registerStylusTools.
    • This enables consumers to import from "@openzeppelin/contracts-mcp" as intended in the PR description.
  • The server startup code previously in src/index.ts was moved to a new src/cli.ts, and package.json’s "bin" now points to dist/cli.js. This cleanly separates the CLI entry point from the library exports.
  • package.json adds "types": "dist/index.d.ts" to provide TypeScript typings for the new public API.

Impact:

  • Breaking change for consumers who relied on the package default behavior of starting the MCP server when importing the module. Now, importing the package will only provide exports; it won’t start a server. However, CLI usage via contracts-mcp remains intact via the new cli.js.
  • Positive change for downstream packages: they can import registration functions directly from the package root rather than deep paths.

Suggestions:

  • Confirm there are no other symbols that should be exported at the root (e.g., any shared types used by the registration functions) to provide a complete public API.
  • Add a brief README section:
    • How to run the server via CLI (unchanged).
    • How to programmatically register tools:
      import { registerSolidityTools } from "@openzeppelin/contracts-mcp";
    • Note the change in behavior: importing the package no longer boots a server.
  • Ensure the build emits dist/cli.js and dist/index.d.ts. The tsconfig and build scripts should include src/cli.ts and generate type declarations for src/index.ts.
  • Consider a deprecation note or minor version bump (already included via changesets) explaining the change in entrypoint behavior for users who might have imported the package expecting side effects.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipped: comment is from another GitHub bot.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the current state of packages/mcp/package.json after exports removal
echo "=== Current packages/mcp/package.json ==="
cat packages/mcp/package.json

echo -e "\n=== Check if index.ts properly exports the functions ==="
cat packages/mcp/src/index.ts

echo -e "\n=== Verify TypeScript configuration ==="
cat packages/mcp/tsconfig.json | jq '{ compilerOptions: { module: .compilerOptions.module, target: .compilerOptions.target, moduleResolution: .compilerOptions.moduleResolution } }'

echo -e "\n=== Check what gets built in dist/ ==="
ls -la packages/mcp/dist/ 2>/dev/null || echo "dist/ directory not found"

Length of output: 2110


@ericglau Removing the exports section is actually a reasonable pragmatic approach that should work for your use case.

Assessment: ✅ This should work

Why this approach works:

  • Node.js falls back to legacy "main" field resolution (dist/index.js)
  • Your src/index.ts properly exports the functions with named exports
  • Modern Node.js versions handle named imports from CommonJS modules when using legacy resolution
  • ESM consumers should be able to use import { registerSolidityTools } from "@openzeppelin/contracts-mcp"

Tradeoffs vs. the original exports approach:

  • Simpler: Avoids the complexity of dual ESM/CJS publishing
  • Works now: Should handle the immediate need for named imports
  • ⚠️ Less explicit: Relies on Node.js interop rather than explicit module resolution
  • ⚠️ Future-proofing: Less control over how different environments resolve the module

Alternative considered: The original suggestion to add proper ESM support would be more robust long-term, but this simplified approach should meet your current requirements without the additional build complexity.

Your approach prioritizes pragmatism over theoretical completeness, which makes sense for this PR's scope.

@socket-security
Copy link

socket-security bot commented Aug 13, 2025

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

Ignoring alerts on:

  • base-x@3.0.10

View full report

@ericglau
Copy link
Member Author

ericglau commented Aug 14, 2025

@SocketSecurity ignore npm/base-x@3.0.10
To be addressed in #633

@ericglau
Copy link
Member Author

@SocketSecurity ignore npm/cookie@0.4.2
@SocketSecurity ignore npm/undici@5.29.0
These are Hardhat dependencies.

@ericglau ericglau merged commit c65acb7 into OpenZeppelin:master Aug 15, 2025
18 checks passed
@ericglau ericglau deleted the exportregistertools branch August 15, 2025 14:10
@github-actions github-actions bot locked and limited conversation to collaborators Aug 15, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export MCP tool registration functions

3 participants