mcp-ts-template 1.8.0 → 1.9.0
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 +31 -27
- package/dist/config/index.d.ts +9 -53
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +64 -131
- package/dist/config/index.js.map +1 -1
- package/dist/index.d.ts +0 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -133
- package/dist/index.js.map +1 -1
- package/dist/mcp-server/resources/echoResource/logic.d.ts +1 -2
- package/dist/mcp-server/resources/echoResource/logic.d.ts.map +1 -1
- package/dist/mcp-server/resources/echoResource/logic.js +5 -6
- package/dist/mcp-server/resources/echoResource/logic.js.map +1 -1
- package/dist/mcp-server/resources/echoResource/registration.d.ts +1 -7
- package/dist/mcp-server/resources/echoResource/registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/echoResource/registration.js +31 -59
- package/dist/mcp-server/resources/echoResource/registration.js.map +1 -1
- package/dist/mcp-server/resources/index.d.ts +10 -0
- package/dist/mcp-server/resources/index.d.ts.map +1 -0
- package/dist/mcp-server/resources/index.js +19 -0
- package/dist/mcp-server/resources/index.js.map +1 -0
- package/dist/mcp-server/resources/utils/resource-utils.d.ts +43 -0
- package/dist/mcp-server/resources/utils/resource-utils.d.ts.map +1 -0
- package/dist/mcp-server/resources/utils/resource-utils.js +44 -0
- package/dist/mcp-server/resources/utils/resource-utils.js.map +1 -0
- package/dist/mcp-server/server.d.ts +2 -2
- package/dist/mcp-server/server.d.ts.map +1 -1
- package/dist/mcp-server/server.js +23 -37
- package/dist/mcp-server/server.js.map +1 -1
- package/dist/mcp-server/tools/catFactFetcher/logic.d.ts +2 -5
- package/dist/mcp-server/tools/catFactFetcher/logic.d.ts.map +1 -1
- package/dist/mcp-server/tools/catFactFetcher/logic.js +15 -20
- package/dist/mcp-server/tools/catFactFetcher/logic.js.map +1 -1
- package/dist/mcp-server/tools/catFactFetcher/registration.d.ts +1 -7
- package/dist/mcp-server/tools/catFactFetcher/registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/catFactFetcher/registration.js +14 -58
- package/dist/mcp-server/tools/catFactFetcher/registration.js.map +1 -1
- package/dist/mcp-server/tools/echoTool/logic.d.ts +4 -6
- package/dist/mcp-server/tools/echoTool/logic.d.ts.map +1 -1
- package/dist/mcp-server/tools/echoTool/logic.js +11 -13
- package/dist/mcp-server/tools/echoTool/logic.js.map +1 -1
- package/dist/mcp-server/tools/echoTool/registration.d.ts +1 -7
- package/dist/mcp-server/tools/echoTool/registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/echoTool/registration.js +18 -71
- package/dist/mcp-server/tools/echoTool/registration.js.map +1 -1
- package/dist/mcp-server/tools/imageTest/logic.d.ts +4 -6
- package/dist/mcp-server/tools/imageTest/logic.d.ts.map +1 -1
- package/dist/mcp-server/tools/imageTest/logic.js +16 -16
- package/dist/mcp-server/tools/imageTest/logic.js.map +1 -1
- package/dist/mcp-server/tools/imageTest/registration.d.ts +1 -6
- package/dist/mcp-server/tools/imageTest/registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/imageTest/registration.js +19 -60
- package/dist/mcp-server/tools/imageTest/registration.js.map +1 -1
- package/dist/mcp-server/tools/index.d.ts +4 -0
- package/dist/mcp-server/tools/index.d.ts.map +1 -0
- package/dist/mcp-server/tools/index.js +19 -0
- package/dist/mcp-server/tools/index.js.map +1 -0
- package/dist/mcp-server/tools/utils/tool-utils.d.ts +43 -0
- package/dist/mcp-server/tools/utils/tool-utils.d.ts.map +1 -0
- package/dist/mcp-server/tools/utils/tool-utils.js +44 -0
- package/dist/mcp-server/tools/utils/tool-utils.js.map +1 -0
- package/dist/mcp-server/transports/auth/authFactory.js +5 -5
- package/dist/mcp-server/transports/auth/authFactory.js.map +1 -1
- package/dist/mcp-server/transports/auth/authMiddleware.d.ts +2 -2
- package/dist/mcp-server/transports/auth/authMiddleware.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/authMiddleware.js +13 -13
- package/dist/mcp-server/transports/auth/authMiddleware.js.map +1 -1
- package/dist/mcp-server/transports/auth/lib/authUtils.js +7 -7
- package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +23 -23
- package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +23 -23
- package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
- package/dist/mcp-server/transports/core/baseTransportManager.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/baseTransportManager.js +1 -1
- package/dist/mcp-server/transports/core/baseTransportManager.js.map +1 -1
- package/dist/mcp-server/transports/core/headerUtils.d.ts +20 -0
- package/dist/mcp-server/transports/core/headerUtils.d.ts.map +1 -0
- package/dist/mcp-server/transports/core/headerUtils.js +38 -0
- package/dist/mcp-server/transports/core/headerUtils.js.map +1 -0
- package/dist/mcp-server/transports/core/honoNodeBridge.d.ts +60 -7
- package/dist/mcp-server/transports/core/honoNodeBridge.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/honoNodeBridge.js +89 -8
- package/dist/mcp-server/transports/core/honoNodeBridge.js.map +1 -1
- package/dist/mcp-server/transports/core/statefulTransportManager.d.ts +53 -8
- package/dist/mcp-server/transports/core/statefulTransportManager.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/statefulTransportManager.js +196 -132
- package/dist/mcp-server/transports/core/statefulTransportManager.js.map +1 -1
- package/dist/mcp-server/transports/core/statelessTransportManager.d.ts +44 -7
- package/dist/mcp-server/transports/core/statelessTransportManager.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/statelessTransportManager.js +92 -34
- package/dist/mcp-server/transports/core/statelessTransportManager.js.map +1 -1
- package/dist/mcp-server/transports/core/transportTypes.d.ts +58 -21
- package/dist/mcp-server/transports/core/transportTypes.d.ts.map +1 -1
- package/dist/mcp-server/transports/core/transportTypes.js +3 -1
- package/dist/mcp-server/transports/core/transportTypes.js.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpErrorHandler.js +37 -49
- package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.d.ts +3 -3
- package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/httpTransport.js +50 -43
- package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.d.ts.map +1 -1
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.js +26 -17
- package/dist/mcp-server/transports/http/mcpTransportMiddleware.js.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
- package/dist/mcp-server/transports/stdio/stdioTransport.js +6 -5
- package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
- package/dist/services/duck-db/duckDBConnectionManager.d.ts.map +1 -1
- package/dist/services/duck-db/duckDBConnectionManager.js +20 -20
- package/dist/services/duck-db/duckDBConnectionManager.js.map +1 -1
- package/dist/services/duck-db/duckDBQueryExecutor.d.ts.map +1 -1
- package/dist/services/duck-db/duckDBQueryExecutor.js +13 -13
- package/dist/services/duck-db/duckDBQueryExecutor.js.map +1 -1
- package/dist/services/duck-db/duckDBService.js +8 -8
- package/dist/services/duck-db/duckDBService.js.map +1 -1
- package/dist/services/llm-providers/openRouterProvider.d.ts.map +1 -1
- package/dist/services/llm-providers/openRouterProvider.js +17 -14
- package/dist/services/llm-providers/openRouterProvider.js.map +1 -1
- package/dist/services/supabase/supabaseClient.js +6 -6
- package/dist/services/supabase/supabaseClient.js.map +1 -1
- package/dist/storage/duckdbExample.js +45 -42
- package/dist/storage/duckdbExample.js.map +1 -1
- package/dist/types-global/errors.d.ts +29 -52
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +30 -51
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/internal/asyncContext.d.ts +35 -0
- package/dist/utils/internal/asyncContext.d.ts.map +1 -0
- package/dist/utils/internal/asyncContext.js +38 -0
- package/dist/utils/internal/asyncContext.js.map +1 -0
- package/dist/utils/internal/errorHandler.d.ts +18 -100
- package/dist/utils/internal/errorHandler.d.ts.map +1 -1
- package/dist/utils/internal/errorHandler.js +91 -219
- package/dist/utils/internal/errorHandler.js.map +1 -1
- package/dist/utils/internal/index.d.ts +1 -0
- package/dist/utils/internal/index.d.ts.map +1 -1
- package/dist/utils/internal/index.js +1 -0
- package/dist/utils/internal/index.js.map +1 -1
- package/dist/utils/internal/logger.d.ts +16 -140
- package/dist/utils/internal/logger.d.ts.map +1 -1
- package/dist/utils/internal/logger.js +133 -423
- package/dist/utils/internal/logger.js.map +1 -1
- package/dist/utils/internal/logging-helpers.d.ts +49 -0
- package/dist/utils/internal/logging-helpers.d.ts.map +1 -0
- package/dist/utils/internal/logging-helpers.js +60 -0
- package/dist/utils/internal/logging-helpers.js.map +1 -0
- package/dist/utils/internal/performance.d.ts +2 -5
- package/dist/utils/internal/performance.d.ts.map +1 -1
- package/dist/utils/internal/performance.js +71 -37
- package/dist/utils/internal/performance.js.map +1 -1
- package/dist/utils/internal/requestContext.d.ts +21 -64
- package/dist/utils/internal/requestContext.d.ts.map +1 -1
- package/dist/utils/internal/requestContext.js +37 -63
- package/dist/utils/internal/requestContext.js.map +1 -1
- package/dist/utils/metrics/tokenCounter.d.ts.map +1 -1
- package/dist/utils/metrics/tokenCounter.js +13 -9
- package/dist/utils/metrics/tokenCounter.js.map +1 -1
- package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
- package/dist/utils/network/fetchWithTimeout.js +27 -9
- package/dist/utils/network/fetchWithTimeout.js.map +1 -1
- package/dist/utils/parsing/dateParser.d.ts.map +1 -1
- package/dist/utils/parsing/dateParser.js +8 -8
- package/dist/utils/parsing/dateParser.js.map +1 -1
- package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
- package/dist/utils/parsing/jsonParser.js +9 -9
- package/dist/utils/parsing/jsonParser.js.map +1 -1
- package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
- package/dist/utils/scheduling/scheduler.js +18 -15
- package/dist/utils/scheduling/scheduler.js.map +1 -1
- package/dist/utils/security/idGenerator.d.ts +6 -0
- package/dist/utils/security/idGenerator.d.ts.map +1 -1
- package/dist/utils/security/idGenerator.js +16 -4
- package/dist/utils/security/idGenerator.js.map +1 -1
- package/dist/utils/security/rateLimiter.d.ts.map +1 -1
- package/dist/utils/security/rateLimiter.js +27 -11
- package/dist/utils/security/rateLimiter.js.map +1 -1
- package/dist/utils/security/sanitization.js +20 -20
- package/dist/utils/security/sanitization.js.map +1 -1
- package/dist/utils/telemetry/instrumentation.d.ts +8 -0
- package/dist/utils/telemetry/instrumentation.d.ts.map +1 -0
- package/dist/utils/telemetry/instrumentation.js +121 -0
- package/dist/utils/telemetry/instrumentation.js.map +1 -0
- package/dist/utils/telemetry/semconv.d.ts +16 -0
- package/dist/utils/telemetry/semconv.d.ts.map +1 -0
- package/dist/utils/telemetry/semconv.js +16 -0
- package/dist/utils/telemetry/semconv.js.map +1 -0
- package/package.json +43 -29
- package/dist/mcp-server/core/managedMcpServer.d.ts +0 -48
- package/dist/mcp-server/core/managedMcpServer.d.ts.map +0 -1
- package/dist/mcp-server/core/managedMcpServer.js +0 -58
- package/dist/mcp-server/core/managedMcpServer.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
**Build production-grade Model Context Protocol (MCP) servers with a powerful, type-safe, and extensible foundation.**
|
|
6
6
|
|
|
7
7
|
[](https://www.typescriptlang.org/)
|
|
8
|
-
[](https://github.com/modelcontextprotocol/typescript-sdk)
|
|
9
9
|
[](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-06-18/changelog.mdx)
|
|
10
|
-
[](./CHANGELOG.md)
|
|
11
|
+
[](./vitest.config.ts)
|
|
12
12
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
13
13
|
[](https://github.com/cyanheads/mcp-ts-template/issues)
|
|
14
14
|
[](https://github.com/cyanheads/mcp-ts-template)
|
|
@@ -26,17 +26,18 @@ Building a robust server for AI agents is more than just writing code. It requir
|
|
|
26
26
|
- **Best Practices by Default**: Enforces a clean, modular architecture that's easy to maintain and extend.
|
|
27
27
|
- **AI-Ready**: Designed with LLM agents in mind, including detailed schemas and rich LLM developer-friendly resources (e.g. .clinerules).
|
|
28
28
|
|
|
29
|
-
> **Note on src/mcp-client & src/agent:** The MCP client & Agent components have been enhanced and moved to the [**atlas-mcp-agent**](https://github.com/cyanheads/atlas-mcp-agent) repository. This template now focuses exclusively on providing a best-in-class server implementation and framework.
|
|
29
|
+
> **Note on src/mcp-client & src/agent:** The MCP client & Agent components have been enhanced and moved to the (Coming Soon)[**atlas-mcp-agent**](https://github.com/cyanheads/atlas-mcp-agent) repository. This template now focuses exclusively on providing a best-in-class server implementation and framework.
|
|
30
30
|
|
|
31
31
|
## ✨ Key Features
|
|
32
32
|
|
|
33
33
|
| Feature Area | Description | Key Components / Location |
|
|
34
34
|
| :-------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------- |
|
|
35
35
|
| **🔌 MCP Server** | A functional server with example tools and resources. Supports `stdio` and a **Streamable HTTP** transport built with [**Hono**](https://hono.dev/). | `src/mcp-server/`, `src/mcp-server/transports/` |
|
|
36
|
-
|
|
|
36
|
+
| **🔭 Observability** | Built-in **OpenTelemetry** for distributed tracing and metrics. Auto-instrumentation for core modules and custom tracing for all tool executions. | `src/utils/telemetry/` |
|
|
37
|
+
| **🚀 Production Utilities** | High-performance logging (Pino), Error Handling, ID Generation, Rate Limiting, Async Request Context, Input Sanitization. | `src/utils/` |
|
|
37
38
|
| **🔒 Type Safety/Security** | Strong type checking via TypeScript & Zod validation. Built-in security utilities (sanitization, auth middleware for HTTP). | Throughout, `src/utils/security/`, `src/mcp-server/transports/auth/` |
|
|
38
|
-
| **⚙️ Error Handling** | Consistent error categorization (`
|
|
39
|
-
| **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments, API references.
|
|
39
|
+
| **⚙️ Error Handling** | Consistent error categorization (`JsonRpcErrorCode`), detailed logging, centralized handling (`ErrorHandler`). | `src/utils/internal/errorHandler.ts`, `src/types-global/` |
|
|
40
|
+
| **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments, API references, and a detailed [Migration Guide](./docs/migrations/v1.9.0.md). | `README.md`, Codebase, `tsdoc.json`, `docs/` |
|
|
40
41
|
| **🕵️ Interaction Logging** | Captures raw requests and responses for all external LLM provider interactions to a dedicated `interactions.log` file for full traceability. | `src/utils/internal/logger.ts` |
|
|
41
42
|
| **🤖 Agent Ready** | Includes a [.clinerules](./.clinerules/clinerules.md) developer cheatsheet tailored for LLM coding agents. | `.clinerules/` |
|
|
42
43
|
| **🛠️ Utility Scripts** | Scripts for cleaning builds, setting executable permissions, generating directory trees, and fetching OpenAPI specs. | `scripts/` |
|
|
@@ -48,12 +49,12 @@ Building a robust server for AI agents is more than just writing code. It requir
|
|
|
48
49
|
|
|
49
50
|
This template is built on a set of architectural principles to ensure modularity, testability, and operational clarity.
|
|
50
51
|
|
|
51
|
-
- **Core Server (`src/mcp-server/server.ts`)**: The central point where tools and resources are registered
|
|
52
|
+
- **Core Server (`src/mcp-server/server.ts`)**: The central point where tools and resources are registered using the standard `McpServer` from the SDK.
|
|
52
53
|
- **Transports (`src/mcp-server/transports/`)**: The transport layer connects the core server to the outside world. It supports both `stdio` for direct process communication and a streamable **Hono**-based `http` server.
|
|
53
54
|
- **"Logic Throws, Handler Catches"**: This is the immutable cornerstone of our error-handling strategy.
|
|
54
55
|
- **Core Logic (`logic.ts`)**: This layer is responsible for pure, self-contained business logic. It **throws** a structured `McpError` on any failure.
|
|
55
|
-
- **Handlers (`registration.ts`)**: This layer interfaces with the server, invokes the core logic, and **catches** any errors. It is the exclusive location where errors are processed and formatted into a final response.
|
|
56
|
-
- **Structured, Traceable Operations**: Every operation is traced from initiation to completion via a `RequestContext` that is
|
|
56
|
+
- **Handlers (`registration.ts`)**: This layer interfaces with the server, invokes the core logic, and **catches** any errors using centralized utilities (`createToolHandler`). It is the exclusive location where errors are processed and formatted into a final response.
|
|
57
|
+
- **Structured, Traceable Operations**: Every operation is traced from initiation to completion via a `RequestContext` that is implicitly available throughout the entire asynchronous call stack using Node.js's `AsyncLocalStorage`.
|
|
57
58
|
|
|
58
59
|
## Quick Start
|
|
59
60
|
|
|
@@ -78,11 +79,11 @@ npm run build
|
|
|
78
79
|
|
|
79
80
|
- **Via Stdio (Default):**
|
|
80
81
|
```bash
|
|
81
|
-
npm run start:
|
|
82
|
+
npm run start:stdio
|
|
82
83
|
```
|
|
83
84
|
- **Via Streamable HTTP:**
|
|
84
85
|
```bash
|
|
85
|
-
npm run start:
|
|
86
|
+
npm run start:http
|
|
86
87
|
```
|
|
87
88
|
|
|
88
89
|
### 4. Running Tests
|
|
@@ -106,18 +107,21 @@ This template uses [Vitest](https://vitest.dev/) for testing, with a strong emph
|
|
|
106
107
|
|
|
107
108
|
Configure the server using these environment variables (or a `.env` file):
|
|
108
109
|
|
|
109
|
-
| Variable
|
|
110
|
-
|
|
|
111
|
-
| `MCP_TRANSPORT_TYPE`
|
|
112
|
-
| `MCP_SESSION_MODE`
|
|
113
|
-
| `MCP_HTTP_PORT`
|
|
114
|
-
| `MCP_HTTP_HOST`
|
|
115
|
-
| `MCP_ALLOWED_ORIGINS`
|
|
116
|
-
| `MCP_AUTH_MODE`
|
|
117
|
-
| `MCP_AUTH_SECRET_KEY`
|
|
118
|
-
| `OAUTH_ISSUER_URL`
|
|
119
|
-
| `OAUTH_AUDIENCE`
|
|
120
|
-
| `OPENROUTER_API_KEY`
|
|
110
|
+
| Variable | Description | Default |
|
|
111
|
+
| :------------------------------------ | :---------------------------------------------------------------------------------------- | :------------------------------------- |
|
|
112
|
+
| `MCP_TRANSPORT_TYPE` | Server transport: `stdio` or `http`. | `stdio` |
|
|
113
|
+
| `MCP_SESSION_MODE` | Session mode for HTTP: `stateless`, `stateful`, or `auto`. | `auto` |
|
|
114
|
+
| `MCP_HTTP_PORT` | Port for the HTTP server. | `3010` |
|
|
115
|
+
| `MCP_HTTP_HOST` | Host address for the HTTP server. | `127.0.0.1` |
|
|
116
|
+
| `MCP_ALLOWED_ORIGINS` | Comma-separated allowed origins for CORS. | (none) |
|
|
117
|
+
| `MCP_AUTH_MODE` | Authentication mode for HTTP: `jwt`, `oauth`, or `none`. | `none` |
|
|
118
|
+
| `MCP_AUTH_SECRET_KEY` | **Required for `jwt` mode.** Secret key (min 32 chars) for signing/verifying auth tokens. | (none - **MUST be set in production**) |
|
|
119
|
+
| `OAUTH_ISSUER_URL` | **Required for `oauth` mode.** The issuer URL of your authorization server. | (none) |
|
|
120
|
+
| `OAUTH_AUDIENCE` | **Required for `oauth` mode.** The audience identifier for this MCP server. | (none) |
|
|
121
|
+
| `OPENROUTER_API_KEY` | API key for OpenRouter.ai service. | (none) |
|
|
122
|
+
| `OTEL_ENABLED` | Set to `true` to enable OpenTelemetry instrumentation. | `false` |
|
|
123
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | The OTLP endpoint for exporting traces (e.g., `http://localhost:4318/v1/traces`). | (none; logs to file) |
|
|
124
|
+
| `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` | The OTLP endpoint for exporting metrics (e.g., `http://localhost:4318/v1/metrics`). | (none) |
|
|
121
125
|
|
|
122
126
|
## 🏗️ Project Structure
|
|
123
127
|
|
|
@@ -146,13 +150,13 @@ This is the cornerstone of the architecture:
|
|
|
146
150
|
|
|
147
151
|
1. **`logic.ts`**: This file contains the pure business logic.
|
|
148
152
|
- It defines the Zod schemas for input and output, which serve as the single source of truth for the tool's data contract.
|
|
149
|
-
- The core logic function is pure: it takes validated parameters and
|
|
153
|
+
- The core logic function is pure: it takes validated parameters and either returns a result or **throws** a structured `McpError`. It retrieves the request context via `getRequestContext()`.
|
|
150
154
|
- It **never** contains `try...catch` blocks for formatting a final response.
|
|
151
155
|
|
|
152
156
|
2. **`registration.ts`**: This file is the "handler" that connects the logic to the MCP server.
|
|
153
157
|
- It imports the schemas and logic function from `logic.ts`.
|
|
154
|
-
- It calls `server.registerTool()`, providing the tool's metadata and the runtime handler.
|
|
155
|
-
- The
|
|
158
|
+
- It calls `server.registerTool()`, providing the tool's metadata and the runtime handler created by the `createToolHandler` utility.
|
|
159
|
+
- The centralized handler **always** wraps the call to the logic function in a `try...catch` block. This is the **only** place where errors are caught, processed by the `ErrorHandler`, and formatted into a standardized error response.
|
|
156
160
|
|
|
157
161
|
This pattern ensures that core logic remains decoupled, pure, and easily testable, while the registration layer handles all transport-level concerns, side effects, and response formatting.
|
|
158
162
|
|
package/dist/config/index.d.ts
CHANGED
|
@@ -4,87 +4,43 @@
|
|
|
4
4
|
* environment variables and `package.json`. It uses Zod for schema validation
|
|
5
5
|
* to ensure type safety and correctness of configuration parameters.
|
|
6
6
|
*
|
|
7
|
-
* Key responsibilities:
|
|
8
|
-
* - Load environment variables from a `.env` file.
|
|
9
|
-
* - Read `package.json` for default server name and version.
|
|
10
|
-
* - Define a Zod schema for all expected environment variables.
|
|
11
|
-
* - Validate environment variables against the schema.
|
|
12
|
-
* - Construct and export a comprehensive `config` object.
|
|
13
|
-
* - Export individual configuration values like `logLevel` and `environment` for convenience.
|
|
14
|
-
*
|
|
15
7
|
* @module src/config/index
|
|
16
8
|
*/
|
|
17
|
-
/**
|
|
18
|
-
* Main application configuration object.
|
|
19
|
-
* Aggregates settings from validated environment variables and `package.json`.
|
|
20
|
-
*/
|
|
21
9
|
export declare const config: {
|
|
22
|
-
/** Information from package.json. */
|
|
23
10
|
pkg: {
|
|
24
11
|
name: string;
|
|
25
12
|
version: string;
|
|
26
13
|
};
|
|
27
|
-
/** MCP server name. Env `MCP_SERVER_NAME` > `package.json` name > "mcp-ts-template". */
|
|
28
14
|
mcpServerName: string;
|
|
29
|
-
/** MCP server version. Env `MCP_SERVER_VERSION` > `package.json` version > "0.0.0". */
|
|
30
15
|
mcpServerVersion: string;
|
|
31
|
-
/** Logging level. From `MCP_LOG_LEVEL` env var. Default: "debug". */
|
|
32
16
|
logLevel: string;
|
|
33
|
-
/** Absolute path to the logs directory. From `LOGS_DIR` env var. */
|
|
34
17
|
logsPath: string | null;
|
|
35
|
-
/** Runtime environment. From `NODE_ENV` env var. Default: "development". */
|
|
36
18
|
environment: string;
|
|
37
|
-
/** MCP transport type ('stdio' or 'http'). From `MCP_TRANSPORT_TYPE` env var. Default: "stdio". */
|
|
38
19
|
mcpTransportType: "stdio" | "http";
|
|
39
|
-
/** MCP session mode ('stateless', 'stateful', 'auto'). From `MCP_SESSION_MODE` env var. Default: "auto". */
|
|
40
20
|
mcpSessionMode: "stateless" | "stateful" | "auto";
|
|
41
|
-
/** HTTP server port (if http transport). From `MCP_HTTP_PORT` env var. Default: 3010. */
|
|
42
21
|
mcpHttpPort: number;
|
|
43
|
-
/** HTTP server host (if http transport). From `MCP_HTTP_HOST` env var. Default: "127.0.0.1". */
|
|
44
22
|
mcpHttpHost: string;
|
|
45
|
-
/** MCP endpoint path for HTTP transport. From `MCP_HTTP_ENDPOINT_PATH`. Default: "/mcp". */
|
|
46
23
|
mcpHttpEndpointPath: string;
|
|
47
|
-
/** Max retries for port binding. From `MCP_HTTP_MAX_PORT_RETRIES`. Default: 15. */
|
|
48
24
|
mcpHttpMaxPortRetries: number;
|
|
49
|
-
/** Delay between port binding retries. From `MCP_HTTP_PORT_RETRY_DELAY_MS`. Default: 50. */
|
|
50
25
|
mcpHttpPortRetryDelayMs: number;
|
|
51
|
-
/** Timeout for stale stateful sessions. From `MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS`. Default: 1800000. */
|
|
52
26
|
mcpStatefulSessionStaleTimeoutMs: number;
|
|
53
|
-
/** Array of allowed CORS origins (http transport). From `MCP_ALLOWED_ORIGINS` (comma-separated). */
|
|
54
27
|
mcpAllowedOrigins: string[] | undefined;
|
|
55
|
-
/** Auth secret key (JWTs, http transport). From `MCP_AUTH_SECRET_KEY`. CRITICAL. */
|
|
56
28
|
mcpAuthSecretKey: string | undefined;
|
|
57
|
-
/** The authentication mode ('jwt' or 'oauth'). From `MCP_AUTH_MODE`. */
|
|
58
29
|
mcpAuthMode: "jwt" | "oauth" | "none";
|
|
59
|
-
/** OAuth 2.1 Issuer URL. From `OAUTH_ISSUER_URL`. */
|
|
60
30
|
oauthIssuerUrl: string | undefined;
|
|
61
|
-
/** OAuth 2.1 JWKS URI. From `OAUTH_JWKS_URI`. */
|
|
62
31
|
oauthJwksUri: string | undefined;
|
|
63
|
-
/** OAuth 2.1 Audience. From `OAUTH_AUDIENCE`. */
|
|
64
32
|
oauthAudience: string | undefined;
|
|
65
|
-
/** Development mode client ID. From `DEV_MCP_CLIENT_ID`. */
|
|
66
33
|
devMcpClientId: string | undefined;
|
|
67
|
-
/** Development mode scopes. From `DEV_MCP_SCOPES`. */
|
|
68
34
|
devMcpScopes: string[] | undefined;
|
|
69
|
-
/** OpenRouter App URL. From `OPENROUTER_APP_URL`. Default: "http://localhost:3000". */
|
|
70
35
|
openrouterAppUrl: string;
|
|
71
|
-
/** OpenRouter App Name. From `OPENROUTER_APP_NAME`. Defaults to `mcpServerName`. */
|
|
72
36
|
openrouterAppName: string;
|
|
73
|
-
/** OpenRouter API Key. From `OPENROUTER_API_KEY`. */
|
|
74
37
|
openrouterApiKey: string | undefined;
|
|
75
|
-
/** Default LLM model. From `LLM_DEFAULT_MODEL`. */
|
|
76
38
|
llmDefaultModel: string;
|
|
77
|
-
/** Default LLM temperature. From `LLM_DEFAULT_TEMPERATURE`. */
|
|
78
39
|
llmDefaultTemperature: number | undefined;
|
|
79
|
-
/** Default LLM top_p. From `LLM_DEFAULT_TOP_P`. */
|
|
80
40
|
llmDefaultTopP: number | undefined;
|
|
81
|
-
/** Default LLM max tokens. From `LLM_DEFAULT_MAX_TOKENS`. */
|
|
82
41
|
llmDefaultMaxTokens: number | undefined;
|
|
83
|
-
/** Default LLM top_k. From `LLM_DEFAULT_TOP_K`. */
|
|
84
42
|
llmDefaultTopK: number | undefined;
|
|
85
|
-
/** Default LLM min_p. From `LLM_DEFAULT_MIN_P`. */
|
|
86
43
|
llmDefaultMinP: number | undefined;
|
|
87
|
-
/** OAuth Proxy configurations. Undefined if no related env vars are set. */
|
|
88
44
|
oauthProxy: {
|
|
89
45
|
authorizationUrl: string | undefined;
|
|
90
46
|
tokenUrl: string | undefined;
|
|
@@ -93,21 +49,21 @@ export declare const config: {
|
|
|
93
49
|
serviceDocumentationUrl: string | undefined;
|
|
94
50
|
defaultClientRedirectUris: string[] | undefined;
|
|
95
51
|
} | undefined;
|
|
96
|
-
/** Supabase configuration. Undefined if no related env vars are set. */
|
|
97
52
|
supabase: {
|
|
98
53
|
url: string;
|
|
99
54
|
anonKey: string;
|
|
100
55
|
serviceRoleKey: string | undefined;
|
|
101
56
|
} | undefined;
|
|
57
|
+
openTelemetry: {
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
serviceName: string;
|
|
60
|
+
serviceVersion: string;
|
|
61
|
+
tracesEndpoint: string | undefined;
|
|
62
|
+
metricsEndpoint: string | undefined;
|
|
63
|
+
samplingRatio: number;
|
|
64
|
+
logLevel: "NONE" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "VERBOSE" | "ALL";
|
|
65
|
+
};
|
|
102
66
|
};
|
|
103
|
-
/**
|
|
104
|
-
* Configured logging level for the application.
|
|
105
|
-
* Exported for convenience.
|
|
106
|
-
*/
|
|
107
67
|
export declare const logLevel: string;
|
|
108
|
-
/**
|
|
109
|
-
* Configured runtime environment ("development", "production", etc.).
|
|
110
|
-
* Exported for convenience.
|
|
111
|
-
*/
|
|
112
68
|
export declare const environment: string;
|
|
113
69
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoRH,eAAO,MAAM,MAAM;;cAhOiB,MAAM;iBAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuS1D,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,MAAwB,CAAC;AAChD,eAAO,MAAM,WAAW,EAAE,MAA2B,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -4,14 +4,6 @@
|
|
|
4
4
|
* environment variables and `package.json`. It uses Zod for schema validation
|
|
5
5
|
* to ensure type safety and correctness of configuration parameters.
|
|
6
6
|
*
|
|
7
|
-
* Key responsibilities:
|
|
8
|
-
* - Load environment variables from a `.env` file.
|
|
9
|
-
* - Read `package.json` for default server name and version.
|
|
10
|
-
* - Define a Zod schema for all expected environment variables.
|
|
11
|
-
* - Validate environment variables against the schema.
|
|
12
|
-
* - Construct and export a comprehensive `config` object.
|
|
13
|
-
* - Export individual configuration values like `logLevel` and `environment` for convenience.
|
|
14
|
-
*
|
|
15
7
|
* @module src/config/index
|
|
16
8
|
*/
|
|
17
9
|
import dotenv from "dotenv";
|
|
@@ -21,13 +13,12 @@ import { fileURLToPath } from "url";
|
|
|
21
13
|
import { z } from "zod";
|
|
22
14
|
dotenv.config();
|
|
23
15
|
// --- Determine Project Root ---
|
|
24
|
-
/**
|
|
25
|
-
* Finds the project root directory by searching upwards for package.json.
|
|
26
|
-
* @param startDir The directory to start searching from.
|
|
27
|
-
* @returns The absolute path to the project root, or throws an error if not found.
|
|
28
|
-
*/
|
|
29
16
|
const findProjectRoot = (startDir) => {
|
|
30
17
|
let currentDir = startDir;
|
|
18
|
+
// If the start directory is in `dist`, start searching from the parent directory.
|
|
19
|
+
if (path.basename(currentDir) === "dist") {
|
|
20
|
+
currentDir = path.dirname(currentDir);
|
|
21
|
+
}
|
|
31
22
|
while (true) {
|
|
32
23
|
const packageJsonPath = join(currentDir, "package.json");
|
|
33
24
|
if (existsSync(packageJsonPath)) {
|
|
@@ -35,7 +26,6 @@ const findProjectRoot = (startDir) => {
|
|
|
35
26
|
}
|
|
36
27
|
const parentDir = dirname(currentDir);
|
|
37
28
|
if (parentDir === currentDir) {
|
|
38
|
-
// Reached the root of the filesystem without finding package.json
|
|
39
29
|
throw new Error(`Could not find project root (package.json) starting from ${startDir}`);
|
|
40
30
|
}
|
|
41
31
|
currentDir = parentDir;
|
|
@@ -43,165 +33,150 @@ const findProjectRoot = (startDir) => {
|
|
|
43
33
|
};
|
|
44
34
|
let projectRoot;
|
|
45
35
|
try {
|
|
46
|
-
// For ESM, __dirname is not available directly.
|
|
47
|
-
// import.meta.url gives the URL of the current module.
|
|
48
36
|
const currentModuleDir = dirname(fileURLToPath(import.meta.url));
|
|
49
37
|
projectRoot = findProjectRoot(currentModuleDir);
|
|
50
38
|
}
|
|
51
39
|
catch (error) {
|
|
52
40
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
53
41
|
console.error(`FATAL: Error determining project root: ${errorMessage}`);
|
|
54
|
-
// Fallback to process.cwd() if project root cannot be determined.
|
|
55
|
-
// This might happen in unusual execution environments.
|
|
56
42
|
projectRoot = process.cwd();
|
|
57
|
-
console.warn(`Warning: Using process.cwd() (${projectRoot}) as fallback project root.`);
|
|
58
|
-
}
|
|
59
|
-
// --- End Determine Project Root ---
|
|
60
|
-
const pkgPath = join(projectRoot, "package.json"); // Use determined projectRoot
|
|
61
|
-
let pkg = { name: "mcp-ts-template", version: "0.0.0" };
|
|
62
|
-
try {
|
|
63
|
-
pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
43
|
if (process.stdout.isTTY) {
|
|
67
|
-
console.
|
|
44
|
+
console.warn(`Warning: Using process.cwd() (${projectRoot}) as fallback project root.`);
|
|
68
45
|
}
|
|
69
46
|
}
|
|
47
|
+
// --- End Determine Project Root ---
|
|
70
48
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
49
|
+
* Loads and parses the package.json file from the project root.
|
|
50
|
+
* @returns The parsed package.json object or a fallback default.
|
|
73
51
|
* @private
|
|
74
52
|
*/
|
|
53
|
+
const loadPackageJson = () => {
|
|
54
|
+
const pkgPath = join(projectRoot, "package.json");
|
|
55
|
+
const fallback = { name: "mcp-ts-template", version: "1.0.0" };
|
|
56
|
+
if (!existsSync(pkgPath)) {
|
|
57
|
+
if (process.stdout.isTTY) {
|
|
58
|
+
console.warn(`Warning: package.json not found at ${pkgPath}. Using fallback values. This is expected in some environments (e.g., Docker) but may indicate an issue with project root detection.`);
|
|
59
|
+
}
|
|
60
|
+
return fallback;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const fileContents = readFileSync(pkgPath, "utf-8");
|
|
64
|
+
const parsed = JSON.parse(fileContents);
|
|
65
|
+
return {
|
|
66
|
+
name: typeof parsed.name === "string" ? parsed.name : fallback.name,
|
|
67
|
+
version: typeof parsed.version === "string" ? parsed.version : fallback.version,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (process.stdout.isTTY) {
|
|
72
|
+
console.error("Warning: Could not read or parse package.json. Using hardcoded defaults.", error);
|
|
73
|
+
}
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const pkg = loadPackageJson();
|
|
75
78
|
const EnvSchema = z.object({
|
|
76
|
-
|
|
79
|
+
// --- Existing MCP and other variables ---
|
|
77
80
|
MCP_SERVER_NAME: z.string().optional(),
|
|
78
|
-
/** Optional. The version of the MCP server. Defaults to `package.json` version. */
|
|
79
81
|
MCP_SERVER_VERSION: z.string().optional(),
|
|
80
|
-
/** Minimum logging level. See `McpLogLevel` in logger utility. Default: "debug". */
|
|
81
82
|
MCP_LOG_LEVEL: z.string().default("debug"),
|
|
82
|
-
/** Directory for log files. Defaults to "logs" in project root. */
|
|
83
83
|
LOGS_DIR: z.string().default(path.join(projectRoot, "logs")),
|
|
84
|
-
/** Runtime environment (e.g., "development", "production"). Default: "development". */
|
|
85
84
|
NODE_ENV: z.string().default("development"),
|
|
86
|
-
/** MCP communication transport ("stdio" or "http"). Default: "stdio". */
|
|
87
85
|
MCP_TRANSPORT_TYPE: z.enum(["stdio", "http"]).default("stdio"),
|
|
88
|
-
/** MCP session mode ('stateless', 'stateful', 'auto'). Default: 'auto'. */
|
|
89
86
|
MCP_SESSION_MODE: z.enum(["stateless", "stateful", "auto"]).default("auto"),
|
|
90
|
-
/** HTTP server port (if MCP_TRANSPORT_TYPE is "http"). Default: 3010. */
|
|
91
87
|
MCP_HTTP_PORT: z.coerce.number().int().positive().default(3010),
|
|
92
|
-
/** HTTP server host (if MCP_TRANSPORT_TYPE is "http"). Default: "127.0.0.1". */
|
|
93
88
|
MCP_HTTP_HOST: z.string().default("127.0.0.1"),
|
|
94
|
-
/** The endpoint path for the MCP server. Default: "/mcp". */
|
|
95
89
|
MCP_HTTP_ENDPOINT_PATH: z.string().default("/mcp"),
|
|
96
|
-
/** Max retries for binding to a port if the initial one is in use. Default: 15. */
|
|
97
90
|
MCP_HTTP_MAX_PORT_RETRIES: z.coerce.number().int().nonnegative().default(15),
|
|
98
|
-
/** Delay in ms between port binding retries. Default: 50. */
|
|
99
91
|
MCP_HTTP_PORT_RETRY_DELAY_MS: z.coerce
|
|
100
92
|
.number()
|
|
101
93
|
.int()
|
|
102
94
|
.nonnegative()
|
|
103
95
|
.default(50),
|
|
104
|
-
/** Timeout in ms for considering a stateful session stale and eligible for cleanup. Default: 1800000 (30 minutes). */
|
|
105
96
|
MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS: z.coerce
|
|
106
97
|
.number()
|
|
107
98
|
.int()
|
|
108
99
|
.positive()
|
|
109
100
|
.default(1_800_000),
|
|
110
|
-
/** Optional. Comma-separated allowed origins for CORS (HTTP transport). */
|
|
111
101
|
MCP_ALLOWED_ORIGINS: z.string().optional(),
|
|
112
|
-
/** Optional. Secret key (min 32 chars) for auth tokens (HTTP transport). CRITICAL for production. */
|
|
113
102
|
MCP_AUTH_SECRET_KEY: z
|
|
114
103
|
.string()
|
|
115
104
|
.min(32, "MCP_AUTH_SECRET_KEY must be at least 32 characters long for security reasons.")
|
|
116
105
|
.optional(),
|
|
117
|
-
/** The authentication mode to use. 'jwt' for internal simple JWTs, 'oauth' for OAuth 2.1, or 'none'. Default: 'none'. */
|
|
118
106
|
MCP_AUTH_MODE: z.enum(["jwt", "oauth", "none"]).default("none"),
|
|
119
|
-
/** The expected issuer URL for OAuth 2.1 access tokens. CRITICAL for validation. */
|
|
120
107
|
OAUTH_ISSUER_URL: z.string().url().optional(),
|
|
121
|
-
/** The JWKS (JSON Web Key Set) URI for the OAuth 2.1 provider. If not provided, it's often discoverable from the issuer URL. */
|
|
122
108
|
OAUTH_JWKS_URI: z.string().url().optional(),
|
|
123
|
-
/** The audience claim for the OAuth 2.1 access tokens. This server will reject tokens not intended for it. */
|
|
124
109
|
OAUTH_AUDIENCE: z.string().optional(),
|
|
125
|
-
/** Optional. Client ID to use in development mode for JWT strategy. Default: "dev-client-id". */
|
|
126
110
|
DEV_MCP_CLIENT_ID: z.string().optional(),
|
|
127
|
-
/** Optional. Comma-separated scopes for development mode JWT strategy. Default: "dev-scope". */
|
|
128
111
|
DEV_MCP_SCOPES: z.string().optional(),
|
|
129
|
-
/** Optional. Application URL for OpenRouter integration. */
|
|
130
112
|
OPENROUTER_APP_URL: z
|
|
131
113
|
.string()
|
|
132
114
|
.url("OPENROUTER_APP_URL must be a valid URL (e.g., http://localhost:3000)")
|
|
133
115
|
.optional(),
|
|
134
|
-
/** Optional. Application name for OpenRouter. Defaults to MCP_SERVER_NAME or package name. */
|
|
135
116
|
OPENROUTER_APP_NAME: z.string().optional(),
|
|
136
|
-
/** Optional. API key for OpenRouter services. */
|
|
137
117
|
OPENROUTER_API_KEY: z.string().optional(),
|
|
138
|
-
/** Default LLM model. Default: "google/gemini-2.5-flash". */
|
|
139
118
|
LLM_DEFAULT_MODEL: z.string().default("google/gemini-2.5-flash"),
|
|
140
|
-
/** Optional. Default LLM temperature (0.0-2.0). */
|
|
141
119
|
LLM_DEFAULT_TEMPERATURE: z.coerce.number().min(0).max(2).optional(),
|
|
142
|
-
/** Optional. Default LLM top_p (0.0-1.0). */
|
|
143
120
|
LLM_DEFAULT_TOP_P: z.coerce.number().min(0).max(1).optional(),
|
|
144
|
-
/** Optional. Default LLM max tokens (positive integer). */
|
|
145
121
|
LLM_DEFAULT_MAX_TOKENS: z.coerce.number().int().positive().optional(),
|
|
146
|
-
/** Optional. Default LLM top_k (non-negative integer). */
|
|
147
122
|
LLM_DEFAULT_TOP_K: z.coerce.number().int().nonnegative().optional(),
|
|
148
|
-
/** Optional. Default LLM min_p (0.0-1.0). */
|
|
149
123
|
LLM_DEFAULT_MIN_P: z.coerce.number().min(0).max(1).optional(),
|
|
150
|
-
/** Optional. OAuth provider authorization endpoint URL. */
|
|
151
124
|
OAUTH_PROXY_AUTHORIZATION_URL: z
|
|
152
125
|
.string()
|
|
153
126
|
.url("OAUTH_PROXY_AUTHORIZATION_URL must be a valid URL.")
|
|
154
127
|
.optional(),
|
|
155
|
-
/** Optional. OAuth provider token endpoint URL. */
|
|
156
128
|
OAUTH_PROXY_TOKEN_URL: z
|
|
157
129
|
.string()
|
|
158
130
|
.url("OAUTH_PROXY_TOKEN_URL must be a valid URL.")
|
|
159
131
|
.optional(),
|
|
160
|
-
/** Optional. OAuth provider revocation endpoint URL. */
|
|
161
132
|
OAUTH_PROXY_REVOCATION_URL: z
|
|
162
133
|
.string()
|
|
163
134
|
.url("OAUTH_PROXY_REVOCATION_URL must be a valid URL.")
|
|
164
135
|
.optional(),
|
|
165
|
-
/** Optional. OAuth provider issuer URL. */
|
|
166
136
|
OAUTH_PROXY_ISSUER_URL: z
|
|
167
137
|
.string()
|
|
168
138
|
.url("OAUTH_PROXY_ISSUER_URL must be a valid URL.")
|
|
169
139
|
.optional(),
|
|
170
|
-
/** Optional. OAuth service documentation URL. */
|
|
171
140
|
OAUTH_PROXY_SERVICE_DOCUMENTATION_URL: z
|
|
172
141
|
.string()
|
|
173
142
|
.url("OAUTH_PROXY_SERVICE_DOCUMENTATION_URL must be a valid URL.")
|
|
174
143
|
.optional(),
|
|
175
|
-
/** Optional. Comma-separated default OAuth client redirect URIs. */
|
|
176
144
|
OAUTH_PROXY_DEFAULT_CLIENT_REDIRECT_URIS: z.string().optional(),
|
|
177
|
-
/** Supabase Project URL. From `SUPABASE_URL`. */
|
|
178
145
|
SUPABASE_URL: z.string().url("SUPABASE_URL must be a valid URL.").optional(),
|
|
179
|
-
/** Supabase Anon Key (public). From `SUPABASE_ANON_KEY`. */
|
|
180
146
|
SUPABASE_ANON_KEY: z.string().optional(),
|
|
181
|
-
/** Supabase Service Role Key (secret). From `SUPABASE_SERVICE_ROLE_KEY`. */
|
|
182
147
|
SUPABASE_SERVICE_ROLE_KEY: z.string().optional(),
|
|
148
|
+
// --- START: OpenTelemetry Configuration ---
|
|
149
|
+
/** If 'true', OpenTelemetry will be initialized and enabled. Default: 'false'. */
|
|
150
|
+
OTEL_ENABLED: z
|
|
151
|
+
.string()
|
|
152
|
+
.transform((v) => v.toLowerCase() === "true")
|
|
153
|
+
.default("false"),
|
|
154
|
+
/** The logical name of the service. Defaults to MCP_SERVER_NAME or package name. */
|
|
155
|
+
OTEL_SERVICE_NAME: z.string().optional(),
|
|
156
|
+
/** The version of the service. Defaults to MCP_SERVER_VERSION or package version. */
|
|
157
|
+
OTEL_SERVICE_VERSION: z.string().optional(),
|
|
158
|
+
/** The OTLP endpoint for traces. If not set, traces are logged to a file in development. */
|
|
159
|
+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: z.string().url().optional(),
|
|
160
|
+
/** The OTLP endpoint for metrics. If not set, metrics are not exported. */
|
|
161
|
+
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: z.string().url().optional(),
|
|
162
|
+
/** Sampling ratio for traces (0.0 to 1.0). 1.0 means sample all. Default: 1.0 */
|
|
163
|
+
OTEL_TRACES_SAMPLER_ARG: z.coerce.number().min(0).max(1).default(1.0),
|
|
164
|
+
/** Log level for OpenTelemetry's internal diagnostic logger. Default: "INFO". */
|
|
165
|
+
OTEL_LOG_LEVEL: z
|
|
166
|
+
.enum(["NONE", "ERROR", "WARN", "INFO", "DEBUG", "VERBOSE", "ALL"])
|
|
167
|
+
.default("INFO"),
|
|
183
168
|
});
|
|
184
169
|
const parsedEnv = EnvSchema.safeParse(process.env);
|
|
185
170
|
if (!parsedEnv.success) {
|
|
186
171
|
if (process.stdout.isTTY) {
|
|
187
172
|
console.error("❌ Invalid environment variables found:", parsedEnv.error.flatten().fieldErrors);
|
|
188
173
|
}
|
|
189
|
-
// Consider throwing an error in production for critical misconfigurations.
|
|
190
174
|
}
|
|
191
175
|
const env = parsedEnv.success ? parsedEnv.data : EnvSchema.parse({});
|
|
192
|
-
// --- Directory Ensurance Function ---
|
|
193
|
-
/**
|
|
194
|
-
* Ensures a directory exists and is within the project root.
|
|
195
|
-
* @param dirPath The desired path for the directory (can be relative or absolute).
|
|
196
|
-
* @param rootDir The root directory of the project to contain the directory.
|
|
197
|
-
* @param dirName The name of the directory type for logging (e.g., "logs").
|
|
198
|
-
* @returns The validated, absolute path to the directory, or null if invalid.
|
|
199
|
-
*/
|
|
200
176
|
const ensureDirectory = (dirPath, rootDir, dirName) => {
|
|
201
177
|
const resolvedDirPath = path.isAbsolute(dirPath)
|
|
202
178
|
? dirPath
|
|
203
179
|
: path.resolve(rootDir, dirPath);
|
|
204
|
-
// Ensure the resolved path is within the project root boundary
|
|
205
180
|
if (!resolvedDirPath.startsWith(rootDir + path.sep) &&
|
|
206
181
|
resolvedDirPath !== rootDir) {
|
|
207
182
|
if (process.stdout.isTTY) {
|
|
@@ -244,95 +219,53 @@ const ensureDirectory = (dirPath, rootDir, dirName) => {
|
|
|
244
219
|
}
|
|
245
220
|
return resolvedDirPath;
|
|
246
221
|
};
|
|
247
|
-
// --- End Directory Ensurance Function ---
|
|
248
|
-
// --- Logs Directory Handling ---
|
|
249
222
|
let validatedLogsPath = ensureDirectory(env.LOGS_DIR, projectRoot, "logs");
|
|
250
223
|
if (!validatedLogsPath) {
|
|
251
224
|
if (process.stdout.isTTY) {
|
|
252
225
|
console.warn(`Warning: Custom logs directory ('${env.LOGS_DIR}') is invalid or outside the project boundary. Falling back to default.`);
|
|
253
226
|
}
|
|
254
|
-
// Try again with the absolute default path
|
|
255
227
|
const defaultLogsDir = path.join(projectRoot, "logs");
|
|
256
228
|
validatedLogsPath = ensureDirectory(defaultLogsDir, projectRoot, "logs");
|
|
257
229
|
if (!validatedLogsPath) {
|
|
258
230
|
if (process.stdout.isTTY) {
|
|
259
|
-
// This is just a warning now, not fatal.
|
|
260
231
|
console.warn("Warning: Default logs directory could not be created. File logging will be disabled.");
|
|
261
232
|
}
|
|
262
|
-
// Do not exit. validatedLogsPath remains null, and the logger will handle it.
|
|
263
233
|
}
|
|
264
234
|
}
|
|
265
|
-
// --- End Logs Directory Handling ---
|
|
266
|
-
/**
|
|
267
|
-
* Main application configuration object.
|
|
268
|
-
* Aggregates settings from validated environment variables and `package.json`.
|
|
269
|
-
*/
|
|
270
235
|
export const config = {
|
|
271
|
-
/** Information from package.json. */
|
|
272
236
|
pkg,
|
|
273
|
-
/** MCP server name. Env `MCP_SERVER_NAME` > `package.json` name > "mcp-ts-template". */
|
|
274
237
|
mcpServerName: env.MCP_SERVER_NAME || pkg.name,
|
|
275
|
-
/** MCP server version. Env `MCP_SERVER_VERSION` > `package.json` version > "0.0.0". */
|
|
276
238
|
mcpServerVersion: env.MCP_SERVER_VERSION || pkg.version,
|
|
277
|
-
/** Logging level. From `MCP_LOG_LEVEL` env var. Default: "debug". */
|
|
278
239
|
logLevel: env.MCP_LOG_LEVEL,
|
|
279
|
-
/** Absolute path to the logs directory. From `LOGS_DIR` env var. */
|
|
280
240
|
logsPath: validatedLogsPath,
|
|
281
|
-
/** Runtime environment. From `NODE_ENV` env var. Default: "development". */
|
|
282
241
|
environment: env.NODE_ENV,
|
|
283
|
-
/** MCP transport type ('stdio' or 'http'). From `MCP_TRANSPORT_TYPE` env var. Default: "stdio". */
|
|
284
242
|
mcpTransportType: env.MCP_TRANSPORT_TYPE,
|
|
285
|
-
/** MCP session mode ('stateless', 'stateful', 'auto'). From `MCP_SESSION_MODE` env var. Default: "auto". */
|
|
286
243
|
mcpSessionMode: env.MCP_SESSION_MODE,
|
|
287
|
-
/** HTTP server port (if http transport). From `MCP_HTTP_PORT` env var. Default: 3010. */
|
|
288
244
|
mcpHttpPort: env.MCP_HTTP_PORT,
|
|
289
|
-
/** HTTP server host (if http transport). From `MCP_HTTP_HOST` env var. Default: "127.0.0.1". */
|
|
290
245
|
mcpHttpHost: env.MCP_HTTP_HOST,
|
|
291
|
-
/** MCP endpoint path for HTTP transport. From `MCP_HTTP_ENDPOINT_PATH`. Default: "/mcp". */
|
|
292
246
|
mcpHttpEndpointPath: env.MCP_HTTP_ENDPOINT_PATH,
|
|
293
|
-
/** Max retries for port binding. From `MCP_HTTP_MAX_PORT_RETRIES`. Default: 15. */
|
|
294
247
|
mcpHttpMaxPortRetries: env.MCP_HTTP_MAX_PORT_RETRIES,
|
|
295
|
-
/** Delay between port binding retries. From `MCP_HTTP_PORT_RETRY_DELAY_MS`. Default: 50. */
|
|
296
248
|
mcpHttpPortRetryDelayMs: env.MCP_HTTP_PORT_RETRY_DELAY_MS,
|
|
297
|
-
/** Timeout for stale stateful sessions. From `MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS`. Default: 1800000. */
|
|
298
249
|
mcpStatefulSessionStaleTimeoutMs: env.MCP_STATEFUL_SESSION_STALE_TIMEOUT_MS,
|
|
299
|
-
/** Array of allowed CORS origins (http transport). From `MCP_ALLOWED_ORIGINS` (comma-separated). */
|
|
300
250
|
mcpAllowedOrigins: env.MCP_ALLOWED_ORIGINS?.split(",")
|
|
301
251
|
.map((origin) => origin.trim())
|
|
302
252
|
.filter(Boolean),
|
|
303
|
-
/** Auth secret key (JWTs, http transport). From `MCP_AUTH_SECRET_KEY`. CRITICAL. */
|
|
304
253
|
mcpAuthSecretKey: env.MCP_AUTH_SECRET_KEY,
|
|
305
|
-
/** The authentication mode ('jwt' or 'oauth'). From `MCP_AUTH_MODE`. */
|
|
306
254
|
mcpAuthMode: env.MCP_AUTH_MODE,
|
|
307
|
-
/** OAuth 2.1 Issuer URL. From `OAUTH_ISSUER_URL`. */
|
|
308
255
|
oauthIssuerUrl: env.OAUTH_ISSUER_URL,
|
|
309
|
-
/** OAuth 2.1 JWKS URI. From `OAUTH_JWKS_URI`. */
|
|
310
256
|
oauthJwksUri: env.OAUTH_JWKS_URI,
|
|
311
|
-
/** OAuth 2.1 Audience. From `OAUTH_AUDIENCE`. */
|
|
312
257
|
oauthAudience: env.OAUTH_AUDIENCE,
|
|
313
|
-
/** Development mode client ID. From `DEV_MCP_CLIENT_ID`. */
|
|
314
258
|
devMcpClientId: env.DEV_MCP_CLIENT_ID,
|
|
315
|
-
/** Development mode scopes. From `DEV_MCP_SCOPES`. */
|
|
316
259
|
devMcpScopes: env.DEV_MCP_SCOPES?.split(",").map((s) => s.trim()),
|
|
317
|
-
/** OpenRouter App URL. From `OPENROUTER_APP_URL`. Default: "http://localhost:3000". */
|
|
318
260
|
openrouterAppUrl: env.OPENROUTER_APP_URL || "http://localhost:3000",
|
|
319
|
-
|
|
320
|
-
openrouterAppName: env.OPENROUTER_APP_NAME || pkg.name || "MCP TS App",
|
|
321
|
-
/** OpenRouter API Key. From `OPENROUTER_API_KEY`. */
|
|
261
|
+
openrouterAppName: env.OPENROUTER_APP_NAME || pkg.name || "mcp-ts-template",
|
|
322
262
|
openrouterApiKey: env.OPENROUTER_API_KEY,
|
|
323
|
-
/** Default LLM model. From `LLM_DEFAULT_MODEL`. */
|
|
324
263
|
llmDefaultModel: env.LLM_DEFAULT_MODEL,
|
|
325
|
-
/** Default LLM temperature. From `LLM_DEFAULT_TEMPERATURE`. */
|
|
326
264
|
llmDefaultTemperature: env.LLM_DEFAULT_TEMPERATURE,
|
|
327
|
-
/** Default LLM top_p. From `LLM_DEFAULT_TOP_P`. */
|
|
328
265
|
llmDefaultTopP: env.LLM_DEFAULT_TOP_P,
|
|
329
|
-
/** Default LLM max tokens. From `LLM_DEFAULT_MAX_TOKENS`. */
|
|
330
266
|
llmDefaultMaxTokens: env.LLM_DEFAULT_MAX_TOKENS,
|
|
331
|
-
/** Default LLM top_k. From `LLM_DEFAULT_TOP_K`. */
|
|
332
267
|
llmDefaultTopK: env.LLM_DEFAULT_TOP_K,
|
|
333
|
-
/** Default LLM min_p. From `LLM_DEFAULT_MIN_P`. */
|
|
334
268
|
llmDefaultMinP: env.LLM_DEFAULT_MIN_P,
|
|
335
|
-
/** OAuth Proxy configurations. Undefined if no related env vars are set. */
|
|
336
269
|
oauthProxy: env.OAUTH_PROXY_AUTHORIZATION_URL ||
|
|
337
270
|
env.OAUTH_PROXY_TOKEN_URL ||
|
|
338
271
|
env.OAUTH_PROXY_REVOCATION_URL ||
|
|
@@ -350,7 +283,6 @@ export const config = {
|
|
|
350
283
|
.filter(Boolean),
|
|
351
284
|
}
|
|
352
285
|
: undefined,
|
|
353
|
-
/** Supabase configuration. Undefined if no related env vars are set. */
|
|
354
286
|
supabase: env.SUPABASE_URL && env.SUPABASE_ANON_KEY
|
|
355
287
|
? {
|
|
356
288
|
url: env.SUPABASE_URL,
|
|
@@ -358,15 +290,16 @@ export const config = {
|
|
|
358
290
|
serviceRoleKey: env.SUPABASE_SERVICE_ROLE_KEY,
|
|
359
291
|
}
|
|
360
292
|
: undefined,
|
|
293
|
+
openTelemetry: {
|
|
294
|
+
enabled: env.OTEL_ENABLED,
|
|
295
|
+
serviceName: env.OTEL_SERVICE_NAME || env.MCP_SERVER_NAME || pkg.name,
|
|
296
|
+
serviceVersion: env.OTEL_SERVICE_VERSION || env.MCP_SERVER_VERSION || pkg.version,
|
|
297
|
+
tracesEndpoint: env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
|
|
298
|
+
metricsEndpoint: env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT,
|
|
299
|
+
samplingRatio: env.OTEL_TRACES_SAMPLER_ARG,
|
|
300
|
+
logLevel: env.OTEL_LOG_LEVEL,
|
|
301
|
+
},
|
|
361
302
|
};
|
|
362
|
-
/**
|
|
363
|
-
* Configured logging level for the application.
|
|
364
|
-
* Exported for convenience.
|
|
365
|
-
*/
|
|
366
303
|
export const logLevel = config.logLevel;
|
|
367
|
-
/**
|
|
368
|
-
* Configured runtime environment ("development", "production", etc.).
|
|
369
|
-
* Exported for convenience.
|
|
370
|
-
*/
|
|
371
304
|
export const environment = config.environment;
|
|
372
305
|
//# sourceMappingURL=index.js.map
|