@novorb/mcp-core 2.1.1 → 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 +82 -161
  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 +278 -43
  44. package/dist/http-client.d.ts.map +1 -1
  45. package/dist/http-client.js +620 -182
  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 +49 -10
  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 -36
  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 +144 -53
  192. package/dist/transport.d.ts.map +1 -1
  193. package/dist/transport.js +305 -122
  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 +140 -18
  237. package/dist/logger.d.ts +0 -80
  238. package/dist/logger.d.ts.map +0 -1
  239. package/dist/logger.js +0 -236
  240. package/dist/logger.js.map +0 -1
@@ -0,0 +1,248 @@
1
+ /**
2
+ * @novorb/mcp-core - Tool result limits
3
+ *
4
+ * `registerTools` enforces two caps on every tool result, by default:
5
+ *
6
+ * - items: a list-shaped result (`structuredContent` of the `PagedResult` shape `{ items, nextCursor?,
7
+ * total? }`) carries at most `maxItems` items (MCP_MAX_RESULT_ITEMS, default 100; a smaller `limit`
8
+ * argument wins). The rest is reached through an opaque `nextCursor`.
9
+ * - bytes: the serialized result is at most `maxBytes` (MCP_MAX_RESULT_BYTES, default 256 KiB). A
10
+ * list-shaped result is first paged smaller; anything still too large becomes an actionable isError
11
+ * result (never a truncated, invalid or schema-breaking body).
12
+ *
13
+ * Cursors are stateless. mcp-core's cursor records the tool, a fingerprint of the other arguments, the
14
+ * offset inside the handler's page, and the handler's own cursor for that page; on the next call the
15
+ * handler is re-run with its own cursor (as `args.cursor` and `ctx.cursor`) and mcp-core serves the next
16
+ * slice, or wraps the handler's own `nextCursor` once its page is exhausted. A cursor for another tool or
17
+ * other arguments, or a malformed one, is refused (`Invalid cursor: ...`), so an edited cursor can only
18
+ * ever address the caller's own result set. The handler must be a deterministic read for a given cursor
19
+ * (list tools are).
20
+ */
21
+ import { createHash } from 'node:crypto';
22
+ import { decodeCursor, encodeCursor, InvalidCursorError } from './pagination.js';
23
+ import { getLogger } from './utils/logger.js';
24
+ function isPagedShape(value) {
25
+ return (typeof value === 'object' && value !== null && !Array.isArray(value) && Array.isArray(value.items));
26
+ }
27
+ function stable(value) {
28
+ if (Array.isArray(value))
29
+ return value.map(stable);
30
+ if (typeof value === 'object' && value !== null) {
31
+ const out = {};
32
+ for (const key of Object.keys(value).sort())
33
+ out[key] = stable(value[key]);
34
+ return out;
35
+ }
36
+ return value;
37
+ }
38
+ /** A short fingerprint of the arguments other than `cursor` / `limit` (binds a cursor to its query). */
39
+ export function argsFingerprint(args) {
40
+ const rest = typeof args === 'object' && args !== null ? { ...args } : {};
41
+ delete rest.cursor;
42
+ delete rest.limit;
43
+ return createHash('sha256')
44
+ .update(JSON.stringify(stable(rest)) ?? '')
45
+ .digest('hex')
46
+ .slice(0, 16);
47
+ }
48
+ function isToolCursorData(tool, fingerprint) {
49
+ return (data) => {
50
+ const r = typeof data === 'object' && data !== null && !Array.isArray(data) ? data : undefined;
51
+ if (!r || typeof r.t !== 'string')
52
+ return false;
53
+ if (r.t !== tool)
54
+ throw new InvalidCursorError('issued for another tool');
55
+ if (r.h !== fingerprint)
56
+ throw new InvalidCursorError('issued for other arguments');
57
+ return (typeof r.o === 'number' && Number.isInteger(r.o) && r.o >= 0 && (r.c === undefined || typeof r.c === 'string'));
58
+ };
59
+ }
60
+ /**
61
+ * Decode `cursor` as an mcp-core tool cursor. Returns undefined when it is not one (a handler's own
62
+ * cursor; only allowed when `strict` is false). Throws `InvalidCursorError` for a mismatch.
63
+ */
64
+ export function decodeToolCursor(tool, args, cursor, strict) {
65
+ try {
66
+ const data = decodeCursor(cursor, { validate: isToolCursorData(tool, argsFingerprint(args)) });
67
+ return data.c !== undefined ? { o: data.o, c: data.c } : { o: data.o };
68
+ }
69
+ catch (e) {
70
+ if (e instanceof InvalidCursorError && /another tool|other arguments/.test(e.message))
71
+ throw e;
72
+ if (strict)
73
+ throw e instanceof InvalidCursorError ? e : new InvalidCursorError('unrecognised format');
74
+ return undefined;
75
+ }
76
+ }
77
+ function encodeToolCursor(tool, args, position) {
78
+ const data = { t: tool, h: argsFingerprint(args), o: position.o };
79
+ if (position.c !== undefined)
80
+ data.c = position.c;
81
+ return encodeCursor(data);
82
+ }
83
+ /** The arguments handed to the handler: `cursor` = its own cursor (or none), `limit` capped. */
84
+ export function handlerArgs(args, decoded, maxItems) {
85
+ if (typeof args !== 'object' || args === null || Array.isArray(args))
86
+ return args;
87
+ const out = { ...args };
88
+ if (decoded) {
89
+ if (decoded.c !== undefined)
90
+ out.cursor = decoded.c;
91
+ else
92
+ delete out.cursor;
93
+ }
94
+ if (typeof out.limit === 'number')
95
+ out.limit = Math.max(1, Math.min(Math.floor(out.limit), maxItems));
96
+ return out;
97
+ }
98
+ function byteSize(value) {
99
+ return Buffer.byteLength(JSON.stringify(value) ?? '', 'utf8');
100
+ }
101
+ function pretty(value) {
102
+ return JSON.stringify(value, null, 2);
103
+ }
104
+ function refusal(text) {
105
+ return { content: [{ type: 'text', text }], isError: true };
106
+ }
107
+ /** The bytes of `result` with any text block that only repeats `payload` left out (it is counted once). */
108
+ function envelopeBytes(result, payload) {
109
+ const compact = JSON.stringify(payload);
110
+ const copies = new Set([compact, pretty(payload)]);
111
+ const content = result.content.filter((block) => !(block.type === 'text' && copies.has(block.text)));
112
+ return byteSize(content.length === result.content.length ? result : { ...result, content });
113
+ }
114
+ /** The caps for an envelope result: items of the payload member, bytes with the payload counted once. */
115
+ function enforceEnvelopeLimits(ctx, envelope, result) {
116
+ const sc = (result.isError === true ? undefined : result.structuredContent);
117
+ if (!sc || !(envelope.key in sc))
118
+ return enforceResultLimits({ ...ctx, envelope: undefined }, result);
119
+ const payload = sc[envelope.key];
120
+ const hint = envelope.hint ? `; ${envelope.hint}` : '';
121
+ const items = Array.isArray(payload) ? payload : isPagedShape(payload) ? payload.items : undefined;
122
+ if (items && items.length > ctx.maxItems) {
123
+ getLogger().warn(`Tool result over the item limit: ${ctx.tool}`, 'Tools', {
124
+ tool: ctx.tool,
125
+ items: items.length,
126
+ maxItems: ctx.maxItems,
127
+ });
128
+ return refusal(`${ctx.tool}: the result has ${items.length} items, over the ${ctx.maxItems} item limit per response${hint}`);
129
+ }
130
+ const bytes = envelopeBytes(result, payload);
131
+ if (bytes <= ctx.maxBytes)
132
+ return result;
133
+ getLogger().warn(`Tool result over the byte limit: ${ctx.tool}`, 'Tools', {
134
+ tool: ctx.tool,
135
+ bytes,
136
+ maxBytes: ctx.maxBytes,
137
+ isError: false,
138
+ });
139
+ const replacement = ctx.onOversize?.({
140
+ tool: ctx.tool,
141
+ bytes,
142
+ maxBytes: ctx.maxBytes,
143
+ result,
144
+ ...(ctx.authInfo ? { authInfo: ctx.authInfo } : {}),
145
+ });
146
+ if (replacement && byteSize(replacement) <= ctx.maxBytes)
147
+ return replacement;
148
+ return refusal(`${ctx.tool}: the result is ${bytes} bytes, over the ${ctx.maxBytes} byte limit per response${hint}`);
149
+ }
150
+ function oversizeError(tool, bytes, maxBytes, paged) {
151
+ const hint = paged
152
+ ? 'even one item is too large; request fewer fields or a narrower item'
153
+ : 'narrow the request (filters, fewer fields, a smaller range) or use a paginated variant with cursor/limit';
154
+ return {
155
+ content: [
156
+ {
157
+ type: 'text',
158
+ text: `${tool}: the result is ${bytes} bytes, over the ${maxBytes} byte limit per response; ${hint}`,
159
+ },
160
+ ],
161
+ isError: true,
162
+ };
163
+ }
164
+ function pageOf(ctx, result, sc, limit) {
165
+ const offset = ctx.decoded?.o ?? 0;
166
+ const end = offset + limit;
167
+ const page = { ...sc, items: sc.items.slice(offset, end) };
168
+ delete page.nextCursor;
169
+ const inner = ctx.decoded?.c;
170
+ let next;
171
+ if (end < sc.items.length)
172
+ next = inner !== undefined ? { o: end, c: inner } : { o: end };
173
+ else if (typeof sc.nextCursor === 'string' && sc.nextCursor !== '')
174
+ next = { o: 0, c: sc.nextCursor };
175
+ if (next)
176
+ page.nextCursor = encodeToolCursor(ctx.tool, ctx.args, next);
177
+ const first = result.content[0];
178
+ const textWasDump = result.content.length === 1 && first?.type === 'text' && first.text === pretty(sc);
179
+ const cut = page.items.length < sc.items.length;
180
+ const content = cut || textWasDump ? [{ type: 'text', text: pretty(page) }] : result.content;
181
+ return { ...result, content, structuredContent: page };
182
+ }
183
+ /** Apply the item and byte caps to one handler result. */
184
+ export function enforceResultLimits(ctx, result) {
185
+ if (ctx.envelope)
186
+ return enforceEnvelopeLimits(ctx, ctx.envelope, result);
187
+ const log = getLogger();
188
+ const sc = result.isError === true ? undefined : result.structuredContent;
189
+ let out = result;
190
+ if (isPagedShape(sc)) {
191
+ const requested = typeof ctx.args?.limit === 'number';
192
+ const limit = Math.max(1, Math.min(requested ? Number(ctx.args.limit) : ctx.maxItems, ctx.maxItems));
193
+ const needsPaging = (ctx.decoded?.o ?? 0) > 0 || sc.items.length > limit || typeof sc.nextCursor === 'string';
194
+ if (needsPaging) {
195
+ out = pageOf(ctx, result, sc, limit);
196
+ const served = out.structuredContent.items.length;
197
+ if (served < sc.items.length) {
198
+ log.info(`Tool result paged: ${ctx.tool}`, 'Tools', { tool: ctx.tool, items: sc.items.length, served, limit });
199
+ }
200
+ }
201
+ let bytes = byteSize(out);
202
+ let size = out.structuredContent.items.length;
203
+ while (bytes > ctx.maxBytes && size > 1) {
204
+ size = Math.max(1, Math.floor(size / 2));
205
+ out = pageOf(ctx, result, sc, size);
206
+ bytes = byteSize(out);
207
+ }
208
+ if (size < limit && bytes <= ctx.maxBytes) {
209
+ log.warn(`Tool result paged to fit the byte limit: ${ctx.tool}`, 'Tools', {
210
+ tool: ctx.tool,
211
+ items: sc.items.length,
212
+ served: size,
213
+ bytes,
214
+ maxBytes: ctx.maxBytes,
215
+ });
216
+ }
217
+ }
218
+ const bytes = byteSize(out);
219
+ if (bytes <= ctx.maxBytes)
220
+ return out;
221
+ log.warn(`Tool result over the byte limit: ${ctx.tool}`, 'Tools', {
222
+ tool: ctx.tool,
223
+ bytes,
224
+ maxBytes: ctx.maxBytes,
225
+ isError: out.isError === true,
226
+ });
227
+ const replacement = ctx.onOversize?.({
228
+ tool: ctx.tool,
229
+ bytes,
230
+ maxBytes: ctx.maxBytes,
231
+ result: out,
232
+ ...(ctx.authInfo ? { authInfo: ctx.authInfo } : {}),
233
+ });
234
+ if (replacement && byteSize(replacement) <= ctx.maxBytes)
235
+ return replacement;
236
+ return oversizeError(ctx.tool, bytes, ctx.maxBytes, isPagedShape(sc));
237
+ }
238
+ /** Whether an input schema declares `cursor` and `limit` properties (required for `paginated` tools). */
239
+ export function declaresPageArgs(schema) {
240
+ try {
241
+ const json = schema['~standard'].jsonSchema.input({ target: 'draft-2020-12' });
242
+ return json.properties?.cursor !== undefined && json.properties?.limit !== undefined;
243
+ }
244
+ catch {
245
+ return true;
246
+ }
247
+ }
248
+ //# sourceMappingURL=result-limits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result-limits.js","sourceRoot":"","sources":["../src/result-limits.ts"],"names":[],"mappings":"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"}
package/dist/retry.d.ts CHANGED
@@ -1,51 +1,107 @@
1
1
  /**
2
- * @novorb/mcp-core — Retry utilities
2
+ * @novorb/mcp-core - Retry utilities
3
3
  *
4
- * Exponential backoff with jitter for retrying failed HTTP requests.
4
+ * One retry policy for the whole package, shared by `retryWithBackoff` and the HTTP client:
5
+ * - retryable statuses: 408, 425, 429, 500, 502, 503, 504 (never 501, never any other 4xx)
6
+ * - retryable network errors: ECONNRESET, ETIMEDOUT, EAI_AGAIN, and ECONNREFUSED on connect only
7
+ * - `Retry-After` (seconds or HTTP date) is honoured, capped by `maxRetryAfterMs`
8
+ * - otherwise exponential backoff with full jitter, capped by `maxDelayMs`
9
+ * - bounded attempts (a loop, never recursion) and abort-signal aware
10
+ *
11
+ * Idempotency (which methods may be replayed) is decided by the caller; the HTTP client only retries
12
+ * GET/HEAD/OPTIONS/PUT/DELETE unless the request carries an idempotency key or opts in explicitly.
5
13
  */
