@novorb/mcp-core 2.1.2 → 3.0.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 (240) hide show
  1. package/README.md +77 -163
  2. package/bin/mcp-core-jest.mjs +112 -0
  3. package/dist/auth.d.ts +57 -0
  4. package/dist/auth.d.ts.map +1 -0
  5. package/dist/auth.js +74 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/bootstrap.d.ts +129 -0
  8. package/dist/bootstrap.d.ts.map +1 -0
  9. package/dist/bootstrap.js +206 -0
  10. package/dist/bootstrap.js.map +1 -0
  11. package/dist/client-input.d.ts +72 -0
  12. package/dist/client-input.d.ts.map +1 -0
  13. package/dist/client-input.js +109 -0
  14. package/dist/client-input.js.map +1 -0
  15. package/dist/credential-checks.d.ts +80 -0
  16. package/dist/credential-checks.d.ts.map +1 -0
  17. package/dist/credential-checks.js +189 -0
  18. package/dist/credential-checks.js.map +1 -0
  19. package/dist/credential-health.d.ts +12 -0
  20. package/dist/credential-health.d.ts.map +1 -0
  21. package/dist/credential-health.js +12 -0
  22. package/dist/credential-health.js.map +1 -0
  23. package/dist/credential-report.d.ts +46 -0
  24. package/dist/credential-report.d.ts.map +1 -0
  25. package/dist/credential-report.js +135 -0
  26. package/dist/credential-report.js.map +1 -0
  27. package/dist/credential-status-tool.d.ts +20 -0
  28. package/dist/credential-status-tool.d.ts.map +1 -0
  29. package/dist/credential-status-tool.js +33 -0
  30. package/dist/credential-status-tool.js.map +1 -0
  31. package/dist/credentials.d.ts +288 -0
  32. package/dist/credentials.d.ts.map +1 -0
  33. package/dist/credentials.js +652 -0
  34. package/dist/credentials.js.map +1 -0
  35. package/dist/express-peers.d.ts +29 -0
  36. package/dist/express-peers.d.ts.map +1 -0
  37. package/dist/express-peers.js +36 -0
  38. package/dist/express-peers.js.map +1 -0
  39. package/dist/express.d.ts +74 -0
  40. package/dist/express.d.ts.map +1 -0
  41. package/dist/express.js +164 -0
  42. package/dist/express.js.map +1 -0
  43. package/dist/http-client.d.ts +277 -42
  44. package/dist/http-client.d.ts.map +1 -1
  45. package/dist/http-client.js +620 -180
  46. package/dist/http-client.js.map +1 -1
  47. package/dist/index.d.ts +27 -6
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +47 -8
  50. package/dist/index.js.map +1 -1
  51. package/dist/limits.d.ts +28 -0
  52. package/dist/limits.d.ts.map +1 -0
  53. package/dist/limits.js +37 -0
  54. package/dist/limits.js.map +1 -0
  55. package/dist/list-pagination.d.ts +41 -0
  56. package/dist/list-pagination.d.ts.map +1 -0
  57. package/dist/list-pagination.js +104 -0
  58. package/dist/list-pagination.js.map +1 -0
  59. package/dist/net.d.ts +112 -0
  60. package/dist/net.d.ts.map +1 -0
  61. package/dist/net.js +490 -0
  62. package/dist/net.js.map +1 -0
  63. package/dist/notifications.d.ts +78 -0
  64. package/dist/notifications.d.ts.map +1 -0
  65. package/dist/notifications.js +173 -0
  66. package/dist/notifications.js.map +1 -0
  67. package/dist/pagination.d.ts +236 -5
  68. package/dist/pagination.d.ts.map +1 -1
  69. package/dist/pagination.js +393 -6
  70. package/dist/pagination.js.map +1 -1
  71. package/dist/prompts.d.ts +70 -0
  72. package/dist/prompts.d.ts.map +1 -0
  73. package/dist/prompts.js +109 -0
  74. package/dist/prompts.js.map +1 -0
  75. package/dist/protocol-errors.d.ts +15 -0
  76. package/dist/protocol-errors.d.ts.map +1 -0
  77. package/dist/protocol-errors.js +28 -0
  78. package/dist/protocol-errors.js.map +1 -0
  79. package/dist/protocol-logging.d.ts +37 -0
  80. package/dist/protocol-logging.d.ts.map +1 -0
  81. package/dist/protocol-logging.js +77 -0
  82. package/dist/protocol-logging.js.map +1 -0
  83. package/dist/rate-limiter.d.ts +36 -0
  84. package/dist/rate-limiter.d.ts.map +1 -0
  85. package/dist/rate-limiter.js +79 -0
  86. package/dist/rate-limiter.js.map +1 -0
  87. package/dist/request-state.d.ts +74 -0
  88. package/dist/request-state.d.ts.map +1 -0
  89. package/dist/request-state.js +190 -0
  90. package/dist/request-state.js.map +1 -0
  91. package/dist/resources.d.ts +181 -0
  92. package/dist/resources.d.ts.map +1 -0
  93. package/dist/resources.js +302 -0
  94. package/dist/resources.js.map +1 -0
  95. package/dist/result-limits.d.ts +80 -0
  96. package/dist/result-limits.d.ts.map +1 -0
  97. package/dist/result-limits.js +248 -0
  98. package/dist/result-limits.js.map +1 -0
  99. package/dist/retry.d.ts +79 -23
  100. package/dist/retry.d.ts.map +1 -1
  101. package/dist/retry.js +170 -57
  102. package/dist/retry.js.map +1 -1
  103. package/dist/sdk/client-stdio.d.ts +6 -0
  104. package/dist/sdk/client-stdio.d.ts.map +1 -0
  105. package/dist/sdk/client-stdio.js +6 -0
  106. package/dist/sdk/client-stdio.js.map +1 -0
  107. package/dist/sdk/client.d.ts +6 -0
  108. package/dist/sdk/client.d.ts.map +1 -0
  109. package/dist/sdk/client.js +6 -0
  110. package/dist/sdk/client.js.map +1 -0
  111. package/dist/sdk/express.d.ts +3 -0
  112. package/dist/sdk/express.d.ts.map +1 -0
  113. package/dist/sdk/express.js +11 -0
  114. package/dist/sdk/express.js.map +1 -0
  115. package/dist/sdk/node.d.ts +6 -0
  116. package/dist/sdk/node.d.ts.map +1 -0
  117. package/dist/sdk/node.js +6 -0
  118. package/dist/sdk/node.js.map +1 -0
  119. package/dist/sdk/server-stdio.d.ts +6 -0
  120. package/dist/sdk/server-stdio.d.ts.map +1 -0
  121. package/dist/sdk/server-stdio.js +6 -0
  122. package/dist/sdk/server-stdio.js.map +1 -0
  123. package/dist/sdk/server.d.ts +6 -0
  124. package/dist/sdk/server.d.ts.map +1 -0
  125. package/dist/sdk/server.js +6 -0
  126. package/dist/sdk/server.js.map +1 -0
  127. package/dist/server.d.ts +88 -35
  128. package/dist/server.d.ts.map +1 -1
  129. package/dist/server.js +98 -44
  130. package/dist/server.js.map +1 -1
  131. package/dist/task-request.d.ts +20 -0
  132. package/dist/task-request.d.ts.map +1 -0
  133. package/dist/task-request.js +43 -0
  134. package/dist/task-request.js.map +1 -0
  135. package/dist/task-store.d.ts +230 -0
  136. package/dist/task-store.d.ts.map +1 -0
  137. package/dist/task-store.js +459 -0
  138. package/dist/task-store.js.map +1 -0
  139. package/dist/task-tools.d.ts +115 -0
  140. package/dist/task-tools.d.ts.map +1 -0
  141. package/dist/task-tools.js +397 -0
  142. package/dist/task-tools.js.map +1 -0
  143. package/dist/testing/client.d.ts +25 -0
  144. package/dist/testing/client.d.ts.map +1 -0
  145. package/dist/testing/client.js +11 -0
  146. package/dist/testing/client.js.map +1 -0
  147. package/dist/testing/in-memory.d.ts +26 -0
  148. package/dist/testing/in-memory.d.ts.map +1 -0
  149. package/dist/testing/in-memory.js +41 -0
  150. package/dist/testing/in-memory.js.map +1 -0
  151. package/dist/testing/index.d.ts +20 -0
  152. package/dist/testing/index.d.ts.map +1 -0
  153. package/dist/testing/index.js +20 -0
  154. package/dist/testing/index.js.map +1 -0
  155. package/dist/testing/isolated-dirs.d.ts +27 -0
  156. package/dist/testing/isolated-dirs.d.ts.map +1 -0
  157. package/dist/testing/isolated-dirs.js +67 -0
  158. package/dist/testing/isolated-dirs.js.map +1 -0
  159. package/dist/testing/logs.d.ts +61 -0
  160. package/dist/testing/logs.d.ts.map +1 -0
  161. package/dist/testing/logs.js +113 -0
  162. package/dist/testing/logs.js.map +1 -0
  163. package/dist/testing/raw-http.d.ts +25 -0
  164. package/dist/testing/raw-http.d.ts.map +1 -0
  165. package/dist/testing/raw-http.js +41 -0
  166. package/dist/testing/raw-http.js.map +1 -0
  167. package/dist/testing/raw-peer.d.ts +43 -0
  168. package/dist/testing/raw-peer.d.ts.map +1 -0
  169. package/dist/testing/raw-peer.js +101 -0
  170. package/dist/testing/raw-peer.js.map +1 -0
  171. package/dist/testing/recording-server.d.ts +38 -0
  172. package/dist/testing/recording-server.d.ts.map +1 -0
  173. package/dist/testing/recording-server.js +38 -0
  174. package/dist/testing/recording-server.js.map +1 -0
  175. package/dist/testing/server-process.d.ts +76 -0
  176. package/dist/testing/server-process.d.ts.map +1 -0
  177. package/dist/testing/server-process.js +241 -0
  178. package/dist/testing/server-process.js.map +1 -0
  179. package/dist/testing/tools.d.ts +53 -0
  180. package/dist/testing/tools.d.ts.map +1 -0
  181. package/dist/testing/tools.js +98 -0
  182. package/dist/testing/tools.js.map +1 -0
  183. package/dist/testing/unit.d.ts +52 -0
  184. package/dist/testing/unit.d.ts.map +1 -0
  185. package/dist/testing/unit.js +95 -0
  186. package/dist/testing/unit.js.map +1 -0
  187. package/dist/tools.d.ts +205 -0
  188. package/dist/tools.d.ts.map +1 -0
  189. package/dist/tools.js +370 -0
  190. package/dist/tools.js.map +1 -0
  191. package/dist/transport.d.ts +143 -52
  192. package/dist/transport.d.ts.map +1 -1
  193. package/dist/transport.js +292 -123
  194. package/dist/transport.js.map +1 -1
  195. package/dist/url-path.d.ts +49 -0
  196. package/dist/url-path.d.ts.map +1 -0
  197. package/dist/url-path.js +165 -0
  198. package/dist/url-path.js.map +1 -0
  199. package/dist/utils/dataStore.d.ts +143 -0
  200. package/dist/utils/dataStore.d.ts.map +1 -0
  201. package/dist/utils/dataStore.js +429 -0
  202. package/dist/utils/dataStore.js.map +1 -0
  203. package/dist/utils/envLoader.d.ts +129 -0
  204. package/dist/utils/envLoader.d.ts.map +1 -0
  205. package/dist/utils/envLoader.js +399 -0
  206. package/dist/utils/envLoader.js.map +1 -0
  207. package/dist/utils/logger.d.ts +181 -0
  208. package/dist/utils/logger.d.ts.map +1 -0
  209. package/dist/utils/logger.js +664 -0
  210. package/dist/utils/logger.js.map +1 -0
  211. package/dist/utils/redact.d.ts +50 -0
  212. package/dist/utils/redact.d.ts.map +1 -0
  213. package/dist/utils/redact.js +318 -0
  214. package/dist/utils/redact.js.map +1 -0
  215. package/docs/api-reference.md +29 -0
  216. package/docs/building-a-server.md +63 -0
  217. package/docs/credentials.md +131 -0
  218. package/docs/data-store.md +37 -0
  219. package/docs/env.md +38 -0
  220. package/docs/features.md +28 -0
  221. package/docs/http-client.md +116 -0
  222. package/docs/logger.md +100 -0
  223. package/docs/migrating-to-v3.md +45 -0
  224. package/docs/outbound-urls.md +104 -0
  225. package/docs/pagination.md +45 -0
  226. package/docs/protocol-features.md +62 -0
  227. package/docs/resources-prompts-tasks.md +95 -0
  228. package/docs/sdk.md +33 -0
  229. package/docs/server.md +68 -0
  230. package/docs/testing-harness.md +139 -0
  231. package/docs/testing.md +151 -0
  232. package/docs/tools.md +88 -0
  233. package/docs/transport.md +85 -0
  234. package/examples/testing/tools.integration.test.example.ts +312 -0
  235. package/examples/testing/tools.unit.test.example.ts +149 -0
  236. package/package.json +130 -17
  237. package/dist/logger.d.ts +0 -80
  238. package/dist/logger.d.ts.map +0 -1
  239. package/dist/logger.js +0 -237
  240. package/dist/logger.js.map +0 -1
