mcp2cli 2.7.0__tar.gz → 2.8.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp2cli
3
- Version: 2.7.0
3
+ Version: 2.8.1
4
4
  Summary: Turn any MCP server or OpenAPI spec into a CLI
5
5
  Author: Stephan Fitzpatrick
6
6
  Author-email: Stephan Fitzpatrick <stephan@knowsuchagency.com>
@@ -216,6 +216,26 @@ Filtering options:
216
216
 
217
217
  Configs are stored in `~/.config/mcp2cli/baked.json`. Override with `MCP2CLI_CONFIG_DIR`.
218
218
 
219
+ ### Usage-aware tool ranking
220
+
221
+ mcp2cli tracks tool invocations locally and uses that data to rank `--list` output, reducing token costs for LLM agents working with large servers.
222
+
223
+ ```bash
224
+ # Default --list: ~1,400 tokens for 96 tools
225
+ mcp2cli @myapi --list
226
+
227
+ # Top 10 most-used tools, names only: ~20 tokens
228
+ mcp2cli @myapi --list --top 10 --compact
229
+
230
+ # Sort by most recently used
231
+ mcp2cli @myapi --list --sort recent
232
+
233
+ # Alphabetical sort
234
+ mcp2cli @myapi --list --sort alpha
235
+ ```
236
+
237
+ When usage data exists for a source, `--list` defaults to sorting by call frequency. Otherwise insertion order is preserved. Usage data is stored in `~/.cache/mcp2cli/usage.json`.
238
+
219
239
  ### Output control
220
240
 
221
241
  ```bash
@@ -286,6 +306,10 @@ Options:
286
306
  --refresh Bypass cache
287
307
  --list List available subcommands
288
308
  --search PATTERN Search tools by name or description (implies --list)
309
+ --sort MODE Sort --list output: usage|recent|alpha|default
310
+ --top N Show only the top N tools in --list output
311
+ --compact Space-separated tool names only, no descriptions
312
+ --verbose Show full tool descriptions (unwrapped)
289
313
  --fields FIELDS Override GraphQL selection set (e.g. "id name email")
290
314
  --pretty Pretty-print JSON output
291
315
  --raw Print raw response body
@@ -197,6 +197,26 @@ Filtering options:
197
197
 
198
198
  Configs are stored in `~/.config/mcp2cli/baked.json`. Override with `MCP2CLI_CONFIG_DIR`.
199
199
 
200
+ ### Usage-aware tool ranking
201
+
202
+ mcp2cli tracks tool invocations locally and uses that data to rank `--list` output, reducing token costs for LLM agents working with large servers.
203
+
204
+ ```bash
205
+ # Default --list: ~1,400 tokens for 96 tools
206
+ mcp2cli @myapi --list
207
+
208
+ # Top 10 most-used tools, names only: ~20 tokens
209
+ mcp2cli @myapi --list --top 10 --compact
210
+
211
+ # Sort by most recently used
212
+ mcp2cli @myapi --list --sort recent
213
+
214
+ # Alphabetical sort
215
+ mcp2cli @myapi --list --sort alpha
216
+ ```
217
+
218
+ When usage data exists for a source, `--list` defaults to sorting by call frequency. Otherwise insertion order is preserved. Usage data is stored in `~/.cache/mcp2cli/usage.json`.
219
+
200
220
  ### Output control
201
221
 
202
222
  ```bash
@@ -267,6 +287,10 @@ Options:
267
287
  --refresh Bypass cache
268
288
  --list List available subcommands
269
289
  --search PATTERN Search tools by name or description (implies --list)
290
+ --sort MODE Sort --list output: usage|recent|alpha|default
291
+ --top N Show only the top N tools in --list output
292
+ --compact Space-separated tool names only, no descriptions
293
+ --verbose Show full tool descriptions (unwrapped)
270
294
  --fields FIELDS Override GraphQL selection set (e.g. "id name email")
271
295
  --pretty Pretty-print JSON output
272
296
  --raw Print raw response body
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mcp2cli"
3
- version = "2.7.0"
3
+ version = "2.8.1"
4
4
  description = "Turn any MCP server or OpenAPI spec into a CLI"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -26,6 +26,8 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
26
26
  from pathlib import Path
27
27
  from urllib.parse import parse_qs, urlparse
28
28
 
29
+ from datetime import datetime, timezone
30
+
29
31
  import anyio
