LearnNewsExamplesServices
Frontmatter
id7950
titleRefactor ToolService to Class-based Architecture
stateClosed
labels
enhancementairefactoring
assigneestobiu
createdAtNov 30, 2025, 3:38 PM
updatedAtNov 30, 2025, 4:10 PM
githubUrlhttps://github.com/neomjs/neo/issues/7950
authortobiu
commentsCount1
parentIssue7931
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtNov 30, 2025, 4:10 PM

Refactor ToolService to Class-based Architecture

Closed v11.14.0 enhancementairefactoring
tobiu
tobiu commented on Nov 30, 2025, 3:38 PM

Context

In #7949, we moved toolService.mjs to a shared location to support client-side validation. However, the service remains a singleton module with module-level state (toolMapping). This prevents a single process (like an Agent) from initializing multiple internal server contexts (Zod schemas) simultaneously, as subsequent initializations overwrite the global state.

Goal

Refactor ai/mcp/toolService.mjs into a class-based Neo.ai.mcp.ToolService extending Neo.core.Base. This allows each Server or Client connection to maintain its own independent tool registry and validation context.

Requirements

  1. Rename & Refactor: Rename ai/mcp/toolService.mjs to ai/mcp/ToolService.mjs. Convert it to export a ToolService class extending Neo.core.Base.
  2. Configuration:
    • openApiFilePath: Define as a non-reactive config (no trailing underscore) to allow prototype or instance-level overrides.
  3. Class Fields:
    • serviceMapping: Define as a class field.
    • toolMapping & allToolsForListing: Define as instance properties (lazy-loaded state).
  4. Server Update: Update all MCP Servers (github-workflow, knowledge-base, memory-core) to instantiate new ToolService({ serviceMapping, openApiFilePath }) (or similar config pattern) in their local service wrappers.
  5. Client Update: Update Neo.ai.mcp.client.Client to:
    • Instantiate a ToolService for each connection.
    • Pass the openApiFilePath (retrieved from config) to the ToolService if available, enabling robust Zod validation for internal servers.

Deliverables

  • ai/mcp/ToolService.mjs (Class-based).
  • Updated Servers and Client using the new class.
tobiu added the enhancement label on Nov 30, 2025, 3:38 PM
tobiu added the ai label on Nov 30, 2025, 3:38 PM
tobiu added the refactoring label on Nov 30, 2025, 3:38 PM
tobiu added parent issue #7931 on Nov 30, 2025, 3:38 PM
tobiu assigned to @tobiu on Nov 30, 2025, 3:38 PM
tobiu referenced in commit 7284f44 - "Refactor ToolService to Class-based Architecture #7950" on Nov 30, 2025, 4:10 PM
tobiu
tobiu Nov 30, 2025, 4:10 PM

Input from Gemini 2.5 pro:

✦ I have successfully completed the singleton-to-class refactoring for ToolService.

Refactoring Details

  1. Class Architecture: ai/mcp/ToolService.mjs is now a class extending Neo.core.Base.
    • State (toolMapping, allToolsForListing) is instance-scoped.
    • Configuration (openApiFilePath) is handled via static config and construct.
  2. Server Migration: All three MCP servers (github-workflow, knowledge-base, memory-core) now instantiate a new ToolService(...) in their respective services/toolService.mjs wrappers, ensuring isolation.
  3. Client Migration: Neo.ai.mcp.client.Client now creates a private ToolService instance for each connection (initAsync). This enables the Client to maintain separate validation contexts (e.g., separate Zod schemas) for different internal servers within the same process.

Verification

The mcp-demo-agent.mjs runs successfully, confirming that:

  • Servers initialize correctly with the new class-based service.
  • The Client connects and executes tools (using the new class-based validation logic).
  • The architecture handles the multi-server setup without state pollution.

I am ready to close this ticket.

tobiu closed this issue on Nov 30, 2025, 4:10 PM