6
14
  export interface RetryOptions {
7
- /** Maximum number of retries (default: 3) */
15
+ /** Maximum number of retries after the first attempt (default: 3). */
8
16
  maxRetries?: number;
9
- /** Initial delay in milliseconds (default: 1000) */
17
+ /** Base delay of the first retry in milliseconds (default: 1000). */
10
18
  initialDelayMs?: number;
11
- /** Maximum delay in milliseconds (default: 10000) */
19
+ /** Cap of one backoff delay in milliseconds (default: 10000). */
12
20
  maxDelayMs?: number;
13
- /** Backoff multiplier (default: 2) */
21
+ /** Backoff multiplier (default: 2). */
14
22
  backoffMultiplier?: number;
15
- /** Jitter factor 0-1 (default: 0.1 = 10%) */
16
- jitterFactor?: number;
23
+ /** Cap applied to a server-sent Retry-After in milliseconds (default: 30000). */
24
+ maxRetryAfterMs?: number;
25
+ /** Stop retrying (and reject with the abort reason) once this signal aborts. */
26
+ signal?: AbortSignal;
27
+ /** Override the retry decision (default: `isRetryableError`). */
28
+ shouldRetry?: (error: unknown, context: RetryContext) => boolean;
29
+ /** Called before each wait with the delay about to be slept. */
30
+ onRetry?: (info: RetryInfo) => void;
31
+ /** Random source in [0, 1) for the jitter (default: Math.random). */
32
+ random?: () => number;
17
33
  }