30
32
  import httpx
31
33
 
@@ -33,6 +35,7 @@ CACHE_DIR = Path(
33
35
  os.environ.get("MCP2CLI_CACHE_DIR", Path.home() / ".cache" / "mcp2cli")
34
36
  )
35
37
  DEFAULT_CACHE_TTL = 3600
38
+ USAGE_FILE = CACHE_DIR / "usage.json"
36
39
  CONFIG_DIR = Path(
37
40
  os.environ.get("MCP2CLI_CONFIG_DIR", Path.home() / ".config" / "mcp2cli")
38
41
  )
@@ -387,6 +390,94 @@ def save_cache(key: str, data: dict):
387
390
  (CACHE_DIR / f"{key}.json").write_text(json.dumps(data))
388
391
 
389
392
 
393
+ # ---------------------------------------------------------------------------
394
+ # Usage tracking
395
+ # ---------------------------------------------------------------------------
396
+
397
+
398
+ def _load_usage() -> dict:
399
+ """Load the usage tracking file. Returns empty dict on any failure."""
400
+ if not USAGE_FILE.exists():
401
+ return {}
402
+ try:
403
+ return json.loads(USAGE_FILE.read_text())
404
+ except (json.JSONDecodeError, OSError):
405
+ return {}
406
+
407
+
408
+ def _save_usage(data: dict) -> None:
409
+ """Write usage data. Last-write-wins -- no file locking."""
410
+ CACHE_DIR.mkdir(parents=True, exist_ok=True)
411
+ USAGE_FILE.write_text(json.dumps(data, indent=2))
412
+
413
+
414
+ def record_usage(source_hash: str, tool_name: str) -> None:
415
+ """Increment the call count and update last_used for a tool."""
416
+ usage = _load_usage()
417
+ bucket = usage.setdefault(source_hash, {})
418
+ entry = bucket.setdefault(tool_name, {"count": 0, "last_used": ""})
419
+ entry["count"] += 1
420
+ entry["last_used"] = datetime.now(timezone.utc).isoformat()
421
+ _save_usage(usage)
422
+
423
+
424
+ def _source_hash_for(source: str) -> str:
425
+ """Derive a stable hash key from a source URL/command string."""
426
+ return hashlib.sha256(source.encode()).hexdigest()[:16]
427
+
428
+
429
+ def sort_commands(
430
+ commands: list["CommandDef"],
431
+ sort_mode: str,
432
+ source_hash: str,
433
+ ) -> list["CommandDef"]:
434
+ """Sort commands by the given mode using usage data.
435
+
436
+ Modes:
437
+ usage -- most-called first (default when usage data exists)
438
+ recent -- most-recently-used first
439
+ alpha -- alphabetical by name
440
+ default -- original insertion order
441
+ """
442
+ if sort_mode == "default":
443
+ return commands
444
+ if sort_mode == "alpha":
445
+ return sorted(commands, key=lambda c: c.name)
446
+
447
+ usage = _load_usage().get(source_hash, {})
448
+ if not usage:
449
+ return commands # no data, keep insertion order
450
+
451
+ def _usage_key(c: "CommandDef") -> str:
452
+ return c.tool_name or c.graphql_field_name or c.name
453
+
454
+ if sort_mode == "usage":
455
+ return sorted(
456
+ commands,
457
+ key=lambda c: usage.get(_usage_key(c), {}).get("count", 0),
458
+ reverse=True,
459
+ )
460
+ if sort_mode == "recent":
461
+ return sorted(
462
+ commands,
463
+ key=lambda c: usage.get(_usage_key(c), {}).get("last_used", ""),
464
+ reverse=True,
465
+ )
466
+ return commands
467
+
468
+
469
+ def _resolve_sort_mode(explicit_sort: str | None, source_hash: str) -> str:
470
+ """Determine the effective sort mode.
471
+
472
+ If the user passed --sort explicitly, use that. Otherwise, default to
473
+ 'usage' when usage data exists for this source, else 'default'.
474
+ """
475
+ if explicit_sort is not None:
476
+ return explicit_sort
477
+ usage = _load_usage().get(source_hash, {})
478
+ return "usage" if usage else "default"
479
+
480
+
390
481
  # ---------------------------------------------------------------------------
391
482
  # OAuth support
392
483
  # ---------------------------------------------------------------------------
