v2.15.0 — chat catalog consumer + dangerous-floor escalation (PR5')
Chat catalog consumer + dangerous-floor escalation — PR5'
Final CLI-side PR of the dynamic-tool-catalog migration. Pairs with the web-side PR1' / PR3' / PR4' work shipped to staging earlier today (2026-05-26 UTC). This release flips capabilities.supports_dynamic_catalog: true on the connect handshake — the signal the hosted backend gates the CHAT_CATALOG_EXPANSION_ENABLED flag-flip on.
What's new
57 new chat-routable tool dispatches. services/ai_tool_bridge.py::_LOCAL_TOOL_HANDLERS now routes every non-relay tool in the server-side catalog to its handler in ServonautTools. Once the staging flag flips, the hosted AI chat panel can invoke any of the following without tool_unavailable errors:
- AWS describe (6):
aws_list_regions,aws_list_amis,aws_list_instance_types,aws_list_key_pairs,aws_list_subnets,aws_list_security_groups - AWS lifecycle standard (3):
aws_start_instance,aws_stop_instance,aws_reboot_instance - AWS lifecycle dangerous (2):
aws_run_instances,aws_terminate_instance(MCP-relay surface only — chat surface gates these per the server tier filter + ApprovalService UX deferred to follow-up) - S3 read (2):
s3_list_buckets,s3_list_objects - S3 mutations dangerous (8):
s3_create_bucket,s3_delete_bucket,s3_upload_object,s3_delete_object,s3_copy_object,s3_move_object,s3_generate_presigned_url,s3_download_object - AWS observability + IP ban (7):
cloudwatch_list_log_groups,cloudwatch_get_log_events,cloudwatch_top_ips,cloudtrail_lookup_events,ip_ban_list_configs,ip_ban_list_banned,ip_ban_set - Log fetch (1):
get_logs - Hetzner read + power (8):
hetzner_list_servers,hetzner_list_server_types,hetzner_list_ssh_keys,hetzner_power_on,hetzner_power_off,hetzner_shutdown,hetzner_reboot,hetzner_create_ssh_key - Hetzner lifecycle dangerous (3):
hetzner_create_server,hetzner_delete_server,hetzner_delete_ssh_key - OVH read + lifecycle (11):
ovh_monitoring,ovh_list_ips,ovh_firewall_rules,ovh_ssh_keys,ovh_snapshots,ovh_dns_records,ovh_billing,ovh_invoices,ovh_start_instance,ovh_stop_instance,ovh_reboot_instance - OVH lifecycle dangerous (2):
ovh_create_instance,ovh_delete_instance - Memory (4):
get_server_memory,list_server_memories,build_server_memory,refresh_server_memory
Dangerous-floor escalation is now ACTIVE
The 18-pattern regex floor shipped dormant in v2.14.0 (PR2'). v2.15.0 wires it into the dispatch path:
- Every
tool_callarriving viaai_tool_bridge.handle_tool_callpasses through_FloorDangerousMixin._floor_dangerous(name, server_tier)before guard enforcement. - If the tool name matches one of the destructive-pattern regexes AND the server-asserted tier is below
dangerous, the call is escalated todangeroustier and the mismatch is audit-logged to~/.servonaut/mcp_audit.jsonlwith reasondangerous_floor_escalation. - This is defense-in-depth — a buggy server catalog or wire-shape regression can no longer silently downgrade a destructive operation. The CLI refuses to take the server's word on what counts as dangerous.
This also caught one legitimate pre-existing miss: run_command was historically classified standard for chat-surface dispatch despite being arbitrary shell exec. v2.15.0 escalates it to dangerous automatically. The associated audit-row test was updated to reflect the corrected tier.
Capability bit
capabilities.supports_dynamic_catalog: true on the connect handshake. Hosted backends gate their dynamic-catalog activation on this bit — older CLIs (v2.14.x and earlier) keep receiving the original 9-tool chat surface; v2.15.0+ CLIs receive the expanded catalog.
tool_catalog SSE event handler
services/ai_providers/servonaut_provider.py now handles the tool_catalog SSE event emitted by /api/ai/chat/stream. Audit-only in v2.15.0 — the handler logs receipt to mcp_audit.jsonl with reason tool_catalog_received plus catalog_version, surface, and tool_count. The static _LOCAL_TOOL_HANDLERS map remains source of truth for dispatch; the audit row proves the wire works for a future PR to consume the catalog dynamically without changing v2.15.0 behaviour.
Install / upgrade
pipx install servonaut --force
# or
pipx upgrade servonautFull diff
What's next
The dynamic-tool-catalog migration is feature-complete on both sides. Staging-flip protocol:
- v2.15.0 deployed to PyPI (this release)
- Operator runs
pipx upgrade servonauton the staging-connected CLI - v2.15.0 CLI heartbeat carries
capabilities.supports_dynamic_catalog: true - Operator flips
CHAT_CATALOG_EXPANSION_ENABLED=trueon the staging web env var (no redeploy needed, ~10s container restart) - End-to-end test: ask the hosted AI chat "list my EC2 regions" — the 40 newly-chat-exposed tools dispatch through this CLI's
ai_tool_bridgeto the localmcp/tools.pyhandlers and return real responses
Once staging E2E is verified, production flag-flip happens on the user's schedule.