18
34
  export interface RetryContext {
19
- /** Current attempt number (0-based) */
35
+ /** Current attempt number (0-based). */
20
36
  attempt: number;
21
- /** Maximum retries configured */
37
+ /** Maximum retries configured. */
22
38
  maxRetries: number;
23
- /** Last error encountered */
39
+ /** Last error encountered. */
24
40
  lastError?: Error;
25
41
  }
42
+ export interface RetryInfo {
43
+ /** The attempt that failed (0-based). */
44
+ attempt: number;
45
+ /** Delay before the next attempt in milliseconds. */
46
+ delayMs: number;
47
+ /** True when the delay came from a Retry-After header. */
48
+ fromRetryAfter: boolean;
49
+ /** The error that triggered the retry. */
50
+ error: unknown;
51
+ }
52
+ /** HTTP statuses that are retried. 501 Not Implemented is permanent and deliberately absent. */
53
+ export declare const RETRYABLE_STATUS_CODES: ReadonlySet<number>;
54
+ /** Network error codes that are retried. ECONNREFUSED additionally requires the connect syscall. */
55
+ export declare const RETRYABLE_NETWORK_CODES: ReadonlySet<string>;
56
+ /** Methods that are safe to replay without an idempotency key. */
57
+ export declare const IDEMPOTENT_METHODS: ReadonlySet<string>;
58
+ /** True for a status in `RETRYABLE_STATUS_CODES`. */
59
+ export declare function isRetryableStatus(status: number): boolean;
60
+ /** True for GET/HEAD/OPTIONS/PUT/DELETE (case-insensitive). A missing method counts as GET. */
61
+ export declare function isIdempotentMethod(method: string | undefined): boolean;
62
+ /** Reads an HTTP status from an axios-style error (`response.status`) or a normalized one (`status`). */
63
+ export declare function errorStatus(error: unknown): number | undefined;
26
64
  /**
27
- * Calculate retry delay with exponential backoff and jitter.
65
+ * Determine if an error is retryable under the shared policy. A response status decides when one is
66
+ * present; otherwise the network error code (own or `cause`) decides.
67
+ */
68
+ export declare function isRetryableError(error: unknown): boolean;
69
+ /**
70
+ * Exponential backoff with full jitter: a uniform value in [0, min(maxDelayMs, initial * mult^attempt)].
28
71
  */