@@ -1225,8 +1316,20 @@ def _wrap_description(description: str, indent: int, total_width: int = 110) ->
1225
1316
  )
1226
1317
 
1227
1318
 
1228
- def list_graphql_commands(commands: list[CommandDef], verbose: bool = False):
1319
+ def list_graphql_commands(
1320
+ commands: list[CommandDef],
1321
+ verbose: bool = False,
1322
+ compact: bool = False,
1323
+ source_hash: str = "",
1324
+ sort_mode: str | None = None,
1325
+ top: int | None = None,
1326
+ ):
1229
1327
  """Group commands by operation type and print."""
1328
+ commands = _apply_list_options(commands, source_hash, sort_mode, top)
1329
+
1330
+ if compact:
1331
+ print(" ".join(cmd.name for cmd in commands))
1332
+ return
1230
1333
 
1231
1334
  groups: dict[str, list[CommandDef]] = {}
1232
1335
  for cmd in commands:
@@ -1364,19 +1467,30 @@ def handle_graphql(
1364
1467
  jq_expr: str | None = None,
1365
1468
  head: int | None = None,
1366
1469
  verbose: bool = False,
1470
+ sort_mode: str | None = None,
1471
+ top: int | None = None,
1472
+ compact: bool = False,
1367
1473
  ):
1368
1474
  """Top-level handler for --graphql mode."""
1475
+ src_hash = _source_hash_for(url)
1369
1476
  schema = load_graphql_schema(url, auth_headers, cache_key, ttl, refresh, oauth_provider=oauth_provider)
1370
1477
  commands = extract_graphql_commands(schema)
1371
1478
 
1479
+ list_kwargs = dict(
1480
+ verbose=verbose, compact=compact,
1481
+ source_hash=src_hash, sort_mode=sort_mode, top=top,
1482
+ )
1483
+
1372
1484
  if list_mode:
1373
- list_graphql_commands(commands, verbose=verbose)
1485
+ list_graphql_commands(commands, **list_kwargs)
1374
1486
  return
1375
1487
 
1376
1488
  if not remaining:
1377
- print("Available operations:")
1378
- list_graphql_commands(commands, verbose=verbose)
1379
- print("\nUse --list for the same output, or provide a subcommand.")
1489
+ if not compact:
1490
+ print("Available operations:")
1491
+ list_graphql_commands(commands, **list_kwargs)
1492
+ if not compact:
1493
+ print("\nUse --list for the same output, or provide a subcommand.")
1380
1494
  return
1381
1495
 
1382
1496
  pre_for_gql = argparse.ArgumentParser(add_help=False)
@@ -1394,6 +1508,9 @@ def handle_graphql(
1394
1508
  jq_expr=jq_expr, head=head,
1395
1509
  )
1396
1510
 
1511
+ # Record usage after successful execution
1512
+ record_usage(src_hash, cmd.graphql_field_name or cmd.name)
1513
+
1397
1514
 
1398
1515
  # ---------------------------------------------------------------------------
1399
1516
  # Command filtering (bake mode)
