mcp-ts-template 1.3.2 → 1.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  # MCP TypeScript Template 🚀
2
2
 
3
3
  [![TypeScript](https://img.shields.io/badge/TypeScript-^5.8.3-blue.svg)](https://www.typescriptlang.org/)
4
- [![Model Context Protocol SDK](https://img.shields.io/badge/MCP%20SDK-1.12.0-green.svg)](https://github.com/modelcontextprotocol/typescript-sdk)
4
+ [![Model Context Protocol SDK](https://img.shields.io/badge/MCP%20SDK-1.12.1-green.svg)](https://github.com/modelcontextprotocol/typescript-sdk)
5
5
  [![MCP Spec Version](https://img.shields.io/badge/MCP%20Spec-2025--03--26-lightgrey.svg)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/changelog.mdx)
6
- [![Version](https://img.shields.io/badge/Version-1.3.2-blue.svg)](./CHANGELOG.md)
6
+ [![Version](https://img.shields.io/badge/Version-1.3.4-blue.svg)](./CHANGELOG.md)
7
7
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
8
8
  [![Status](https://img.shields.io/badge/Status-Stable-green.svg)](https://github.com/cyanheads/mcp-ts-template/issues)
9
9
  [![GitHub](https://img.shields.io/github/stars/cyanheads/mcp-ts-template?style=social)](https://github.com/cyanheads/mcp-ts-template)
@@ -16,16 +16,16 @@ Whether you're creating a new MCP server to extend an AI's capabilities or integ
16
16
 
17
17
  ## ✨ Key Features
18
18
 
19
- | Feature Area | Description | Key Components / Location |
20
- | :-------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------- |
21
- | **🔌 MCP Server** | Functional server example with Echo Tool & Resource. Supports `stdio` and `http` (SSE) transports. | `src/mcp-server/` |
22
- | **💻 MCP Client** | Working client aligned with **MCP 2025-03-26 spec**. Connects via `mcp-config.json`. Includes detailed comments. | `src/mcp-client/` |
23
- | **🚀 Production Utilities** | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | `src/utils/` |
24
- | **🔒 Type Safety/Security** | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware stub for HTTP). | Throughout, `src/utils/security/`, `src/mcp-server/transports/authentication/` |
25
- | **⚙️ Error Handling** | Consistent error categorization (`BaseErrorCode`), detailed logging, centralized handling (`ErrorHandler`). | `src/utils/internal/errorHandler.ts`, `src/types-global/` |
26
- | **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments (via `tsdoc.json`), API references. | `README.md`, Codebase, `tsdoc.json`, `docs/api-references/` |
27
- | **🤖 Agent Ready** | Includes a [.clinerules](.clinerules) developer cheatsheet tailored for LLM coding agents. | `.clinerules` |
28
- | **🛠️ Utility Scripts** | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | `scripts/` |
19
+ | Feature Area | Description | Key Components / Location |
20
+ | :-------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------- |
21
+ | **🔌 MCP Server** | Functional server example with Echo Tool & Resource. Supports `stdio` and **Streamable HTTP** (which utilizes Server-Sent Events for server-to-client streaming) transports. | `src/mcp-server/` |
22
+ | **💻 MCP Client** | Working client aligned with **MCP 2025-03-26 spec**. Connects via `mcp-config.json`. Includes detailed comments. | `src/mcp-client/` |
23
+ | **🚀 Production Utilities** | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | `src/utils/` |
24
+ | **🔒 Type Safety/Security** | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware stub for HTTP). | Throughout, `src/utils/security/`, `src/mcp-server/transports/authentication/` |
25
+ | **⚙️ Error Handling** | Consistent error categorization (`BaseErrorCode`), detailed logging, centralized handling (`ErrorHandler`). | `src/utils/internal/errorHandler.ts`, `src/types-global/` |
26
+ | **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments (via `tsdoc.json`), API references. | `README.md`, Codebase, `tsdoc.json`, `docs/api-references/` |
27
+ | **🤖 Agent Ready** | Includes a [.clinerules](.clinerules) developer cheatsheet tailored for LLM coding agents. | `.clinerules` |
28
+ | **🛠️ Utility Scripts** | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | `scripts/` |
29
29
 
30
30
  _For a more granular breakdown, see the [Detailed Features Table](#detailed-features-table) below._
31
31
 
@@ -35,10 +35,11 @@ This template is already powering several MCP servers, demonstrating its flexibi
35
35
 
36
36
  | Project | Description | Status / Notes |
37
37
  | :-------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | [**pubmed-mcp-server**](https://github.com/cyanheads/pubmed-mcp-server) | MCP server for PubMed, enabling AI agents to search, retrieve, analyze, and visualize biomedical literature via NCBI E-utilities. Features advanced research workflow capabilities. | Actively using this template. |
38
39
  | [**git-mcp-server**](https://github.com/cyanheads/git-mcp-server) | Provides an enterprise-ready MCP interface for Git operations. Allows LLM agents to initialize, clone, branch, commit, and manage repositories via STDIO & Streamable HTTP. | Actively using this template. |
39
40
  | [**obsidian-mcp-server**](https://github.com/cyanheads/obsidian-mcp-server/tree/mcp-ts-template-refactor) | Enables LLMs to interact securely with Obsidian vaults via MCP. Offers token-aware tools for searching, navigating, and updating Obsidian notes, facilitating seamless knowledge base management with Properties management. | Refactor in progress using this template ([see branch](https://github.com/cyanheads/obsidian-mcp-server/tree/mcp-ts-template-refactor)). |
40
- | [**filesystem-mcp-server**](https://github.com/cyanheads/filesystem-mcp-server) | Offers platform-agnostic file system capabilities for AI agents via MCP. Enables reading, writing, updating, and managing files/directories, featuring advanced search/replace and directory traversal. | Actively using this template. |
41
41
  | [**atlas-mcp-server**](https://github.com/cyanheads/atlas-mcp-server) | Advanced task and knowledge management system with Neo4j backend, enabling structured data organization and complex querying for AI agents. | Aligned with this template (as of v2.8.8). |
42
+ | [**filesystem-mcp-server**](https://github.com/cyanheads/filesystem-mcp-server) | Offers platform-agnostic file system capabilities for AI agents via MCP. Enables reading, writing, updating, and managing files/directories, featuring advanced search/replace and directory traversal. | Actively using this template. |
42
43
 
43
44
  _Note: [**toolkit-mcp-server**](https://github.com/cyanheads/toolkit-mcp-server) was initially built using an older version of this template and is pending updates to the latest structure._
44
45
 
@@ -85,11 +86,11 @@ Get the example server running in minutes:
85
86
  npm start
86
87
  # or 'npm run start:stdio'
87
88
  ```
88
- - **Via HTTP (SSE):**
89
+ - **Via Streamable HTTP:**
89
90
  ```bash
90
91
  npm run start:http
91
92
  ```
92
- This starts an HTTP server (default: `http://127.0.0.1:3010`) using Server-Sent Events. The port, host, and allowed origins are configurable via environment variables (see [Configuration](#configuration)).
93
+ This starts a **Streamable HTTP** server (default: `http://127.0.0.1:3010`) which uses Server-Sent Events for the server-to-client streaming component. The port, host, and allowed origins are configurable via environment variables (see [Configuration](#configuration)).
93
94
 
94
95
  ## ⚙️ Configuration
95
96
 
@@ -192,6 +193,8 @@ The `src/` directory is organized for clarity:
192
193
 
193
194
  **Explore the structure yourself:**
194
195
 
196
+ See the current file tree in [docs/tree.md](docs/tree.md) or generate it dynamically:
197
+
195
198
  ```bash
196
199
  npm run tree
197
200
  ```
@@ -226,38 +229,38 @@ This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE
226
229
 
227
230
  ## Detailed Features Table
228
231
 
229
- | Category | Feature | Description | Location(s) |
230
- | :----------------------- | :------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ |
231
- | **Core Components** | MCP Server | Core server logic, tool/resource registration, transport handling. Includes Echo Tool & Resource examples. | `src/mcp-server/` |
232
- | | MCP Client | Logic for connecting to external MCP servers (updated to **MCP 2025-03-26 spec**). Refactored for modularity. | `src/mcp-client/` (see subdirs: `core/`, `client-config/`, `transports/`) |
233
- | | Configuration | Environment-aware settings with Zod validation. | `src/config/`, `src/mcp-client/client-config/configLoader.ts` |
234
- | | HTTP Transport | Express-based server with SSE, session management, CORS, port retries. | `src/mcp-server/transports/httpTransport.ts` |
235
- | | Stdio Transport | Handles MCP communication over standard input/output. | `src/mcp-server/transports/stdioTransport.ts` |
236
- | **Utilities (Core)** | Logger | Structured, context-aware logging (files with rotation & MCP notifications). | `src/utils/internal/logger.ts` |
237
- | | ErrorHandler | Centralized error processing, classification, and logging. | `src/utils/internal/errorHandler.ts` |
238
- | | RequestContext | Request/operation tracking and correlation. | `src/utils/internal/requestContext.ts` |
239
- | **Utilities (Metrics)** | TokenCounter | Estimates token counts using `tiktoken`. | `src/utils/metrics/tokenCounter.ts` |
240
- | **Utilities (Parsing)** | DateParser | Parses natural language date strings using `chrono-node`. | `src/utils/parsing/dateParser.ts` |
241
- | | JsonParser | Parses potentially partial JSON, handles `<think>` blocks. | `src/utils/parsing/jsonParser.ts` |
242
- | **Utilities (Security)** | IdGenerator | Generates unique IDs (prefixed or UUIDs). | `src/utils/security/idGenerator.ts` |
243
- | | RateLimiter | Request throttling based on keys. | `src/utils/security/rateLimiter.ts` |
244
- | | Sanitization | Input validation/cleaning (HTML, paths, URLs, numbers, JSON) & log redaction (`validator`, `sanitize-html`). | `src/utils/security/sanitization.ts` |
245
- | **Services** | OpenRouter Provider | Service for interacting with OpenRouter API via OpenAI SDK compatibility. | `src/services/llm-providers/openRouter/openRouterProvider.ts` |
246
- | | LLM Provider Factory | Centralized factory for creating LLM client instances (e.g., OpenRouter, Gemini (partial integration in LLMFactory but not usable yet)). | `src/services/llm-providers/llmFactory.ts` |
247
- | **Type Safety** | Global Types | Shared TypeScript definitions for consistent interfaces (Errors, MCP types). | `src/types-global/` |
248
- | | Zod Schemas | Used for robust validation of configuration files and tool/resource inputs. | Throughout (`config`, `mcp-client`, tools, etc.) |
249
- | **Error Handling** | Pattern-Based Classification | Automatically categorize errors based on message patterns. | `src/utils/internal/errorHandler.ts` |
250
- | | Consistent Formatting | Standardized error responses with additional context. | `src/utils/internal/errorHandler.ts` |
251
- | | Safe Try/Catch Patterns | Centralized error processing helpers (`ErrorHandler.tryCatch`). | `src/utils/internal/errorHandler.ts` |
252
- | | Client/Transport Error Handling | Specific handlers for MCP client and transport error handling. | `src/mcp-client/core/`, `src/mcp-client/transports/` |
253
- | **Security** | Input Validation | Using `validator` and `zod` for various data type checks. | `src/utils/security/sanitization.ts`, etc. |
254
- | | Input Sanitization | Using `sanitize-html` to prevent injection attacks. | `src/utils/security/sanitization.ts` |
255
- | | Sensitive Data Redaction | Automatic redaction in logs. | `src/utils/security/sanitization.ts` |
256
- | | Configuration Fallback | Safely falls back to `mcp-config.json.example` if primary client config is missing. | `src/mcp-client/client-config/configLoader.ts` |
257
- | **Scripts** | Clean Script | Removes `dist` and `logs` directories (or custom targets). | `scripts/clean.ts` |
258
- | | Make Executable Script | Sets executable permissions (`chmod +x`) on specified files (Unix-like only). | `scripts/make-executable.ts` |
259
- | | Tree Script | Generates a directory structure tree, respecting `.gitignore`. | `scripts/tree.ts` |
260
- | | Fetch OpenAPI Spec Script | Fetches an OpenAPI spec (YAML/JSON) from a URL with fallbacks, saves locally. | `scripts/fetch-openapi-spec.ts` |
232
+ | Category | Feature | Description | Location(s) |
233
+ | :----------------------- | :------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------ |
234
+ | **Core Components** | MCP Server | Core server logic, tool/resource registration, transport handling. Includes Echo Tool & Resource examples. | `src/mcp-server/` |
235
+ | | MCP Client | Logic for connecting to external MCP servers (updated to **MCP 2025-03-26 spec**). Refactored for modularity. | `src/mcp-client/` (see subdirs: `core/`, `client-config/`, `transports/`) |
236
+ | | Configuration | Environment-aware settings with Zod validation. | `src/config/`, `src/mcp-client/client-config/configLoader.ts` |
237
+ | | Streamable HTTP Transport | Express-based server implementing the MCP **Streamable HTTP** transport (utilizing Server-Sent Events for server-to-client streaming), with session management, CORS, and port retries. | `src/mcp-server/transports/httpTransport.ts` |
238
+ | | Stdio Transport | Handles MCP communication over standard input/output. | `src/mcp-server/transports/stdioTransport.ts` |
239
+ | **Utilities (Core)** | Logger | Structured, context-aware logging (files with rotation & MCP notifications). | `src/utils/internal/logger.ts` |
240
+ | | ErrorHandler | Centralized error processing, classification, and logging. | `src/utils/internal/errorHandler.ts` |
241
+ | | RequestContext | Request/operation tracking and correlation. | `src/utils/internal/requestContext.ts` |
242
+ | **Utilities (Metrics)** | TokenCounter | Estimates token counts using `tiktoken`. | `src/utils/metrics/tokenCounter.ts` |
243
+ | **Utilities (Parsing)** | DateParser | Parses natural language date strings using `chrono-node`. | `src/utils/parsing/dateParser.ts` |
244
+ | | JsonParser | Parses potentially partial JSON, handles `<think>` blocks. | `src/utils/parsing/jsonParser.ts` |
245
+ | **Utilities (Security)** | IdGenerator | Generates unique IDs (prefixed or UUIDs). | `src/utils/security/idGenerator.ts` |
246
+ | | RateLimiter | Request throttling based on keys. | `src/utils/security/rateLimiter.ts` |
247
+ | | Sanitization | Input validation/cleaning (HTML, paths, URLs, numbers, JSON) & log redaction (`validator`, `sanitize-html`). | `src/utils/security/sanitization.ts` |
248
+ | **Services** | OpenRouter Provider | Service for interacting with OpenRouter API via OpenAI SDK compatibility. | `src/services/llm-providers/openRouter/openRouterProvider.ts` |
249
+ | | LLM Provider Factory | Centralized factory for creating LLM client instances (e.g., OpenRouter). | `src/services/llm-providers/llmFactory.ts` |
250
+ | **Type Safety** | Global Types | Shared TypeScript definitions for consistent interfaces (Errors, MCP types). | `src/types-global/` |
251
+ | | Zod Schemas | Used for robust validation of configuration files and tool/resource inputs. | Throughout (`config`, `mcp-client`, tools, etc.) |
252
+ | **Error Handling** | Pattern-Based Classification | Automatically categorize errors based on message patterns. | `src/utils/internal/errorHandler.ts` |
253
+ | | Consistent Formatting | Standardized error responses with additional context. | `src/utils/internal/errorHandler.ts` |
254
+ | | Safe Try/Catch Patterns | Centralized error processing helpers (`ErrorHandler.tryCatch`). | `src/utils/internal/errorHandler.ts` |
255
+ | | Client/Transport Error Handling | Specific handlers for MCP client and transport error handling. | `src/mcp-client/core/`, `src/mcp-client/transports/` |
256
+ | **Security** | Input Validation | Using `validator` and `zod` for various data type checks. | `src/utils/security/sanitization.ts`, etc. |
257
+ | | Input Sanitization | Using `sanitize-html` to prevent injection attacks. | `src/utils/security/sanitization.ts` |
258
+ | | Sensitive Data Redaction | Automatic redaction in logs. | `src/utils/security/sanitization.ts` |
259
+ | | Configuration Fallback | Safely falls back to `mcp-config.json.example` if primary client config is missing. | `src/mcp-client/client-config/configLoader.ts` |
260
+ | **Scripts** | Clean Script | Removes `dist` and `logs` directories (or custom targets). | `scripts/clean.ts` |
261
+ | | Make Executable Script | Sets executable permissions (`chmod +x`) on specified files (Unix-like only). | `scripts/make-executable.ts` |
262
+ | | Tree Script | Generates a directory structure tree, respecting `.gitignore`. | `scripts/tree.ts` |
263
+ | | Fetch OpenAPI Spec Script | Fetches an OpenAPI spec (YAML/JSON) from a URL with fallbacks, saves locally. | `scripts/fetch-openapi-spec.ts` |
261
264
 
262
265
  ---
263
266
 
@@ -57,8 +57,6 @@ export declare const config: {
57
57
  llmDefaultTopK: number | undefined;
58
58
  /** Default LLM min_p. From `LLM_DEFAULT_MIN_P`. */
59
59
  llmDefaultMinP: number | undefined;
60
- /** Gemini API Key. From `GEMINI_API_KEY`. */
61
- geminiApiKey: string | undefined;
62
60
  /** OAuth Proxy configurations. Undefined if no related env vars are set. */
63
61
  oauthProxy: {
64
62
  authorizationUrl: string | undefined;
@@ -104,7 +104,7 @@ const EnvSchema = z.object({
104
104
  OPENROUTER_APP_NAME: z.string().optional(),
105
105
  /** Optional. API key for OpenRouter services. */
106
106
  OPENROUTER_API_KEY: z.string().optional(),
107
- /** Default LLM model. Default: "google/gemini-2.5-flash-preview:thinking". */
107
+ /** Default LLM model. Default: "google/gemini-2.5-flash-preview-05-20". */
108
108
  LLM_DEFAULT_MODEL: z
109
109
  .string()
110
110
  .default("google/gemini-2.5-flash-preview-05-20"),
@@ -118,8 +118,6 @@ const EnvSchema = z.object({
118
118
  LLM_DEFAULT_TOP_K: z.coerce.number().int().nonnegative().optional(),
119
119
  /** Optional. Default LLM min_p (0.0-1.0). */
120
120
  LLM_DEFAULT_MIN_P: z.coerce.number().min(0).max(1).optional(),
121
- /** Optional. API key for Google Gemini services. */
122
- GEMINI_API_KEY: z.string().optional(),
123
121
  /** Optional. OAuth provider authorization endpoint URL. */
124
122
  OAUTH_PROXY_AUTHORIZATION_URL: z
125
123
  .string()
@@ -265,8 +263,6 @@ export const config = {
265
263
  llmDefaultTopK: env.LLM_DEFAULT_TOP_K,
266
264
  /** Default LLM min_p. From `LLM_DEFAULT_MIN_P`. */
267
265
  llmDefaultMinP: env.LLM_DEFAULT_MIN_P,
268
- /** Gemini API Key. From `GEMINI_API_KEY`. */
269
- geminiApiKey: env.GEMINI_API_KEY,
270
266
  /** OAuth Proxy configurations. Undefined if no related env vars are set. */
271
267
  oauthProxy: env.OAUTH_PROXY_AUTHORIZATION_URL ||
272
268
  env.OAUTH_PROXY_TOKEN_URL ||
package/dist/index.js CHANGED
@@ -70,14 +70,18 @@ const shutdown = async (signal) => {
70
70
  };
71
71
  if (mcpStdioServer) {
72
72
  logger.info("Attempting to close main MCP server (STDIO)...", shutdownContext);
73
- mcpStdioServer.close()
73
+ mcpStdioServer
74
+ .close()
74
75
  .then(() => {
75
76
  logger.info("Main MCP server (STDIO) closed successfully.", shutdownContext);
76
77
  mcpClosed = true;
77
78
  checkAndExit();
78
79
  })
79
80
  .catch((err) => {
80
- logger.error("Error closing MCP server (STDIO).", { ...shutdownContext, error: err });
81
+ logger.error("Error closing MCP server (STDIO).", {
82
+ ...shutdownContext,
83
+ error: err,
84
+ });
81
85
  mcpClosed = true; // Consider it closed even on error to allow exit
82
86
  if (!closeError)
83
87
  closeError = err;
@@ -91,7 +95,10 @@ const shutdown = async (signal) => {
91
95
  logger.info("Attempting to close HTTP server...", shutdownContext);
92
96
  actualHttpServer.close((err) => {
93
97
  if (err) {
94
- logger.error("Error closing HTTP server.", { ...shutdownContext, error: err });
98
+ logger.error("Error closing HTTP server.", {
99
+ ...shutdownContext,
100
+ error: err,
101
+ });
95
102
  if (!closeError)
96
103
  closeError = err;
97
104
  }
@@ -170,7 +177,8 @@ const start = async () => {
170
177
  mcpStdioServer = serverInstance;
171
178
  logger.info("STDIO McpServer instance stored globally for shutdown.", startupContext);
172
179
  }
173
- else if (transportType === "http" && serverInstance instanceof http.Server) {
180
+ else if (transportType === "http" &&
181
+ serverInstance instanceof http.Server) {
174
182
  actualHttpServer = serverInstance;
175
183
  logger.info("HTTP transport initialized, http.Server instance stored globally for shutdown.", startupContext);
176
184
  }
@@ -28,8 +28,7 @@ export function createHttpClientTransport(transportConfig, parentContext) {
28
28
  logger.debug("Creating StreamableHTTPClientTransport", context);
29
29
  // The check for `startsWith("http")` should have been done by the caller (e.g., transportFactory)
30
30
  // which should have already validated the nature of the command string for HTTP transport.
31
- if (!transportConfig.baseUrl ||
32
- typeof transportConfig.baseUrl !== "string") {
31
+ if (!transportConfig.baseUrl || typeof transportConfig.baseUrl !== "string") {
33
32
  const httpConfigError = `Invalid baseUrl for StreamableHTTPClientTransport: command must be a non-empty URL string. Found: "${transportConfig.baseUrl}"`;
34
33
  logger.error(httpConfigError, context);
35
34
  throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, httpConfigError, context);
@@ -4,7 +4,11 @@ import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
4
4
  import { logger, requestContextService, sanitizeInputForLogging, } from "../../../utils/index.js";
5
5
  // Minimal input schema, as the tool will return a dynamic image
6
6
  export const FetchImageTestInputSchema = z.object({
7
- trigger: z.boolean().optional().default(true).describe("A trigger to invoke the tool and fetch a new cat image."),
7
+ trigger: z
8
+ .boolean()
9
+ .optional()
10
+ .default(true)
11
+ .describe("A trigger to invoke the tool and fetch a new cat image."),
8
12
  });
9
13
  const CAT_API_URL = "https://cataas.com/cat";
10
14
  export async function fetchImageTestLogic(input, parentRequestContext) {
@@ -20,7 +24,9 @@ export async function fetchImageTestLogic(input, parentRequestContext) {
20
24
  throw new McpError(BaseErrorCode.SERVICE_UNAVAILABLE, `Failed to fetch cat image from ${CAT_API_URL}. Status: ${response.status}`, {
21
25
  statusCode: response.status,
22
26
  statusText: response.statusText,
23
- responseBody: await response.text().catch(() => "Could not read response body"),
27
+ responseBody: await response
28
+ .text()
29
+ .catch(() => "Could not read response body"),
24
30
  });
25
31
  }
26
32
  const imageBuffer = Buffer.from(await response.arrayBuffer());
@@ -1,17 +1,15 @@
1
1
  /**
2
2
  * @fileoverview Factory for creating LLM client instances.
3
- * Provides a centralized way to instantiate clients for different LLM providers
4
- * like OpenRouter and Google Gemini, handling API key configuration and
5
- * basic client setup.
3
+ * Provides a centralized way to instantiate clients for LLM providers
4
+ * like OpenRouter, handling API key configuration and basic client setup.
6
5
  * @module src/services/llm-providers/llmFactory
7
6
  */
8
- import { GoogleGenAI } from "@google/genai";
9
7
  import OpenAI from "openai";
10
8
  import { RequestContext } from "../../utils/index.js";
11
9
  /**
12
10
  * Defines the supported LLM providers.
13
11
  */
14
- export type LlmProviderType = "openrouter" | "gemini";
12
+ export type LlmProviderType = "openrouter";
15
13
  /**
16
14
  * Options for configuring the OpenRouter client.
17
15
  */
@@ -21,21 +19,10 @@ export interface OpenRouterClientOptions {
21
19
  siteUrl?: string;
22
20
  siteName?: string;
23
21
  }
24
- /**
25
- * Options for configuring the Gemini client using @google/genai.
26
- * The factory will return a GoogleGenAI instance.
27
- * Vertex AI specific options are included here.
28
- */
29
- export interface GeminiClientOptions {
30
- apiKey?: string;
31
- useVertexAi?: boolean;
32
- project?: string;
33
- location?: string;
34
- }
35
22
  /**
36
23
  * Union type for all LLM client options.
37
24
  */
38
- export type LlmClientOptions = OpenRouterClientOptions | GeminiClientOptions;
25
+ export type LlmClientOptions = OpenRouterClientOptions;
39
26
  /**
40
27
  * LLM Factory class to create and configure LLM clients.
41
28
  */
@@ -46,21 +33,15 @@ declare class LlmFactory {
46
33
  * @param provider - The LLM provider to create a client for.
47
34
  * @param context - The request context for logging.
48
35
  * @param options - Optional provider-specific configuration options.
49
- * @returns A Promise resolving to an instance of OpenAI (for OpenRouter)
50
- * or GoogleGenAI (for Gemini).
36
+ * @returns A Promise resolving to an instance of OpenAI (for OpenRouter).
51
37
  * @throws {McpError} If the provider is unsupported or API key/config is missing.
52
38
  */
53
- getLlmClient(provider: LlmProviderType, context: RequestContext, options?: LlmClientOptions): Promise<OpenAI | GoogleGenAI>;
39
+ getLlmClient(provider: LlmProviderType, context: RequestContext, options?: LlmClientOptions): Promise<OpenAI>;
54
40
  /**
55
41
  * Creates an OpenAI client configured for OpenRouter.
56
42
  * @private
57
43
  */
58
44
  private createOpenRouterClient;
59
- /**
60
- * Creates a GoogleGenAI client for Gemini, supporting standard API key or Vertex AI.
61
- * @private
62
- */
63
- private createGeminiClient;
64
45
  }
65
46
  /**
66
47
  * Singleton instance of the LlmFactory.
@@ -1,11 +1,9 @@
1
1
  /**
2
2
  * @fileoverview Factory for creating LLM client instances.
3
- * Provides a centralized way to instantiate clients for different LLM providers
4
- * like OpenRouter and Google Gemini, handling API key configuration and
5
- * basic client setup.
3
+ * Provides a centralized way to instantiate clients for LLM providers
4
+ * like OpenRouter, handling API key configuration and basic client setup.
6
5
  * @module src/services/llm-providers/llmFactory
7
6
  */
8
- import { GoogleGenAI } from "@google/genai"; // Updated import path
9
7
  import OpenAI from "openai";
10
8
  import { config } from "../../config/index.js";
11
9
  import { BaseErrorCode, McpError } from "../../types-global/errors.js";
@@ -20,12 +18,10 @@ class LlmFactory {
20
18
  * @param provider - The LLM provider to create a client for.
21
19
  * @param context - The request context for logging.
22
20
  * @param options - Optional provider-specific configuration options.
23
- * @returns A Promise resolving to an instance of OpenAI (for OpenRouter)
24
- * or GoogleGenAI (for Gemini).
21
+ * @returns A Promise resolving to an instance of OpenAI (for OpenRouter).
25
22
  * @throws {McpError} If the provider is unsupported or API key/config is missing.
26
23
  */
27
24
  async getLlmClient(provider, context, options) {
28
- // Return type changed for Gemini
29
25
  const operation = `LlmFactory.getLlmClient.${provider}`;
30
26
  logger.info(`[${operation}] Requesting LLM client`, {
31
27
  ...context,
@@ -34,11 +30,14 @@ class LlmFactory {
34
30
  switch (provider) {
35
31
  case "openrouter":
36
32
  return this.createOpenRouterClient(context, options);
37
- case "gemini":
38
- return this.createGeminiClient(context, options);
33
+ // No default case needed if LlmProviderType only allows 'openrouter'
34
+ // However, to be safe and handle potential future extensions or direct calls with invalid provider:
39
35
  default:
40
- logger.error(`[${operation}] Unsupported LLM provider requested: ${provider}`, context);
41
- throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, `Unsupported LLM provider: ${provider}`, { operation, provider });
36
+ // This part of the code should ideally be unreachable if LlmProviderType is strictly 'openrouter'.
37
+ // If it's reached, it implies an internal logic error or misuse.
38
+ const exhaustiveCheck = provider; // Ensures all LlmProviderType cases are handled
39
+ logger.error(`[${operation}] Unsupported LLM provider requested: ${exhaustiveCheck}`, context);
40
+ throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, `Unsupported LLM provider: ${provider}`, { operation, provider: exhaustiveCheck });
42
41
  }
43
42
  }
44
43
  /**
@@ -75,56 +74,6 @@ class LlmFactory {
75
74
  throw new McpError(BaseErrorCode.INITIALIZATION_FAILED, `Failed to initialize OpenRouter client: ${error.message}`, { operation, cause: error });
76
75
  }
77
76
  }
78
- /**
79
- * Creates a GoogleGenAI client for Gemini, supporting standard API key or Vertex AI.
80
- * @private
81
- */
82
- createGeminiClient(context, options) {
83
- const operation = "LlmFactory.createGeminiClient";
84
- if (options?.useVertexAi) {
85
- if (!options.project || !options.location) {
86
- logger.error(`[${operation}] Vertex AI project and location are required when useVertexAi is true.`, context);
87
- throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, "Vertex AI project and location must be configured if useVertexAi is true.", { operation });
88
- }
89
- try {
90
- // For Vertex AI, apiKey in GoogleGenAI constructor is optional if ADC are set up.
91
- // The SDK handles ADC automatically if apiKey is not provided.
92
- const clientConfig = {
93
- project: options.project,
94
- location: options.location,
95
- vertexai: true,
96
- };
97
- if (options.apiKey) {
98
- // Allow API key to be passed for Vertex if specific auth needed
99
- clientConfig.apiKey = options.apiKey;
100
- }
101
- const genAI = new GoogleGenAI(clientConfig);
102
- logger.info(`[${operation}] GoogleGenAI client for Vertex AI created successfully.`, context);
103
- return genAI;
104
- }
105
- catch (error) {
106
- logger.error(`[${operation}] Failed to create Gemini client for Vertex AI`, { ...context, error: error.message });
107
- throw new McpError(BaseErrorCode.INITIALIZATION_FAILED, `Failed to initialize Gemini client for Vertex AI: ${error.message}`, { operation, cause: error });
108
- }
109
- }
110
- else {
111
- // Standard Gemini API key authentication
112
- const apiKey = options?.apiKey || config.geminiApiKey;
113
- if (!apiKey) {
114
- logger.error(`[${operation}] GEMINI_API_KEY is not set for standard API usage.`, context);
115
- throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, "Gemini API key is not configured for standard API usage.", { operation });
116
- }
117
- try {
118
- const genAI = new GoogleGenAI({ apiKey });
119
- logger.info(`[${operation}] GoogleGenAI client (standard API key) created successfully.`, context);
120
- return genAI;
121
- }
122
- catch (error) {
123
- logger.error(`[${operation}] Failed to create Gemini client (standard API key)`, { ...context, error: error.message });
124
- throw new McpError(BaseErrorCode.INITIALIZATION_FAILED, `Failed to initialize Gemini client (standard API key): ${error.message}`, { operation, cause: error });
125
- }
126
- }
127
- }
128
77
  }
129
78
  /**
130
79
  * Singleton instance of the LlmFactory.
@@ -1,7 +1,7 @@
1
- import { OpenRouterClientOptions } from "../llmFactory.js";
2
1
  import { ChatCompletion, ChatCompletionChunk, ChatCompletionCreateParamsNonStreaming, ChatCompletionCreateParamsStreaming } from "openai/resources/chat/completions";
3
2
  import { Stream } from "openai/streaming";
4
3
  import { OperationContext, RequestContext } from "../../../utils/internal/requestContext.js";
4
+ import { OpenRouterClientOptions } from "../llmFactory.js";
5
5
  /**
6
6
  * Defines the parameters for an OpenRouter chat completion request.
7
7
  * This type extends standard OpenAI chat completion parameters and includes
@@ -1,4 +1,3 @@
1
- import { llmFactory } from "../llmFactory.js"; // Import factory
2
1
  import { config } from "../../../config/index.js";
3
2
  import { BaseErrorCode, McpError } from "../../../types-global/errors.js";
4
3
  import { ErrorHandler } from "../../../utils/internal/errorHandler.js";
@@ -6,6 +5,7 @@ import { logger } from "../../../utils/internal/logger.js";
6
5
  import { requestContextService, } from "../../../utils/internal/requestContext.js";
7
6
  import { rateLimiter } from "../../../utils/security/rateLimiter.js";
8
7
  import { sanitization } from "../../../utils/security/sanitization.js";
8
+ import { llmFactory } from "../llmFactory.js"; // Import factory
9
9
  /**
10
10
  * Service class for interacting with the OpenRouter API.
11
11
  * Uses the OpenAI SDK for chat completions, configured for OpenRouter.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "mcp-ts-template",
3
- "version": "1.3.2",
4
- "description": "TypeScript template for building Model Context Protocol (MCP) servers & clients. Features production-ready utilities, stdio/HTTP transports (with JWT auth), examples, and type safety. Ideal starting point for creating MCP-based applications.",
3
+ "version": "1.3.4",
4
+ "description": "TypeScript template for building Model Context Protocol (MCP) Servers & Clients. Features extensive utilities (logger, requestContext, etc.), STDIO & Streamable HTTP (with authMiddleware), examples, and type safety. Ideal starting point for creating production-ready MCP Servers & Clients.",
5
5
  "main": "dist/index.js",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
9
9
  "bin": {
10
- "mcp-ts-template": "./dist/index.js"
10
+ "mcp-ts-template": "dist/index.js"
11
11
  },
12
12
  "exports": "./dist/index.js",
13
13
  "type": "module",
@@ -33,10 +33,9 @@
33
33
  "start:client-cli": "node dist/mcp-client/cli/mcp-client-cli.js"
34
34
  },
35
35
  "dependencies": {
36
- "@google/genai": "^1.0.1",
37
- "@modelcontextprotocol/sdk": "^1.11.5",
36
+ "@modelcontextprotocol/sdk": "^1.12.1",
38
37
  "@types/jsonwebtoken": "^9.0.9",
39
- "@types/node": "^22.15.21",
38
+ "@types/node": "^22.15.28",
40
39
  "@types/sanitize-html": "^2.16.0",
41
40
  "@types/validator": "13.15.1",
42
41
  "chalk": "^5.4.1",
@@ -46,17 +45,17 @@
46
45
  "express": "^5.1.0",
47
46
  "ignore": "^7.0.4",
48
47
  "jsonwebtoken": "^9.0.2",
49
- "openai": "^4.102.0",
48
+ "openai": "^5.0.1",
50
49
  "partial-json": "^0.1.7",
51
50
  "sanitize-html": "^2.17.0",
52
51
  "tiktoken": "^1.0.21",
53
52
  "ts-node": "^10.9.2",
54
53
  "typescript": "^5.8.3",
55
- "validator": "13.15.0",
54
+ "validator": "13.15.15",
56
55
  "winston": "^3.17.0",
57
56
  "winston-daily-rotate-file": "^5.0.0",
58
- "yargs": "^17.7.2",
59
- "zod": "^3.25.20"
57
+ "yargs": "^18.0.0",
58
+ "zod": "^3.25.42"
60
59
  },
61
60
  "keywords": [
62
61
  "typescript",
@@ -65,15 +64,14 @@
65
64
  "model-context-protocol",
66
65
  "LLM",
67
66
  "AI-integration",
68
- "server",
69
- "client",
70
- "sdk",
71
- "http",
72
- "sse",
73
- "jwt",
67
+ "mcp-server",
68
+ "mcp-client",
69
+ "mcp-template",
70
+ "stdio",
71
+ "streamable-http",
74
72
  "authentication"
75
73
  ],
76
- "author": "Casey Hand <casey@caseyjhand.com> (https://github.com/cyanheads/mcp-ts-template#readme)",
74
+ "author": "cyanheads <casey@caseyjhand.com> (https://github.com/cyanheads/mcp-ts-template#readme)",
77
75
  "license": "Apache-2.0",
78
76
  "engines": {
79
77
  "node": ">=16.0.0"
@@ -81,9 +79,10 @@
81
79
  "devDependencies": {
82
80
  "@types/express": "^5.0.2",
83
81
  "@types/js-yaml": "^4.0.9",
82
+ "@types/node-fetch": "^2.6.12",
84
83
  "axios": "^1.9.0",
85
84
  "js-yaml": "^4.1.0",
86
85
  "prettier": "^3.5.3",
87
- "typedoc": "^0.28.4"
86
+ "typedoc": "^0.28.5"
88
87
  }
89
88
  }