29
72
  export declare function calculateRetryDelay(attempt: number, options?: RetryOptions): number;
30
73
  /**
31
- * Sleep for specified milliseconds.
74
+ * Parse a Retry-After header value (delta seconds or an HTTP date) to milliseconds. Returns undefined
75
+ * for a missing or unparseable value; a date in the past gives 0.
32
76
  */
33
- export declare function sleep(ms: number): Promise<void>;
77
+ export declare function parseRetryAfter(retryAfter: string | undefined, now?: number): number | undefined;
34
78
  /**
35
- * Determine if an error is retryable.
79
+ * The Retry-After delay carried by an error, in milliseconds: a normalized error's `retryAfterMs`, or
80
+ * the `retry-after` header of an axios-style `response`.
36
81
  */
37
- export declare function isRetryableError(error: unknown): boolean;
82
+ export declare function retryAfterFromError(error: unknown, now?: number): number | undefined;
38
83
  /**
39
- * Retry a function with exponential backoff.
84
+ * The delay before the next attempt: the error's Retry-After capped by `maxRetryAfterMs`, else the
85
+ * full-jitter backoff for `attempt`.
86
+ */
87
+ export declare function retryDelayFor(error: unknown, attempt: number, options?: RetryOptions): {
88
+ delayMs: number;
89
+ fromRetryAfter: boolean;
90
+ };
91
+ /** Throws the signal's abort reason when it has aborted. */
92
+ export declare function throwIfAborted(signal: AbortSignal | undefined): void;
93
+ /**
94
+ * Sleep for `ms` milliseconds. With a signal, rejects with its abort reason as soon as it aborts.
95
+ */
96
+ export declare function sleep(ms: number, signal?: AbortSignal): Promise<void>;
97
+ /**
98
+ * Retry a function under the shared policy.
40
99
  *
41
100
  * @param fn - Async function to retry (receives RetryContext)
42
101
  * @param options - Retry options
43
- * @returns Result of successful function call
44
- * @throws Last error if all retries exhausted or error is not retryable
102
+ * @returns Result of the first successful call
103
+ * @throws The last error when retries are exhausted or the error is not retryable; the abort reason
104
+ * when the signal aborts
45
105
  */
46
106
  export declare function retryWithBackoff<T>(fn: (context: RetryContext) => Promise<T>, options?: RetryOptions): Promise<T>;
47
- /**
48
- * Parse Retry-After header value to milliseconds.
49
- */
50
- export declare function parseRetryAfter(retryAfter: string | undefined): number | undefined;
51
107
  //# sourceMappingURL=retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sCAAsC;IACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAUD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,MAAM,CAOR;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAQD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAiBxD;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,EAAE,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,EACzC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAUlF"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gFAAgF;IAChF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC;IACjE,gEAAgE;IAChE,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;IACpC,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,cAAc,EAAE,OAAO,CAAC;IACxB,0CAA0C;IAC1C,KAAK,EAAE,OAAO,CAAC;CAChB;AAUD,gGAAgG;AAChG,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAAgD,CAAC;AAExG,oGAAoG;AACpG,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAKtD,CAAC;AAEH,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAwD,CAAC;AAE5G,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEtE;AAMD,yGAAyG;AACzG,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAK9D;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASxD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAOvF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,SAAS,CAQ5G;AAgBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,SAAS,CAKhG;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,CAO9C;AAUD,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAEpE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBrE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,CAAC,EACtC,EAAE,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,EACzC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAsBZ"}