@@ -0,0 +1,399 @@
1
+ /**
2
+ * @novorb/mcp-core - Env loader
3
+ *
4
+ * Every MCP server declares its own env schema (`EnvSchema`) and loads its environment through
5
+ * `loadEnv` (no dotenv). mcp-core's own keys (`CORE_ENV_SCHEMA`: transport,
6
+ * auth, logger, data storage) are merged in, so a server declares only its own keys.
7
+ *
8
+ * Sources, highest first: the real process env > `<rootDir>/.env` > the spec `value` default.
9
+ * `MCP_ENV_FILE` (read from the real env only) overrides the file path (absolute, or relative to
10
+ * rootDir); `MCP_ENV_FILE=none` disables the file. The file is parsed with Node's `util.parseEnv`.
11
+ *
12
+ * const env = loadEnv([
13
+ * { key: 'GITLAB_URL', type: 'url', value: 'https://gitlab.com', description: 'GitLab base URL' },
14
+ * { key: 'GITLAB_PERSONAL_ACCESS_TOKEN', required: true, secret: true, description: 'API token' },
15
+ * ], { rootDir: packageRootFrom(import.meta.url) });
16
+ * if (!env.isConfigured()) getLogger().warn(`not configured: set ${env.missing.join(', ')}`);
17
+ *
18
+ * Values are never logged, never returned by `describe()`, and every set `secret: true` value is
19
+ * registered with the logger so it is masked verbatim in every log entry.
20
+ */
21
+ import { existsSync, readFileSync } from 'node:fs';
22
+ import * as path from 'node:path';
23
+ import { parseEnv } from 'node:util';
24
+ import { getLogger, MIN_SECRET_LENGTH, registerSecretValues } from './logger.js';
25
+ /** mcp-core's own variables (transport, auth, logger, data storage), merged into every schema. */
26
+ export const CORE_ENV_SCHEMA = [
27
+ {
28
+ key: 'MCP_TRANSPORT',
29
+ type: 'enum',
30
+ values: ['stdio', 'http'],
31
+ description: 'Transport: stdio (default) or http',
32
+ },
33
+ { key: 'PORT', type: 'int', description: 'HTTP listen port (default 8080)' },
34
+ { key: 'MCP_HTTP_HOST', description: 'HTTP bind address (default 0.0.0.0; 127.0.0.1 for local-only)' },
35
+ {
36
+ key: 'MCP_API_KEY',
37
+ secret: true,
38
+ description: 'Bearer token required on /mcp in HTTP mode (unless MCP_AUTH_DISABLED=true)',
39
+ },
40
+ { key: 'MCP_AUTH_DISABLED', type: 'bool', description: 'Run HTTP without auth (only behind a gateway)' },
41
+ { key: 'MCP_MAX_BODY_BYTES', type: 'int', description: 'Max POST body size in bytes (default 4 MiB)' },
42
+ { key: 'MCP_ALLOWED_HOSTS', description: 'Comma-separated Host allowlist (enables DNS-rebinding protection)' },
43
+ { key: 'MCP_ALLOWED_ORIGINS', description: 'Comma-separated Origin allowlist (enables DNS-rebinding protection)' },
44
+ { key: 'MCP_ENV_FILE', description: 'Env file path (absolute or relative to the package root); none disables it' },
45
+ { key: 'LOG_LEVEL', type: 'enum', values: ['DEBUG', 'INFO', 'WARN', 'ERROR'], description: 'Log level (INFO)' },
46
+ { key: 'LOG_FORMAT', type: 'enum', values: ['text', 'json'], description: 'Log line format (text)' },
47
+ { key: 'LOG_CONSOLE', type: 'bool', description: 'stderr log sink (true)' },
48
+ { key: 'LOG_FILE_MAIN', type: 'bool', description: 'Main <name>.log sink (true)' },
49
+ { key: 'LOG_FILE_EXCEPTIONS', type: 'bool', description: 'exceptions.log sink (true)' },
50
+ { key: 'LOG_FILE_DEBUG', type: 'bool', description: 'debug.log sink (true)' },
51
+ { key: 'LOG_PATH', description: 'Log directory (default <package root>/.logs)' },
52
+ { key: 'LOG_FILE', description: 'Main log file name (default <name>.log)' },
53
+ {
54
+ key: 'LOG_PROTOCOL',
55
+ type: 'bool',
56
+ description: 'Also send log entries to the client as MCP logging notifications (false; deprecated by 2026-07-28)',
57
+ },
58
+ { key: 'DATA_PATH', description: 'Data directory (default <package root>/.data)' },
59
+ {
60
+ key: 'DATA_STORAGE',
61
+ type: 'bool',
62
+ value: 'true',
63
+ description: 'Write to disk; false runs stateless (an invalid value also disables writes)',
64
+ },
65
+ {
66
+ key: 'MCP_LIST_PAGE_SIZE',
67
+ type: 'int',
68
+ description: 'tools/list (and resources/prompts) page size; 0 disables list pagination (default 100)',
69
+ },
70
+ {
71
+ key: 'MCP_MAX_RESULT_ITEMS',
72
+ type: 'int',
73
+ description: 'Max items per list-shaped tool result before it is paginated (default 100)',
74
+ },
75
+ {
76
+ key: 'MCP_MAX_RESULT_BYTES',
77
+ type: 'int',
78
+ description: 'Max serialized size of one tool result in bytes (default 262144)',
79
+ },
80
+ {
81
+ key: 'MCP_MAX_TOOL_INPUT_ELEMENTS',
82
+ type: 'int',
83
+ description: 'Max array elements plus object members in one tools/call arguments payload (default 10000)',
84
+ },
85
+ {
86
+ key: 'MCP_REQUEST_STATE_KEY',
87
+ secret: true,
88
+ description: 'Secret (at least 32 bytes) sealing multi-step requestState (AES-256-GCM); the same on every instance',
89
+ },
90
+ {
91
+ key: 'MCP_REQUEST_STATE_PREVIOUS_KEY',
92
+ secret: true,
93
+ multi: true,
94
+ description: 'Previous requestState secret(s) still accepted after a rotation (_1, _2, ...)',
95
+ },
96
+ {
97
+ key: 'MCP_CREDENTIAL_CHECKS',
98
+ type: 'bool',
99
+ value: 'true',
100
+ description: 'Run the credential checks once at startup; false skips them (offline or stateless starts)',
101
+ },
102
+ {
103
+ key: 'MCP_CREDENTIAL_RECHECK_MS',
104
+ type: 'int',
105
+ description: 'How long an invalid or expired credential waits before its check runs again (default 300000)',
106
+ },
107
+ {
108
+ key: 'MCP_CREDENTIAL_CHECK_TIMEOUT_MS',
109
+ type: 'int',
110
+ description: 'Timeout of one startup credential check in milliseconds (default 5000; a timeout reads unknown)',
111
+ },
112
+ {
113
+ key: 'MCP_REQUEST_STATE_TTL_SECONDS',
114
+ type: 'int',
115
+ description: 'Lifetime of a minted requestState in seconds (default 600)',
116
+ },
117
+ ];
118
+ const ENV_FILE_NONE = 'none';
119
+ /** A secret spec: `secret: true`, or any credential with a `check` (its value is a credential too). */
120
+ export function isSecret(spec) {
121
+ return spec.secret === true || spec.check !== undefined;
122
+ }
123
+ const TRUE_WORDS = new Set(['true', '1', 'yes', 'on']);
124
+ const FALSE_WORDS = new Set(['false', '0', 'no', 'off']);
125
+ function parseBoolWord(value) {
126
+ const v = value.trim().toLowerCase();
127
+ if (TRUE_WORDS.has(v))
128
+ return true;
129
+ if (FALSE_WORDS.has(v))
130
+ return false;
131
+ return undefined;
132
+ }
133
+ function parseIntStrict(value) {
134
+ const v = value.trim();
135
+ if (!/^[+-]?\d+$/.test(v))
136
+ return undefined;
137
+ const n = Number(v);
138
+ return Number.isSafeInteger(n) ? n : undefined;
139
+ }
140
+ function isValidUrl(value) {
141
+ try {
142
+ new URL(value);
143
+ return true;
144
+ }
145
+ catch {
146
+ return false;
147
+ }
148
+ }
149
+ /** Merge schemas by key: a later spec for the same key replaces the earlier one (server overrides core). */
150
+ function mergeSchemas(...schemas) {
151
+ const byKey = new Map();
152
+ for (const schema of schemas)
153
+ for (const spec of schema)
154
+ byKey.set(spec.key, spec);
155
+ return [...byKey.values()];
156
+ }
157
+ /** Order multi-family suffixes: numeric first (numeric order), then the rest alphabetically. */
158
+ function compareSuffixes(a, b) {
159
+ const na = /^\d+$/.test(a);
160
+ const nb = /^\d+$/.test(b);
161
+ if (na && nb)
162
+ return Number(a) - Number(b) || a.localeCompare(b);
163
+ if (na)
164
+ return -1;
165
+ if (nb)
166
+ return 1;
167
+ return a < b ? -1 : a > b ? 1 : 0;
168
+ }
169
+ function nonEmpty(value) {
170
+ return value === undefined || value === '' ? undefined : value;
171
+ }
172
+ function readEnvFile(rootDir, override) {
173
+ if (override !== undefined && override.trim().toLowerCase() === ENV_FILE_NONE)
174
+ return { file: null, values: {} };
175
+ const explicit = override !== undefined && override !== '';
176
+ const file = explicit ? path.resolve(rootDir, override) : path.join(path.resolve(rootDir), '.env');
177
+ if (!existsSync(file)) {
178
+ return explicit ? { file: null, values: {}, error: 'env file not found' } : { file: null, values: {} };
179
+ }
180
+ try {
181
+ const parsed = parseEnv(readFileSync(file, 'utf8'));
182
+ const values = {};
183
+ for (const [k, v] of Object.entries(parsed))
184
+ if (v !== undefined)
185
+ values[k] = v;
186
+ return { file, values };
187
+ }
188
+ catch {
189
+ return { file: null, values: {}, error: 'env file could not be read' };
190
+ }
191
+ }
192
+ function validate(spec, value) {
193
+ switch (spec.type) {
194
+ case 'int':
195
+ return parseIntStrict(value) === undefined ? 'must be an integer' : undefined;
196
+ case 'bool':
197
+ return parseBoolWord(value) === undefined ? 'must be a boolean (true/false, 1/0, yes/no, on/off)' : undefined;
198
+ case 'url':
199
+ return isValidUrl(value) ? undefined : 'must be a URL';
200
+ case 'enum': {
201
+ const allowed = spec.values ?? [];
202
+ return allowed.includes(value) ? undefined : `must be one of: ${allowed.join(', ')}`;
203
+ }
204
+ default:
205
+ return undefined;
206
+ }
207
+ }
208
+ /**
209
+ * Load the environment for `schema` (merged with `CORE_ENV_SCHEMA`). Collects validation errors by key
210
+ * name (throws only with `strict: true`), warns once about undeclared env-file keys (names only),
211
+ * populates `env` for keys resolved from the file or a default (never overriding a set variable), and
212
+ * registers every set secret with the logger for verbatim masking.
213
+ */
214
+ export function loadEnv(schema, options) {
215
+ const target = options.env ?? process.env;
216
+ const merged = options.includeCore === false ? mergeSchemas(schema) : mergeSchemas(CORE_ENV_SCHEMA, schema);
217
+ const specs = new Map(merged.map((s) => [s.key, s]));
218
+ const fileRead = readEnvFile(options.rootDir, target.MCP_ENV_FILE);
219
+ const resolved = new Map();
220
+ const resolveName = (name, fallback) => {
221
+ const fromEnv = nonEmpty(target[name]);
222
+ if (fromEnv !== undefined)
223
+ resolved.set(name, { value: fromEnv, source: 'env' });
224
+ else if (nonEmpty(fileRead.values[name]) !== undefined) {
225
+ resolved.set(name, { value: fileRead.values[name], source: 'file' });
226
+ }
227
+ else if (nonEmpty(fallback) !== undefined && fallback !== undefined) {
228
+ resolved.set(name, { value: fallback, source: 'default' });
229
+ }
230
+ };
231
+ // Multi families: KEY plus KEY_<suffix> from the env and the file, excluding keys declared on their own.
232
+ const families = new Map();
233
+ const claimed = new Set(specs.keys());
234
+ for (const spec of merged) {
235
+ resolveName(spec.key, spec.value);
236
+ if (!spec.multi)
237
+ continue;
238
+ const prefix = `${spec.key}_`;
239
+ const suffixes = new Set();
240
+ for (const name of [...Object.keys(target), ...Object.keys(fileRead.values)]) {
241
+ if (name.startsWith(prefix) && name.length > prefix.length && !specs.has(name)) {
242
+ suffixes.add(name.slice(prefix.length));
243
+ }
244
+ }
245
+ const members = [...suffixes].sort(compareSuffixes).map((s) => `${prefix}${s}`);
246
+ for (const member of members) {
247
+ claimed.add(member);
248
+ resolveName(member);
249
+ }
250
+ families.set(spec.key, members);
251
+ }
252
+ const errors = [];
253
+ if (fileRead.error)
254
+ errors.push({ key: 'MCP_ENV_FILE', message: fileRead.error });
255
+ for (const spec of merged) {
256
+ const names = [spec.key, ...(families.get(spec.key) ?? [])];
257
+ for (const name of names) {
258
+ const entry = resolved.get(name);
259
+ if (!entry)
260
+ continue;
261
+ const problem = validate(spec, entry.value);
262
+ if (problem)
263
+ errors.push({ key: name, message: problem });
264
+ }
265
+ }
266
+ const unknownFileKeys = Object.keys(fileRead.values)
267
+ .filter((k) => !claimed.has(k))
268
+ .sort();
269
+ if (unknownFileKeys.length > 0) {
270
+ getLogger().warn(`env file declares ${unknownFileKeys.length} key(s) no schema knows (not loaded): ${unknownFileKeys.join(', ')}`, 'Env');
271
+ }
272
+ // Populate the target env for file/default values so legacy `process.env.X` reads keep working.
273
+ for (const [name, entry] of resolved) {
274
+ if (entry.source !== 'env' && nonEmpty(target[name]) === undefined)
275
+ target[name] = entry.value;
276
+ }
277
+ // Secrets: hand every set secret value to the logger for verbatim masking.
278
+ const secretValues = [];
279
+ for (const spec of merged) {
280
+ if (!isSecret(spec))
281
+ continue;
282
+ for (const name of [spec.key, ...(families.get(spec.key) ?? [])]) {
283
+ const entry = resolved.get(name);
284
+ if (!entry)
285
+ continue;
286
+ secretValues.push(entry.value);
287
+ if (entry.value.length < MIN_SECRET_LENGTH) {
288
+ getLogger().warn(`env ${name} is a secret shorter than ${MIN_SECRET_LENGTH} characters and cannot be masked in logs or errors`, 'Env');
289
+ }
290
+ }
291
+ }
292
+ registerSecretValues(secretValues);
293
+ const has = (key) => {
294
+ if (resolved.has(key))
295
+ return true;
296
+ return (families.get(key) ?? []).some((m) => resolved.has(m));
297
+ };
298
+ const missing = merged.filter((s) => s.required && !has(s.key)).map((s) => s.key);
299
+ if (options.strict && errors.length > 0) {
300
+ throw new Error(`loadEnv: invalid environment: ${errors.map((e) => `${e.key} ${e.message}`).join('; ')}`);
301
+ }
302
+ const get = (key) => resolved.get(key)?.value;
303
+ const valid = (key) => {
304
+ const value = get(key);
305
+ if (value === undefined)
306
+ return undefined;
307
+ return errors.some((e) => e.key === key) ? undefined : value;
308
+ };
309
+ return {
310
+ schema: merged,
311
+ envFile: fileRead.file,
312
+ missing,
313
+ errors,
314
+ unknownFileKeys,
315
+ get,
316
+ members: (key) => [key, ...(families.get(key) ?? [])].filter((name) => resolved.has(name)),
317
+ getAll: (key) => {
318
+ const out = [];
319
+ const base = get(key);
320
+ if (base !== undefined)
321
+ out.push(base);
322
+ for (const member of families.get(key) ?? []) {
323
+ const value = get(member);
324
+ if (value !== undefined)
325
+ out.push(value);
326
+ }
327
+ return out;
328
+ },
329
+ int: (key) => {
330
+ const value = valid(key);
331
+ return value === undefined ? undefined : parseIntStrict(value);
332
+ },
333
+ bool: (key) => {
334
+ const value = valid(key);
335
+ return value === undefined ? undefined : parseBoolWord(value);
336
+ },
337
+ has,
338
+ isConfigured: (keys) => (keys ?? merged.filter((s) => s.required).map((s) => s.key)).every(has),
339
+ describe: () => merged.map((spec) => {
340
+ const state = {
341
+ key: spec.key,
342
+ set: has(spec.key),
343
+ required: spec.required === true,
344
+ secret: isSecret(spec),
345
+ };
346
+ const source = resolved.get(spec.key)?.source;
347
+ if (source)
348
+ state.source = source;
349
+ if (spec.multi) {
350
+ state.count = [spec.key, ...(families.get(spec.key) ?? [])].filter((n) => resolved.has(n)).length;
351
+ }
352
+ return state;
353
+ }),
354
+ };
355
+ }
356
+ function escapeCell(text) {
357
+ return text.replace(/\|/g, '\\|').replace(/[\r\n]+/g, ' ');
358
+ }
359
+ function typeLabel(spec) {
360
+ if (spec.type === 'enum')
361
+ return `enum (${(spec.values ?? []).join(', ')})`;
362
+ return spec.type ?? 'string';
363
+ }
364
+ /** A markdown table (key, type, required, multi, secret, default, description) for READMEs. */
365
+ export function renderEnvTable(schema, options = {}) {
366
+ const specs = options.includeCore ? mergeSchemas(CORE_ENV_SCHEMA, schema) : mergeSchemas(schema);
367
+ const lines = [
368
+ '| Key | Type | Required | Multi | Secret | Default | Description |',
369
+ '|-----|------|----------|-------|--------|---------|-------------|',
370
+ ];
371
+ for (const s of specs) {
372
+ const key = s.multi ? `\`${s.key}\`, \`${s.key}_*\`` : `\`${s.key}\``;
373
+ const def = isSecret(s) || s.value === undefined || s.value === '' ? '' : `\`${escapeCell(s.value)}\``;
374
+ lines.push(`| ${key} | ${escapeCell(typeLabel(s))} | ${s.required ? 'yes' : 'no'} | ${s.multi ? 'yes' : 'no'} | ` +
375
+ `${isSecret(s) ? 'yes' : 'no'} | ${def} | ${escapeCell(s.description ?? '')} |`);
376
+ }
377
+ return `${lines.join('\n')}\n`;
378
+ }
379
+ /** `.env.example` text: a comment per key, the default as the value, secrets always empty. */
380
+ export function renderEnvExample(schema, options = {}) {
381
+ const specs = options.includeCore ? mergeSchemas(CORE_ENV_SCHEMA, schema) : mergeSchemas(schema);
382
+ const blocks = [];
383
+ for (const s of specs) {
384
+ const notes = [];
385
+ if (s.required)
386
+ notes.push('required');
387
+ if (isSecret(s))
388
+ notes.push('secret');
389
+ if (s.type && s.type !== 'string')
390
+ notes.push(typeLabel(s));
391
+ if (s.multi)
392
+ notes.push(`multi: also ${s.key}_1, ${s.key}_2, ...`);
393
+ const head = [s.description ?? '', notes.length ? `(${notes.join('; ')})` : ''].filter(Boolean).join(' ');
394
+ const value = isSecret(s) ? '' : (s.value ?? '');
395
+ blocks.push(`${head ? `# ${head.replace(/[\r\n]+/g, ' ')}\n` : ''}${s.key}=${value}`);
396
+ }
397
+ return `${blocks.join('\n\n')}\n`;
398
+ }
399
+ //# sourceMappingURL=envLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envLoader.js","sourceRoot":"","sources":["../../src/utils/envLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @novorb/mcp-core - Logger
3
+ *
4
+ * One logging utility for every MCP server. Sinks:
5
+ * - console: process.stderr only (never stdout, the stdio protocol channel)
6
+ * - <name>.log: the main log, every entry at or above the level
7
+ * - exceptions.log: ERROR entries only
8
+ * - debug.log: DEBUG entries only (so only when the level is DEBUG)
9
+ *
10
+ * Log directory: `<rootDir>/.logs` by default (rootDir = the consumer's package root, see
11
+ * `packageRootFrom`). LOG_PATH overrides it (absolute, or relative to rootDir). Without rootDir and
12
+ * without an absolute LOG_PATH the file sinks stay off (one console warning from initLogger); nothing
13
+ * is ever written relative to cwd.
14
+ *
15
+ * Switches (explicit config overrides env, env overrides the default):
16
+ * LOG_LEVEL DEBUG | INFO | WARN | ERROR default INFO
17
+ * LOG_FORMAT text | json default text
18
+ * LOG_CONSOLE true | false default true
19
+ * LOG_FILE_MAIN true | false default true (needs a directory)
20
+ * LOG_FILE_EXCEPTIONS true | false default true (needs a directory)
21
+ * LOG_FILE_DEBUG true | false default true (needs a directory)
22
+ * LOG_PATH log directory default <rootDir>/.logs
23
+ * LOG_FILE main file name (absolute = as-is) default <name>.log
24
+ *
25
+ * Text line: 2026-03-22T13:27:58.513Z | INFO | Server | Starting... | {"meta":"json"}
26
+ * JSON line: {"level":"INFO","timestamp":"...","component":"Server","message":"Starting...",...meta}
27
+ *
28
+ * Every entry is sanitised: sensitive-keyed meta fields become [REDACTED], secret query parameters
29
+ * in strings become name=[REDACTED], and PII in the message and every meta string is masked
30
+ * ([EMAIL] [PHONE] [CARD] [IBAN] [JWT] [TOKEN] [IP]). Text mode also strips control characters.
31
+ *
32
+ * `initLogger` reconfigures the singleton IN PLACE, so a logger obtained with `getLogger()` at import
33
+ * time (before init) writes to the configured sinks after init.
34
+ */
35
+ export { maskPii, redactSecrets } from './redact.js';
36
+ export declare enum LogLevel {
37
+ DEBUG = 0,
38
+ INFO = 1,
39
+ WARN = 2,
40
+ ERROR = 3
41
+ }
42
+ export type LogFormat = 'text' | 'json';
43
+ export interface LoggerConfig {
44
+ /** Server name; the main log file is `<name>.log`. Required by initLogger when the main file is on. */
45
+ name?: string;
46
+ /** The consumer's package root; the default log directory is `<rootDir>/.logs`. */
47
+ rootDir?: string;
48
+ /** Log directory (overrides LOG_PATH); absolute, or relative to rootDir. */
49
+ logDir?: string;
50
+ /** Main log file name (overrides LOG_FILE); an absolute path is used as-is. */
51
+ logFile?: string;
52
+ /** Minimum level (LOG_LEVEL, default INFO). */
53
+ level: LogLevel;
54
+ /** Line format (LOG_FORMAT, default text). */
55
+ format: LogFormat;
56
+ /** stderr sink (LOG_CONSOLE, default true). */
57
+ console: boolean;
58
+ /** Main file sink (LOG_FILE_MAIN, default true). */
59
+ fileMain: boolean;
60
+ /** exceptions.log sink (LOG_FILE_EXCEPTIONS, default true). */
61
+ fileExceptions: boolean;
62
+ /** debug.log sink (LOG_FILE_DEBUG, default true). */
63
+ fileDebug: boolean;
64
+ /** Max size per file in bytes before rotation (default 10 MB). */
65
+ maxLogSize: number;
66
+ /** Rotated generations kept per file (default 5). */
67
+ maxLogFiles: number;
68
+ /** Log uncaught exceptions / unhandled rejections to main + exceptions, then exit(1). Default false. */
69
+ captureProcessErrors: boolean;
70
+ }
71
+ export type LoggerOptions = Partial<LoggerConfig>;
72
+ /** The resolved sinks of a logger: console on/off and the absolute path of each active file. */
73
+ export interface LogSinks {
74
+ console: boolean;
75
+ main?: string;
76
+ exceptions?: string;
77
+ debug?: string;
78
+ }
79
+ /** Registered secret values shorter than this are ignored (they would mask ordinary words). */
80
+ export declare const MIN_SECRET_LENGTH = 6;
81
+ /**
82
+ * Register secret VALUES (API tokens, passwords) that are masked verbatim as `[SECRET]` wherever they
83
+ * appear in any log entry, in both line formats (raw and JSON-escaped). The env loader calls this for
84
+ * every set `secret: true` variable. Process-global; values shorter than MIN_SECRET_LENGTH are ignored.
85
+ */
86
+ export declare function registerSecretValues(values: Iterable<string>): void;
87
+ /** Forget every registered secret value (tests). */
88
+ export declare function clearSecretValues(): void;
89
+ /** Replace every registered secret value in `s` with `[SECRET]` (longest first). */
90
+ export declare function maskSecretValues(s: string): string;
91
+ /** One accepted log entry as a listener sees it: already redacted and masked like the file lines. */
92
+ export interface LogEntry {
93
+ level: LogLevel;
94
+ /** The logger name (`initLogger({ name })`), when set. */
95
+ logger?: string;
96
+ context: string;
97
+ message: string;
98
+ /** Redacted, PII-masked meta (secret values masked), or undefined. */
99
+ meta?: unknown;
100
+ }
101
+ /** Receives every entry the logger accepts (at or above its level), after redaction and masking. */
102
+ export type LogListener = (entry: LogEntry) => void;
103
+ /**
104
+ * Subscribe to accepted log entries (process-global, survives `initLogger` reconfiguration; cleared by
105
+ * `resetLogger`). Returns the unsubscribe function. A throwing listener is ignored, and a listener that
106
+ * logs from inside its own callback is not re-entered.
107
+ */
108
+ export declare function addLogListener(listener: LogListener): () => void;
109
+ export declare class Logger {
110
+ private config;
111
+ private resolved;
112
+ private fatalHandlers;
113
+ private sizes;
114
+ constructor(options?: LoggerOptions);
115
+ /**
116
+ * Reconfigure in place: recompute every setting from defaults + env + `options` (exactly as the
117
+ * constructor does), create the log directories, and install or remove the process-error handlers.
118
+ */
119
+ configure(options?: LoggerOptions): void;
120
+ /** The active sinks (console flag and absolute file paths). */
121
+ sinks(): LogSinks;
122
+ /** Remove the process-error handlers and this logger's claim on the stderr guard. */
123
+ detach(): void;
124
+ /** Remove the process-error handlers, if installed. */
125
+ detachProcessHandlers(): void;
126
+ private attachProcessHandlers;
127
+ private onFatal;
128
+ /** Write one WARN line to the console sink only (used for the directory warning). */
129
+ consoleWarn(message: string, context: string): void;
130
+ private formatText;
131
+ private formatJson;
132
+ private format;
133
+ private write;
134
+ private writeConsole;
135
+ private knownSize;
136
+ private writeFile;
137
+ /** maxLogFiles counts the active file: N keeps the active file plus N-1 rotated ones (minimum 1). */
138
+ private rotate;
139
+ debug(message: string, context?: string, meta?: unknown): void;
140
+ info(message: string, context?: string, meta?: unknown): void;
141
+ warn(message: string, context?: string, meta?: unknown): void;
142
+ error(message: string, context?: string, meta?: unknown): void;
143
+ setLevel(level: LogLevel): void;
144
+ }
145
+ /**
146
+ * Initialise (or reconfigure in place) the logger singleton. Call once at startup with the server
147
+ * `name` and its package `rootDir`. Throws when the main file is on, a directory exists, and neither
148
+ * `name` nor LOG_FILE is given. Warns once on the console when file sinks are on but there is no
149
+ * usable directory.
150
+ */
151
+ export declare function initLogger(options?: LoggerOptions): Logger;
152
+ /** Get the singleton, creating a default (console-only unless LOG_PATH is absolute) one if needed. */
153
+ export declare function getLogger(options?: LoggerOptions): Logger;
154
+ /** Drop the singleton, its process handlers and the process-global console state (tests). */
155
+ export declare function resetLogger(): void;
156
+ /**
157
+ * The package root of the module at `importMetaUrl` (pass `import.meta.url`): the nearest ancestor
158
+ * directory holding a package.json. Works from `src/` and `dist/` alike and is Windows-safe
159
+ * (`fileURLToPath`, never `URL.pathname`). Also accepts a plain file path.
160
+ */
161
+ export declare function packageRootFrom(importMetaUrl: string | URL): string;
162
+ /** Shape-only summary of tool arguments: one descriptor string per top-level key. */
163
+ export type ArgsSummary = Record<string, string>;
164
+ /**
165
+ * Summarise tool arguments by shape only, never by value. Per top-level key: `string(<len>)`,
166
+ * `array(<len>)`, `object{<key names, one level, max 20>}`, `number`, `boolean`, `null`, `undefined`,
167
+ * `bigint`, `function`. Non-object args are summarised under `_args`; null/undefined give `{}`.
168
+ */
169
+ export declare function summarizeArgs(args: unknown): ArgsSummary;
170
+ /** INFO `Tool call: <name>` with meta `{ tool, args: summarizeArgs(args) }`. Never the argument values. */
171
+ export declare function logToolCall(name: string, args: unknown, context?: string): void;
172
+ /**
173
+ * `Tool result: <name>` with meta `{ tool, isError, durationMs }` (durationMs rounded). INFO on
174
+ * success, WARN when isError. Never the result content.
175
+ */
176
+ export declare function logToolResult(name: string, outcome: {
177
+ isError: boolean;
178
+ durationMs: number;
179
+ }, context?: string): void;
180
+ export default getLogger;
181
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}