bticket-mcp
bticket-mcp
Servidor MCP fino que expõe a API Laravel Sanctum do B-Ticket como ferramentas. O Cursor (e o Grok Bot) passam a consultar usuário, quadros, cards, tickets, dashboard e notificações — e também criar card com horas — sem inventar rotas.
A maior parte das tools é somente leitura. bticket_create_card é a tool de escrita: cria o card, lança horas e se atribui ao card.
O que este servidor faz
Ferramenta MCP | Endpoint B-Ticket |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bticket_list_my_open_cards prefere board_uuid. Sem o UUID, lista os quadros e agrega até 8 boards — isso é mais pesado e deve ser evitado no dia a dia.
Host de produção
A API B-Ticket em produção é https://bticket.brediweb.com.br (sem barra no final). As rotas Laravel ficam em /api, por exemplo:
POST https://bticket.brediweb.com.br/api/user/login
GET https://bticket.brediweb.com.br/api/userUse esse valor em BTICKET_API_URL. Não coloque e-mail, senha nem token no git — só placeholders em .env.example.
Requisitos
Node.js 18+
Acesso HTTPS à API B-Ticket (
https://bticket.brediweb.com.brem produção)Credenciais Sanctum ou um token de longa duração
Setup
git clone https://github.com/Silvio-Batista/bticket-mcp.git
cd bticket-mcp
cp .env.example .env
npm install
npm run buildEdite .env (nunca commite este arquivo):
BTICKET_API_URL=https://bticket.brediweb.com.br
BTICKET_EMAIL=voce@empresa.com
BTICKET_PASSWORD=sua-senha
BTICKET_TOKEN=
PORT=3000BTICKET_API_URLé a origem sem barra final e sem/api. As chamadas vão para{BTICKET_API_URL}/api/...(produção:https://bticket.brediweb.com.br/api/user/login).Se
BTICKET_TOKENestiver preenchido, o login é ignorado e o token é usado emAuthorization: Bearer ….Sem token, o servidor faz
POST /api/user/logincom{ email, password }, lêresults.token(SanctumplainTextToken) e guarda o valor em memória até o processo reiniciar. Em401subsequente, tenta um novo login (somente quando o token não veio deBTICKET_TOKEN).
Scripts
Script | Uso |
| Compila TypeScript para |
| Transporte stdio (Cursor local) |
| Transporte Streamable HTTP ( |
| HTTP com reload ( |
| Smoke test com API Laravel mockada |
Uso local (stdio) no Cursor
Copie
.enve rodenpm run build.Em Cursor Settings → MCP (ou
~/.cursor/mcp.json/.cursor/mcp.json):
{
"mcpServers": {
"bticket": {
"command": "node",
"args": ["/caminho/absoluto/bticket-mcp/dist/index.js"],
"env": {
"BTICKET_API_URL": "https://bticket.brediweb.com.br",
"BTICKET_EMAIL": "voce@empresa.com",
"BTICKET_PASSWORD": "sua-senha"
}
}
}
}Equivalente com token estático:
{
"mcpServers": {
"bticket": {
"command": "node",
"args": ["/caminho/absoluto/bticket-mcp/dist/index.js"],
"env": {
"BTICKET_API_URL": "https://bticket.brediweb.com.br",
"BTICKET_TOKEN": "1|seu-token-sanctum"
}
}
}
}Reinicie o MCP no Cursor. Em Output → MCP Logs você deve ver a sessão stdio e as 10 tools.
Não use console.log no processo stdio: stdout é o protocolo MCP. Logs vão para stderr.
Deploy como MCP remoto (HTTPS)
O modo HTTP sobe:
GET /health— livenessPOST|GET|DELETE /mcp— Streamable HTTP (transporte atual, use esta URL no Cursor)GET /sse+POST /messages?sessionId=— SSE legado (clientes antigos)
npm run build
npm run start:httpO servidor escuta em 0.0.0.0:$PORT (default 3000). Coloque-o atrás de HTTPS (Railway, Render, Fly, Nginx, Cloudflare Tunnel, etc.) com as variáveis de ambiente acima. O processo autentica na API B-Ticket, não no cliente MCP: as credenciais ficam só no host.
URL pública esperada:
https://seu-mcp.example.com/mcpHealth check:
curl https://seu-mcp.example.com/healthConectar no Cursor (Add MCP Server / URL)
Publique o serviço com HTTPS.
Cursor → Settings → MCP → Add new MCP server (ou edite
mcp.json):
{
"mcpServers": {
"bticket": {
"url": "https://seu-mcp.example.com/mcp"
}
}
}Se o cliente só falar SSE antigo, use
https://seu-mcp.example.com/sse.Ative o servidor e confirme as tools
bticket_*.
O Grok Bot / Cloud Agent usa o mesmo URL HTTPS. Não coloque senha no mcp.json remoto: o MCP já autentica na API com o .env do host.
Filtros de cards
bticket_list_cards encaminha os query params oficiais:
busca, membro_id, etiqueta_id, cliente_id, projeto_id, coluna_id, data_prazo_de, data_prazo_ate, sem_data, atrasado, checklist_concluido, incluir_arquivados, page, per_page.
membro_id do usuário logado é o campo id de GET /api/user (inteiro numérico da API, enviado como string).
Erros da API
Falhas 401 / 422 / 500 voltam como resultado de tool com isError e o texto de messages, message ou errors do Laravel. Exemplo: credenciais inválidas → B-Ticket API HTTP 401: Suas credenciais estão incorretas.
Testes
npm install
npm test
npm run buildO smoke sobe um HTTP mock no estilo apiResponse do B-Ticket, valida login + cache de token, paths reais, as tools de leitura e a criação de card (horas + membro) via transporte in-memory do SDK.
Criar card e lançar horas
Use bticket_create_card no final de uma missão, por exemplo:
faça isso na tarefa X, projeto Sistema Secretaria, e depois crie um card para registrar 2 horas e o que foi feito
A tool resolve quadro/projeto/coluna por nome. Campos principais:
titulo— obrigatóriodescricao— texto puro (sem HTML) com o pedido e o que foi feitoqtd_horas— lança na API viaPUTqtd_horas(não manda hora no POST de criação)projetoouprojeto_idboard_uuidouboard(se só existir um quadro, usa ele)colunaoucoluna_id— se houver horas e a coluna não for informada, cai em Concluído
atribuir_a_mim vem ligado por padrão.
Segurança
.envestá no.gitignore. Só.env.examplecom placeholders entra no git.Prefira
BTICKET_TOKENde escopo limitado em produção.Hoste o MCP remoto só em HTTPS e em rede confiável: quem chama o MCP herda o acesso B-Ticket daquele processo.