mcp-ts-template 1.4.1 → 1.4.2
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 +55 -65
- package/dist/services/llm-providers/{openRouter/openRouterProvider.d.ts → openRouterProvider.d.ts} +11 -3
- package/dist/services/llm-providers/{openRouter/openRouterProvider.js → openRouterProvider.js} +38 -39
- package/package.json +3 -3
- package/dist/services/index.d.ts +0 -7
- package/dist/services/index.js +0 -7
- package/dist/services/llm-providers/index.d.ts +0 -7
- package/dist/services/llm-providers/index.js +0 -7
- package/dist/services/llm-providers/llmFactory.d.ts +0 -50
- package/dist/services/llm-providers/llmFactory.js +0 -81
- package/dist/services/llm-providers/openRouter/index.d.ts +0 -6
- package/dist/services/llm-providers/openRouter/index.js +0 -7
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.typescriptlang.org/)
|
|
4
4
|
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
5
5
|
[](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-03-26/changelog.mdx)
|
|
6
|
-
[](./CHANGELOG.md)
|
|
7
7
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
8
8
|
[](https://github.com/cyanheads/mcp-ts-template/issues)
|
|
9
9
|
[](https://github.com/cyanheads/mcp-ts-template)
|
|
@@ -14,23 +14,37 @@ This template provides a solid, beginner-friendly foundation for building robust
|
|
|
14
14
|
|
|
15
15
|
Whether you're creating a new MCP server to extend an AI's capabilities or integrating MCP client features into your application, this template is your starting point.
|
|
16
16
|
|
|
17
|
+
## 📋 Table of Contents
|
|
18
|
+
|
|
19
|
+
- [✨ Key Features](#-key-features)
|
|
20
|
+
- [🌟 Projects Using This Template](#-projects-using-this-template)
|
|
21
|
+
- [🏁 Quick Start](#quick-start)
|
|
22
|
+
- [⚙️ Configuration](#️-configuration)
|
|
23
|
+
- [🔩 Server Configuration (Environment Variables)](#server-configuration-environment-variables)
|
|
24
|
+
- [🔌 Client Configuration (`src/mcp-client/client-config/mcp-config.json`)](#client-configuration-mcp-configjson)
|
|
25
|
+
- [🏗️ Project Structure](#️-project-structure)
|
|
26
|
+
- [🧩 Adding Tools/Resources](#-adding-your-own-tools--resources)
|
|
27
|
+
- [🌍 More MCP Resources](#-explore-more-mcp-resources)
|
|
28
|
+
- [📜 License](#-license)
|
|
29
|
+
- [📊 Detailed Features Table](#detailed-features-table)
|
|
30
|
+
|
|
17
31
|
## ✨ Key Features
|
|
18
32
|
|
|
19
|
-
| Feature Area | Description
|
|
20
|
-
| :-------------------------- |
|
|
33
|
+
| Feature Area | Description | Key Components / Location |
|
|
34
|
+
| :-------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------- |
|
|
21
35
|
| **🔌 MCP Server** | Functional server with example tools (`EchoTool`, `CatFactFetcher` for async/Promise API example) and an `EchoResource`. Supports `stdio` and **Streamable HTTP** transports. | `src/mcp-server/` |
|
|
22
|
-
| **💻 MCP Client** | Working client aligned with **MCP 2025-03-26 spec**. Connects via `mcp-config.json`. Includes detailed comments.
|
|
23
|
-
| **🚀 Production Utilities** | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization.
|
|
24
|
-
| **🔒 Type Safety/Security** | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware stub for HTTP).
|
|
25
|
-
| **⚙️ Error Handling** | Consistent error categorization (`BaseErrorCode`), detailed logging, centralized handling (`ErrorHandler`).
|
|
26
|
-
| **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments, API references
|
|
27
|
-
| **🤖 Agent Ready** | Includes a [.clinerules](.clinerules) developer cheatsheet tailored for LLM coding agents.
|
|
28
|
-
| **🛠️ Utility Scripts** | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs.
|
|
29
|
-
| **🧩 Services** | Reusable modules for LLM (OpenRouter) and data storage (DuckDB) integration, with examples.
|
|
36
|
+
| **💻 MCP Client** | Working client aligned with **MCP 2025-03-26 spec**. Connects via `mcp-config.json`. Includes detailed comments. | `src/mcp-client/` |
|
|
37
|
+
| **🚀 Production Utilities** | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | `src/utils/` |
|
|
38
|
+
| **🔒 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/` |
|
|
39
|
+
| **⚙️ Error Handling** | Consistent error categorization (`BaseErrorCode`), detailed logging, centralized handling (`ErrorHandler`). | `src/utils/internal/errorHandler.ts`, `src/types-global/` |
|
|
40
|
+
| **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments, API references | `README.md`, Codebase, `tsdoc.json`, `docs/api-references/` |
|
|
41
|
+
| **🤖 Agent Ready** | Includes a [.clinerules](.clinerules) developer cheatsheet tailored for LLM coding agents. | `.clinerules` |
|
|
42
|
+
| **🛠️ Utility Scripts** | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | `scripts/` |
|
|
43
|
+
| **🧩 Services** | Reusable modules for LLM (OpenRouter) and data storage (DuckDB) integration, with examples. | `src/services/`, `src/storage/duckdbExample.ts` |
|
|
30
44
|
|
|
31
45
|
_For a more granular breakdown, see the [Detailed Features Table](#detailed-features-table) below._
|
|
32
46
|
|
|
33
|
-
##
|
|
47
|
+
## 🌟 Projects Using This Template
|
|
34
48
|
|
|
35
49
|
This template is already powering several MCP servers, demonstrating its flexibility and robustness:
|
|
36
50
|
|
|
@@ -46,11 +60,7 @@ _Note: [**toolkit-mcp-server**](https://github.com/cyanheads/toolkit-mcp-server)
|
|
|
46
60
|
|
|
47
61
|
You can also **see my [GitHub profile](https://github.com/cyanheads/)** for additional MCP servers I've created, many of which are planned to be migrated to or built upon this template in the future.
|
|
48
62
|
|
|
49
|
-
##
|
|
50
|
-
|
|
51
|
-
[✨ Key Features](#-key-features) | [🚀 Projects Using This Template](#-projects-using-this-template) | [🚀 Quick Start](#quick-start) | [⚙️ Configuration](#️-configuration) | [Server Configuration](#server-configuration-environment-variables) | [Client Configuration](#client-configuration-mcp-configjson) | [🏗️ Project Structure](#️-project-structure) | [🧩 Adding Tools/Resources](#-adding-your-own-tools--resources) | [🌍 More MCP Resources](#-explore-more-mcp-resources) | [📜 License](#-license) | [Detailed Features](#detailed-features-table)
|
|
52
|
-
|
|
53
|
-
## Quick Start
|
|
63
|
+
## 🏁 Quick Start
|
|
54
64
|
|
|
55
65
|
Get the example server running in minutes:
|
|
56
66
|
|
|
@@ -95,7 +105,7 @@ Get the example server running in minutes:
|
|
|
95
105
|
|
|
96
106
|
## ⚙️ Configuration
|
|
97
107
|
|
|
98
|
-
### Server Configuration (Environment Variables)
|
|
108
|
+
### 🔩 Server Configuration (Environment Variables)
|
|
99
109
|
|
|
100
110
|
Configure the MCP server's behavior using these environment variables:
|
|
101
111
|
|
|
@@ -111,21 +121,15 @@ Configure the MCP server's behavior using these environment variables:
|
|
|
111
121
|
| `LOGS_DIR` | Directory for log files. | `logs/` (in project root) |
|
|
112
122
|
| `NODE_ENV` | Runtime environment (`development`, `production`). | `development` |
|
|
113
123
|
| `MCP_AUTH_SECRET_KEY` | **Required for HTTP transport.** Secret key (min 32 chars) for signing/verifying auth tokens (JWT). | (none - **MUST be set in production**) |
|
|
114
|
-
| `OPENROUTER_APP_URL` | URL of the application (used by OpenRouter service for HTTP Referer). | `http://localhost:3000` |
|
|
115
|
-
| `OPENROUTER_APP_NAME` | Name of the application (used by OpenRouter service for X-Title header). | 'mcp-ts-template' |
|
|
116
124
|
| `OPENROUTER_API_KEY` | API key for OpenRouter.ai service. Optional, but service will be unconfigured without it. | (none) |
|
|
117
125
|
| `LLM_DEFAULT_MODEL` | Default model to use for LLM calls via OpenRouter. | `google/gemini-2.5-flash-preview-05-20` |
|
|
118
126
|
| `LLM_DEFAULT_TEMPERATURE` | Default temperature for LLM calls (0-2). Optional. | (none) |
|
|
119
|
-
| `LLM_DEFAULT_TOP_P` | Default top_p for LLM calls (0-1). Optional. | (none) |
|
|
120
|
-
| `LLM_DEFAULT_MAX_TOKENS` | Default max_tokens for LLM calls. Optional. | (none) |
|
|
121
|
-
| `LLM_DEFAULT_TOP_K` | Default top_k for LLM calls (non-negative integer). Optional. | (none) |
|
|
122
|
-
| `LLM_DEFAULT_MIN_P` | Default min_p for LLM calls (0-1). Optional. | (none) |
|
|
123
127
|
|
|
124
128
|
**Note on HTTP Port Retries:** If the `MCP_HTTP_PORT` is busy, the server automatically tries the next port (up to 15 times).
|
|
125
129
|
|
|
126
130
|
**Security Note for HTTP Transport:** When using `MCP_TRANSPORT_TYPE=http`, authentication is **mandatory** as per the MCP specification. This template includes JWT-based authentication middleware (`src/mcp-server/transports/authentication/authMiddleware.ts`). You **MUST** set a strong, unique `MCP_AUTH_SECRET_KEY` in your production environment for this security mechanism to function correctly. Failure to do so will result in bypassed authentication checks in development and fatal errors in production.
|
|
127
131
|
|
|
128
|
-
### Client Configuration (`src/mcp-client/client-config/mcp-config.json`)
|
|
132
|
+
### 🔌 Client Configuration (`src/mcp-client/client-config/mcp-config.json`)
|
|
129
133
|
|
|
130
134
|
Configure the connections for the built-in **MCP client** using `src/mcp-client/client-config/mcp-config.json`. If this file is missing, it falls back to `src/mcp-client/client-config/mcp-config.json.example`.
|
|
131
135
|
|
|
@@ -148,7 +152,6 @@ This file defines external MCP servers the client can connect to. The client imp
|
|
|
148
152
|
"env": {}, // Not used for HTTP
|
|
149
153
|
"transportType": "http" // Explicitly http
|
|
150
154
|
}
|
|
151
|
-
// ... add other servers
|
|
152
155
|
}
|
|
153
156
|
}
|
|
154
157
|
```
|
|
@@ -162,43 +165,30 @@ See `src/mcp-client/client-config/configLoader.ts` for the Zod validation schema
|
|
|
162
165
|
|
|
163
166
|
## 🏗️ Project Structure
|
|
164
167
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
- `
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
- `
|
|
177
|
-
- `
|
|
178
|
-
- `
|
|
179
|
-
- `
|
|
180
|
-
|
|
181
|
-
- `
|
|
182
|
-
- `
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
- `duckDBQueryExecutor.ts`: Executes SQL queries and manages transactions.
|
|
190
|
-
- `duckDBService.ts`: Main service class for DuckDB interaction.
|
|
191
|
-
- `types.ts`: TypeScript types and interfaces for the DuckDB service.
|
|
192
|
-
- `llm-providers/`: API Providers for Large Language Models.
|
|
193
|
-
- `openRouter/`: OpenRouter provider implementation.
|
|
194
|
-
- `llmFactory.ts`: Factory for creating LLM provider clients.
|
|
195
|
-
- `index.ts`: Barrel file for all LLM providers.
|
|
196
|
-
- `index.ts`: Barrel file for services.
|
|
197
|
-
- `storage/`: Example usage of services, e.g., `duckdbExample.ts`.
|
|
198
|
-
- `types-global/`: Shared TypeScript definitions (Errors, MCP types).
|
|
199
|
-
- `utils/`: Reusable utilities (logging, errors, security, parsing, etc.). Exported via `index.ts`.
|
|
200
|
-
|
|
201
|
-
**Explore the structure yourself:**
|
|
168
|
+
This project follows a standard TypeScript project layout. Here's an overview of the key directories and files:
|
|
169
|
+
|
|
170
|
+
- **`.clinerules`**: Developer cheatsheet and guidelines for LLM coding agents working with this repository.
|
|
171
|
+
- **`docs/`**: Contains project documentation, including API references and the auto-generated `tree.md` file.
|
|
172
|
+
- **`scripts/`**: Utility scripts for development tasks like cleaning builds, generating directory trees, and fetching OpenAPI specs.
|
|
173
|
+
- **`src/`**: The heart of the application, containing all TypeScript source code.
|
|
174
|
+
- `src/config/`: Handles loading and validation of environment variables and application configuration.
|
|
175
|
+
- `src/mcp-client/`: Implements the MCP client logic for connecting to and interacting with external MCP servers. This includes client configuration, core connection management, and transport handlers.
|
|
176
|
+
- `src/mcp-server/`: Contains the MCP server implementation provided by this template, including example tools, resources, and transport handlers (Stdio, HTTP).
|
|
177
|
+
- `src/services/`: Provides reusable modules for integrating with external services, such as DuckDB for local data storage and OpenRouter for LLM access.
|
|
178
|
+
- `src/types-global/`: Defines shared TypeScript interfaces and type definitions used across the project, particularly for error handling and MCP-specific types.
|
|
179
|
+
- `src/utils/`: A collection of core utilities.
|
|
180
|
+
- `src/utils/internal/`: Core internal utilities like the logger, error handler, and request context management.
|
|
181
|
+
- `src/utils/metrics/`: Utilities related to metrics, such as token counting.
|
|
182
|
+
- `src/utils/network/`: Network-related utilities, like fetch with timeout.
|
|
183
|
+
- `src/utils/parsing/`: Utilities for parsing data, such as dates and JSON.
|
|
184
|
+
- `src/utils/security/`: Security-focused utilities including ID generation, rate limiting, and input sanitization.
|
|
185
|
+
- `src/index.ts`: The main entry point for the application, responsible for initializing and starting the MCP server. The MCP client is meant to be built upon, so it does not have a dedicated entry point in this template.
|
|
186
|
+
- **`package.json`**: Defines project metadata, dependencies, and npm scripts.
|
|
187
|
+
- **`README.md`**: This file, providing an overview of the project.
|
|
188
|
+
- **`tsconfig.json`**: TypeScript compiler options for the project.
|
|
189
|
+
- **`LICENSE`**: Apache 2.0 License file.
|
|
190
|
+
|
|
191
|
+
**Explore the full structure yourself:**
|
|
202
192
|
|
|
203
193
|
See the current file tree in [docs/tree.md](docs/tree.md) or generate it dynamically:
|
|
204
194
|
|
|
@@ -206,7 +196,7 @@ See the current file tree in [docs/tree.md](docs/tree.md) or generate it dynamic
|
|
|
206
196
|
npm run tree
|
|
207
197
|
```
|
|
208
198
|
|
|
209
|
-
(This uses `scripts/tree.ts` to generate a current file tree
|
|
199
|
+
(This uses `scripts/tree.ts` to generate a current file tree, respecting `.gitignore`.)
|
|
210
200
|
|
|
211
201
|
## 🧩 Adding Your Own Tools & Resources
|
|
212
202
|
|
|
@@ -236,7 +226,7 @@ This collection includes servers for Filesystem, Obsidian, Git, GitHub, Perplexi
|
|
|
236
226
|
|
|
237
227
|
This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details.
|
|
238
228
|
|
|
239
|
-
## Detailed Features Table
|
|
229
|
+
## 📊 Detailed Features Table
|
|
240
230
|
|
|
241
231
|
| Category | Feature | Description | Location(s) |
|
|
242
232
|
| :----------------------- | :------------------------------ | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------- |
|
package/dist/services/llm-providers/{openRouter/openRouterProvider.d.ts → openRouterProvider.d.ts}
RENAMED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import { ChatCompletion, ChatCompletionChunk, ChatCompletionCreateParamsNonStreaming, ChatCompletionCreateParamsStreaming } from "openai/resources/chat/completions";
|
|
2
2
|
import { Stream } from "openai/streaming";
|
|
3
|
-
import { OperationContext, RequestContext } from "
|
|
4
|
-
|
|
3
|
+
import { OperationContext, RequestContext } from "../../utils/internal/requestContext.js";
|
|
4
|
+
/**
|
|
5
|
+
* Options for configuring the OpenRouter client.
|
|
6
|
+
*/
|
|
7
|
+
export interface OpenRouterClientOptions {
|
|
8
|
+
apiKey?: string;
|
|
9
|
+
baseURL?: string;
|
|
10
|
+
siteUrl?: string;
|
|
11
|
+
siteName?: string;
|
|
12
|
+
}
|
|
5
13
|
/**
|
|
6
14
|
* Defines the parameters for an OpenRouter chat completion request.
|
|
7
15
|
* This type extends standard OpenAI chat completion parameters and includes
|
|
@@ -53,7 +61,7 @@ declare class OpenRouterProvider {
|
|
|
53
61
|
* Constructs an `OpenRouterProvider` instance.
|
|
54
62
|
* Initializes the OpenAI client for OpenRouter if an API key is provided.
|
|
55
63
|
* Sets default headers required by OpenRouter.
|
|
56
|
-
* @param
|
|
64
|
+
* @param options - Optional configuration for the OpenRouter client.
|
|
57
65
|
* @param parentOpContext - Optional parent operation context for linked logging.
|
|
58
66
|
*/
|
|
59
67
|
constructor(options?: OpenRouterClientOptions, parentOpContext?: OperationContext);
|
package/dist/services/llm-providers/{openRouter/openRouterProvider.js → openRouterProvider.js}
RENAMED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Provides a service class (`OpenRouterProvider`) for interacting with the
|
|
3
|
+
* OpenRouter API, using the OpenAI SDK for chat completions. It handles API key
|
|
4
|
+
* configuration, default parameters, rate limiting, model-specific parameter adjustments,
|
|
5
|
+
* and error handling.
|
|
6
|
+
* @module src/services/llm-providers/openRouterProvider
|
|
7
|
+
*/
|
|
8
|
+
import OpenAI from "openai";
|
|
9
|
+
import { config } from "../../config/index.js";
|
|
10
|
+
import { BaseErrorCode, McpError } from "../../types-global/errors.js";
|
|
11
|
+
import { ErrorHandler } from "../../utils/internal/errorHandler.js";
|
|
12
|
+
import { logger } from "../../utils/internal/logger.js";
|
|
13
|
+
import { requestContextService, } from "../../utils/internal/requestContext.js";
|
|
14
|
+
import { rateLimiter } from "../../utils/security/rateLimiter.js";
|
|
15
|
+
import { sanitization } from "../../utils/security/sanitization.js";
|
|
9
16
|
/**
|
|
10
17
|
* Service class for interacting with the OpenRouter API.
|
|
11
18
|
* Uses the OpenAI SDK for chat completions, configured for OpenRouter.
|
|
@@ -17,7 +24,7 @@ class OpenRouterProvider {
|
|
|
17
24
|
* Constructs an `OpenRouterProvider` instance.
|
|
18
25
|
* Initializes the OpenAI client for OpenRouter if an API key is provided.
|
|
19
26
|
* Sets default headers required by OpenRouter.
|
|
20
|
-
* @param
|
|
27
|
+
* @param options - Optional configuration for the OpenRouter client.
|
|
21
28
|
* @param parentOpContext - Optional parent operation context for linked logging.
|
|
22
29
|
*/
|
|
23
30
|
constructor(options, parentOpContext) {
|
|
@@ -34,38 +41,43 @@ class OpenRouterProvider {
|
|
|
34
41
|
parentRequestId: parentOpContext?.requestId,
|
|
35
42
|
});
|
|
36
43
|
this.status = "initializing";
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if (!
|
|
44
|
+
const apiKey = options?.apiKey || config.openrouterApiKey;
|
|
45
|
+
const baseURL = options?.baseURL || "https://openrouter.ai/api/v1";
|
|
46
|
+
const siteUrl = options?.siteUrl || config.openrouterAppUrl;
|
|
47
|
+
const siteName = options?.siteName || config.openrouterAppName;
|
|
48
|
+
if (!apiKey) {
|
|
42
49
|
this.status = "unconfigured";
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
this.initializationError = new McpError(BaseErrorCode.CONFIGURATION_ERROR, "OpenRouter API key is not configured.", { operation: operationName });
|
|
51
|
+
logger.error(`[${operationName}] OpenRouter API key not provided in options or global config. Service is unconfigured.`, { ...opContext, service: "OpenRouterProvider" });
|
|
52
|
+
return;
|
|
46
53
|
}
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
54
|
+
try {
|
|
55
|
+
this.client = new OpenAI({
|
|
56
|
+
baseURL,
|
|
57
|
+
apiKey,
|
|
58
|
+
defaultHeaders: {
|
|
59
|
+
"HTTP-Referer": siteUrl,
|
|
60
|
+
"X-Title": siteName,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
51
63
|
this.status = "ready";
|
|
52
|
-
logger.info("OpenRouter Service Initialized and Ready
|
|
64
|
+
logger.info("OpenRouter Service Initialized and Ready", {
|
|
53
65
|
...opContext,
|
|
54
66
|
service: "OpenRouterProvider",
|
|
55
67
|
});
|
|
56
|
-
}
|
|
57
|
-
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
58
70
|
this.status = "error";
|
|
59
71
|
this.initializationError =
|
|
60
72
|
error instanceof Error
|
|
61
73
|
? error
|
|
62
74
|
: new McpError(BaseErrorCode.INITIALIZATION_FAILED, String(error));
|
|
63
|
-
logger.error("Failed to initialize OpenRouter client
|
|
75
|
+
logger.error("Failed to initialize OpenRouter client", {
|
|
64
76
|
...opContext,
|
|
65
77
|
service: "OpenRouterProvider",
|
|
66
78
|
error: this.initializationError.message,
|
|
67
79
|
});
|
|
68
|
-
}
|
|
80
|
+
}
|
|
69
81
|
}
|
|
70
82
|
/**
|
|
71
83
|
* Checks if the service is ready to make API calls.
|
|
@@ -165,11 +177,6 @@ class OpenRouterProvider {
|
|
|
165
177
|
else if (extraBody.provider === undefined) {
|
|
166
178
|
extraBody.provider = { sort: "throughput" };
|
|
167
179
|
}
|
|
168
|
-
// Conditional logic for max_tokens vs max_completion_tokens
|
|
169
|
-
// Certain underlying models (e.g., newer OpenAI models like the o1 series)
|
|
170
|
-
// may require `max_completion_tokens` instead of `max_tokens`.
|
|
171
|
-
// This client sends `max_completion_tokens` in `extra_body` for these models if a limit is specified.
|
|
172
|
-
// For other models, `max_tokens` is used as a standard parameter.
|
|
173
180
|
const modelsRequiringMaxCompletionTokens = ["openai/o1", "openai/gpt-4.1"];
|
|
174
181
|
const needsMaxCompletionTokens = modelsRequiringMaxCompletionTokens.some((modelPrefix) => effectiveModelId.startsWith(modelPrefix));
|
|
175
182
|
const effectiveMaxTokensValue = params.max_tokens ?? config.llmDefaultMaxTokens;
|
|
@@ -179,8 +186,6 @@ class OpenRouterProvider {
|
|
|
179
186
|
logger.info(`[${operation}] Using 'max_completion_tokens: ${effectiveMaxTokensValue}' for model ${effectiveModelId} (sent via extra_body).`, context);
|
|
180
187
|
}
|
|
181
188
|
else {
|
|
182
|
-
// For models not in the list, or if OpenRouter handles the mapping transparently,
|
|
183
|
-
// send max_tokens as a standard parameter.
|
|
184
189
|
standardParams.max_tokens = effectiveMaxTokensValue;
|
|
185
190
|
logger.info(`[${operation}] Using 'max_tokens: ${effectiveMaxTokensValue}' for model ${effectiveModelId}.`, context);
|
|
186
191
|
}
|
|
@@ -280,8 +285,6 @@ class OpenRouterProvider {
|
|
|
280
285
|
method: "GET",
|
|
281
286
|
headers: {
|
|
282
287
|
"Content-Type": "application/json",
|
|
283
|
-
// Authorization header might be needed if OpenRouter changes their /models endpoint access
|
|
284
|
-
// "Authorization": `Bearer ${this.client?.apiKey}`, // apiKey is private on OpenAI client
|
|
285
288
|
},
|
|
286
289
|
});
|
|
287
290
|
if (!response.ok) {
|
|
@@ -321,9 +324,5 @@ class OpenRouterProvider {
|
|
|
321
324
|
* Singleton instance of the `OpenRouterProvider`.
|
|
322
325
|
* Initialized with the OpenRouter API key from application configuration.
|
|
323
326
|
*/
|
|
324
|
-
// Update instantiation to pass options if needed, or rely on factory's use of global config.
|
|
325
|
-
// For a singleton, it usually relies on global config.
|
|
326
|
-
// If the constructor now takes OpenRouterClientOptions, and we want the singleton
|
|
327
|
-
// to use global config, we'd pass undefined or an empty object for options.
|
|
328
327
|
const openRouterProviderInstance = new OpenRouterProvider(undefined);
|
|
329
328
|
export { openRouterProviderInstance as openRouterProvider };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-ts-template",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
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": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"express": "^5.1.0",
|
|
47
47
|
"ignore": "^7.0.5",
|
|
48
48
|
"jsonwebtoken": "^9.0.2",
|
|
49
|
-
"openai": "^5.0.
|
|
49
|
+
"openai": "^5.0.2",
|
|
50
50
|
"partial-json": "^0.1.7",
|
|
51
51
|
"sanitize-html": "^2.17.0",
|
|
52
52
|
"tiktoken": "^1.0.21",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"winston": "^3.17.0",
|
|
57
57
|
"winston-daily-rotate-file": "^5.0.0",
|
|
58
58
|
"yargs": "^18.0.0",
|
|
59
|
-
"zod": "^3.25.
|
|
59
|
+
"zod": "^3.25.49"
|
|
60
60
|
},
|
|
61
61
|
"keywords": [
|
|
62
62
|
"typescript",
|
package/dist/services/index.d.ts
DELETED
package/dist/services/index.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Barrel file for LLM provider services.
|
|
3
|
-
* This file re-exports all services related to different Large Language Model providers,
|
|
4
|
-
* making them easily accessible from a single import path.
|
|
5
|
-
* @module src/services/llm-providers/index
|
|
6
|
-
*/
|
|
7
|
-
export * from "./openRouter";
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Barrel file for LLM provider services.
|
|
3
|
-
* This file re-exports all services related to different Large Language Model providers,
|
|
4
|
-
* making them easily accessible from a single import path.
|
|
5
|
-
* @module src/services/llm-providers/index
|
|
6
|
-
*/
|
|
7
|
-
export * from "./openRouter"; // Changed to export from the new barrel file
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Factory for creating LLM client instances.
|
|
3
|
-
* Provides a centralized way to instantiate clients for LLM providers
|
|
4
|
-
* like OpenRouter, handling API key configuration and basic client setup.
|
|
5
|
-
* @module src/services/llm-providers/llmFactory
|
|
6
|
-
*/
|
|
7
|
-
import OpenAI from "openai";
|
|
8
|
-
import { RequestContext } from "../../utils/index.js";
|
|
9
|
-
/**
|
|
10
|
-
* Defines the supported LLM providers.
|
|
11
|
-
*/
|
|
12
|
-
export type LlmProviderType = "openrouter";
|
|
13
|
-
/**
|
|
14
|
-
* Options for configuring the OpenRouter client.
|
|
15
|
-
*/
|
|
16
|
-
export interface OpenRouterClientOptions {
|
|
17
|
-
apiKey?: string;
|
|
18
|
-
baseURL?: string;
|
|
19
|
-
siteUrl?: string;
|
|
20
|
-
siteName?: string;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Union type for all LLM client options.
|
|
24
|
-
*/
|
|
25
|
-
export type LlmClientOptions = OpenRouterClientOptions;
|
|
26
|
-
/**
|
|
27
|
-
* LLM Factory class to create and configure LLM clients.
|
|
28
|
-
*/
|
|
29
|
-
declare class LlmFactory {
|
|
30
|
-
/**
|
|
31
|
-
* Creates and returns an LLM client instance for the specified provider.
|
|
32
|
-
*
|
|
33
|
-
* @param provider - The LLM provider to create a client for.
|
|
34
|
-
* @param context - The request context for logging.
|
|
35
|
-
* @param options - Optional provider-specific configuration options.
|
|
36
|
-
* @returns A Promise resolving to an instance of OpenAI (for OpenRouter).
|
|
37
|
-
* @throws {McpError} If the provider is unsupported or API key/config is missing.
|
|
38
|
-
*/
|
|
39
|
-
getLlmClient(provider: LlmProviderType, context: RequestContext, options?: LlmClientOptions): Promise<OpenAI>;
|
|
40
|
-
/**
|
|
41
|
-
* Creates an OpenAI client configured for OpenRouter.
|
|
42
|
-
* @private
|
|
43
|
-
*/
|
|
44
|
-
private createOpenRouterClient;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Singleton instance of the LlmFactory.
|
|
48
|
-
*/
|
|
49
|
-
export declare const llmFactory: LlmFactory;
|
|
50
|
-
export {};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Factory for creating LLM client instances.
|
|
3
|
-
* Provides a centralized way to instantiate clients for LLM providers
|
|
4
|
-
* like OpenRouter, handling API key configuration and basic client setup.
|
|
5
|
-
* @module src/services/llm-providers/llmFactory
|
|
6
|
-
*/
|
|
7
|
-
import OpenAI from "openai";
|
|
8
|
-
import { config } from "../../config/index.js";
|
|
9
|
-
import { BaseErrorCode, McpError } from "../../types-global/errors.js";
|
|
10
|
-
import { logger } from "../../utils/index.js";
|
|
11
|
-
/**
|
|
12
|
-
* LLM Factory class to create and configure LLM clients.
|
|
13
|
-
*/
|
|
14
|
-
class LlmFactory {
|
|
15
|
-
/**
|
|
16
|
-
* Creates and returns an LLM client instance for the specified provider.
|
|
17
|
-
*
|
|
18
|
-
* @param provider - The LLM provider to create a client for.
|
|
19
|
-
* @param context - The request context for logging.
|
|
20
|
-
* @param options - Optional provider-specific configuration options.
|
|
21
|
-
* @returns A Promise resolving to an instance of OpenAI (for OpenRouter).
|
|
22
|
-
* @throws {McpError} If the provider is unsupported or API key/config is missing.
|
|
23
|
-
*/
|
|
24
|
-
async getLlmClient(provider, context, options) {
|
|
25
|
-
const operation = `LlmFactory.getLlmClient.${provider}`;
|
|
26
|
-
logger.info(`[${operation}] Requesting LLM client`, {
|
|
27
|
-
...context,
|
|
28
|
-
provider,
|
|
29
|
-
});
|
|
30
|
-
switch (provider) {
|
|
31
|
-
case "openrouter":
|
|
32
|
-
return this.createOpenRouterClient(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:
|
|
35
|
-
default:
|
|
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 });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Creates an OpenAI client configured for OpenRouter.
|
|
45
|
-
* @private
|
|
46
|
-
*/
|
|
47
|
-
createOpenRouterClient(context, options) {
|
|
48
|
-
const operation = "LlmFactory.createOpenRouterClient";
|
|
49
|
-
const apiKey = options?.apiKey || config.openrouterApiKey;
|
|
50
|
-
const baseURL = options?.baseURL || "https://openrouter.ai/api/v1";
|
|
51
|
-
const siteUrl = options?.siteUrl || config.openrouterAppUrl;
|
|
52
|
-
const siteName = options?.siteName || config.openrouterAppName;
|
|
53
|
-
if (!apiKey) {
|
|
54
|
-
logger.error(`[${operation}] OPENROUTER_API_KEY is not set.`, context);
|
|
55
|
-
throw new McpError(BaseErrorCode.CONFIGURATION_ERROR, "OpenRouter API key is not configured.", { operation });
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const client = new OpenAI({
|
|
59
|
-
baseURL,
|
|
60
|
-
apiKey,
|
|
61
|
-
defaultHeaders: {
|
|
62
|
-
"HTTP-Referer": siteUrl,
|
|
63
|
-
"X-Title": siteName,
|
|
64
|
-
},
|
|
65
|
-
});
|
|
66
|
-
logger.info(`[${operation}] OpenRouter client created successfully.`, context);
|
|
67
|
-
return client;
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
logger.error(`[${operation}] Failed to create OpenRouter client`, {
|
|
71
|
-
...context,
|
|
72
|
-
error: error.message,
|
|
73
|
-
});
|
|
74
|
-
throw new McpError(BaseErrorCode.INITIALIZATION_FAILED, `Failed to initialize OpenRouter client: ${error.message}`, { operation, cause: error });
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Singleton instance of the LlmFactory.
|
|
80
|
-
*/
|
|
81
|
-
export const llmFactory = new LlmFactory();
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Barrel file for the OpenRouter provider service.
|
|
3
|
-
* Exports the OpenRouterProvider class and any related types.
|
|
4
|
-
* @module services/llm-providers/openRouter/index
|
|
5
|
-
*/
|
|
6
|
-
export * from "./openRouterProvider";
|
|
7
|
-
// Add other exports from this module if any in the future
|