• MIT
  • macOS 14+ · Apple Silicon
  • Local-first
  • v0.1.0 early

WhatsApp on your desk,wired for code and Claude.

ZapDesk is an open-source desktop app for macOS that runs entirely on your machine. Chat from several accounts, send personalized messages to lead lists, track deals on a Kanban — and let Claude do it for you through 69 MCP tools.

Apple Silicon · macOS 14+ · not notarized yet — see Quick start

The app UI is in Brazilian Portuguese.

// 01 — features

Everything on one desk

A full WhatsApp client plus the tools to work a lead list — all running on your Mac.

  • Multiple accounts

    Connect each number by QR code, like a linked device. Sessions persist between launches.

  • The full chat

    Groups, search, media, voice notes, quotes, reactions, edits, stickers, labels, notes and / templates. Voice and video calls are not supported.

  • Bulk send at your pace

    {nome} variables, attachments, scheduling, a sending window and random intervals with hourly and daily limits. Per-recipient report, exportable to CSV.

  • A lead base without duplicates

    Import CSV/XLSX, paste numbers or pick contacts. Every phone is normalized to E.164 and deduplicated, with a report of new, existing and invalid numbers.

  • An MCP server for Claude

    69 tools let Claude Code or Claude Desktop read conversations, import leads, create sends and move deals.

  • Sales funnels

    As many funnels as you need, with stages on a Kanban board and the history of every move.

  • No-code chatbots & flows

    Build menus, questions and hand-offs in a visual node editor, or trigger → condition → action flows. Test them in a simulated chat.

  • AI automations in TypeScript

    Write an automation as a small TypeScript project with a typed ctx API and Claude models. Each one runs in its own locked-down process.

// 02 — tour

A tour of the desk

What a working day looks like in ZapDesk. Real screens, fictional data.

Bulk send

Pace and schedule, your call

Pick the interval range, hourly and daily limits, pauses and a sending window. If the pace is aggressive the app tells you; you decide.

  • A random interval between your minimum and maximum, drawn for every message.
  • Hourly and daily limits, a pause every N messages and a stop after consecutive failures.
  • Start now or schedule the start, and only send inside a time window.
The app UI is in Brazilian Portuguese.

Report

Know what happened to every message

Sent, delivered, read, replied or failed — per recipient, live. Export the whole thing to CSV.

  • Live counters while the send is running.
  • The state of every recipient, with the reason when something fails.
  • One click exports the report to CSV.
The app UI is in Brazilian Portuguese.

Funnel

Deals on a board

Drag contacts across stages, or let an automation move them for you.

  • As many funnels as you need, each with its own stages.
  • Every move is kept in the funnel history.
  • Automations and Claude, through MCP, can move cards too.
The app UI is in Brazilian Portuguese.

// 03 — mcp

Hand the desk to Claude

ZapDesk ships an MCP server. Add it to Claude Code or Claude Desktop and Claude can work the app with the same tools you have.

69

tools in 10 groups

Every tool, by group

  • Accounts & system2
    • listar_contas
    • status_zapdesk
  • Leads2
    • importar_leads
    • listar_leads
  • Conversations9
    • listar_conversas
    • ler_mensagens
    • buscar_mensagens
    • enviar_mensagem
    • reagir_mensagem
    • editar_mensagem
    • apagar_mensagem
    • marcar_como_lida
    • ver_status
  • Contacts & labels6
    • listar_contatos
    • atualizar_contato
    • listar_etiquetas
    • criar_etiqueta
    • atualizar_etiqueta
    • excluir_etiqueta
  • Templates4
    • listar_templates
    • criar_template
    • atualizar_template
    • excluir_template
  • Bulk sends8
    • criar_disparo
    • listar_disparos
    • ver_disparo
    • iniciar_disparo
    • pausar_disparo
    • retomar_disparo
    • cancelar_disparo
    • exportar_relatorio
  • Funnel10
    • listar_funis
    • criar_funil
    • editar_funil
    • excluir_etapa
    • excluir_funil
    • listar_cards_funil
    • mover_card_funil
    • remover_card_funil
    • historico_funil
    • atualizar_lead
  • Automations12
    • listar_automacoes
    • ver_automacao
    • ver_formatos_automacao
    • criar_automacao
    • editar_automacao
    • validar_automacao
    • excluir_automacao
    • ativar_automacao
    • desativar_automacao
    • executar_automacao
    • testar_automacao
    • simular_chatbot
  • AI automations (code)9
    • ver_tipos_sdk
    • listar_modelos_automacao_ia
    • criar_automacao_ia
    • listar_arquivos_automacao
    • ler_arquivo_automacao
    • escrever_arquivo_automacao
    • renomear_arquivo_automacao
    • excluir_arquivo_automacao
    • compilar_automacao
  • Runs & safety7
    • listar_execucoes
    • ver_execucao
    • listar_pausas
    • pausar_conversa
    • retomar_conversa
    • listar_segredos
    • ver_configuracao_automacoes

