When making code organization decisions, consider the broader impact beyond just eliminating duplication or following patterns. Sometimes a slightly less “clean” solution is preferable when it preserves type safety, maintains clear class responsibilities, or avoids exposing unnecessary implementation details.

Key considerations:

Example: Instead of extracting common code that would lose TypeScript type information:

// Prefer this (preserves type safety)
if (this.#protocol === "sse") {
  this.#transport = new McpSSETransport(() => this.getWebSocket());
  await this.server.connect(this.#transport);
} else if (this.#protocol === "streamable-http") {
  this.#transport = new McpStreamableHttpTransport(/*...*/);
  await this.server.connect(this.#transport);
}

// Over this (loses type information, requires assertions)
this.#transport = this.#protocol === "sse" 
  ? new McpSSETransport(/*...*/) 
  : new McpStreamableHttpTransport(/*...*/);
await this.server.connect(this.#transport!); // Type assertion needed

The goal is maintainable code that serves developers well, not just adherence to abstract principles.