Skip to content

refactor: modularize tools into individual modules with build-time definitions #356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 8, 2025

Conversation

dcramer
Copy link
Member

@dcramer dcramer commented Jul 8, 2025

  • Split monolithic tools.ts into individual tool modules
  • Each tool module uses defineTool helper for consistency
  • Create build-time generation of toolDefinitions.json
  • Update mcp-cloudflare to use generated definitions
  • Remove toolDefinitions.ts in favor of build-time generation
  • Add comprehensive refactoring documentation

This refactoring improves maintainability by:

  • Limiting tool files to ~200 lines for better AI agent context
  • Using type-safe defineTool helper pattern
  • Generating client-safe definitions without server dependencies
  • Following one-tool-per-file architecture

🤖 Generated with Claude Code

…finitions

- Split monolithic tools.ts into 19 individual tool modules
- Each tool module uses defineTool helper for consistency
- Create build-time generation of toolDefinitions.json
- Update mcp-cloudflare to use generated definitions
- Remove toolDefinitions.ts in favor of build-time generation
- Add comprehensive refactoring documentation

This refactoring improves maintainability by:
- Limiting tool files to ~200 lines for better AI agent context
- Using type-safe defineTool helper pattern
- Generating client-safe definitions without server dependencies
- Following one-tool-per-file architecture

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Copy link

codecov bot commented Jul 8, 2025

Codecov Report

Attention: Patch coverage is 75.73604% with 478 lines in your changes missing coverage. Please review.

Project coverage is 58.79%. Comparing base (409f4a3) to head (c4cbbc2).
Report is 1 commits behind head on main.

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/mcp-server/src/server.ts 0.00% 103 Missing ⚠️
...es/mcp-server/scripts/generate-tool-definitions.ts 1.33% 74 Missing ⚠️
...es/mcp-server/src/tools/analyze-issue-with-seer.ts 58.04% 73 Missing ⚠️
packages/mcp-server/src/tools/utils/seer-utils.ts 46.87% 51 Missing ⚠️
packages/mcp-server/src/tools/index.ts 0.00% 40 Missing ⚠️
packages/mcp-server/src/tools/find-releases.ts 74.01% 33 Missing ⚠️
packages/mcp-server/src/tools/get-doc.ts 88.57% 12 Missing ⚠️
packages/mcp-server/src/tools/get-issue-details.ts 89.47% 12 Missing ⚠️
packages/mcp-server/src/tools/update-project.ts 91.11% 12 Missing ⚠️
packages/mcp-server/src/tools/utils/api-utils.ts 68.57% 11 Missing ⚠️
... and 13 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #356      +/-   ##
==========================================
- Coverage   59.70%   58.79%   -0.91%     
==========================================
  Files          51       77      +26     
  Lines        6159     6414     +255     
  Branches      477      481       +4     
