BotSupply

BotSupply: créditos em atacado + MCP para horários de funcionamento, capturas de concorrentes e documentos de receita de reservas.

Servidor MCP hospedado

npx add-mcp 'https://botsupply.onrender.com/mcp'

Instala no Claude Code, Codex, Cursor e outros

Documentação

BotSupply

Atacado para agentes de IA. BotSupply é uma API de marketplace B2B: um agente abre uma carteira, carrega créditos pré-pagos e compra produtos JSON.

1 crédito = US$ 0,01. POST /v1/wallets/:id/topup é um reforço gratuito de desenvolvimento apenas quando STRIPE_SECRET_KEY não está definido. Quando STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET e PUBLIC_BASE_URL estão todos definidos, essa rota gratuita retorna 403 e os agentes pagam com Stripe Checkout.

Agentes que chamam a API hospedada: AGENT_INSTALL.md. Ferramentas MCP para o mesmo catálogo: MCP_INSTALL.md. Script de demonstração público: DEMO.md.

Produtos

SKUTipoCréditosPreço de varejo sugerido
pack.competitor-snapshotpacote50US$ 0,50
pack.venue-hourspacote20US$ 0,20
recipe.book-tablereceita100US$ 1,00

pack.competitor-snapshot é um conjunto competitivo de restaurantes casuais em Cobble Hill. pack.venue-hours são os horários semanais e a política de reservas desses estabelecimentos. recipe.book-table é uma receita de reserva executável que o próprio agente executa. Os payloads são entregues na compra.

Executar localmente

Requer Node.js 22+.

npm install
npm test
npm run build
npm start

O processo vincula 0.0.0.0 e escuta em PORT, padrão 4317.

curl -s http://127.0.0.1:4317/health

Abra http://127.0.0.1:4317 para a tabela de preços e exemplos de curl.

npm run dev recarrega o servidor TypeScript com tsx.

Dados

SQLite é um único arquivo.

  1. SQLITE_PATH, se definido, é usado como está.
  2. Caso contrário, o arquivo é /data/botsupply.sqlite quando /data é gravável.
  3. Caso contrário, é ./data/botsupply.sqlite.

O banco de dados e o catálogo são criados na inicialização. As carteiras começam com 0 créditos.

API

POST /v1/wallets

Abre uma carteira. A chave de API é retornada uma única vez.

curl -s -X POST http://127.0.0.1:4317/v1/wallets \
  -H 'content-type: application/json' \
  -d '{"label":"desk-agent"}'
{ "wallet_id": "wal_…", "api_key": "bsk_…", "balance_credits": 0 }

POST /v1/wallets/:id/topup

Recarga de créditos DEV. Nenhum pagamento é cobrado. Este é o comportamento atual apenas quando STRIPE_SECRET_KEY não está definido (execuções locais e o serviço hospedado antes da adição das chaves Stripe). Após a definição da chave, a rota retorna 403 dev_topup_disabled.

curl -s -X POST http://127.0.0.1:4317/v1/wallets/$WALLET_ID/topup \
  -H 'content-type: application/json' \
  -d '{"credits":500}'

credits é um inteiro de 1 a 1000000.

POST /v1/wallets/:id/checkout

Recarga paga. Requer Authorization: Bearer <api_key> para essa carteira e todas as três variáveis de ambiente do Stripe. O corpo é { "credits": number } de 100 a 100000. Cada crédito é um item de linha do Checkout de 1 centavo (unit_amount 1, quantidade = créditos).

curl -s -X POST "$BASE/v1/wallets/$WALLET_ID/checkout" \
  -H "authorization: Bearer $API_KEY" \
  -H 'content-type: application/json' \
  -d '{"credits":500}'

A resposta url é https://<host>/v1/pay/s/<session_id>. Abri-la redireciona para o Checkout hospedado e mantém o fragmento # que o Stripe exige. Um id de sessão sozinho mostra "Este link está incompleto." stripe_url é o link completo do Checkout.

GET /v1/pay?credits=100 cria uma carteira de demonstração e redireciona para o Checkout. Adicione wallet_id para pagar em uma carteira existente. Os créditos são de 100 a 100000.

Os créditos são aplicados quando o Stripe chama POST /v1/stripe/webhook com checkout.session.completed e payment_status paid. O mesmo id de Sessão do Checkout é creditado uma única vez.

Stripe no Render

O serviço ao vivo não cobra cartões até que estes sejam definidos. No Painel do Render, abra o serviço botsupply, depois Ambiente, e adicione:

ChaveValor
STRIPE_SECRET_KEYChave secreta do Stripe (sk_test_… ou sk_live_…). Não a envie para o repositório.
STRIPE_WEBHOOK_SECRETSegredo de assinatura para o endpoint abaixo (whsec_…).
PUBLIC_BASE_URLhttps://botsupply.onrender.com

Salve e faça o redeploy. No Stripe, adicione um endpoint de webhook https://botsupply.onrender.com/v1/stripe/webhook para o evento checkout.session.completed e cole o segredo de assinatura em STRIPE_WEBHOOK_SECRET.

render.yaml lista os dois segredos com sync: false e define PUBLIC_BASE_URL. O serviço já existe, então preencha os segredos no Painel. Um valor vazio conta como não definido, e a recarga DEV permanece ativa até que STRIPE_SECRET_KEY não esteja vazio. Deixe a chave não definida para manter recargas gratuitas.

GET /v1/catalog

Lista SKUs, preços em créditos e a taxa de varejo sugerida. Os payloads dos produtos não são incluídos.

GET /v1/balance

Requer Authorization: Bearer <api_key>. Retorna wallet_id, balance_credits, label e created_at. A chave de API não é incluída.

MCP

POST /mcp é um servidor MCP Streamable HTTP sem estado neste mesmo processo. As ferramentas chamam as rotas acima (list_catalog, open_wallet, get_balance, purchase, create_checkout). Etapas de instalação e autenticação: MCP_INSTALL.md.

POST /v1/purchase

Requer Authorization: Bearer <api_key>. Gasta o preço do SKU e retorna o payload JSON.

curl -s -X POST http://127.0.0.1:4317/v1/purchase \
  -H "authorization: Bearer $API_KEY" \
  -H 'content-type: application/json' \
  -d '{"sku":"pack.venue-hours"}'

Saldo insuficiente retorna 402 e não deduz créditos. Um SKU desconhecido retorna 404. Uma chave ausente ou desconhecida retorna 401.

GET /v1/purchases/:id

Repete uma compra para a carteira que a possui. Mesmo token de portador da compra.

GET /health

{ "status": "ok", "service": "botsupply" }

Testes

npm test

Cobre criação de carteira, recarga DEV, compra de cada SKU, dedução de créditos e aplicação idempotente de créditos do Stripe. Os testes de Checkout usam um cliente Stripe fictício e não chamam a rede.

Implantação

As instruções para Docker, Render e Fly.io estão em DEPLOY.md.