Skip to main content
Glama

MCP Bling

Servidor MCP (Model Context Protocol) remoto que expõe a API v3 do Bling a agentes de IA — multi-tenant, stateless e rodando na edge com Cloudflare Workers.

TypeScript Cloudflare Workers MCP Hono

Stack: TypeScript · @modelcontextprotocol/sdk · Cloudflare Workers · Hono · Zod

Ferramenta de desenvolvimento/debug: o time aponta o MCP para a conta de qualquer cliente (passando o access_token daquele cliente) e trabalha com dados reais — NF-e, etiquetas, particularidades — direto de um assistente de IA, sem o cliente precisar reautenticar nada.

Destaques de engenharia

  • 🔑 Modelo read-through de token — o Worker é stateless e nunca guarda nem renova credenciais. Decisão deliberada: o Bling rotaciona o refresh_token a cada refresh, então renovar aqui invalidaria o token do app em produção do cliente. O MCP só repassa um access_token já válido.

  • 🔒 Somente-leitura por padrão — as tools de escrita nem aparecem para o agente; habilitar escrita exige um header explícito, e há um kill-switch global (FORCE_READ_ONLY) no Worker.

  • 🧩 CRUD genérico tipado — 6 tools cobrem ~40 módulos do Bling (produtos, pedidos, NF-e/NFC-e/NFS-e, estoque, financeiro…) via um enum recurso, em vez de dezenas de tools redundantes. Uma "escotilha" (bling_request) cobre sub-rotas especiais.

  • ☁️ Edge nativo — deploy global em Cloudflare Workers, transporte Streamable HTTP, custom domain e observabilidade habilitada.

Related MCP server: omie-mcp

Sumário


  • Transporte: Streamable HTTP (/mcp)

  • Auth do chamador: service token compartilhado (Authorization: Bearer …)

  • Token do cliente: header X-Bling-Access-Token (pass-through, somente leitura — o MCP nunca renova)

  • Stateless: sem Durable Objects, sem KV, sem credenciais do Bling no Worker

Produção: https://mcp-bling.bconnector.com.br — endpoint MCP em …/mcp.

Modelo de auth

A API v3 do Bling é OAuth 2.0 (a apikey da v2 foi desativada em ago/2024). Cada app de vocês já guarda e renova o token de cada cliente. O MCP não gerencia token nenhum: o chamador envia um access_token válido e o MCP só o repassa para a API do Bling.

você (Claude Code) ──(Bearer SERVICE_TOKEN + X-Bling-Access-Token)──► MCP Worker ──► API Bling do cliente

Por que o MCP não renova o token

O Bling rotaciona o refresh_token a cada refresh. Como cada app de vocês tem a própria cópia do token do cliente, se o MCP renovasse, invalidaria o token do app em produção daquele cliente. Por isso o MCP é read-through: recebe um access_token já válido (vence em ~6h) e nunca renova. Quem renova continua sendo o app dono do token.

Endpoints

Método

Rota

Auth

Descrição

GET

/

Landing/health

POST

/mcp

Bearer SERVICE_TOKEN + X-Bling-Access-Token

Endpoint MCP (Streamable HTTP)

Arquivos

Arquivo

Papel

src/index.ts

Worker: valida o service token e monta o handler MCP por requisição

src/tools.ts

Tools MCP (CRUD genérico por recurso + escotilha)

src/bling-client.ts

createRequester(accessToken) — chamadas à API com o token recebido

Setup

npm install
npx wrangler secret put SERVICE_TOKEN   # token compartilhado entre quem usa o MCP
npm run deploy

Para dev local: copie .dev.vars.example para .dev.vars e preencha o SERVICE_TOKEN.

Uso (Claude Code / VS Code)

Pegue o access_token vivo do cliente-alvo (aquele que o app daquele cliente já usa) e configure:

