Skip to main content
Glama

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 dashboard

Related 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.005

npm 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:8403site/ полностью статичен и самодостаточен, можно разместить на Vercel/Netlify как есть. Включает интерактивную песочницу (site/playground.html), которая запускает реальную логику принятия решений по политике на стороне клиента — задайте бюджет, запустите расходы агента, наблюдайте, как он проходит/приостанавливается/блокируется — и страницу вариантов использования, основанную на реальных сценариях расходов агентов 2026 года.

Каталог

Три реальных инструмента на базе Claude по трём ценам (shared-config.js):

Инструмент

Цена

Путь управления

translate

$0.005

автоодобрение

review

$0.01

автоодобрение

summarize

$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 в единственный компонент, чья работа — отказываться доверять вещам, добавило бы поверхность атаки цепочки поставок без выгоды. Передайте W3C traceparent, и отказ попадёт под запуск агента, который пытался потратить; идентификаторы спанов выводятся из хеша записи, так что повторный экспорт не дублирует спаны в бэкенде; некорректный заголовок деградирует до отдельной трассы, а не ломает поверхность решений. Заблокированный расход — это статус 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 too

Auth/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 политики, действовавшей в этот момент. «Какая политика разрешила эту трату?» — ответ можно получить из одной книги учёта, после любого количества правок политики.

  • Оценка мандатов в стиле AP2POST /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). Команды могут коммитить свои собственные пакеты.

Утверждение с участием человека

Цены выше requireApprovalAboveUSDdata/policy.json) приостанавливают вызов и публикуют его в очередь утверждения на дашборде — кнопки Approve / Deny, вживую. Три исхода, все зафиксированы в журнале с причинами: одобрено → платит; отклонено → выходит без оплаты; нет решения за 30 секунд → закрывается с ошибкой (никогда не тратит без подписи).

Два режима, оба реальные

simulate (по умолчанию)

testnet

Крипто

Реальная пара ключей secp256k1, реальная подпись и проверка ECDSA (viem)

Реальная авторизация платежа EIP-3009

Расчёт

Офчейн-баланс в data/balances.json, начальные $5.00

Реальный x402 v2 на Base Sepolia (CAIP-2 id, пакеты @x402/*) через публичный фасилитатор — укажите SPENDVETO_FACILITATOR_URL на фасилитатор Coinbase CDP (самообслуживаемый API-ключ), чтобы разблокировать mainnet-сети, которые он обслуживает

Настройка

Ноль

Пополните один кошелёк на 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.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    A
    maintenance
    Budget & 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
  • A
    license
    B
    quality
    A
    maintenance
    A 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.
    13
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    An 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.
    349
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Governed 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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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