Skip to content

Modularize factory monolith#73

Merged
binit2-1 merged 14 commits intobinit2-1:mainfrom
Shreehari-Acharya:modularize-factory-monolith
Jan 23, 2026
Merged

Modularize factory monolith#73
binit2-1 merged 14 commits intobinit2-1:mainfrom
Shreehari-Acharya:modularize-factory-monolith

Conversation

@Shreehari-Acharya
Copy link
Collaborator


name: 🔧 Refactor
about: Code refactor with no functional changes

Description

This pull request refactors the packages/mcp package to improve modularity, maintainability, and type safety. The logic has been decoupled into dedicated service layers and utilities, and the tool registration system has been updated to use the modern MCP SDK patterns.

Related Issue

Closes #65 #67 #68 #69 #70

Motivation

The previous implementation of the MCP tools was becoming a monolithic file that was difficult to test and extend. As the number of supported tools grew, the complexity of managing natural language parsing, fuzzy matching, and API calls in a single location became a bottleneck.

Changes Made

Refactored Component and Category Management:

  • Moved data fetching logic into dedicated api.js and catalog.js service modules. This centralizes authenticated API requests and provides a cleaner interface for retrieving categories, components, and search results.

Optimized Query Processing & Fuzzy Matching:

  • Extracted natural language processing into nlp.js to handle query routing more efficiently.
  • Isolated fuzzy matching logic into a standalone fuzzy.js utility, ensuring consistent title and category resolution across all tools.

Modernized Tool Architecture:

  • Modular Registration: Split monolithic tool definitions into tools/general.js and tools/components.js.
  • SDK Migration: Updated all tools to use the server.registerTool syntax and modernized Zod schema patterns as supported by the latest @modelcontextprotocol/sdk.
  • Centralized Initialization: Introduced src/tools/index.js with a registerTools(server) function to streamline server setup.

Improved Formatting & Tooling:

  • Consolidated display logic into formatting.js to ensure uniform output for code blocks, dependency lists, and user guidance.
  • Added jsconfig.json to enhance IDE IntelliSense and type checking.
  • Upgraded zod to v3.24+ / v4.x to leverage improved schema validation and performance.

Impact

  • Performance improvement
  • Code readability
  • Maintainability
  • Reduced bundle size
  • Other:

Breaking Changes

  • This PR introduces breaking changes

How Has This Been Tested?

  • All existing tests pass
  • Manually tested affected features

Checklist

  • My code follows the project's style guidelines
  • I have tested my changes locally
  • No functional changes (refactor only)

Copilot AI review requested due to automatic review settings January 22, 2026 08:19
@vercel
Copy link

vercel bot commented Jan 22, 2026

@Shreehari-Acharya is attempting to deploy a commit to the binit2-1's projects Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the monolithic packages/mcp/lib/factory.js file into a modular architecture by splitting it into dedicated service layers, utilities, and tool registration modules. The refactoring aims to improve code maintainability and testability without introducing functional changes.

Changes:

  • Extracted API and catalog data fetching into separate service modules (api.js, catalog.js)
  • Isolated natural language processing, fuzzy matching, formatting, and regex patterns into utility modules
  • Split tool registration into modular files (tools/general.js, tools/components.js) with centralized initialization
  • Attempted to upgrade Zod dependency from v3.23.0 to v4.3.5
  • Added jsconfig.json for IDE support

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
packages/mcp/lib/factory.js Removed all implementation code, now only imports and delegates to tool registration
packages/mcp/src/services/api.js New service module for authenticated API requests
packages/mcp/src/services/catalog.js New service module for component and category data fetching
packages/mcp/src/utils/nlp.js New utility for natural language query processing
packages/mcp/src/utils/fuzzy.js New utility for fuzzy matching logic
packages/mcp/src/utils/formatting.js New utility for output formatting
packages/mcp/src/utils/regexPatterns.js New utility containing regex pattern definitions
packages/mcp/src/tools/index.js New entry point for tool registration
packages/mcp/src/tools/general.js New module for general tool registration
packages/mcp/src/tools/components.js New module for component-related tool registration
packages/mcp/package.json Updated Zod dependency version
package-lock.json Updated lock file with new Zod version
packages/mcp/jsconfig.json New configuration file for IDE type support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 22, 2026 08:24
Shreehari-Acharya and others added 2 commits January 22, 2026 13:55
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Shreehari-Acharya and others added 2 commits January 22, 2026 14:05
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings January 22, 2026 08:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +62 to +65
const normalized = title.toLowerCase();
const fuzzyMatch = categoryComponents?.find(c =>
c.title.toLowerCase().includes(normalized)
);
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The fuzzy matching logic here is inconsistent with the logic used in nlp.js (lines 108-111). This implementation only checks if the component title includes the normalized input in one direction, and uses simple toLowerCase() instead of the normalizeText() utility function.