{
  "mcpServers": {
    "bling": {
      "type": "http",
      "url": "https://mcp-bling.bconnector.com.br/mcp",
      "headers": {
        "Authorization": "Bearer ${BLING_SERVICE_TOKEN}",
        "X-Bling-Access-Token": "${BLING_ACCESS_TOKEN}"
      }
    }
  }
}

Use ${...} para o Claude Code expandir variáveis de ambiente — assim você não commita segredo. Defina BLING_SERVICE_TOKEN (o service token) e BLING_ACCESS_TOKEN (o token do cliente do momento) no ambiente. O access_token vence em ~6h; quando expirar, atualize a env var com um novo (pego do app daquele cliente) e reconecte (/mcp).

Testar no Inspector: npx @modelcontextprotocol/inspector → Transport Streamable HTTP, URL …/mcp, e em Headers adicione Authorization: Bearer <SERVICE_TOKEN> e X-Bling-Access-Token: <token>.

Tools disponíveis

São 6 tools: 5 genéricas tipadas (CRUD) parametrizadas pelo recurso, + uma escotilha.

Tool

Descrição

bling_listar

Lista (paginado) registros de um recurso, com filtros de query

bling_obter

Detalhe de um registro por ID

bling_criar

Cria um registro (POST)

bling_atualizar

Atualiza um registro (PUT, ou PATCH com parcial=true)

bling_excluir

Remove um registro (DELETE)

bling_request

Escotilha: sub-rotas/endpoints especiais (/estoques/saldos, etc.)

O parâmetro recurso é um enum que cobre ~40 módulos do Bling (produtos, pedidos-vendas, pedidos-compras, contatos, contas-pagar, contas-receber, contas-contabeis, caixas, nfe, nfce, nfse, estoques, depositos, empresas, categorias-produtos, categorias-receitas-despesas, canais-venda, formas-pagamentos, naturezas-operacoes, logisticas[-objetos/-remessas/-servicos], ordens-producao, produtos-[estruturas/fornecedores/variacoes/lotes], propostas-comerciais, anuncios[-categorias], grupos-produtos, campos-customizados, vendedores, notificacoes, borderos, situacoes[-modulos/-transicoes], contratos, usuarios). O mapa recurso→path está em src/tools.ts.

Sincronizado com o changelog da API do Bling até ago/2026 (novas APIs de caixas e bancos, controle de lotes, anúncios/marketplaces e NFS-e; ver notas no bling_request sobre as breaking changes de pedido de compra e documentos referenciados em notas fiscais).

Modo somente-leitura (padrão)

Você opera sobre a conta de produção do cliente, então o MCP é somente-leitura por padrão: expõe apenas bling_listar, bling_obter e bling_request (limitado a GET). As tools de escrita nem aparecem.

Para habilitar escrita (bling_criar/bling_atualizar/bling_excluir e métodos não-GET no bling_request), envie o header na conexão:

X-Bling-Allow-Write: true

Kill-switch global: defina o secret/var FORCE_READ_ONLY=true no Worker para travar tudo em somente-leitura, ignorando o header (npx wrangler secret put FORCE_READ_ONLY).

Mesmo com escrita habilitada: bling_criar/bling_atualizar/bling_excluir alteram dados reais do cliente. Use com cuidado.

Hardening (próximos passos sugeridos)

  • Chave por dev/app em vez de service token único (auditoria/revogação).

  • Espelho de token central (Supabase): cada app grava o access_token atual numa tabela read-only; o MCP passa a ler por X-Tenant-Id e você escolhe o cliente sem colar token na mão.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for the Billingo V3 Hungarian invoicing API. Manage invoices, partners, products, spendings, and bank accounts from any MCP client.
    4 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for the Omie API to list products, consult clients, and create budgets
    8 npm
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server for Bling ERP, enabling read and write operations on sales orders, products, contacts, accounts payable/receivable, NF-e, inventory, and more via OAuth 2.0.
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Read-only MCP server for Olist Tiny ERP, enabling querying of products, inventory, orders, invoices, accounts, contacts, shipping, purchase orders, CRM, and price lists via the official REST API v3.
    MIT