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
| SKU | Tipo | Créditos | Preço de varejo sugerido |
|---|---|---|---|
pack.competitor-snapshot | pacote | 50 | US$ 0,50 |
pack.venue-hours | pacote | 20 | US$ 0,20 |
recipe.book-table | receita | 100 | US$ 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.
SQLITE_PATH, se definido, é usado como está.- Caso contrário, o arquivo é
/data/botsupply.sqlitequando/dataé gravável. - 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:
| Chave | Valor |
|---|---|
STRIPE_SECRET_KEY | Chave secreta do Stripe (sk_test_… ou sk_live_…). Não a envie para o repositório. |
STRIPE_WEBHOOK_SECRET | Segredo de assinatura para o endpoint abaixo (whsec_…). |
PUBLIC_BASE_URL | https://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.