For consistency and better matching behavior, this should use the normalizeText() function from fuzzy.js and check bidirectional inclusion, matching the pattern used in nlp.js.

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,26 @@
import { getAuthToken, getBaseUrl } from "../../lib/auth";
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The import statement is missing the .js file extension. In ES modules, it's a best practice to include file extensions in import statements. While Node.js may resolve this without the extension in some cases, explicit extensions improve clarity and avoid potential issues.

Consider changing to: import { getAuthToken, getBaseUrl } from "../../lib/auth.js";

Suggested change
import { getAuthToken, getBaseUrl } from "../../lib/auth";
import { getAuthToken, getBaseUrl } from "../../lib/auth.js";

Copilot uses AI. Check for mistakes.

let component = await getComponent(categoryName, title.trim());

// Fuzzy logic remains same
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

This comment states "Fuzzy logic remains same" but the fuzzy matching logic is actually inconsistent with the implementation in nlp.js. The comment is misleading because the logic here is simplified (using only toLowerCase() and one-directional matching) compared to the more sophisticated bidirectional matching with normalizeText() used elsewhere.

Consider updating this comment to accurately describe what the code does, or better yet, extract this logic into a shared utility function to ensure consistency.

Suggested change
// Fuzzy logic remains same
// Simple, case-insensitive, one-directional fuzzy match on component titles

Copilot uses AI. Check for mistakes.
Comment on lines +106 to +120
const categoryComponents = await getComponentsByCategory(categoryName);
if (categoryComponents) {
const normalized = normalizeText(titleInput);
const fuzzyMatch = categoryComponents.find(c =>
normalizeText(c.title).includes(normalized) ||
normalized.includes(normalizeText(c.title))
);
if (fuzzyMatch) {
component = await getComponent(categoryName, fuzzyMatch.title);
}
}
}

if (!component) {
const categoryComponents = await getComponentsByCategory(categoryName);
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The getComponentsByCategory function is called twice when a component is not found - once on line 106 for fuzzy matching, and again on line 120 for generating suggestions. This results in a redundant API call that impacts performance.

The result from line 106 should be cached and reused on line 120 to avoid the duplicate API call.

Copilot uses AI. Check for mistakes.
Comment on lines +117 to +134
if (component.dependencies && Object.keys(component.dependencies).length > 0) {
const deps = Object.entries(component.dependencies)
.map(([pkg, ver]) => ` • \`${pkg}\`: ${ver}`)
.join("\n");

const installCmd = Object.keys(component.dependencies).join(" ");
depsSection = `
---

### 📦 Dependencies

${deps}

**Install command:**
\`\`\`bash
npm install ${installCmd}
\`\`\`
`;
Copy link

Copilot AI Jan 22, 2026

Choose a reason for hiding this comment

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

The dependencies check assumes component.dependencies is already an object, but based on the getDepsCount function (lines 1-11), dependencies can be a string that needs to be parsed. This will cause a runtime error when trying to call Object.keys() on a string.

The code should parse the dependencies first if they are a string, similar to how it's done in getDepsCount.

Suggested change
if (component.dependencies && Object.keys(component.dependencies).length > 0) {
const deps = Object.entries(component.dependencies)
.map(([pkg, ver]) => ` • \`${pkg}\`: ${ver}`)
.join("\n");
const installCmd = Object.keys(component.dependencies).join(" ");
depsSection = `
---
### 📦 Dependencies
${deps}
**Install command:**
\`\`\`bash
npm install ${installCmd}
\`\`\`
`;
if (component.dependencies) {
try {
const deps = typeof component.dependencies === "string"
? JSON.parse(component.dependencies)
: component.dependencies;
if (deps && typeof deps === "object" && !Array.isArray(deps) && Object.keys(deps).length > 0) {
const depsList = Object.entries(deps)
.map(([pkg, ver]) => ` • \`${pkg}\`: ${ver}`)
.join("\n");
const installCmd = Object.keys(deps).join(" ");
depsSection = `
---
### 📦 Dependencies
${depsList}
**Install command:**
\`\`\`bash
npm install ${installCmd}
\`\`\`
`;
}
} catch {
// If dependencies cannot be parsed, skip the dependencies section
}

Copilot uses AI. Check for mistakes.
@binit2-1 binit2-1 merged commit 273dbc0 into binit2-1:main Jan 23, 2026
1 of 3 checks passed
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.

[REFACTOR] Modularize factory.js Monolith

3 participants