@rulvar/core 1.171.0 → 1.172.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -10855,6 +10855,18 @@ interface McpConfig {
10855
10855
  */
10856
10856
  maxTools?: number;
10857
10857
  /**
10858
+ * Cap on tools/list PAGES fetched in one sweep (RV1602): a server
10859
+ * paginating past it refuses typed, fail closed like maxTools (a
10860
+ * truncated import would silently admit a subset of the declared
10861
+ * surface). Bounds the sweep's WIRE CALL count where maxTools bounds
10862
+ * its volume: unique cursors over empty pages grow neither the tool
10863
+ * count nor any timeout (each page answers inside listMs), so only a
10864
+ * page bound stops them. Positive integer; absent = unbounded.
10865
+ * Independent of the unconditional cursor-echo cycle guard, which
10866
+ * needs no configuration.
10867
+ */
10868
+ maxPages?: number;
10869
+ /**
10858
10870
  * Per ADMITTED tool (allow/deny filter first): the UTF-8 byte length
10859
10871
  * of the serialized inputSchema plus outputSchema when present
10860
10872
  * (RV1515). An oversized tool refuses the resolution typed, naming
package/dist/index.js CHANGED
@@ -3885,6 +3885,7 @@ function validateBounds(cfg) {
3885
3885
  if (value !== void 0 && (!Number.isInteger(value) || value <= 0)) throw new ConfigError(`mcp: '${key}' must be a positive integer, got ${String(value)}`);
3886
3886
  };
3887
3887
  positiveInt("maxTools");
3888
+ positiveInt("maxPages");
3888
3889
  positiveInt("maxSchemaBytes");
3889
3890
  for (const key of [
3890
3891
  "connectMs",
@@ -4034,12 +4035,16 @@ function mcp(cfg) {
4034
4035
  const listAll = async (client) => {
4035
4036
  const tools = [];
4036
4037
  let cursor;
4038
+ let pages = 0;
4037
4039
  const listOptions = cfg.timeouts?.listMs === void 0 ? void 0 : { timeout: cfg.timeouts.listMs };
4038
4040
  do {
4039
4041
  const page = await client.listTools(cursor === void 0 ? {} : { cursor }, listOptions);
4042
+ pages += 1;
4040
4043
  tools.push(...page.tools);
4041
4044
  if (cfg.maxTools !== void 0 && tools.length > cfg.maxTools) throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' returned at least ${tools.length} wire tools, over the declared maxTools ${cfg.maxTools}; raise the cap or trim the server`);
4045
+ if (page.nextCursor !== void 0 && page.nextCursor !== "" && page.nextCursor === cursor) throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' returned the cursor it was queried with ('${page.nextCursor}') on page ${pages}: the pagination makes no progress`);
4042
4046
  cursor = page.nextCursor;
4047
+ if (cfg.maxPages !== void 0 && pages >= cfg.maxPages && cursor !== void 0 && cursor !== "") throw new ConfigError(`mcp: tools/list of '${sourceIdOf(cfg)}' still reports another page after ${pages} page(s), over the declared maxPages ${cfg.maxPages}; raise the cap or trim the server`);
4043
4048
  } while (cursor !== void 0 && cursor !== "");
4044
4049
  return tools;
4045
4050
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.171.0",
3
+ "version": "1.172.0",
4
4
  "description": "Rulvar core: L0 contracts, journal kernel, ctx primitives, agent runtime, model router, tool system, dynamic orchestrator, InMemory and JSONL stores, event stream.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",