@@ -1820,7 +1937,34 @@ def build_argparse(
1820
1937
  # ---------------------------------------------------------------------------
1821
1938
 
1822
1939
 
1823
- def list_openapi_commands(commands: list[CommandDef], verbose: bool = False):
1940
+ def _apply_list_options(
1941
+ commands: list[CommandDef],
1942
+ source_hash: str = "",
1943
+ sort_mode: str | None = None,
1944
+ top: int | None = None,
1945
+ ) -> list[CommandDef]:
1946
+ """Apply sort and top-N filtering to a command list."""
1947
+ effective_sort = _resolve_sort_mode(sort_mode, source_hash)
1948
+ commands = sort_commands(commands, effective_sort, source_hash)
1949
+ if top is not None:
1950
+ commands = commands[:top]
1951
+ return commands
1952
+
1953
+
1954
+ def list_openapi_commands(
1955
+ commands: list[CommandDef],
1956
+ verbose: bool = False,
1957
+ compact: bool = False,
1958
+ source_hash: str = "",
1959
+ sort_mode: str | None = None,
1960
+ top: int | None = None,
1961
+ ):
1962
+ commands = _apply_list_options(commands, source_hash, sort_mode, top)
1963
+
1964
+ if compact:
1965
+ print(" ".join(cmd.name for cmd in commands))
1966
+ return
1967
+
1824
1968
  groups: dict[str, list[CommandDef]] = {}
1825
1969
  for cmd in commands:
1826
1970
  prefix = cmd.name.split("-", 1)[0] if "-" in cmd.name else "other"
@@ -1840,7 +1984,20 @@ def list_openapi_commands(commands: list[CommandDef], verbose: bool = False):
1840
1984
  print(line)
1841
1985
 
1842
1986
 
1843
- def list_mcp_commands(commands: list[CommandDef], verbose: bool = False):
1987
+ def list_mcp_commands(
1988
+ commands: list[CommandDef],
1989
+ verbose: bool = False,
1990
+ compact: bool = False,
1991
+ source_hash: str = "",
1992
+ sort_mode: str | None = None,
1993
+ top: int | None = None,
1994
+ ):
1995
+ commands = _apply_list_options(commands, source_hash, sort_mode, top)
1996
+
1997
+ if compact:
1998
+ print(" ".join(cmd.name for cmd in commands))
1999
+ return
2000
+
1844
2001
  for cmd in commands:
1845
2002
  if cmd.description:
1846
2003
  if verbose:
@@ -2030,6 +2187,10 @@ def run_mcp_http(
2030
2187
  jq_expr: str | None = None,
2031
2188
  head: int | None = None,
2032
2189
  verbose: bool = False,
2190
+ sort_mode: str | None = None,
2191
+ top: int | None = None,
2192
+ compact: bool = False,
2193
+ source_hash: str = "",
2033
2194
  ):
2034
2195
  extra = dict(
2035
2196
  resource_action=resource_action,
@@ -2041,6 +2202,10 @@ def run_mcp_http(
2041
2202
  jq_expr=jq_expr,
2042
2203
  head=head,
2043
2204
  verbose=verbose,
2205
+ sort_mode=sort_mode,
2206
+ top=top,
2207
+ compact=compact,
2208
+ source_hash=source_hash,
2044
2209
  )
2045
2210
 
2046
2211
  async def _run():
@@ -2127,6 +2292,10 @@ def run_mcp_stdio(
2127
2292
  jq_expr: str | None = None,
2128
2293
  head: int | None = None,
2129
2294
  verbose: bool = False,
2295
+ sort_mode: str | None = None,
2296
+ top: int | None = None,
2297
+ compact: bool = False,
2298
+ source_hash: str = "",
2130
2299
  ):
2131
2300
  extra = dict(
2132
2301
  resource_action=resource_action,
@@ -2138,6 +2307,10 @@ def run_mcp_stdio(
2138
2307
  jq_expr=jq_expr,
2139
2308
  head=head,
2140
2309
  verbose=verbose,
2310
+ sort_mode=sort_mode,
2311
+ top=top,
2312
+ compact=compact,
2313
+ source_hash=source_hash,
2141
2314
  )
2142
2315
 
2143
2316
  import anyio
@@ -2190,6 +2363,10 @@ async def _mcp_session(
2190
2363
  jq_expr: str | None = None,
2191
2364
  head: int | None = None,
2192
2365
  verbose: bool = False,
2366
+ sort_mode: str | None = None,
2367
+ top: int | None = None,
2368
+ compact: bool = False,
2369
+ source_hash: str = "",
2193
2370
  ):
2194
2371
  # Handle resource operations
2195
2372
  if resource_action:
@@ -2207,6 +2384,11 @@ async def _mcp_session(
2207
2384
  )
2208
2385
  return
2209
2386
 
2387
+ list_kwargs = dict(
2388
+ verbose=verbose, compact=compact,
2389
+ source_hash=source_hash, sort_mode=sort_mode, top=top,
2390
+ )
2391
+
2210
2392
  if list_mode:
2211
2393
  result = await session.list_tools()
2212
2394
  tools = [
@@ -2223,10 +2405,12 @@ async def _mcp_session(
2223
2405
  if not commands:
2224
2406
  print(f"\nNo tools matching '{search_pattern}'.")
2225
2407
  return
2226
- print(f"\nTools matching '{search_pattern}':")
2408
+ if not compact:
2409
+ print(f"\nTools matching '{search_pattern}':")
2227
2410
  else:
2228
- print("\nAvailable tools:")
2229
- list_mcp_commands(commands, verbose=verbose)
2411
+ if not compact:
2412
+ print("\nAvailable tools:")
2413
+ list_mcp_commands(commands, **list_kwargs)
2230
2414
  return
2231
2415
 
2232
2416
  if tool_name is None:
@@ -2845,6 +3029,9 @@ def handle_mcp(
2845
3029
  jq_expr: str | None = None,
2846
3030
  head: int | None = None,
2847
3031
  verbose: bool = False,
3032
+ sort_mode: str | None = None,
3033
+ top: int | None = None,
3034
+ compact: bool = False,
2848
3035
  ):
2849
3036
  # Build a config dict for cache key generation (future-proof)
2850
3037
  config_for_cache = {
@@ -2854,8 +3041,9 @@ def handle_mcp(
2854
3041
  'env_vars': env_vars,
2855
3042
  'is_stdio': is_stdio,
2856
3043
  }
2857
-
3044
+
2858
3045
  key = cache_key_override or cache_key_for(config_for_cache)
3046
+ src_hash = _source_hash_for(source)
2859
3047
 
2860
3048
  # Resource/prompt operations skip the tool flow entirely
2861
3049
  if resource_action or prompt_action:
@@ -2876,9 +3064,14 @@ def handle_mcp(
2876
3064
  )
2877
3065
  return
2878
3066
 
3067
+ list_kwargs = dict(
3068
+ verbose=verbose, compact=compact,
3069
+ source_hash=src_hash, sort_mode=sort_mode, top=top,
3070
+ )
3071
+
2879
3072
  if list_mode:
2880
3073
  if bake_config and (bake_config.include or bake_config.exclude or bake_config.methods):
2881
- # Fetch tools, filter, then list don't delegate to unfiltered path
3074
+ # Fetch tools, filter, then list -- don't delegate to unfiltered path
2882
3075
  tools = _fetch_or_cache_mcp_tools(
2883
3076
  key, ttl, refresh, source, is_stdio, auth_headers, env_vars,
2884
3077
  transport=transport, oauth_provider=oauth_provider,
@@ -2887,8 +3080,9 @@ def handle_mcp(
2887
3080
  commands = filter_commands(
2888
3081
  commands, bake_config.include, bake_config.exclude, bake_config.methods,
2889
3082
  )
2890
- print("\nAvailable tools:")
2891
- list_mcp_commands(commands, verbose=verbose)
3083
+ if not compact:
3084
+ print("\nAvailable tools:")
3085
+ list_mcp_commands(commands, **list_kwargs)
2892
3086
  return
2893
3087
  _dispatch_mcp_call(
2894
3088
  source, is_stdio, auth_headers, env_vars,
@@ -2897,6 +3091,8 @@ def handle_mcp(
2897
3091
  search_pattern=search_pattern,
2898
3092
  jq_expr=jq_expr, head=head,
2899
3093
  verbose=verbose,
3094
+ sort_mode=sort_mode, top=top, compact=compact,
3095
+ source_hash=src_hash,
2900
3096
  )
2901
3097
  return
2902
3098
 
@@ -2913,9 +3109,11 @@ def handle_mcp(
2913
3109
  )
2914
3110
 
2915
3111
  if not remaining:
2916
- print("Available tools:")
2917
- list_mcp_commands(commands, verbose=verbose)
2918
- print("\nUse --list for the same output, or provide a subcommand.")
3112
+ if not compact:
3113
+ print("Available tools:")
3114
+ list_mcp_commands(commands, **list_kwargs)
3115
+ if not compact:
3116
+ print("\nUse --list for the same output, or provide a subcommand.")
2919
3117
  return
2920
3118
 
2921
3119
  pre = argparse.ArgumentParser(add_help=False)
@@ -2944,6 +3142,9 @@ def handle_mcp(
2944
3142
  jq_expr=jq_expr, head=head,
2945
3143
  )
2946
3144
 
3145
+ # Record usage after successful execution
3146
+ record_usage(src_hash, cmd.tool_name or cmd.name)
3147
+
2947
3148
 
2948
3149
  def _fetch_mcp_tools(
2949
3150
  source: str,
@@ -3130,6 +3331,30 @@ def _build_main_parser() -> argparse.ArgumentParser:
3130
3331
  dest="verbose",
3131
3332
  help="Show full tool descriptions in --list output, wrapped to terminal width (default: truncated with ...)",
3132
3333
  )
3334
+ pre.add_argument(
3335
+ "--sort",
3336
+ choices=["usage", "recent", "alpha", "default"],
3337
+ default=None,
3338
+ dest="sort_mode",
3339
+ help=(
3340
+ "Sort order for --list output. 'usage' sorts by call frequency, "
3341
+ "'recent' by last-used time, 'alpha' alphabetically, 'default' keeps "
3342
+ "insertion order. When omitted, defaults to 'usage' if usage data "
3343
+ "exists, otherwise 'default'."
3344
+ ),
3345
+ )
3346
+ pre.add_argument(
3347
+ "--top",
3348
+ type=int,
3349
+ default=None,
3350
+ metavar="N",
3351
+ help="Show only the top N tools in --list output (useful for LLM agents)",
3352
+ )
3353
+ pre.add_argument(
3354
+ "--compact",
3355
+ action="store_true",
3356
+ help="Space-separated tool names only, no descriptions (~2 tokens/tool)",
3357
+ )
3133
3358
  pre.add_argument("--pretty", action="store_true", help="Pretty-print JSON output")
3134
3359
  pre.add_argument("--raw", action="store_true", help="Print raw response body")
3135
3360
  pre.add_argument(
@@ -3541,6 +3766,7 @@ def _handle_openapi_mode(
3541
3766
  oauth_provider: "httpx.Auth | None" = None,
3542
3767
  ) -> None:
3543
3768
  """Execute OpenAPI mode: load spec, build parser, execute."""
3769
+ src_hash = _source_hash_for(pre_args.spec)
3544
3770
  spec = load_openapi_spec(
3545
3771
  pre_args.spec,
3546
3772
  auth_headers,
@@ -3555,14 +3781,20 @@ def _handle_openapi_mode(
3555
3781
  commands, bake_config.include, bake_config.exclude, bake_config.methods,
3556
3782
  )
3557
3783
 
3784
+ list_kwargs = dict(
3785
+ verbose=pre_args.verbose, compact=pre_args.compact,
3786
+ source_hash=src_hash, sort_mode=pre_args.sort_mode, top=pre_args.top,
3787
+ )
3788
+
3558
3789
  if pre_args.list_commands:
3559
3790
  if search_pattern:
3560
3791
  commands = _filter_commands(commands, search_pattern)
3561
3792
  if not commands:
3562
3793
  print(f"\nNo tools matching '{search_pattern}'.")
3563
3794
  return
3564
- print(f"\nTools matching '{search_pattern}':")
3565
- list_openapi_commands(commands, verbose=pre_args.verbose)
3795
+ if not pre_args.compact:
3796
+ print(f"\nTools matching '{search_pattern}':")
3797
+ list_openapi_commands(commands, **list_kwargs)
3566
3798
  return
3567
3799
 
3568
3800
  if not remaining:
@@ -3608,6 +3840,9 @@ def _handle_openapi_mode(
3608
3840
  jq_expr=pre_args.jq, head=pre_args.head,
3609
3841
  )
3610
3842
 
3843
+ # Record usage after successful execution
3844
+ record_usage(src_hash, cmd.tool_name or cmd.graphql_field_name or cmd.name)
3845
+
3611
3846
 
3612
3847
  def _main_impl(argv: list[str], bake_config: BakeConfig | None = None):
3613
3848
  pre = _build_main_parser()
@@ -3665,6 +3900,9 @@ def _main_impl(argv: list[str], bake_config: BakeConfig | None = None):
3665
3900
  jq_expr=pre_args.jq,
3666
3901
  head=pre_args.head,
3667
3902
  verbose=pre_args.verbose,
3903
+ sort_mode=pre_args.sort_mode,
3904
+ top=pre_args.top,
3905
+ compact=pre_args.compact,
3668
3906
  )
3669
3907
  return
3670
3908
 
@@ -3697,6 +3935,9 @@ def _main_impl(argv: list[str], bake_config: BakeConfig | None = None):
3697
3935
  jq_expr=pre_args.jq,
3698
3936
  head=pre_args.head,
3699
3937
  verbose=pre_args.verbose,
3938
+ sort_mode=pre_args.sort_mode,
3939
+ top=pre_args.top,
3940
+ compact=pre_args.compact,
3700
3941
  )
3701
3942
  return
3702
3943
 
File without changes
File without changes