spendveto
SpendVeto
Уровень контроля расходов для ИИ-агентов, которые платят за что-либо. Платёжные рельсы перемещают деньги агента; SpendVeto решает, следует ли агенту вообще позволять их перемещать — проверки политик, одобрение человеком, делегированные лимиты бюджета и аварийный рубильник для вышедшего из-под контроля агента, применяемые до того, как произойдёт любой платёж.
Начался как «самый маленький реальный тест» из исследовательского брифа web3; вырос через два исследовательских раунда функций (GPT deep-research + живое маркетинговое исследование) в управляемый стек x402 + MCP. Позиционирование финансирования и рыночные цифры — в PITCH.md.
Что это на самом деле
Шлюз управления перед каталогом платных конечных точек, доступный тремя способами — CLI, делегированные дочерние агенты и любой MCP-клиент:
agent (CLI / child wallet / Claude via MCP)
→ frozen? (manual kill switch, or auto-frozen by the runaway-burst detector)
→ policy check (per-call, hourly, rate, cascading delegation caps)
→ [maybe: human approval on the dashboard — fails closed on timeout]
→ pay $X USDC via x402 (simulate or Base Sepolia testnet)
→ GET /api/agent/<tool> → Claude does the task
→ everything lands in the ledger; blocked-spend dollars roll up on the dashboardRelated MCP server: Proofpane
Быстрый старт
npm install
npm run server # terminal 1 — :8402, dashboard at http://localhost:8402
npm run call # terminal 2 — pays for "review" ($0.01), auto-approved
npm run call -- summarize # $0.02 — above the approval line: go approve/deny it on the dashboard
npm run call -- translate # $0.005npm run verify прогоняет всё в headless-режиме — 264 сквозных проверки: каталог, отклонение подделанных подписей, жёсткие блокировки политик, все три исхода одобрения (одобрено / отклонено / тайм-аут с закрытием в безопасное состояние), лимиты делегирования, включая каскад из n уровней, ограничение по инструментам и цепочкам, мультичейн-расчёты (подписи с привязкой к цепочке, балансы по цепочкам, списки разрешённых цепочек), автоматическая заморозка при всплеске вышедшего из-под контроля агента, ручной рубильник, проверка подписанных чеков, экспорт CSV, аналитика по инструментам/кошелькам/цепочкам, вебхук-оповещения, реально доходящие до живого получателя, структурированные самоисправляющиеся отказы, сухие прогоны без побочных эффектов, истечение срока грантов по TTL, ссылки одобрения в один клик, эндпоинт статистики, обнаружение дрейфа цепочки мандатов AP2, власть при отсутствии человека, управляемое обнаружение Bazaar, область общего платёжного токена ACP, привязка целостности запроса (включая полезную нагрузку, подменённую после авторизации), подписанные пакеты доказательств споров и их обнаружение подделки, экспорт спанов OpenTelemetry под входящим traceparent и реальный JSON-RPC-цикл MCP stdio.
По поводу числа: свежий клон выполняет 264 проверки. Ещё три проверяют реальную кросс-проектную интеграцию с Basis и запускаются только когда
../prediction-copilotвыкачан рядом с этим репозиторием — набор печатает(skipped: cross-project Basis integration test …), когда его нет. Каждая опубликованная цифра — это 264, которые может воспроизвести любой.
Маркетинговый сайт: npm run site обслуживает готовую к деплою лендинг-страницу (hero на Three.js, анимированная демонстрация продукта) на http://localhost:8403 — site/ полностью статичен и самодостаточен, можно разместить на Vercel/Netlify как есть. Включает интерактивную песочницу (site/playground.html), которая запускает реальную логику принятия решений по политике на стороне клиента — задайте бюджет, запустите расходы агента, наблюдайте, как он проходит/приостанавливается/блокируется — и страницу вариантов использования, основанную на реальных сценариях расходов агентов 2026 года.
Каталог
Три реальных инструмента на базе Claude по трём ценам (shared-config.js):
Инструмент | Цена | Путь управления |
| $0.005 | автоодобрение |
| $0.01 | автоодобрение |
| $0.02 | пауза для одобрения человеком (> $0.015) |
MCP: управление, от которого модель не может отказаться
mcp/server.js открывает платный каталог для любого MCP-клиента. Агент видит обычные инструменты; каждый вызов молча прогоняется через полный управляемый конвейер (политика → одобрение → платёж x402) до выполнения задачи. Заблокированные вызовы возвращаются как ошибки инструмента с объяснением, какой шлюз их остановил и что ничего не было потрачено.
# Register with Claude Code (server must be running: npm run server)
claude mcp add spendveto -- node ~/Desktop/spendveto/mcp/server.jsИли в конфиге Claude Desktop:
{ "mcpServers": { "spendveto": { "command": "node", "args": ["/Users/you/Desktop/spendveto/mcp/server.js"] } } }Появляются четыре инструмента: review, summarize, translate (каждый с ценой в описании) и spendveto_status (бесплатный — кошелёк, баланс, политика, расходы за последний час, ожидающие одобрения, делегированные бюджеты). Спросите у Claude «какой статус бюджета моего агента?», затем «запусти платный инструмент summarize» — и наблюдайте, как одобрение появляется на дашборде.
Делегирование бюджета («IAM для денег»)
Родительский кошелёк выдаёт кошельку дочернего агента ограниченный пожизненный бюджет — и дети могут делегировать дальше. Лимиты каскадируются: расходы внучатого агента учитываются против его собственного лимита и лимита каждого предка, так что целая команда субагентов никогда не сможет превысить бюджет на вершине своей ветви. Контроль выполняется в собственной проверке политики вызывающего при каждом вызове; дашборд показывает иерархию в виде живых полос «расходы против лимита».
npm run delegate -- 0.015 "team lead" # main wallet grants $0.015
npm run delegate -- 0.05 "intern" --parent "team lead" # team lead grants onward
npm run call -- review --child=intern # fine — fits both caps
npm run call -- review --child=intern # BLOCKED … granted to ancestor "team lead"
npm run delegate -- 0.02 "translator" --tools translate # scope, not just size
npm run call -- review --child=translator # BLOCKED … outside its delegated scope
npm run delegate -- 0.02 "base only" --chains base-sepolia # pin the settlement chain too
npm run call -- review --child="base only" --chain=polygon # BLOCKED … outside its delegated chain scope
npm run delegate -- 0.05 "flash task" --ttl 10m # time-boxed budget: self-expiresОтзыв в любой момент: POST /api/delegations/:id/revoke — отозванная ссылка убивает всю ветвь ниже себя.
Чеки, экспорт, оповещения, аналитика
Каждый расчёт в режиме симуляции возвращается подписанным ECDSA сервером (settlement.signature / signedBy / receiptId), так что чеки можно независимо проверить — и теперь они адресуемы: GET /api/receipts/:id находит чек, POST /api/receipts/verify проверяет подпись любого чека на стороне сервера (подделанная цена не проходит — протестировано). Установите alertSigningSecret в политике, и каждая доставка вебхука будет нести HMAC-заголовок X-SpendVeto-Signature, так что получатели смогут доказать, что оповещение действительно пришло от вашего SpendVeto. Полный реестр экспортируется в CSV на /api/export.csv; сводки по инструментам и кошелькам — на /api/analytics; а если задать alertWebhookUrl в data/policy.json, заморозки, заблокированные вызовы и ожидающие одобрения будут POST-иться туда в реальном времени (укажите входящий вебхук Slack).
Рубильник + обнаружение вышедшего из-под контроля агента
Любой кошелёк можно заморозить с дашборда (или через POST /api/freezes), а кошелёк, отправляющий попытки платежей быстрее порога всплеска из политики (по умолчанию: 10 попыток за 10 секунд), замораживается автоматически — цикл вышедшего из-под контроля агента ловится в середине всплеска, а не по счёту в следующем месяце. Замороженные кошельки блокируются в собственной проверке политики и отклоняются на шлюзе симуляции платежа даже с корректно подписанным платежом (403). Разморозка в один клик, как только вы разобрались, что делал агент.
Прокси принудительного исполнения — агенты без ключей («SpendVeto на денежном пути»)
npm run proxy (:8404) переворачивает модель доверия: агенты вообще не держат ключи. Они POST-ят намерение потратить; прокси хранит ключи, прогоняет полный конвейер (заморозка → политика → каскадные лимиты/области → одобрение) и только затем подписывает и платит. Вредоносный агент не может пропустить проверку политики, потому что ему нечем подписывать.
curl -X POST localhost:8404/proxy/call -H 'Content-Type: application/json' \
-d '{"tool":"review"}' # custody wallet
-d '{"tool":"review","child":"intern"}' # spend as a delegated child, by labelОтклонённые намерения возвращаются 403 с указанием шлюза, причины и структурированным отказом — ничего не подписано, ничего не перемещено. Отправьте Idempotency-Key (в заголовке или теле), и повторное намерение воспроизводит сохранённый ответ вместо двойной оплаты — агент в цикле падений не может потратить дважды (протестировано: один и тот же ключ дважды → одна запись в реестре).
Отказы, на которые агенты могут реагировать, сухие прогоны, бюджеты с ограничением по времени
Три элемента управления, рождённые в исследовательском раунде июля 2026 года (см. launch/DEEP_RESEARCH_PROMPTS.md):
Самоисправляющиеся отказы — каждая блокировка несёт машиночитаемый
code(per_call_cap,chain_scope,hourly_usd_cap,delegation_expired, …) и конкретнуюsuggestion(«повторите на разрешённой цепочке: base-sepolia, base» / «оставшийся бюджет по этой строке — $0.0050 — выберите более дешёвый инструмент»). CLI печатает это строкойFix:, ошибки заблокированных инструментов MCP включают это, чтобы модель могла самоисправиться вместо повторных циклов, а прокси возвращает это в теле 403.Сухие прогоны —
npm run call -- summarize --dry-run(или{"dryRun": true}на прокси) оценивает весь конвейер — заморозку, правила цепочек, лимиты, обход делегирования, порог одобрения — и сообщает заплатил бы / приостановил бы для одобрения / заблокировал бы (с исправлением) с нулевыми побочными эффектами: без платежа, без запроса одобрения, без записи в реестре (протестировано).Бюджеты с ограничением по времени —
--ttl 90/--ttl 10m/--ttl 2hна любом гранте: послеexpiresAtгрант так же мёртв, как отозванный, а истёкший предок убивает всю свою ветвь.Одобрения в один клик — вебхуки одобрений теперь несут
approveUrl/denyUrl; вставьте оповещение в Slack, и утверждающий решает одним кликом прямо из чата.
Один API, любые рельсы (rails/)
Каждый платёжный рельс подключается за одним и тем же контрактом из четырёх строк — { id, name, status, pay({ tool, account, chain, baseUrl }) } — и конвейер управления никогда не узнаёт, какой рельс провёл расчёт. Сегодня работают два рельса (x402-simulate, x402-live — последний адаптивно подстраивается под фасилитатора на всех цепочках реестра, которые фасилитатор поддерживает); Google AP2, OpenAI ACP и Stripe Machine Payments — объявленные слоты адаптеров, которые честно отказываются (not implemented yet — funded-roadmap slot) вместо притворства. GET /api/rails отдаёт реестр; прокси рекламирует его в /proxy/health. Это форма «Stripe для расходов агентов» без лицензии оператора денежных переводов: одна интеграция перед каждым рельсом, управление сверху, расчёты снизу.
SDK, LangChain и потокобезопасные лимиты
Две интеграционные поверхности на уровне кода помимо CLI и MCP-сервера, обе без зависимостей и обе проверяемые сквозным образом в npm run verify, а не просто парсингом:
sdk/— Node-клиент (классSpendVeto):.pay(),.dryRun(),.chat()(управляемые расходы на LLM/API),.registerAgent(),.catalog(). Заблокированный вызов бросает типизированнуюSpendVetoDenialError{code, suggestion, stage}вместо молчаливого no-op.integrations/langchain.js— инструменты каталога, представленные как объекты в форме LangChain{ name, description, func }, без жёсткой зависимости от@langchain/core. Отказы бросают ошибку со встроенным структурированным кодом, чтобы следующий шаг рассуждения агента мог самоисправиться.integrations/openai-agents.js— тот же управляемый каталог в виде инструментов в форме OpenAI Agents SDK{ name, description, parameters, execute }(контракт хелпераtool()), без жёсткой зависимости от@openai/agents; он переиспользует адаптер LangChain, так что оба работают на одном конвейере.
Оба проходят через прокси принудительного исполнения, который теперь сериализует блок «решение-и-фиксация» каждого кошелька (withWalletLock в client/pay.js) — закрывая реальную гонку, где параллельные вызовы против одного кошелька могли каждый прочитать один и тот же снимок «потрачено на данный момент» и совместно превысить лимит, рассчитанный на одного. Доказано 6 параллельными вызовами против лимита с местом ровно на одного: ровно один побеждает, каждый запуск. Примеры кода: docs.html#sdk.
Страницы Agents, Marketplace и Report (Консоль, завершено)
Две страницы замыкают петлю между тем, что API уже мог делать, и тем, на что человек может кликнуть: Agents выпускает привязанные к кошельку токены идентичности и перечисляет инструменты маркетплейса из форм (без curl), а Report отвечает на вопрос «во что это нам обошлось и что остановило управление?» за скользящее окно — GET /api/report?days=7 — с однострочным заголовком, готовым для вставки в Slack, разбивкой расходов по категориям и по цепочкам и главными причинами, по которым управление что-то заблокировало.
Элементы управления на уровне конкурентов (из исследовательской карты июля 2026 года)
Четыре элемента управления, которые выпускают финансируемые игроки, честно пересобраны и протестированы:
Идентичности агентов (в стиле Skyfire «know your agent») —
POST /proxy/agents {label, child}выпускает bearer-токен, опционально привязанный к одному кошельку. Открытый режим, пока ни одной идентичности нет (демо без настройки); как только регистрируется первая идентичность, прокси-интенты требуютAuthorization: Bearer …, и привязанный токен может тратить только как собственный кошелёк (проверено: переопределениеchildв теле игнорируется).GET /proxy/agents/:id/credential— это сам KYA-сертификат: одно чтение, связывающее эту идентичность с текущим доверительным скорингом её кошелька, статусом заморозки и объёмом делегирования (лимиты/инструменты/цепи/получатели), так что контрагент может проверить «что этому агенту на самом деле разрешено делать», не сверяя четыре эндпоинта вручную.Категорийные лимиты (в стиле Ramp) — инструменты несут категорию расходов;
"categoryCapsUSD": {"content": 5}в политике ограничивает каждую категорию в час, вычисляя по собственным тегам реестра.Правило N-подтверждающих (в стиле Safe) —
"approversRequired": 2: отказ мгновенен и окончателен, но одобрение наступает только когда достаточно людей нажали (проверено: одно одобрение оставляет в статусе ожидания).Окно торговых часов —
"allowedHoursUTC": {"start": 13, "end": 21}: вне окна ничего не тратится. Контроль «мой бот торговал в 3 часа ночи», включая окна с переходом через полночь.
Ещё пять, из повторного сканирования конкурентов за июль 2026 (запуск x402 Foundation, AP2/Mastercard Agent Pay/Visa Trusted Agent выходят в продакшн)
Ограничение частоты и заморозка для каждого агента (
proxy/server.js) — бюджетные лимиты на уровне кошелька остаются источником истины для денег, но несколько идентичностей агентов могут делить один кошелёк (agents.json), поэтому одного сбойного или зациклившегося агента нужно иметь возможность остановить без заморозки всех остальных агентов на этом кошельке. Каждая идентичность получает собственный лимит вызовов со скользящим окном (PER_AGENT_CALLS_PER_MIN, по умолчанию 20); 3 последовательных превышения лимита автоматически замораживают только эту идентичность (POST /proxy/agents/:id/freeze//unfreezeтакже для ручного управления) — повторно используя существующее хранилище заморозок под синтетическим ключомagent:<id>, так что это по-прежнему видно на дашборде и вызывает алерты, как любая другая заморозка.Подписанные записи согласий (
server/consents.js, в стиле Visa Trusted-Agent-Protocol) — предоставление или отзыв делегирования теперь также записывает ECDSA-подписанную запись согласия (тем же серверным ключом, который подписывает расчётные квитанции и вердикты AP2) —GET /api/consent/:delegationIdдля трассировки,POST /api/consent/verifyдля независимой проверки подписи любой записи, без доверия к JSON-файлу.Агентные токены (
POST /api/agentic-token, в стиле Mastercard-Agent-Pay) — тонкий, честный пакет поверх двух примитивов выше: делегирование, ограниченное ровно одним получателем-мерчантом, плюс его подписанное согласие, возвращаемое одним объектом (GET /api/agentic-token/:idдля просмотра). Принудительное исполнение — та же проверка allowlist получателей + лимита, которую получает каждое делегирование.Экспорт проверяемых учётных данных для вердиктов AP2 (
server/vc.js) —POST /api/ap2/evaluate?format=vcпереформатирует тот же подписанный вердикт в обёртку в форме W3C-VC (сам AP2 построен на Verifiable Credentials). Честно помечено: тип доказательства — собственный SpendVeto, а не зарегистрированный DID-метод/набор доказательств — ноproof.message+proof.proofValue— это та же самая ECDSA-подпись, которую уже возвращает развёрнутый эндпоинт, независимо проверяемая с помощьюverifyMessageили любой ECDSA-библиотеки.Нормализация квитанций между рельсами (
server/receipts.js) —GET /api/receipts/normalizedпроецирует каждую запись реестра (крипто-расчёт x402, оплата за метрированный LLM/API и любой следующий рельс) через одну стабильную форму, так что клиенту не нужно знать, какой рельс создал какую запись.proofзаполняется только для записей, у которых действительно есть подписанная квитанция — никогда не фабрикуется для тех, у кого её нет.
Ещё три, из повторного сканирования за август 2026 (AP2 v0.2.0, x402 v2 Bazaar)
Два протокольных изменения с прошлого раунда изменили то, что должен покрывать слой управления, и оба открывают пробел, который структурно не видит лимит на каждый вызов.
Цепочки мандатов AP2 — намерение корзины всё ещё то же? (
server/ap2.js,POST /api/ap2/mandate-chain) — AP2 моделирует покупку как цепочку: Intent Mandate, который подписывает человек, затем Cart Mandate, который собирает агент./api/ap2/evaluateоценивает одну сумму, поэтому не может поймать сбой, для выявления которого существует цепочка — корзину, которая комфортно укладывается в бюджет и всё равно не авторизована. Этот эндпоинт проверяет корзину против намерения, из которого она, как заявлено, происходит: сумма выше потолка намерения (cart_exceeds_intent), заявленная сумма, противоречащая собственным позициям (cart_total_mismatch— проверяется до любого лимита, поскольку сумма, которую корзина не может обосновать, — не то число, по которому нужно проверять лимит), мерчант или категория, не авторизованные намерением (merchant_drift/category_drift), одна авторизация, размазанная по большему числу продавцов, чем позволяет намерение (multi_merchant_spray— документированный признак компрометации агента), истёкшее намерение и корзина, представленная с намерением, из которого она не выведена. Детерминированно и локально; никакая модель не оценивает отклонение. Вердикты подписаны ECDSA, как и любое другое решение.Авторитет при отсутствии человека (тот же эндпоинт) — AP2 v0.2.0 формализовал сценарии, где агент покупает без доступного человека. В таких случаях «пауза для одобрения» — не пауза, а безответный вопрос, и отношение к ней как к паузе либо зависает поток, либо тихо пропускает его. Правило SpendVeto: подписанный intent mandate и есть предварительная авторизация человека, поэтому в пределах заявленного потолка вызов продолжается (
preAuthorizedByIntent: true, и вердикт это говорит); за его пределами — или когда намерение вообще не указывает потолок — нет ни авторитета, ни того, кого спрашивать, поэтому происходит отказ по закрытому принципу (hnp_no_authority). Никогда не происходит тихого повышения траты сверх намерения до разрешения.Управляемое обнаружение Bazaar (
server/discovery.js) — слой Bazaar в x402 v2 позволяет агенту обнаружить и оплатить сервис, о котором он никогда не слышал, без предварительно настроенной интеграции. В этом суть, и в этом же проблема: allowlist получателей, проверяемый при расчёте, узнаёт о выбранном эндпоинте агента, подвергшегося prompt-инъекции, слишком поздно, чтобы помочь.GET /api/discovery/resourcesпубликует собственный каталог SpendVeto в схеме Bazaar (сеть CAIP-2, базовые единицы USDC, помеченоgoverned, чтобы покупатель знал, что цена — это нижняя граница).POST /api/discovery/governработает в другом направлении — он фильтрует обнаруженный каталог через действующую политику до того, как агент его увидит, так что сервис, который агенту никогда не было бы разрешено оплачивать, никогда не появляется в списке, из которого он выбирает, причём каждое удаление называет правило, которое его исключило, и версию политики, действовавшую в этот момент. Предварительный фильтр, который сужает то, что скомпрометированный агент вообще может назвать; что бы он ни выбрал, всё равно проходит полный конвейер в момент вызова.
Ещё четыре, из глубокого сканирования конкурентов за август 2026 (Fireblocks/x402, ACP, чарджбэки агентов, OTel)
Сторона покупателя быстро заполнилась: Fireblocks присоединился к x402 Foundation и вносит расширение безопасности для целостности запросов и управления расходами; AWS анонсировала Bedrock AgentCore Payments с лимитами расходов; Cloudflare объявила Account Wallets с контролем расходов; опрос Cloud Security Alliance за 2026 год показал, что 65% предприятий, запускающих агентов, столкнулись с одним или несколькими инцидентами, связанными с агентами, за двенадцать месяцев. Из этого сканирования выявились четыре пробела, каждый из которых структурно не может закрыть лимит на каждый вызов.
Целостность запроса — «это тот расход, который я разрешил?» (
server/integrity.js,POST /api/integrity/bind→/api/integrity/verify) — каждый контроль здесь отвечает на вопрос разрешён ли этот расход. Ни один не отвечал на вопрос это тот расход, который я разрешил. Политика выполняется над описанным запросом; исполняется что-то другое. Между ними скомпрометированный или просто багованный агент может изменить полезную нагрузку — тот же плательщик, та же цена, то же одобрение, но другой мерчант или другие товары — и все контроли, основанные на сумме, проходят, потому что сумма не изменилась. Итак: канонически хешируем запрос (рекурсивный SHA-256 с сортировкой ключей, чтобы порядок ключей не мог изменить ответ), подписываем хеш тем же ключом, который подписывает квитанции и вердикты, и отказываем при исполнении, когда полезная нагрузка больше не совпадает (request_integrity_mismatch). Привязки одноразовые (binding_consumed— авторизация, которую можно воспроизвести, это купон, а не привязка), ограничены TTL (binding_expired) и привязаны к агенту (binding_agent_mismatch). Это аналог на стороне покупателя того, что Fireblocks вносит в x402.Область действия ACP Shared-Payment-Token (
server/acp.js,POST /api/acp/checkout) — спецификация ACP Delegated Payments выпускает SPT: bearer-учётные данные, выпущенные на сумму, мерчанта и окно, позволяющие агенту оформить покупку, не видя карту покупателя. Мерчант проверяет токен. Никто не проверяет покупки — и токен, ограниченный $200 у одного мерчанта, с радостью проведёт $200 за неправильные товары. Та же форма, что и отклонение AP2 выше, поэтому получает ту же обработку:spt_merchant_drift,session_exceeds_spt,spt_expired,spt_category_drift,session_total_mismatch(арифметика проверяется до потолка, потому что сумма, которую не обосновывают позиции, — не то число, по которому нужно измерять), иspt_currency_mismatch— SpendVeto отказывается сравнивать потолок в одной валюте с платежом в другой, а не угадывать курс. Разрешённая сессия остаётся привязанной к своим собственным байтам; отклонённая не получает привязки.Пакеты доказательств для споров (
server/disputes.js,GET /api/disputes/:entryHash/evidence) — когда человек оспаривает платёж, мерчант защищается отпечатком устройства, IP, сессией браузера, подтверждением доставки. Агентская покупка не даёт ничего из этого, поэтому транзакции агентов проигрывают по умолчанию, и платит мерчант. Visa TAP, Mastercard Agent Pay, AP2 и защита агентов Amex описывают авторизацию; ни один пока не определяет посмертный файл защиты. SpendVeto уже на этом сидит — ничего нового не захватывается. Пакет собирает запись реестра, зажатую между соседними хешами (аргумент против бэкдэйтинга), хеш действующей политики с любым отклонением с тех пор, раскрытым, а не скрытым, запись одобрения человеком и подписанные согласия на делегирование, под которым платил плательщик — затем подписывает пакет по его собственному дайджесту, так что пакет, изменённый при передаче, перестаёт проверяться (pack_tampered). Каждый пакет несёт списокdoesNotEstablishвнутри артефакта: он никогда не подразумевает доставку, удовлетворённость или что политика была хорошей — только что она действовала и была применена.OpenTelemetry-спаны решений (
server/otel.js,GET /api/otel/spans) — команды агентов уже трассируют промпты, вызовы инструментов и субагентов, и требование, которое постоянно появляется в оценках управления агентами, — это нативная видимость OTel: решение о расходе должно появляться как спан внутри трассы, которая его вызвала, а не во второй системе, которую кто-то сопоставляет по таймстампу в 3 часа ночи. OTLP/HTTP — это JSON через POST, так что это без зависимостей — добавление OpenTelemetry SDK в единственный компонент, чья работа — отказываться доверять вещам, добавило бы поверхность атаки цепочки поставок без выгоды. Передайте W3Ctraceparent, и отказ попадёт под запуск агента, который пытался потратить; идентификаторы спанов выводятся из хеша записи, так что повторный экспорт не дублирует спаны в бэкенде; некорректный заголовок деградирует до отдельной трассы, а не ломает поверхность решений. Заблокированный расход — это статус OK, а не ERROR — шлюз выполнил свою работу, и окрашивание отказов в красный учит команду игнорировать тот цвет, который важен.
Маркетплейс + разрешения: двусторонний маховик
Любой может выставить платный инструмент за шлюзом — каталог это предложение, а не фиксированное демо:
curl -X POST localhost:8402/api/catalog/tools -H 'Content-Type: application/json' \
-d '{"id":"haiku","price":0.008,"label":"Haiku writer","upstreamUrl":"https://your-api.example/haiku"}'
npm run call -- haiku # any agent pays it through the full governed pipelineЗарегистрированные инструменты получают идентичный шлюз 402 (подписи с привязкой к цепи, квитанции, реестр); с upstreamUrl платный вызов пересылается, без него — отвечает готовым телом. Продавцы выставляют, покупатели управляют — обе стороны агентной коммерции в одном стеке.
Бюджеты могут быть разрешениями — лимиты, которые пополняются в скользящем окне, а не заканчиваются навсегда:
npm run delegate -- 5 "shopping agent" --every 7d # $5 a week, self-refillingТраты в пределах окна учитываются в лимите; когда окно истекает, бюджет восполняется сам (проверено на 2-секундном окне: трата → блокировка → автовосполнение → снова трата). Это примитив «выдай агенту недельный лимит» — для команд сегодня, для потребительских агентов завтра.
Симулированные пополнения: POST /api/balances/topup {address, chain, amount} пополняет баланс на конкретной сети в режиме simulate (и только там — ончейн-балансы приходят из реальных кранов, никогда через API).
Рельс API-трат: управление деньгами, которые агенты уже жгут
Крипто — рельс №1, потому что его можно было проверить локально, — но тот же конвейер управляет тратами на LLM/API, где сегодня каждая агентная команда теряет деньги:
curl -X POST localhost:8404/proxy/llm -H 'Content-Type: application/json' \
-d '{"prompt":"summarize x402 in one line","maxTokens":200}'
-d '{"prompt":"…","maxTokens":20000}' # big estimate → pauses for human approval, FAILS CLOSED
-d '{"prompt":"…","child":"intern"}' # delegated budgets bind token spend tooAuth/capture, как на реальных платформах трат: худший случай оценивается заранее (LLM_RATE_IN_PER_M / LLM_RATE_OUT_PER_M, доллары за миллион токенов — берите из прайс-листа вашего провайдера), весь конвейер прогоняется против оценки (freeze → policy → каскадные бюджеты → approval), вышестоящий вызов происходит только если проверка пройдена, а фактическая измеренная стоимость попадает в ту же книгу учёта — свёрнутая в собственный бакет api рядом с сетями. С заданным ANTHROPIC_API_KEY завершение реальное; без него завершение симулируется, но управление и учёт — нет. Токены агента, API-вызовы и USDC подчиняются одному движку политик.
Мультичейн: управление с учётом сети, а не полоска логотипов
Семь сетей зарегистрированы в shared-config.js (у каждой свой канонический USDC-контракт и RPC), доступны на /api/chains. Сеть — это управляемый атрибут каждого платежа, от начала до конца:
Подписи с привязкой к сети — сеть встроена в подписанное платёжное сообщение, поэтому авторизация, созданная для Polygon, никогда не сможет быть погашена против баланса другой сети (проверено: авторизация, подписанная для polygon, отклоняется на arbitrum).
Балансы по сетям — каждая пара
(wallet, chain)имеет собственный симулированный USDC-баланс; оплата на Polygon списывает только Polygon.Списки разрешённых сетей —
"allowedChains": ["base-sepolia", "base"]вdata/policy.jsonблокирует агентам расчёты где-либо ещё; пакетыcautiousиproductionпоставляются с зафиксированными сетями.Делегирование с привязкой к сети —
--chains base-sepoliaзакрепляет сети расчёта для дочернего агента, и (как лимиты и области инструментов) каждая сеть предка связывает всё поддерево.Везде —
npm run call -- review --chain=polygon, прокси-интенты ({"tool":"review","chain":"arbitrum"}), сводки по сетям на/api/analytics, колонка сети в CSV-экспорте, теги сетей в журнале на дашборде.Адаптивная живая оплата через фасилитатора — в режиме testnet шлюз при запуске спрашивает у настроенного фасилитатора, что тот может погасить (
GET /supported), и включает все зарегистрированные сети фасилитатора: регистрация схем по сетям и по одной записи accept на каждую сеть в каждом 402, с ценами как явными атомарными USDC-суммами против канонического контракта каждой сети. Проверено на мок-фасилитаторе в обе стороны: реклама всех семи включает все семь; реклама одной включает ровно одну, остальные сообщаютsettlement: "ready"на/api/chains. Публичный фасилитатор сегодня погашает Base Sepolia; если указатьSPENDVETO_FACILITATOR_URLна фасилитатор CDP (с API-ключом) и пополнить кошелёк, его mainnet-сети включаются вживую без изменений кода — оставшийся разрыв до реальных mainnet-трат — это ключ, средства и аудит безопасности, а не инженерия.
Ончейн-расчёт работает на Base Sepolia через x402 уже сегодня; каждая зарегистрированная сеть прогоняет весь конвейер в режиме simulate (реальные подписи с привязкой к сети, локальный расчёт). Адаптеры фасилитатора по сетям — это финансируемая веха — слой управления уже полон по сетям.
Поверхности доказательств: SIEM-события, версионирование политик, подписанные вердикты, биллинг
Июльский исследовательский раунд 2026 года сказал прямо: рельсы логируют платежи; предприятиям нужны доказательства решений до них. Четыре поверхности (все проверены):
События решений —
GET /api/eventsпереформатирует хэш-цепочку в одну стабильную схему (spendveto.decision.v1): агент, решение, сумма, получатель, причина отказа, id чека, версия политики, хэши цепочки хранения.GET /api/events/exportвыдаёт JSON Lines — одно решение на строку, прямо в Splunk/Datadog/Elastic/jq, без разбора обёрток.Версионирование политик — каждое решение шлюза помечено
policyHash— SHA-256 политики, действовавшей в этот момент. «Какая политика разрешила эту трату?» — ответ можно получить из одной книги учёта, после любого количества правок политики.Оценка мандатов в стиле AP2 —
POST /api/ap2/evaluateпрогоняет полный конвейер политики против мандата в формате AP2 (агент, сумма, получатель, срок действия) и возвращает вердикт, подписанный ECDSA ключом подписи сервера: переносимое доказательство, которое может проверить любой. Просроченные мандаты отказывают сmandate_expired. Расчёт AP2 остаётся честным пунктом дорожной карты — это половина управления, реальная сегодня.Управляемый биллинг — расчёт отправляет одно событие
spendveto.usage.v1(по ключуreceipt id) наpolicy.billingWebhookUrl, опционально подписанное HMAC: SpendVeto обеспечивает предоплату; платформы вроде Lago/Orb/Metronome выставляют счета после использования. Разделение труда, а не биллинговый движок.
Инвентарь контролей в CONTROLS.md сопоставляет всё это (и каждый другой контроль) с ожиданиями времени выполнения EU AI Act / NIST AI RMF — каждая строка ссылается на проверочное утверждение, которое его проверяет. Самооценка, а не сертификация.
Доверительные оценки и пакеты политик
GET /api/trust/:address сжимает историю управления кошелька в оценку 0–100 с буквенной оценкой — оплаченная история зарабатывает доверие; блокировки, сбои и заморозки его сжигают (вышедший из-под контроля кошелёк получает F при оценке 0). Оценка теперь масштабируется двумя способами (оба проверены): GET /api/trust/graph строит граф доверия — каждый кошелёк — узел с оценкой, каждая делегация — ребро, каждый корень делегации — «организация» с оценкой, взвешенной по объёму оплат, по всему поддереву, — а GET /api/trust/payee/:address — это бюро контрагентов: репутация получателя, агрегированная по всем кошелькам, которые когда-либо платили (или были заблокированы от оплаты) ему, включая среднюю оценку управления его плательщиков. Всё ещё вычисляется из книги учёта одного развёртывания — межорганизационная федерация этих графов — это дорожная карта, которую это закладывает.
Управление поставляется в виде пресетов: npm run policy перечисляет пакеты (cautious / standard / production), npm run policy -- apply cautious применяет один (предыдущая политика сохраняется в .bak). Команды могут коммитить свои собственные пакеты.
Утверждение с участием человека
Цены выше requireApprovalAboveUSD (в data/policy.json) приостанавливают вызов и публикуют его в очередь утверждения на дашборде — кнопки Approve / Deny, вживую. Три исхода, все зафиксированы в журнале с причинами: одобрено → платит; отклонено → выходит без оплаты; нет решения за 30 секунд → закрывается с ошибкой (никогда не тратит без подписи).
Два режима, оба реальные
|
| |
Крипто | Реальная пара ключей secp256k1, реальная подпись и проверка ECDSA (viem) | Реальная авторизация платежа EIP-3009 |
Расчёт | Офчейн-баланс в | Реальный x402 v2 на Base Sepolia (CAIP-2 id, пакеты |
Настройка | Ноль | Пополните один кошелёк на faucet.circle.com (Base Sepolia) |
Ничего не подделано, чтобы выглядеть реальным — режим simulate проверяет настоящие подписи и отклоняет поддельные (проверено); он просто рассчитывается локально. Режим testnet — это настоящие пакеты @x402/express/@x402/fetch v2 против живого публичного фасилитатора, подтверждённо работающие по каждому инструменту до границы пополнения через кран (браузер + капча — единственный неавтоматизируемый шаг).
Файлы
shared-config.js tool catalog (id/path/price), 7-chain registry (USDC contracts, RPCs), mode, port
server/
index.js Express app: catalog, ledger, stats, analytics, CSV export, policy, approvals, delegations, freezes APIs
simulate.js per-tool 402 gate factory: real signature verify, replay protection, freeze refusal, signed receipts
agent.js the paid tasks — one Claude call per tool, canned fallback without a key
ledger.js JSON ledger + simulated balances
approvals.js in-memory pending-approval store
delegations.js durable budget-grant store (caps + tool scopes)
freezes.js durable kill-switch store
anomaly.js runaway-burst detector → auto-freeze
alerts.js fire-and-forget webhook alerts (Slack-ready)
ap2.js AP2 mandate chains: cart-vs-intent drift + human-not-present authority
discovery.js x402 v2 Bazaar: publish the catalog, and policy-filter a discovered one
acp.js ACP shared-payment-token scope: is the session the purchase the token funds?
integrity.js request binding: is this the spend I allowed? (canonical digest, single-use)
disputes.js signed dispute evidence packs — the agent-chargeback defence file
otel.js OTLP decision spans; adopts an inbound W3C traceparent, blocked ≠ ERROR
client/
wallet.js parent keypair + delegated child wallets (pick by label)
policy.js the governance wedge: freezes, hard limits, approval threshold, cascading caps
pay.js shared governed pipeline: policy → approval → pay → log
pay-and-call.js CLI wrapper (--child, --child=<label-or-address>)
rails/
index.js rail registry: one pay() contract, x402 live, AP2/ACP/MPP as honest slots
x402-simulate.js zero-setup rail: real ECDSA, chain-scoped, local settlement
x402-testnet.js real on-chain rail: Base Sepolia via the public facilitator
mcp/
server.js MCP middleware: paid catalog + spendveto_status over stdio
proxy/
server.js enforcement proxy: key custody, agents POST intents (:8404)
dashboard/ the Console: 8 pages (overview, approvals, budgets, ledger, chains, analytics, trust, policy) with create/edit/freeze/apply controls
scripts/
delegate.mjs grant a capped budget (--parent for deeper levels, --tools for scope)
gen-wallets.mjs one-time testnet wallet generation
policy.mjs list/apply policy packs
site.mjs serves the marketing site on :8403
verify.mjs 264 end-to-end assertions incl. MCP stdio round trip + multichain + auto-freeze
data/
policy.json editable spend rules incl. anomaly burst threshold + alertWebhookUrl
policy-packs/ importable governance presets (cautious/standard/production)
ledger/balances/delegations/children/freezes.json runtime state (gitignored)
site/ deploy-ready landing page (Three.js hero, fully static)
PITCH.md funding pitch: TAM/SAM/SOM, competition, accelerator targets (all cited)
launch/ Show HN draft, 90-second demo script, ecosystem-listing blurbs
RESEARCH_PROMPT.md the deep-research prompt behind feature round 2Дорожная карта (что покупает финансирование — см. PITCH.md)
Хостированный бэкенд (Postgres) вместо JSON-файлового хранилища; организации, SSO, экспорт аудита
Более богатые сигналы аномалий (дрейф цен, новый мерчант, нерабочее время) + вебхук/Slack-алерты при заморозке
Адаптеры мульти-рельс: Google AP2, Stripe MPP, Mastercard AP4M — слой политики не должен заботиться о том, какой рельс расчитывает
Mainnet-расчёт через фасилитатор CDP (миграция x402 v2: готово) — нужен пополненный кошелёк + API-ключ CDP
Хуки фреймворка: middleware CrewAI, более глубокая интеграция Claude Code; гейт реального шага SDLC-конвейера Sentient (LangChain: готово, см.
integrations/langchain.js)
Цены: self-host бесплатен навсегда (этот репозиторий — весь продукт). Хостированные тарифы запуска — Desk $49/мес, Team $199/мес + 0,5% от управляемых API-трат, Money Path по 10–25 б.п. на управляемый объём — на странице цен за списком ожидания.
Лицензия Apache-2.0 — см. LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceBudget & cost control for AI agents: hard per-agent spend caps, rate limits, idempotency, and human-in-the-loop approval — enforced before each LLM call, not after the invoice. One hosted MCP endpoint (no proxy or self-hosting), settled via x402 (USDC on Base).MIT
- AlicenseBqualityAmaintenanceA governance proxy for AI tools — every MCP/agent tool call is policy-gated, secret-redacted, and written to a hash-chained, offline-verifiable audit trail.13MIT
- AlicenseNot gradedqualityAmaintenanceAn MCP compliance proxy that enforces deterministic knowledge governance for AI agents, routing tool calls through a 14-gate planner and generating audit logs, budget ledgers, and approval tickets.349Apache 2.0

evav-gatewayofficial
AlicenseNot gradedqualityBmaintenanceGoverned MCP gateway that lets AI agents call tools with policy enforcement, prompt-injection screening, a kill-switch, and tamper-evident signed audit logs.Apache 2.0
Related MCP Connectors
See, price, and control every tool call your AI agents make: policy checks, cost, and audit tools.
Agent payments, API key vaulting, and governed mandates. Agents spend within user-defined limits.
Runtime permission, approval, and audit layer for AI agent tool execution.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/revanthrajeev/spendveto'
If you have feedback or need assistance with the MCP directory API, please join our Discord server