Skip to content

Commit f663e90

Browse files
committed
feat(mcp-proxy): surface role presets in diagnostics
Add a concise human-only role presets hint to init and doctor output so users can discover static role guidance without adding runtime role demos. Implemented with assistance from Codex.
1 parent a4f5638 commit f663e90

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

packages/agentveil-mcp-proxy/agentveil_mcp_proxy/cli.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,7 @@ def doctor_proxy(
13941394
)
13951395
for warning in warnings:
13961396
print(f"WARN: {warning}", file=out)
1397+
_print_role_presets_discoverability_hint(out)
13971398
return 0
13981399
except ProxyCliError as exc:
13991400
if output_json:
@@ -2798,6 +2799,16 @@ def _with_path_args(parts: list[str]) -> str:
27982799
return doctor_cmd, client_cmd
27992800

28002801

2802+
_ROLE_PRESETS_DISCOVERABILITY_HINT = (
2803+
"Role presets: available. Inspect with "
2804+
"`agentveil-mcp-proxy role doctor --preset reviewer`."
2805+
)
2806+
2807+
2808+
def _print_role_presets_discoverability_hint(out: TextIO) -> None:
2809+
print(_ROLE_PRESETS_DISCOVERABILITY_HINT, file=out)
2810+
2811+
28012812
def _add_passphrase_args(parser: argparse.ArgumentParser) -> None:
28022813
parser.add_argument("--passphrase", default=None, help="MCP proxy identity passphrase")
28032814
parser.add_argument("--passphrase-file", type=Path, default=None, help="Read passphrase from file")
@@ -6508,6 +6519,7 @@ def main(argv: list[str] | None = None) -> int:
65086519
)
65096520
print(f"Next: {doctor_cmd}")
65106521
print(f" {client_cmd}")
6522+
_print_role_presets_discoverability_hint(sys.stdout)
65116523
return 0
65126524
if args.command == "doctor":
65136525
return doctor_proxy(

packages/agentveil-mcp-proxy/tests/test_mcp_proxy_cli.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3165,3 +3165,50 @@ def test_root_help_lists_role_doctor(capsys):
31653165
text = capsys.readouterr().out
31663166
advanced = text.split("Advanced:", 1)[1].split("Typical first-run path:", 1)[0]
31673167
assert "role" in advanced
3168+
3169+
3170+
def test_doctor_human_output_includes_role_presets_hint(tmp_path):
3171+
home = tmp_path / "avp-home"
3172+
init_proxy(home=home, agent_name="proxy", passphrase=TEST_PASSPHRASE)
3173+
out = io.StringIO()
3174+
assert doctor_proxy(home=home, passphrase=TEST_PASSPHRASE, out=out) == 0
3175+
text = out.getvalue()
3176+
assert proxy_cli._ROLE_PRESETS_DISCOVERABILITY_HINT in text
3177+
assert "inferred" not in text.lower()
3178+
assert "adaptive" not in text.lower()
3179+
3180+
3181+
def test_doctor_json_output_omits_role_presets_hint(tmp_path):
3182+
home = tmp_path / "avp-home"
3183+
init_proxy(home=home, agent_name="proxy", passphrase=TEST_PASSPHRASE)
3184+
out = io.StringIO()
3185+
assert doctor_proxy(
3186+
home=home,
3187+
passphrase=TEST_PASSPHRASE,
3188+
output_json=True,
3189+
out=out,
3190+
) == 0
3191+
payload = json.loads(out.getvalue())
3192+
serialized = json.dumps(payload)
3193+
assert proxy_cli._ROLE_PRESETS_DISCOVERABILITY_HINT not in serialized
3194+
assert "role doctor" not in serialized
3195+
3196+
3197+
def test_init_human_output_includes_role_presets_hint(tmp_path, capsys):
3198+
home = tmp_path / "avp-home"
3199+
assert main(["init", "--home", str(home), "--plaintext", "--force"]) == 0
3200+
text = capsys.readouterr().out
3201+
assert proxy_cli._ROLE_PRESETS_DISCOVERABILITY_HINT in text
3202+
assert "Next:" in text
3203+
3204+
3205+
def test_demo_human_output_omits_role_presets_hint(tmp_path, capsys):
3206+
work_dir = tmp_path / "demo-no-role-hint"
3207+
assert main([
3208+
"demo",
3209+
"--work-dir",
3210+
str(work_dir),
3211+
"--demo-auto-approve",
3212+
]) == 0
3213+
text = capsys.readouterr().out
3214+
assert proxy_cli._ROLE_PRESETS_DISCOVERABILITY_HINT not in text

0 commit comments

Comments
 (0)