What MCP can't do

  • Connect or remove accounts (QR only, in the app).
  • Set secret values.
  • Change global limits.

Sends created through MCP start right away, without a confirmation step — review the prompt before you run it.

// 04 — automations

Automate without giving up control

Three ways to automate, from drag-and-drop to code.

  • Flows

    Trigger → conditions → actions, including waits that survive restarts.

  • Chatbots

    A visual node editor with menus, questions, conditions and hand-off to a human.

  • AI (code)

    A TypeScript project per automation, with the typed ctx SDK and Claude models.

The app UI is in Brazilian Portuguese.

Classify a lead and move it on the funnel

Real template shipped with the app: motor/internal/automacoes/projetos/modelos/classificar_funil/index.ts

motor/internal/automacoes/projetos/modelos/classificar_funil/index.ts
import { definirAutomacao } from '@zapdesk/automacao';
import { ACOES, CATEGORIAS, FUNIL } from './categorias';

// Classifica o contato pelas últimas mensagens e move o lead no funil, com uma etiqueta.
// Não envia nada ao contato.
export default definirAutomacao({
  async aoReceberMensagem(ctx, msg) {
    if (!msg.texto || !ctx.conversa) return;
    const historico = await ctx.conversa.historicoParaIA({ limite: 10 });
    const texto = historico.map((m) => `${m.papel === 'user' ? 'Contato' : 'Loja'}: ${m.texto}`).join('\n');
    const { categoria } = await ctx.ia.classificar(texto, CATEGORIAS, {
      instrucoes: 'Classifique o interesse de compra do contato. Na dúvida, escolha "morno".',
    });
    const acao = ACOES[categoria];
    await ctx.funil.mover(FUNIL, acao.etapa);
    await ctx.etiquetas.adicionar(acao.etiqueta);
    ctx.log.info('classificado como', categoria);
  },
});

automacao.json

Triggers
mensagem_recebida
Permissions
ler_conversasfuniletiquetasia
Limits
60 s256 MB

How AI automations are isolated

  • Each AI automation runs in its own Node process and talks to the engine only over JSON-RPC on stdio.
  • Node's permission model is on: no file access outside the bundle, no child processes.
  • No global fetch, empty process.env, no API token, no Anthropic key in the process.
  • Every ctx call is checked against the permissions declared in automacao.json.
  • 60 s and ~256 MB per run.

Safeguards for every automation

  • At most 10 automatic messages per conversation every 10 minutes.
  • Replying by hand pauses automations in that chat for 30 minutes.
  • Groups are off by default.
  • An automation turns itself off after 5 errors in a row.
  • Nothing runs while the app is closed.

Isolation protects against mistakes and accidents, not against malicious code. Only run automations you trust.

// 05 — architecture

Local by design

Every piece runs on your Mac and talks over 127.0.0.1. No cloud in the middle.

Architecture diagram: the ZapDesk app, the MCP server and the automation runners all talk to the Go engine on 127.0.0.1; the engine stores data in SQLite and connects to WhatsApp through whatsmeow.
  1. The app talks to the engine over HTTP + WebSocket on 127.0.0.1 with a per-launch token.
  2. The engine connects to WhatsApp as a linked device, through whatsmeow.
  3. The engine stores everything in a local SQLite database.
  4. Claude Code or Claude Desktop start the MCP server over stdio.
  5. The MCP server calls the same local API as the app.
  6. Each AI automation runs in its own process and reaches the engine only through JSON-RPC on stdio.

