mcp2cli 2.4.3__tar.gz → 2.6.0__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.
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/PKG-INFO +1 -1
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/pyproject.toml +1 -1
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/src/mcp2cli/__init__.py +168 -28
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/README.md +0 -0
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/src/mcp2cli/__main__.py +0 -0
- {mcp2cli-2.4.3 → mcp2cli-2.6.0}/src/mcp2cli/py.typed +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
__version__ = "2.
|
|
5
|
+
__version__ = "2.6.0"
|
|
6
6
|
|
|
7
7
|
import argparse
|
|
8
8
|
import copy
|
|
@@ -352,9 +352,25 @@ def _handle_http_error(resp) -> None:
|
|
|
352
352
|
# ---------------------------------------------------------------------------
|
|
353
353
|
|
|
354
354
|
|
|
355
|
-
def cache_key_for(
|
|
356
|
-
|
|
355
|
+
def cache_key_for(config: dict) -> str:
|
|
356
|
+
"""
|
|
357
|
+
Generate cache key from tool configuration dict.
|
|
357
358
|
|
|
359
|
+
Hashes all config fields that affect MCP server behavior to ensure
|
|
360
|
+
unique caching for tools with the same URL but different configurations.
|
|
361
|
+
"""
|
|
362
|
+
# Exclude fields that don't affect which tools are returned
|
|
363
|
+
cache_config = {
|
|
364
|
+
k: v for k, v in config.items()
|
|
365
|
+
if k not in ('cache_ttl', 'description', 'include', 'exclude', 'methods')
|
|
366
|
+
}
|
|
367
|
+
# Ensure auth_headers are sorted for stable hashing
|
|
368
|
+
if 'auth_headers' in cache_config and cache_config['auth_headers']:
|
|
369
|
+
cache_config['auth_headers'] = sorted(cache_config['auth_headers'])
|
|
370
|
+
|
|
371
|
+
return hashlib.sha256(
|
|
372
|
+
json.dumps(cache_config, sort_keys=True).encode()
|
|
373
|
+
).hexdigest()[:16]
|
|
358
374
|
|
|
359
375
|
def load_cached(key: str, ttl: int) -> dict | None:
|
|
360
376
|
path = CACHE_DIR / f"{key}.json"
|
|
@@ -467,21 +483,34 @@ def build_oauth_provider(
|
|
|
467
483
|
client_secret: str | None = None,
|
|
468
484
|
scope: str | None = None,
|
|
469
485
|
redirect_uri: str | None = None,
|
|
486
|
+
flow: str = "auto",
|
|
470
487
|
) -> "httpx.Auth":
|
|
471
488
|
"""Build an OAuth provider for HTTP connections.
|
|
472
489
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
490
|
+
The ``flow`` parameter controls which grant type is used:
|
|
491
|
+
|
|
492
|
+
- ``"auto"`` (default): client_id + client_secret → client credentials;
|
|
493
|
+
client_id only → authorization code + PKCE (public client);
|
|
494
|
+
neither → authorization code + PKCE with dynamic client registration.
|
|
495
|
+
- ``"authorization_code"``: always use authorization code + PKCE.
|
|
496
|
+
When a client_secret is also provided the token-endpoint request
|
|
497
|
+
authenticates as a confidential client (``client_secret_post``).
|
|
498
|
+
This is required by servers like Slack that issue confidential OAuth
|
|
499
|
+
clients but only support the authorization-code grant.
|
|
500
|
+
- ``"client_credentials"``: always use client credentials (requires both
|
|
501
|
+
client_id and client_secret).
|
|
478
502
|
|
|
479
503
|
redirect_uri controls the full callback URL (scheme, host, port, path).
|
|
480
504
|
When None, defaults to http://127.0.0.1:<random-free-port>/callback.
|
|
481
505
|
"""
|
|
482
506
|
storage = FileTokenStorage(server_url)
|
|
483
507
|
|
|
484
|
-
|
|
508
|
+
use_client_credentials = (
|
|
509
|
+
flow == "client_credentials"
|
|
510
|
+
or (flow == "auto" and client_id and client_secret)
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
if use_client_credentials:
|
|
485
514
|
from mcp.client.auth.extensions.client_credentials import (
|
|
486
515
|
ClientCredentialsOAuthProvider,
|
|
487
516
|
)
|
|
@@ -540,10 +569,18 @@ def build_oauth_provider(
|
|
|
540
569
|
# Pre-seed storage with the caller-supplied client_id so the OAuth
|
|
541
570
|
# provider skips dynamic client registration entirely. The write is
|
|
542
571
|
# synchronous (plain file I/O) so no async context is needed here.
|
|
572
|
+
#
|
|
573
|
+
# When a client_secret is provided (confidential client, e.g. Slack),
|
|
574
|
+
# include it and use client_secret_post so the token-endpoint request
|
|
575
|
+
# sends the secret in the POST body.
|
|
576
|
+
if client_secret:
|
|
577
|
+
auth_method = "client_secret_post"
|
|
578
|
+
else:
|
|
579
|
+
auth_method = "none"
|
|
543
580
|
pre_client_info = OAuthClientInformationFull(
|
|
544
581
|
client_id=client_id,
|
|
545
|
-
client_secret=
|
|
546
|
-
token_endpoint_auth_method=
|
|
582
|
+
client_secret=client_secret,
|
|
583
|
+
token_endpoint_auth_method=auth_method,
|
|
547
584
|
redirect_uris=[redirect_uri],
|
|
548
585
|
grant_types=["authorization_code", "refresh_token"],
|
|
549
586
|
response_types=["code"],
|
|
@@ -642,7 +679,10 @@ def load_openapi_spec(
|
|
|
642
679
|
is_url = source.startswith("http://") or source.startswith("https://")
|
|
643
680
|
|
|
644
681
|
if is_url:
|
|
645
|
-
key = cache_key or cache_key_for(
|
|
682
|
+
key = cache_key or cache_key_for({
|
|
683
|
+
'source': source,
|
|
684
|
+
'auth_headers': auth_headers,
|
|
685
|
+
})
|
|
646
686
|
if not refresh:
|
|
647
687
|
cached = load_cached(key, ttl)
|
|
648
688
|
if cached is not None:
|
|
@@ -1024,7 +1064,10 @@ def load_graphql_schema(
|
|
|
1024
1064
|
oauth_provider: "httpx.Auth | None" = None,
|
|
1025
1065
|
) -> dict:
|
|
1026
1066
|
"""POST introspection query to a GraphQL endpoint, with caching."""
|
|
1027
|
-
key = cache_key or cache_key_for(
|
|
1067
|
+
key = cache_key or cache_key_for({
|
|
1068
|
+
'source': f"graphql:{url}",
|
|
1069
|
+
'auth_headers': auth_headers,
|
|
1070
|
+
})
|
|
1028
1071
|
if not refresh:
|
|
1029
1072
|
cached = load_cached(key, ttl)
|
|
1030
1073
|
if cached is not None:
|
|
@@ -1161,8 +1204,28 @@ def extract_graphql_commands(schema: dict) -> list[CommandDef]:
|
|
|
1161
1204
|
return commands
|
|
1162
1205
|
|
|
1163
1206
|
|
|
1164
|
-
def
|
|
1207
|
+
def _truncate_description(description: str, max_len: int) -> str:
|
|
1208
|
+
"""Truncate at a word boundary and append '...'."""
|
|
1209
|
+
if len(description) <= max_len:
|
|
1210
|
+
return description
|
|
1211
|
+
return description[:max_len].rsplit(" ", 1)[0].rstrip() + "..."
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
def _wrap_description(description: str, indent: int, total_width: int = 110) -> str:
|
|
1215
|
+
"""Wrap long descriptions; indent continuation lines to align with description column."""
|
|
1216
|
+
import textwrap
|
|
1217
|
+
return textwrap.fill(
|
|
1218
|
+
description,
|
|
1219
|
+
width=total_width,
|
|
1220
|
+
subsequent_indent=" " * indent,
|
|
1221
|
+
break_long_words=False,
|
|
1222
|
+
break_on_hyphens=False,
|
|
1223
|
+
)
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
def list_graphql_commands(commands: list[CommandDef], verbose: bool = False):
|
|
1165
1227
|
"""Group commands by operation type and print."""
|
|
1228
|
+
|
|
1166
1229
|
groups: dict[str, list[CommandDef]] = {}
|
|
1167
1230
|
for cmd in commands:
|
|
1168
1231
|
key = cmd.graphql_operation_type or "other"
|
|
@@ -1175,7 +1238,14 @@ def list_graphql_commands(commands: list[CommandDef]):
|
|
|
1175
1238
|
label = "queries" if group == "query" else "mutations"
|
|
1176
1239
|
print(f"\n{label}:")
|
|
1177
1240
|
for cmd in cmds:
|
|
1178
|
-
|
|
1241
|
+
if cmd.description:
|
|
1242
|
+
if verbose:
|
|
1243
|
+
wrapped = _wrap_description(cmd.description, indent=42, total_width=100)
|
|
1244
|
+
desc = f" {wrapped}"
|
|
1245
|
+
else:
|
|
1246
|
+
desc = f" {_truncate_description(cmd.description, 60)}"
|
|
1247
|
+
else:
|
|
1248
|
+
desc = ""
|
|
1179
1249
|
print(f" {cmd.name:<40}{desc}")
|
|
1180
1250
|
|
|
1181
1251
|
|
|
@@ -1291,18 +1361,19 @@ def handle_graphql(
|
|
|
1291
1361
|
oauth_provider: "httpx.Auth | None" = None,
|
|
1292
1362
|
jq_expr: str | None = None,
|
|
1293
1363
|
head: int | None = None,
|
|
1364
|
+
verbose: bool = False,
|
|
1294
1365
|
):
|
|
1295
1366
|
"""Top-level handler for --graphql mode."""
|
|
1296
1367
|
schema = load_graphql_schema(url, auth_headers, cache_key, ttl, refresh, oauth_provider=oauth_provider)
|
|
1297
1368
|
commands = extract_graphql_commands(schema)
|
|
1298
1369
|
|
|
1299
1370
|
if list_mode:
|
|
1300
|
-
list_graphql_commands(commands)
|
|
1371
|
+
list_graphql_commands(commands, verbose=verbose)
|
|
1301
1372
|
return
|
|
1302
1373
|
|
|
1303
1374
|
if not remaining:
|
|
1304
1375
|
print("Available operations:")
|
|
1305
|
-
list_graphql_commands(commands)
|
|
1376
|
+
list_graphql_commands(commands, verbose=verbose)
|
|
1306
1377
|
print("\nUse --list for the same output, or provide a subcommand.")
|
|
1307
1378
|
return
|
|
1308
1379
|
|
|
@@ -1414,6 +1485,8 @@ def _baked_to_argv(config: dict) -> list[str]:
|
|
|
1414
1485
|
argv += ["--oauth-scope", config["oauth_scope"]]
|
|
1415
1486
|
if config.get("oauth_redirect_uri"):
|
|
1416
1487
|
argv += ["--oauth-redirect-uri", config["oauth_redirect_uri"]]
|
|
1488
|
+
if config.get("oauth_flow") and config["oauth_flow"] != "auto":
|
|
1489
|
+
argv += ["--oauth-flow", config["oauth_flow"]]
|
|
1417
1490
|
return argv
|
|
1418
1491
|
|
|
1419
1492
|
|
|
@@ -1462,6 +1535,17 @@ def _bake_create(argv: list[str]) -> None:
|
|
|
1462
1535
|
p.add_argument("--oauth-client-secret", default=None)
|
|
1463
1536
|
p.add_argument("--oauth-scope", default=None)
|
|
1464
1537
|
p.add_argument("--oauth-redirect-uri", default=None, metavar="URI")
|
|
1538
|
+
p.add_argument(
|
|
1539
|
+
"--oauth-flow",
|
|
1540
|
+
choices=["auto", "authorization_code", "client_credentials"],
|
|
1541
|
+
default="auto",
|
|
1542
|
+
help=(
|
|
1543
|
+
"OAuth flow to use. 'auto' (default) picks client_credentials when both "
|
|
1544
|
+
"client-id and client-secret are provided, otherwise authorization_code. "
|
|
1545
|
+
"Use 'authorization_code' to force the auth code + PKCE flow even with a "
|
|
1546
|
+
"client secret (required for confidential-client servers like Slack)."
|
|
1547
|
+
),
|
|
1548
|
+
)
|
|
1465
1549
|
p.add_argument("--include", default="", help="Comma-separated include globs")
|
|
1466
1550
|
p.add_argument("--exclude", default="", help="Comma-separated exclude globs")
|
|
1467
1551
|
p.add_argument("--methods", default="", help="Comma-separated HTTP methods")
|
|
@@ -1516,6 +1600,7 @@ def _bake_create(argv: list[str]) -> None:
|
|
|
1516
1600
|
"oauth_client_secret": args.oauth_client_secret,
|
|
1517
1601
|
"oauth_scope": args.oauth_scope,
|
|
1518
1602
|
"oauth_redirect_uri": args.oauth_redirect_uri,
|
|
1603
|
+
"oauth_flow": args.oauth_flow,
|
|
1519
1604
|
"include": [x.strip() for x in args.include.split(",") if x.strip()],
|
|
1520
1605
|
"exclude": [x.strip() for x in args.exclude.split(",") if x.strip()],
|
|
1521
1606
|
"methods": [x.strip().upper() for x in args.methods.split(",") if x.strip()],
|
|
@@ -1721,7 +1806,7 @@ def build_argparse(
|
|
|
1721
1806
|
# ---------------------------------------------------------------------------
|
|
1722
1807
|
|
|
1723
1808
|
|
|
1724
|
-
def list_openapi_commands(commands: list[CommandDef]):
|
|
1809
|
+
def list_openapi_commands(commands: list[CommandDef], verbose: bool = False):
|
|
1725
1810
|
groups: dict[str, list[CommandDef]] = {}
|
|
1726
1811
|
for cmd in commands:
|
|
1727
1812
|
prefix = cmd.name.split("-", 1)[0] if "-" in cmd.name else "other"
|
|
@@ -1733,13 +1818,24 @@ def list_openapi_commands(commands: list[CommandDef]):
|
|
|
1733
1818
|
method = (cmd.method or "").upper()
|
|
1734
1819
|
line = f" {cmd.name:<45} {method:<6}"
|
|
1735
1820
|
if cmd.description:
|
|
1736
|
-
|
|
1821
|
+
if verbose:
|
|
1822
|
+
wrapped = _wrap_description(cmd.description, indent=54, total_width=110)
|
|
1823
|
+
line += f" {wrapped}"
|
|
1824
|
+
else:
|
|
1825
|
+
line += f" {_truncate_description(cmd.description, 60)}"
|
|
1737
1826
|
print(line)
|
|
1738
1827
|
|
|
1739
1828
|
|
|
1740
|
-
def list_mcp_commands(commands: list[CommandDef]):
|
|
1829
|
+
def list_mcp_commands(commands: list[CommandDef], verbose: bool = False):
|
|
1741
1830
|
for cmd in commands:
|
|
1742
|
-
|
|
1831
|
+
if cmd.description:
|
|
1832
|
+
if verbose:
|
|
1833
|
+
wrapped = _wrap_description(cmd.description, indent=42, total_width=110)
|
|
1834
|
+
desc = f" {wrapped}"
|
|
1835
|
+
else:
|
|
1836
|
+
desc = f" {_truncate_description(cmd.description, 70)}"
|
|
1837
|
+
else:
|
|
1838
|
+
desc = ""
|
|
1743
1839
|
print(f" {cmd.name:<40}{desc}")
|
|
1744
1840
|
|
|
1745
1841
|
|
|
@@ -1919,6 +2015,7 @@ def run_mcp_http(
|
|
|
1919
2015
|
search_pattern: str | None = None,
|
|
1920
2016
|
jq_expr: str | None = None,
|
|
1921
2017
|
head: int | None = None,
|
|
2018
|
+
verbose: bool = False,
|
|
1922
2019
|
):
|
|
1923
2020
|
extra = dict(
|
|
1924
2021
|
resource_action=resource_action,
|
|
@@ -1929,6 +2026,7 @@ def run_mcp_http(
|
|
|
1929
2026
|
search_pattern=search_pattern,
|
|
1930
2027
|
jq_expr=jq_expr,
|
|
1931
2028
|
head=head,
|
|
2029
|
+
verbose=verbose,
|
|
1932
2030
|
)
|
|
1933
2031
|
|
|
1934
2032
|
async def _run():
|
|
@@ -2014,6 +2112,7 @@ def run_mcp_stdio(
|
|
|
2014
2112
|
search_pattern: str | None = None,
|
|
2015
2113
|
jq_expr: str | None = None,
|
|
2016
2114
|
head: int | None = None,
|
|
2115
|
+
verbose: bool = False,
|
|
2017
2116
|
):
|
|
2018
2117
|
extra = dict(
|
|
2019
2118
|
resource_action=resource_action,
|
|
@@ -2024,6 +2123,7 @@ def run_mcp_stdio(
|
|
|
2024
2123
|
search_pattern=search_pattern,
|
|
2025
2124
|
jq_expr=jq_expr,
|
|
2026
2125
|
head=head,
|
|
2126
|
+
verbose=verbose,
|
|
2027
2127
|
)
|
|
2028
2128
|
|
|
2029
2129
|
import anyio
|
|
@@ -2075,6 +2175,7 @@ async def _mcp_session(
|
|
|
2075
2175
|
search_pattern: str | None = None,
|
|
2076
2176
|
jq_expr: str | None = None,
|
|
2077
2177
|
head: int | None = None,
|
|
2178
|
+
verbose: bool = False,
|
|
2078
2179
|
):
|
|
2079
2180
|
# Handle resource operations
|
|
2080
2181
|
if resource_action:
|
|
@@ -2111,7 +2212,7 @@ async def _mcp_session(
|
|
|
2111
2212
|
print(f"\nTools matching '{search_pattern}':")
|
|
2112
2213
|
else:
|
|
2113
2214
|
print("\nAvailable tools:")
|
|
2114
|
-
list_mcp_commands(commands)
|
|
2215
|
+
list_mcp_commands(commands, verbose=verbose)
|
|
2115
2216
|
return
|
|
2116
2217
|
|
|
2117
2218
|
if tool_name is None:
|
|
@@ -2729,8 +2830,18 @@ def handle_mcp(
|
|
|
2729
2830
|
bake_config: BakeConfig | None = None,
|
|
2730
2831
|
jq_expr: str | None = None,
|
|
2731
2832
|
head: int | None = None,
|
|
2833
|
+
verbose: bool = False,
|
|
2732
2834
|
):
|
|
2733
|
-
|
|
2835
|
+
# Build a config dict for cache key generation (future-proof)
|
|
2836
|
+
config_for_cache = {
|
|
2837
|
+
'source': source,
|
|
2838
|
+
'auth_headers': auth_headers,
|
|
2839
|
+
'transport': transport,
|
|
2840
|
+
'env_vars': env_vars,
|
|
2841
|
+
'is_stdio': is_stdio,
|
|
2842
|
+
}
|
|
2843
|
+
|
|
2844
|
+
key = cache_key_override or cache_key_for(config_for_cache)
|
|
2734
2845
|
|
|
2735
2846
|
# Resource/prompt operations skip the tool flow entirely
|
|
2736
2847
|
if resource_action or prompt_action:
|
|
@@ -2763,7 +2874,7 @@ def handle_mcp(
|
|
|
2763
2874
|
commands, bake_config.include, bake_config.exclude, bake_config.methods,
|
|
2764
2875
|
)
|
|
2765
2876
|
print("\nAvailable tools:")
|
|
2766
|
-
list_mcp_commands(commands)
|
|
2877
|
+
list_mcp_commands(commands, verbose=verbose)
|
|
2767
2878
|
return
|
|
2768
2879
|
_dispatch_mcp_call(
|
|
2769
2880
|
source, is_stdio, auth_headers, env_vars,
|
|
@@ -2771,6 +2882,7 @@ def handle_mcp(
|
|
|
2771
2882
|
toon=toon, transport=transport, oauth_provider=oauth_provider,
|
|
2772
2883
|
search_pattern=search_pattern,
|
|
2773
2884
|
jq_expr=jq_expr, head=head,
|
|
2885
|
+
verbose=verbose,
|
|
2774
2886
|
)
|
|
2775
2887
|
return
|
|
2776
2888
|
|
|
@@ -2788,7 +2900,7 @@ def handle_mcp(
|
|
|
2788
2900
|
|
|
2789
2901
|
if not remaining:
|
|
2790
2902
|
print("Available tools:")
|
|
2791
|
-
list_mcp_commands(commands)
|
|
2903
|
+
list_mcp_commands(commands, verbose=verbose)
|
|
2792
2904
|
print("\nUse --list for the same output, or provide a subcommand.")
|
|
2793
2905
|
return
|
|
2794
2906
|
|
|
@@ -2986,6 +3098,12 @@ def _build_main_parser() -> argparse.ArgumentParser:
|
|
|
2986
3098
|
metavar="PATTERN",
|
|
2987
3099
|
help="Search tools by name or description (case-insensitive substring match)",
|
|
2988
3100
|
)
|
|
3101
|
+
pre.add_argument(
|
|
3102
|
+
"--verbose",
|
|
3103
|
+
action="store_true",
|
|
3104
|
+
dest="verbose",
|
|
3105
|
+
help="Show full tool descriptions in --list output, wrapped to terminal width (default: truncated with ...)",
|
|
3106
|
+
)
|
|
2989
3107
|
pre.add_argument("--pretty", action="store_true", help="Pretty-print JSON output")
|
|
2990
3108
|
pre.add_argument("--raw", action="store_true", help="Print raw response body")
|
|
2991
3109
|
pre.add_argument(
|
|
@@ -3055,6 +3173,17 @@ def _build_main_parser() -> argparse.ArgumentParser:
|
|
|
3055
3173
|
help="Full redirect URI for the OAuth callback (e.g. http://localhost:3334/oauth/callback). "
|
|
3056
3174
|
"Overrides the default http://127.0.0.1:<random-port>/callback.",
|
|
3057
3175
|
)
|
|
3176
|
+
pre.add_argument(
|
|
3177
|
+
"--oauth-flow",
|
|
3178
|
+
choices=["auto", "authorization_code", "client_credentials"],
|
|
3179
|
+
default="auto",
|
|
3180
|
+
help=(
|
|
3181
|
+
"OAuth flow to use. 'auto' (default) picks client_credentials when both "
|
|
3182
|
+
"client-id and client-secret are provided, otherwise authorization_code. "
|
|
3183
|
+
"Use 'authorization_code' to force the auth code + PKCE flow even with a "
|
|
3184
|
+
"client secret (required for confidential-client servers like Slack)."
|
|
3185
|
+
),
|
|
3186
|
+
)
|
|
3058
3187
|
# Resource flags
|
|
3059
3188
|
pre.add_argument(
|
|
3060
3189
|
"--list-resources", action="store_true", help="List available resources"
|
|
@@ -3168,12 +3297,21 @@ def _setup_oauth(pre_args):
|
|
|
3168
3297
|
if pre_args.oauth_client_secret
|
|
3169
3298
|
else None
|
|
3170
3299
|
)
|
|
3300
|
+
flow = getattr(pre_args, "oauth_flow", "auto")
|
|
3301
|
+
if flow == "client_credentials" and not (client_id and client_secret):
|
|
3302
|
+
print(
|
|
3303
|
+
"Error: --oauth-flow=client_credentials requires both "
|
|
3304
|
+
"--oauth-client-id and --oauth-client-secret",
|
|
3305
|
+
file=sys.stderr,
|
|
3306
|
+
)
|
|
3307
|
+
sys.exit(1)
|
|
3171
3308
|
return build_oauth_provider(
|
|
3172
3309
|
server_url,
|
|
3173
3310
|
client_id=client_id,
|
|
3174
3311
|
client_secret=client_secret,
|
|
3175
3312
|
scope=pre_args.oauth_scope,
|
|
3176
3313
|
redirect_uri=pre_args.oauth_redirect_uri,
|
|
3314
|
+
flow=flow,
|
|
3177
3315
|
)
|
|
3178
3316
|
|
|
3179
3317
|
|
|
@@ -3286,7 +3424,7 @@ def _handle_session_operations(
|
|
|
3286
3424
|
print(f"\nTools matching '{search_pattern}':")
|
|
3287
3425
|
else:
|
|
3288
3426
|
print("\nAvailable tools:")
|
|
3289
|
-
list_mcp_commands(commands)
|
|
3427
|
+
list_mcp_commands(commands, verbose=pre_args.verbose)
|
|
3290
3428
|
return True
|
|
3291
3429
|
|
|
3292
3430
|
# Tool call via session
|
|
@@ -3294,7 +3432,7 @@ def _handle_session_operations(
|
|
|
3294
3432
|
result = _session_request(sess_name, "list_tools")
|
|
3295
3433
|
commands = extract_mcp_commands(result)
|
|
3296
3434
|
print("Available tools:")
|
|
3297
|
-
list_mcp_commands(commands)
|
|
3435
|
+
list_mcp_commands(commands, verbose=pre_args.verbose)
|
|
3298
3436
|
print("\nUse --list for the same output, or provide a subcommand.")
|
|
3299
3437
|
return True
|
|
3300
3438
|
|
|
@@ -3391,7 +3529,7 @@ def _handle_openapi_mode(
|
|
|
3391
3529
|
print(f"\nNo tools matching '{search_pattern}'.")
|
|
3392
3530
|
return
|
|
3393
3531
|
print(f"\nTools matching '{search_pattern}':")
|
|
3394
|
-
list_openapi_commands(commands)
|
|
3532
|
+
list_openapi_commands(commands, verbose=pre_args.verbose)
|
|
3395
3533
|
return
|
|
3396
3534
|
|
|
3397
3535
|
if not remaining:
|
|
@@ -3493,6 +3631,7 @@ def _main_impl(argv: list[str], bake_config: BakeConfig | None = None):
|
|
|
3493
3631
|
oauth_provider=oauth_provider,
|
|
3494
3632
|
jq_expr=pre_args.jq,
|
|
3495
3633
|
head=pre_args.head,
|
|
3634
|
+
verbose=pre_args.verbose,
|
|
3496
3635
|
)
|
|
3497
3636
|
return
|
|
3498
3637
|
|
|
@@ -3524,6 +3663,7 @@ def _main_impl(argv: list[str], bake_config: BakeConfig | None = None):
|
|
|
3524
3663
|
bake_config=bake_config,
|
|
3525
3664
|
jq_expr=pre_args.jq,
|
|
3526
3665
|
head=pre_args.head,
|
|
3666
|
+
verbose=pre_args.verbose,
|
|
3527
3667
|
)
|
|
3528
3668
|
return
|
|
3529
3669
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|