#!/usr/bin/env python3 """ Консольная точка входа «mcp-sentinel» (ИБ 3.0). """ import argparse import json import os import sys sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) from sentinel import MCPSentinel, run_stdio_proxy def main(): parser = argparse.ArgumentParser( prog="mcp-sentinel", description="Шлюз допустимости действий и Circuit Breaker для MCP-серверов (ИБ 3.0)", ) parser.add_argument( "--ledger", "-l", default="audit_fstec117.jsonl", help="Путь к криптографическому журналу ГОСТ Стрибог (по умолчанию: audit_fstec117.jsonl)", ) parser.add_argument( "--agent", "-a", default="ai-agent", help="Идентификатор агента для протокола (по умолчанию: ai-agent)", ) subparsers = parser.add_subparsers(dest="command", help="Команды") # check check_parser = subparsers.add_parser("check", help="Тестовая проверка отдельного вызова инструмента") check_parser.add_argument("--tool", "-t", required=True, help="Имя инструмента (например: bash, execute_sql)") check_parser.add_argument("--args", required=True, help="Аргументы вызова в формате JSON (например: '{\"path\": \"/etc/shadow\"}')") # wrap wrap_parser = subparsers.add_parser("wrap", help="Запустить прозрачный прокси-шлюз перед дочерней командой MCP") wrap_parser.add_argument("downstream", nargs=argparse.REMAINDER, help="Команда запуска целевого MCP сервера") args = parser.parse_args() if not args.command: parser.print_help() sys.exit(1) if args.command == "check": sentinel = MCPSentinel(ledger_path=args.ledger) try: parsed_args = json.loads(args.args) except json.JSONDecodeError as e: print(f"[-] Ошибка парсинга JSON: {e}") sys.exit(1) allowed, reason, details = sentinel.validate_tool_call( agent_id=args.agent, tool_name=args.tool, arguments=parsed_args, ) if allowed: print("[+] ВЕРДИКТ: PERMIT (РАЗРЕШЕНО)") print(" Инварианты соблюдены, вызов безопасен.") sys.exit(0) else: print("[-] ВЕРДИКТ: BLOCK (ЗАБЛОКИРОВАНО)") print(f" Причина: {reason}") if details: print(f" Детали: {details}") sys.exit(2) elif args.command == "wrap": downstream = args.downstream if downstream and downstream[0] == "--": downstream = downstream[1:] if not downstream: print("[-] Ошибка: Не указана целевая команда для запуска MCP сервера.") sys.exit(1) run_stdio_proxy( downstream_cmd=downstream, agent_id=args.agent, ledger_path=args.ledger, ) if __name__ == "__main__": main()