What "local" means here

  • Opening the app starts the engine; closing it shuts everything down.
  • No cloud server, no Docker, no account to create.
  • Local API on 127.0.0.1, random port, new token every launch.
  • Your data lives in SQLite on your Mac. No telemetry.
  • If a send is running when you quit, the app waits in the menu bar until it finishes.

// 06 — quick start

Quick start

Download the app, or build it from source — then connect it to Claude.

Download

Install the DMG

Requirements
  • Apple Silicon (M1 or later)
  • macOS 14+
  1. Download ZapDesk-<version>-arm64.dmg from GitHub Releases.

  2. Drag ZapDesk to Applications.

  3. The build is not notarized yet: open it once, then go to System Settings › Privacy & Security and click "Open Anyway".

  4. Scan the QR code with your phone (Linked devices).

Build from source

Run it from the repository

Requirements
  • Node ≥ 22.12
  • Go 1.27
  • macOS on Apple Silicon
  1. Clone the repository and install the dependencies.

  2. npm run dev compiles the Go engine and the shared packages, then starts the app.

  3. npm run empacotar builds the DMG in app/dist/ (optional).

Terminal
git clone https://github.com/Gabriel-Almeida0/zapdesk.git
cd zapdesk
npm install
npm run dev            # compiles the Go engine + shared packages, then starts the app
npm run empacotar      # optional: builds app/dist/ZapDesk-<version>-arm64.dmg

Connect to Claude

Add the MCP server

Claude Code

Run this once.

Terminal
claude mcp add -s user -e ELECTRON_RUN_AS_NODE=1 zapdesk -- \
  "/Applications/ZapDesk.app/Contents/MacOS/ZapDesk" \
  "/Applications/ZapDesk.app/Contents/Resources/mcp/zapdesk-mcp.mjs"
claude mcp list

Claude Desktop

Add this to claude_desktop_config.json and restart Claude.

Config file~/Library/Application Support/Claude/claude_desktop_config.json

claude_desktop_config.json
{
  "mcpServers": {
    "zapdesk": {
      "command": "/Applications/ZapDesk.app/Contents/MacOS/ZapDesk",
      "args": ["/Applications/ZapDesk.app/Contents/Resources/mcp/zapdesk-mcp.mjs"],
      "env": { "ELECTRON_RUN_AS_NODE": "1" }
    }
  }
}

The same commands are in the app under Ajustes › Usar com Claude. No separate Node install needed.

// 07 — responsible use

Responsible use

Read this before you connect a number.

  • Unofficial client

    ZapDesk connects through whatsmeow, an open-source, unofficial implementation of the WhatsApp multi-device protocol.

  • Not affiliated

    ZapDesk is not affiliated with, endorsed by or sponsored by WhatsApp or Meta. "WhatsApp" is a trademark of its owner.

  • Your number can be banned

    WhatsApp may restrict or ban numbers that send unsolicited messages. You are responsible for how you use the app.

  • Consent and the law

    Message only people who agreed to hear from you, and follow the LGPD, the GDPR and WhatsApp's terms.

  • Your data stays on your Mac

    Conversations, leads and reports are stored locally. Nothing is sent to a ZapDesk server — there isn’t one.

  • As is, MIT

    The software is provided "as is", without warranty of any kind, under the MIT License.

// 08 — open source

Open source, MIT

Read the code, open an issue, send a pull request. The specs that guided the build are in the repo.

Built with

  • Goengine
  • Electrondesktop app
  • Reactinterface
  • TypeScriptMCP server and automation SDK
  • SQLitelocal database

How to contribute

  • Report bugs and ideas in Issues.
  • Read docs/features and specs/ before larger changes.
  • Run npm test and npm run motor:testar before a PR.

Status

v0.1.0 — early

Not yet

  • Notarized builds
  • Windows and Linux