claude-sniff перехватывает запросы Claude Code к Bedrock

Утилиту claude-sniff показали на Show HN 4 сентября. Она слушает на 127.0.0.1 и перехватывает вызовы, которые Claude Code отправляет в Amazon Bedrock. Каждый такой invoke можно задержать, поправить его JSON и отправить в Bedrock с новой подписью SigV4 или сбросить. Ответ модели утилита при этом не трогает.
Главная оговорка README в репозитории на GitHub звучит так: «Это не ANTHROPIC_BASE_URL=localhost». Claude Code в режиме Bedrock подменённый базовый адрес не поддерживает, поэтому привычный приём с локальным эндпоинтом здесь не работает. claude-sniff устроен как обычный прямой прокси на mitmproxy. Claude Code отправляет на него трафик через HTTP_PROXY и HTTPS_PROXY, а HTTPS расшифровывается за счёт того, что процесс доверяет корневому сертификату mitmproxy. Отдельной обёртки для запуска нет: один слушатель и один веб-интерфейс.
Почему отредактированный запрос нужно переподписать
В режиме Bedrock Claude Code берёт учётные данные из стандартной цепочки AWS SDK, говорится в документации Claude Code, и подписывает ими каждый запрос по SigV4. Подпись считается в том числе по телу запроса, так что после любой правки JSON исходная подпись перестаёт сходиться. Поэтому claude-sniff обрабатывает два случая по-разному. Нетронутый JSON уходит дальше как оригинал, без повторной подписи. Отредактированный подписывается заново, причём учётными данными того процесса, в котором запущен main.py (--aws-profile, AWS_PROFILE или SSO). Отсюда требование README: у этого процесса должно быть право InvokeModel на те же модели, с которыми работает Claude Code.
Задерживаются только вызовы Bedrock Runtime invoke и invoke-with-response-stream с заголовком x-claude-code-session-id. Очередь одна на все сессии и работает по принципу FIFO, а редактировать можно только запрос в её начале. Drop отдаёт клиенту ошибку, пишет в журнал строку с ошибкой, и запрос в Bedrock не уходит. Если выключить Intercept или Proxy, вся накопившаяся очередь уходит в Bedrock как была.
Как запустить
Нужны Python 3.12+ и uv, Claude Code с CLAUDE_CODE_USE_BEDROCK=1, который реально ходит в Bedrock Runtime, и учётные данные AWS в процессе, где запускается main.py. Регион и профиль должны совпадать с рабочей сессией claude. Сам запуск такой: uv sync, затем uv run python main.py --aws-profile your-profile (флаг необязателен, без него используется та же цепочка, что и с AWS_PROFILE). Прокси слушает на http://127.0.0.1:9090, интерфейс открывается на http://127.0.0.1:8765. При первом запуске корневой сертификат записывается в ~/.mitmproxy/mitmproxy-ca-cert.pem.
Дальше три шага.
- В каждом новом процессе Claude Code выставить
HTTP_PROXYиHTTPS_PROXYнаhttp://127.0.0.1:9090. Экспорты из другой оболочки claude не наследует. Пока Proxy выключен, HTTPS идёт туннелем с настоящим сертификатом Bedrock, без подмены. - Включить Proxy в интерфейсе, затем в той же оболочке выставить
NODE_EXTRA_CA_CERTS,SSL_CERT_FILE,REQUESTS_CA_BUNDLEиAWS_CA_BUNDLEна путь к сертификату (готовые строки есть на вкладке Info) и перезапустить claude. После первого сообщения сессия появится на вкладке Sessions, а записи попадут вlogs/<client>/<session-id>.jsonl. - Включить Intercept в шапке. Пока Proxy выключен, этот переключатель неактивен.
Оба режима при старте выключены и между запусками не сохраняются. Автор советует доверять сертификату только на то время, пока включён Proxy. Порты, каталог логов и путь к журналам Claude Code меняются флагами --port, --ui-port, --logs-dir и --claude-projects-dir, интерфейс отключается через --no-ui. Команда uv run python main.py ui поднимает один интерфейс, без перехвата.
Что ложится на диск
Из JSONL вырезаются заголовки Authorization и x-amz-security-token. Второй из них появляется при временных учётных данных, ключах с префиксом ASIA, которым нужен сессионный токен, объясняет руководство на AWS Builder. Тела запросов, включая промпты и системный промпт, сохраняются как есть. Каталог logs/ занесён в .gitignore, но маскировки содержимого нет, и README прямо её не обещает.
Вкладка Usage считает расходы и без прокси: она читает журналы Claude Code в ~/.claude/projects, те же, что разбирает аудитор CostClaw. Если один UUID встречается и в logs/, и в журнале, запись показывается один раз и в ней берётся сумма, посчитанная через перехват. Записи, которые прошли мимо прокси, содержат только стоимость, без переписки. Цены при этом заложены только для одного региона: on-demand в eu-central-1. Семейство модели определяется по ключевым словам в её имени. Для application inference profile, чьи идентификаторы привязаны к аккаунту и имени модели не содержат, нужна ручная разметка через CLAUDE_PROXY_INFERENCE_PROFILES='{"yourId":"sonnet-4.6"}' или файл inference-profiles.json (в репозитории таких идентификаторов нет). Неизвестная модель или профиль считаются как $0. Цены подставляются при чтении, поле costUSD в логи не дописывается.
В списке того, чего claude-sniff не делает, автор называет: работу обратным прокси на ANTHROPIC_BASE_URL, маскировку тел запросов, перехват и правку ответов Bedrock, сохранение переключателей. Последний пункт: в комплекте нет готовых подмен запросов и «примеров джейлбрейков».
Если ничего не появляется, README советует сначала перезапустить claude после экспорта HTTP(S)_PROXY и, при включённом Proxy, переменных с сертификатом. Ошибки TLS означают, что этих экспортов нет или работает старый процесс без них. Если Intercept ничего не задерживает, значит, вызов шёл не в Bedrock Runtime или у него нет заголовка x-claude-code-session-id.
Дальше
Gage ищет баги в транскриптах сессий Claude Code
Ревью переехало с диффа на транскрипт сессии: открытый Gage на Rust сканирует записи Claude Code и заводит issue со ссылками на строки. На повременной оплате скан одной сессии обходится примерно в 0,50–1,00 доллара.
Читайте также
- Toolog ведёт локальный журнал вызовов Claude Code
- lcc сжимает сессии Claude Code, не пересказывая их
- С плагином catnap Claude Code сжимает контекст после задачи
- Скрипт проверит, не ломает ли сеть загрузки в Claude API
- context-tax считает, во что обходится контекст Claude Code
- /design-sync отучает Claude Design выдумывать кнопки
Комментарии
Пока никто не написал. Будьте первым.
Присоединяйтесь к разговору
Войдите, чтобы оставить комментарий. Он появится после модерации.

