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.
Files changed (195) hide show
  1. package/README.md +31 -27
  2. package/dist/config/index.d.ts +9 -53
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/index.js +64 -131
  5. package/dist/config/index.js.map +1 -1
  6. package/dist/index.d.ts +0 -15
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +36 -133
  9. package/dist/index.js.map +1 -1
  10. package/dist/mcp-server/resources/echoResource/logic.d.ts +1 -2
  11. package/dist/mcp-server/resources/echoResource/logic.d.ts.map +1 -1
  12. package/dist/mcp-server/resources/echoResource/logic.js +5 -6
  13. package/dist/mcp-server/resources/echoResource/logic.js.map +1 -1
  14. package/dist/mcp-server/resources/echoResource/registration.d.ts +1 -7
  15. package/dist/mcp-server/resources/echoResource/registration.d.ts.map +1 -1
  16. package/dist/mcp-server/resources/echoResource/registration.js +31 -59
  17. package/dist/mcp-server/resources/echoResource/registration.js.map +1 -1
  18. package/dist/mcp-server/resources/index.d.ts +10 -0
  19. package/dist/mcp-server/resources/index.d.ts.map +1 -0
  20. package/dist/mcp-server/resources/index.js +19 -0
  21. package/dist/mcp-server/resources/index.js.map +1 -0
  22. package/dist/mcp-server/resources/utils/resource-utils.d.ts +43 -0
  23. package/dist/mcp-server/resources/utils/resource-utils.d.ts.map +1 -0
  24. package/dist/mcp-server/resources/utils/resource-utils.js +44 -0
  25. package/dist/mcp-server/resources/utils/resource-utils.js.map +1 -0
  26. package/dist/mcp-server/server.d.ts +2 -2
  27. package/dist/mcp-server/server.d.ts.map +1 -1
  28. package/dist/mcp-server/server.js +23 -37
  29. package/dist/mcp-server/server.js.map +1 -1
  30. package/dist/mcp-server/tools/catFactFetcher/logic.d.ts +2 -5
  31. package/dist/mcp-server/tools/catFactFetcher/logic.d.ts.map +1 -1
  32. package/dist/mcp-server/tools/catFactFetcher/logic.js +15 -20
  33. package/dist/mcp-server/tools/catFactFetcher/logic.js.map +1 -1
  34. package/dist/mcp-server/tools/catFactFetcher/registration.d.ts +1 -7
  35. package/dist/mcp-server/tools/catFactFetcher/registration.d.ts.map +1 -1
  36. package/dist/mcp-server/tools/catFactFetcher/registration.js +14 -58
  37. package/dist/mcp-server/tools/catFactFetcher/registration.js.map +1 -1
  38. package/dist/mcp-server/tools/echoTool/logic.d.ts +4 -6
  39. package/dist/mcp-server/tools/echoTool/logic.d.ts.map +1 -1
  40. package/dist/mcp-server/tools/echoTool/logic.js +11 -13
  41. package/dist/mcp-server/tools/echoTool/logic.js.map +1 -1
  42. package/dist/mcp-server/tools/echoTool/registration.d.ts +1 -7
  43. package/dist/mcp-server/tools/echoTool/registration.d.ts.map +1 -1
  44. package/dist/mcp-server/tools/echoTool/registration.js +18 -71
  45. package/dist/mcp-server/tools/echoTool/registration.js.map +1 -1
  46. package/dist/mcp-server/tools/imageTest/logic.d.ts +4 -6
  47. package/dist/mcp-server/tools/imageTest/logic.d.ts.map +1 -1
  48. package/dist/mcp-server/tools/imageTest/logic.js +16 -16
  49. package/dist/mcp-server/tools/imageTest/logic.js.map +1 -1
  50. package/dist/mcp-server/tools/imageTest/registration.d.ts +1 -6
  51. package/dist/mcp-server/tools/imageTest/registration.d.ts.map +1 -1
  52. package/dist/mcp-server/tools/imageTest/registration.js +19 -60
  53. package/dist/mcp-server/tools/imageTest/registration.js.map +1 -1
  54. package/dist/mcp-server/tools/index.d.ts +4 -0
  55. package/dist/mcp-server/tools/index.d.ts.map +1 -0
  56. package/dist/mcp-server/tools/index.js +19 -0
  57. package/dist/mcp-server/tools/index.js.map +1 -0
  58. package/dist/mcp-server/tools/utils/tool-utils.d.ts +43 -0
  59. package/dist/mcp-server/tools/utils/tool-utils.d.ts.map +1 -0
  60. package/dist/mcp-server/tools/utils/tool-utils.js +44 -0
  61. package/dist/mcp-server/tools/utils/tool-utils.js.map +1 -0
  62. package/dist/mcp-server/transports/auth/authFactory.js +5 -5
  63. package/dist/mcp-server/transports/auth/authFactory.js.map +1 -1
  64. package/dist/mcp-server/transports/auth/authMiddleware.d.ts +2 -2
  65. package/dist/mcp-server/transports/auth/authMiddleware.d.ts.map +1 -1
  66. package/dist/mcp-server/transports/auth/authMiddleware.js +13 -13
  67. package/dist/mcp-server/transports/auth/authMiddleware.js.map +1 -1
  68. package/dist/mcp-server/transports/auth/lib/authUtils.js +7 -7
  69. package/dist/mcp-server/transports/auth/lib/authUtils.js.map +1 -1
  70. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.d.ts.map +1 -1
  71. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js +23 -23
  72. package/dist/mcp-server/transports/auth/strategies/jwtStrategy.js.map +1 -1
  73. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.d.ts.map +1 -1
  74. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js +23 -23
  75. package/dist/mcp-server/transports/auth/strategies/oauthStrategy.js.map +1 -1
  76. package/dist/mcp-server/transports/core/baseTransportManager.d.ts.map +1 -1
  77. package/dist/mcp-server/transports/core/baseTransportManager.js +1 -1
  78. package/dist/mcp-server/transports/core/baseTransportManager.js.map +1 -1
  79. package/dist/mcp-server/transports/core/headerUtils.d.ts +20 -0
  80. package/dist/mcp-server/transports/core/headerUtils.d.ts.map +1 -0
  81. package/dist/mcp-server/transports/core/headerUtils.js +38 -0
  82. package/dist/mcp-server/transports/core/headerUtils.js.map +1 -0
  83. package/dist/mcp-server/transports/core/honoNodeBridge.d.ts +60 -7
  84. package/dist/mcp-server/transports/core/honoNodeBridge.d.ts.map +1 -1
  85. package/dist/mcp-server/transports/core/honoNodeBridge.js +89 -8
  86. package/dist/mcp-server/transports/core/honoNodeBridge.js.map +1 -1
  87. package/dist/mcp-server/transports/core/statefulTransportManager.d.ts +53 -8
  88. package/dist/mcp-server/transports/core/statefulTransportManager.d.ts.map +1 -1
  89. package/dist/mcp-server/transports/core/statefulTransportManager.js +196 -132
  90. package/dist/mcp-server/transports/core/statefulTransportManager.js.map +1 -1
  91. package/dist/mcp-server/transports/core/statelessTransportManager.d.ts +44 -7
  92. package/dist/mcp-server/transports/core/statelessTransportManager.d.ts.map +1 -1
  93. package/dist/mcp-server/transports/core/statelessTransportManager.js +92 -34
  94. package/dist/mcp-server/transports/core/statelessTransportManager.js.map +1 -1
  95. package/dist/mcp-server/transports/core/transportTypes.d.ts +58 -21
  96. package/dist/mcp-server/transports/core/transportTypes.d.ts.map +1 -1
  97. package/dist/mcp-server/transports/core/transportTypes.js +3 -1
  98. package/dist/mcp-server/transports/core/transportTypes.js.map +1 -1
  99. package/dist/mcp-server/transports/http/httpErrorHandler.d.ts.map +1 -1
  100. package/dist/mcp-server/transports/http/httpErrorHandler.js +37 -49
  101. package/dist/mcp-server/transports/http/httpErrorHandler.js.map +1 -1
  102. package/dist/mcp-server/transports/http/httpTransport.d.ts +3 -3
  103. package/dist/mcp-server/transports/http/httpTransport.d.ts.map +1 -1
  104. package/dist/mcp-server/transports/http/httpTransport.js +50 -43
  105. package/dist/mcp-server/transports/http/httpTransport.js.map +1 -1
  106. package/dist/mcp-server/transports/http/mcpTransportMiddleware.d.ts.map +1 -1
  107. package/dist/mcp-server/transports/http/mcpTransportMiddleware.js +26 -17
  108. package/dist/mcp-server/transports/http/mcpTransportMiddleware.js.map +1 -1
  109. package/dist/mcp-server/transports/stdio/stdioTransport.d.ts.map +1 -1
  110. package/dist/mcp-server/transports/stdio/stdioTransport.js +6 -5
  111. package/dist/mcp-server/transports/stdio/stdioTransport.js.map +1 -1
  112. package/dist/services/duck-db/duckDBConnectionManager.d.ts.map +1 -1
  113. package/dist/services/duck-db/duckDBConnectionManager.js +20 -20
  114. package/dist/services/duck-db/duckDBConnectionManager.js.map +1 -1
  115. package/dist/services/duck-db/duckDBQueryExecutor.d.ts.map +1 -1
  116. package/dist/services/duck-db/duckDBQueryExecutor.js +13 -13
  117. package/dist/services/duck-db/duckDBQueryExecutor.js.map +1 -1
  118. package/dist/services/duck-db/duckDBService.js +8 -8
  119. package/dist/services/duck-db/duckDBService.js.map +1 -1
  120. package/dist/services/llm-providers/openRouterProvider.d.ts.map +1 -1
  121. package/dist/services/llm-providers/openRouterProvider.js +17 -14
  122. package/dist/services/llm-providers/openRouterProvider.js.map +1 -1
  123. package/dist/services/supabase/supabaseClient.js +6 -6
  124. package/dist/services/supabase/supabaseClient.js.map +1 -1
  125. package/dist/storage/duckdbExample.js +45 -42
  126. package/dist/storage/duckdbExample.js.map +1 -1
  127. package/dist/types-global/errors.d.ts +29 -52
  128. package/dist/types-global/errors.d.ts.map +1 -1
  129. package/dist/types-global/errors.js +30 -51
  130. package/dist/types-global/errors.js.map +1 -1
  131. package/dist/utils/internal/asyncContext.d.ts +35 -0
  132. package/dist/utils/internal/asyncContext.d.ts.map +1 -0
  133. package/dist/utils/internal/asyncContext.js +38 -0
  134. package/dist/utils/internal/asyncContext.js.map +1 -0
  135. package/dist/utils/internal/errorHandler.d.ts +18 -100
  136. package/dist/utils/internal/errorHandler.d.ts.map +1 -1
  137. package/dist/utils/internal/errorHandler.js +91 -219
  138. package/dist/utils/internal/errorHandler.js.map +1 -1
  139. package/dist/utils/internal/index.d.ts +1 -0
  140. package/dist/utils/internal/index.d.ts.map +1 -1
  141. package/dist/utils/internal/index.js +1 -0
  142. package/dist/utils/internal/index.js.map +1 -1
  143. package/dist/utils/internal/logger.d.ts +16 -140
  144. package/dist/utils/internal/logger.d.ts.map +1 -1
  145. package/dist/utils/internal/logger.js +133 -423
  146. package/dist/utils/internal/logger.js.map +1 -1
  147. package/dist/utils/internal/logging-helpers.d.ts +49 -0
  148. package/dist/utils/internal/logging-helpers.d.ts.map +1 -0
  149. package/dist/utils/internal/logging-helpers.js +60 -0
  150. package/dist/utils/internal/logging-helpers.js.map +1 -0
  151. package/dist/utils/internal/performance.d.ts +2 -5
  152. package/dist/utils/internal/performance.d.ts.map +1 -1
  153. package/dist/utils/internal/performance.js +71 -37
  154. package/dist/utils/internal/performance.js.map +1 -1
  155. package/dist/utils/internal/requestContext.d.ts +21 -64
  156. package/dist/utils/internal/requestContext.d.ts.map +1 -1
  157. package/dist/utils/internal/requestContext.js +37 -63
  158. package/dist/utils/internal/requestContext.js.map +1 -1
  159. package/dist/utils/metrics/tokenCounter.d.ts.map +1 -1
  160. package/dist/utils/metrics/tokenCounter.js +13 -9
  161. package/dist/utils/metrics/tokenCounter.js.map +1 -1
  162. package/dist/utils/network/fetchWithTimeout.d.ts.map +1 -1
  163. package/dist/utils/network/fetchWithTimeout.js +27 -9
  164. package/dist/utils/network/fetchWithTimeout.js.map +1 -1
  165. package/dist/utils/parsing/dateParser.d.ts.map +1 -1
  166. package/dist/utils/parsing/dateParser.js +8 -8
  167. package/dist/utils/parsing/dateParser.js.map +1 -1
  168. package/dist/utils/parsing/jsonParser.d.ts.map +1 -1
  169. package/dist/utils/parsing/jsonParser.js +9 -9
  170. package/dist/utils/parsing/jsonParser.js.map +1 -1
  171. package/dist/utils/scheduling/scheduler.d.ts.map +1 -1
  172. package/dist/utils/scheduling/scheduler.js +18 -15
  173. package/dist/utils/scheduling/scheduler.js.map +1 -1
  174. package/dist/utils/security/idGenerator.d.ts +6 -0
  175. package/dist/utils/security/idGenerator.d.ts.map +1 -1
  176. package/dist/utils/security/idGenerator.js +16 -4
  177. package/dist/utils/security/idGenerator.js.map +1 -1
  178. package/dist/utils/security/rateLimiter.d.ts.map +1 -1
  179. package/dist/utils/security/rateLimiter.js +27 -11
  180. package/dist/utils/security/rateLimiter.js.map +1 -1
  181. package/dist/utils/security/sanitization.js +20 -20
  182. package/dist/utils/security/sanitization.js.map +1 -1
  183. package/dist/utils/telemetry/instrumentation.d.ts +8 -0
  184. package/dist/utils/telemetry/instrumentation.d.ts.map +1 -0
  185. package/dist/utils/telemetry/instrumentation.js +121 -0
  186. package/dist/utils/telemetry/instrumentation.js.map +1 -0
  187. package/dist/utils/telemetry/semconv.d.ts +16 -0
  188. package/dist/utils/telemetry/semconv.d.ts.map +1 -0
  189. package/dist/utils/telemetry/semconv.js +16 -0
  190. package/dist/utils/telemetry/semconv.js.map +1 -0
  191. package/package.json +43 -29
  192. package/dist/mcp-server/core/managedMcpServer.d.ts +0 -48
  193. package/dist/mcp-server/core/managedMcpServer.d.ts.map +0 -1
  194. package/dist/mcp-server/core/managedMcpServer.js +0 -58
  195. 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
  [![TypeScript](https://img.shields.io/badge/TypeScript-^5.8.3-blue?style=flat-square)](https://www.typescriptlang.org/)
8
- [![Model Context Protocol SDK](https://img.shields.io/badge/MCP%20SDK-^1.17.1-green?style=flat-square)](https://github.com/modelcontextprotocol/typescript-sdk)
8
+ [![Model Context Protocol SDK](https://img.shields.io/badge/MCP%20SDK-^1.17.4-green?style=flat-square)](https://github.com/modelcontextprotocol/typescript-sdk)
9
9
  [![MCP Spec Version](https://img.shields.io/badge/MCP%20Spec-2025--06--18-lightgrey?style=flat-square)](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/specification/2025-06-18/changelog.mdx)
10
- [![Version](https://img.shields.io/badge/Version-1.8.0-blue?style=flat-square)](./CHANGELOG.md)
11
- [![Coverage](https://img.shields.io/badge/Coverage-65.8%25-brightgreen?style=flat-square)](./vitest.config.ts)
10
+ [![Version](https://img.shields.io/badge/Version-1.9.0-blue?style=flat-square)](./CHANGELOG.md)
11
+ [![Coverage](https://img.shields.io/badge/Coverage-46.52%25-brightgreen?style=flat-square)](./vitest.config.ts)
12
12
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue?style=flat-square)](https://opensource.org/licenses/Apache-2.0)
13
13
  [![Status](https://img.shields.io/badge/Status-Stable-green?style=flat-square)](https://github.com/cyanheads/mcp-ts-template/issues)
14
14
  [![GitHub](https://img.shields.io/github/stars/cyanheads/mcp-ts-template?style=social)](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
- | **🚀 Production Utilities** | Logging, Error Handling, ID Generation, Rate Limiting, Request Context tracking, Input Sanitization. | `src/utils/` |
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 (`BaseErrorCode`), detailed logging, centralized handling (`ErrorHandler`). | `src/utils/internal/errorHandler.ts`, `src/types-global/` |
39
- | **📚 Documentation** | Comprehensive `README.md`, structured JSDoc comments, API references. | `README.md`, Codebase, `tsdoc.json`, `docs/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. It uses a `ManagedMcpServer` wrapper to provide enhanced introspection capabilities. It acts the same way as the native McpServer, but with additional features like introspection and enhanced error handling.
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 passed through the entire call stack, ensuring comprehensive and structured logging.
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:server
82
+ npm run start:stdio
82
83
  ```
83
84
  - **Via Streamable HTTP:**
84
85
  ```bash
85
- npm run start:server:http
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 | Description | Default |
110
- | :-------------------- | :---------------------------------------------------------------------------------------- | :------------------------------------- |
111
- | `MCP_TRANSPORT_TYPE` | Server transport: `stdio` or `http`. | `stdio` |
112
- | `MCP_SESSION_MODE` | Session mode for HTTP: `stateless`, `stateful`, or `auto`. | `auto` |
113
- | `MCP_HTTP_PORT` | Port for the HTTP server. | `3010` |
114
- | `MCP_HTTP_HOST` | Host address for the HTTP server. | `127.0.0.1` |
115
- | `MCP_ALLOWED_ORIGINS` | Comma-separated allowed origins for CORS. | (none) |
116
- | `MCP_AUTH_MODE` | Authentication mode for HTTP: `jwt`, `oauth`, or `none`. | `none` |
117
- | `MCP_AUTH_SECRET_KEY` | **Required for `jwt` mode.** Secret key (min 32 chars) for signing/verifying auth tokens. | (none - **MUST be set in production**) |
118
- | `OAUTH_ISSUER_URL` | **Required for `oauth` mode.** The issuer URL of your authorization server. | (none) |
119
- | `OAUTH_AUDIENCE` | **Required for `oauth` mode.** The audience identifier for this MCP server. | (none) |
120
- | `OPENROUTER_API_KEY` | API key for OpenRouter.ai service. | (none) |
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 a request context, and either returns a result or **throws** a structured `McpError`.
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 runtime 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.
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
 
@@ -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;;;;;;;;;;;;;;;GAeG;AA8SH;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB,qCAAqC;;;;;IAErC,wFAAwF;;IAExF,uFAAuF;;IAEvF,qEAAqE;;IAErE,oEAAoE;;IAEpE,4EAA4E;;IAE5E,mGAAmG;;IAEnG,4GAA4G;;IAE5G,yFAAyF;;IAEzF,gGAAgG;;IAEhG,4FAA4F;;IAE5F,mFAAmF;;IAEnF,4FAA4F;;IAE5F,2GAA2G;;IAE3G,oGAAoG;;IAIpG,oFAAoF;;IAEpF,wEAAwE;;IAExE,qDAAqD;;IAErD,iDAAiD;;IAEjD,iDAAiD;;IAEjD,4DAA4D;;IAE5D,sDAAsD;;IAEtD,uFAAuF;;IAEvF,oFAAoF;;IAEpF,qDAAqD;;IAErD,mDAAmD;;IAEnD,+DAA+D;;IAE/D,mDAAmD;;IAEnD,6DAA6D;;IAE7D,mDAAmD;;IAEnD,mDAAmD;;IAGnD,4EAA4E;;;;;;;;;IAqB5E,wEAAwE;;;;;;CASzE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,MAAwB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAA2B,CAAC"}
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"}
@@ -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.error("Warning: Could not read package.json for default config values. Using hardcoded defaults.", error);
44
+ console.warn(`Warning: Using process.cwd() (${projectRoot}) as fallback project root.`);
68
45
  }
69
46
  }
47
+ // --- End Determine Project Root ---
70
48
  /**
71
- * Zod schema for validating environment variables.
72
- * Provides type safety, validation, defaults, and clear error messages.
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
- /** Optional. The desired name for the MCP server. Defaults to `package.json` name. */
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
- /** OpenRouter App Name. From `OPENROUTER_APP_NAME`. Defaults to `mcpServerName`. */
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