==========================================
+ Hits         3677     3771      +94     
- Misses       2482     2643     +161     
Flag Coverage Δ
evals 74.54% <ø> (ø)
unittests 58.51% <75.73%> (-0.92%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: JSON Schema Conversion Breaks Description Access

The client code attempts to access value.description for properties within tool.inputSchema. This inputSchema is now a JSON Schema generated from a Zod schema using zod-to-json-schema. The conversion process alters the schema structure such that the description property is no longer directly accessible via value.description, leading to runtime errors when rendering tool documentation. An explicit [string, any] type annotation was added to suppress TypeScript errors, masking this type incompatibility.

packages/mcp-cloudflare/src/client/pages/home.tsx#L166-L175

<dl className="space-y-3 mt-6">
{Object.entries(tool.inputSchema).map(
([key, value]: [string, any]) => {
return (
<div className="p-3 bg-black/30" key={key}>
<dt className="text-sm font-medium text-violet-300">
{key}
</dt>
<dd className="text-sm text-slate-300 mt-1">
{value.description}

Fix in CursorFix in Web


Was this report helpful? Give feedback by reacting with 👍 or 👎

@dcramer dcramer merged commit 23f5cdf into main Jul 8, 2025
13 checks passed
@dcramer dcramer deleted the ref-tool-module branch July 8, 2025 19:40
@rohan-at-sentry
Copy link

@sentry review

Copy link
Contributor

seer-by-sentry bot commented Jul 9, 2025

On it! We are reviewing the PR and will provide feedback shortly.

Copy link
Contributor

seer-by-sentry bot commented Jul 9, 2025

PR Description

This pull request refactors the MCP server's tool implementation from a monolithic structure to a modular one, improving code organization, maintainability, and scalability. It also introduces automated tool definition generation for client consumption.

Click to see more

Key Technical Changes

The core changes involve migrating tool definitions and handlers from centralized toolDefinitions.ts and tools.ts files to individual tool modules within the src/tools/ directory. Each tool now has its own module (e.g., src/tools/your-tool-name.ts) containing its definition, handler, and associated tests. A new generate-tool-definitions.ts script automates the creation of JSON schemas from these tool modules, which are then used by the MCP client. The server's tool registration logic has been updated to dynamically import and register tools from the new module structure.

Architecture Decisions

The primary architectural decision is to adopt a modular, file-based structure for tools. This promotes separation of concerns, improves code discoverability, and simplifies testing. The introduction of the defineTool utility enforces a consistent tool structure and provides type safety. The automated tool definition generation ensures that the client always has an up-to-date view of available tools and their parameters.

Dependencies and Interactions

This change impacts the MCP server's core components, including the server configuration (server.ts), API client usage (api-utils.ts), and documentation. The mcp-cloudflare client now relies on the generated toolDefinitions.js file. The build process is also affected, as it now includes the tool definition generation step. The changes also interact with the testing infrastructure, requiring updates to unit tests and mocks to align with the new module structure.

Risk Considerations

Potential risks include: 1) Errors during tool definition generation due to malformed tool modules. 2) Inconsistencies between the generated tool definitions and the actual tool implementations. 3) Compatibility issues with existing MCP clients that rely on the old tool definition format. 4) Increased complexity in managing and deploying individual tool modules. 5) The type assertions used in packages/mcp-server/src/resources.ts could lead to runtime errors if the resource configurations don't match the expected types.

Notable Implementation Details

The generate-tool-definitions.ts script uses zod-to-json-schema to convert Zod schemas to JSON schemas. The defineTool utility provides type safety and enforces a consistent tool structure. Error handling within the tool registration loop in server.ts has been improved to prevent a single tool registration failure from halting the entire server startup. The documentation has been updated to reflect the new tool development workflow and testing requirements.

Comment on lines +22 to +23
// Import tools from the source directory
const tools = await import("../src/tools/index.js");
Copy link
Contributor

Choose a reason for hiding this comment

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

The script lacks proper error handling for malformed tool modules. If a tool module exports an invalid structure or throws during import, the entire generation process will fail without clear error messages. Consider adding try-catch blocks around individual tool imports and validation to provide better error reporting.

Did we get this right? 👍 / 👎 to inform future reviews.

Comment on lines +28 to +44
function convertInputSchemaToJsonSchema(inputSchema: Record<string, any>) {
if (!inputSchema || Object.keys(inputSchema).length === 0) {
return {};
}

const properties: Record<string, any> = {};

// Convert each individual Zod schema to JSON Schema
for (const [key, zodSchema] of Object.entries(inputSchema)) {
const jsonSchema = zodToJsonSchema(zodSchema, {
$refStrategy: "none", // Don't use $ref for cleaner output
});
properties[key] = jsonSchema;
}

return properties;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The Zod schema conversion could fail silently or produce unexpected results for complex schemas. Consider adding validation to ensure the converted JSON schemas are valid and contain the expected properties before writing to disk.

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants