blip-mcp
Enables sending messages to WhatsApp contacts through the Take Blip platform.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@blip-mcplist my contacts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
blip-mcp
An MCP server for the Take Blip platform. It exposes your Blip account to any MCP client (Claude Code, Claude Desktop, Cursor, …) over the stdio transport, on top of the official Blip HTTP / Command API.
You can:
Reach your Blip resources — contacts (CRM), key/value buckets, broadcast lists, schedules, and a generic escape hatch for anything else.
Ask your bot's AI / knowledge base a question (
blip_ask_ai).Send messages and mutate data — gated behind an explicit safety switch so you don't message real users by accident.
Built with
@modelcontextprotocol/sdk, TypeScript (strict),zodvalidation, per-request timeouts, retry-with-backoff, and secret redaction everywhere.
Requirements
Node.js 18.17+ (uses the built-in global
fetch).A Take Blip bot and its connection credentials (see below).
Related MCP server: WhatsApp MCP Stream
Install
Three ways for people to run it:
Straight from GitHub (no npm needed — works as soon as the repo is pushed):
npx -y github:Michaeltsg/mcp-blip --versionnpm clones, builds (via the
preparescript) and runs it. This is what the.mcp.jsonbelow uses.From npm (smoothest
npxUX) — once you publish it. Note: the nameblip-mcpis already taken on npm, so publish under a free name (this package is set up astake-blip-mcp) and usenpx -y take-blip-mcp.Clone & build (for development or a pinned local copy):
git clone https://github.com/Michaeltsg/mcp-blip.git cd mcp-blip && npm install && npm run build # then point .mcp.json at: node /abs/path/to/mcp-blip/dist/index.js
⚠️ Do not use a bare
npx blip-mcp— that pulls a different, unrelated package from npm. Always use thegithub:Michaeltsg/mcp-blipform (or your own published name).
Get your Blip credentials (portal step-by-step)
Open your bot in the Blip portal (https://blip.ai → your bot).
Go to Configurações (Settings) → Informações de conexão (Connection information).
Open the HTTP Endpoints section.
Copy the value of "Cabeçalho de autenticação (Authorization)" (Authorization header). It already looks like:
Key bWV1Ym90OmFiYzEyMy4uLg==That whole string is your
BLIP_AUTHORIZATION.Your contract id / shortname is the bot subdomain — it forms the host
https://<contract>.http.msging.net. Use it asBLIP_CONTRACT_ID.
Prefer not to copy the ready-made header? You can instead provide
BLIP_BOT_IDENTIFIER+BLIP_ACCESS_KEYand the server computesKey base64("<identifier>:<accessKey>")for you.
Multiple bots (multi-flow)
If your account has several bots (a router + sub-bots), add each as a flow. For EACH bot, repeat the credential steps above to get its name (the bot Id) and an access key:
BLIP_CONTRACT_ID=mycontract
BLIP_FLOW_NAME=my-router-bot
BLIP_AUTHORIZATION="Key ..." # default flow
BLIP_FLOW_1_NAME=my-subbot
BLIP_FLOW_1_AUTHORIZATION="Key ..."
BLIP_FLOW_2_NAME=another-bot
BLIP_FLOW_2_AUTHORIZATION="Key ..."blip_list_flows shows everything configured (names only). When you map a flow,
the server checks that each key's real identity matches its configured name.
Environment variables
Variable | Required | Default | Description |
| one of two modes | — | Ready-made header, e.g. |
| with access key | — | Bot identifier (credential mode 2). |
| with identifier | — | Access key (credential mode 2). |
| no | — | Contract / shortname → host |
| no | — | Alias for |
| no | derived | Full base URL override (rare). |
| no |
| Master switch for side-effecting tools. |
| no |
| Per-request timeout (ms). |
| no |
| Retries on 429/5xx/network errors. |
| no |
|
|
| no |
| Friendly name for the default flow (e.g. your bot Id). |
| no | — | Extra flows: |
| no |
| Where |
| no |
| Path to an env file to auto-load (real env always wins). |
| no |
| Base folder for everything blip-mcp writes. |
If no contract/host is given, the server falls back to the shared host
https://http.msging.net (for accounts not in an organization).
Safety: read-only by default
Every tool that sends a message or mutates data is gated by
BLIP_ALLOW_WRITES (default false). While off:
blip_send_message,blip_set_bucket,blip_set_contact,blip_delete_contactreturn a "READ-ONLY MODE" notice instead of running.blip_commandrefuses any method other thanget.
Start in read-only mode while you explore. Set BLIP_ALLOW_WRITES=true (and
restart the server) only when you're ready to cause real side effects.
Configure your MCP client
Project file .mcp.json (recommended)
Drop a .mcp.json at your project root (any MCP client picks it up). Keep your
secrets in a gitignored blip.env and point the server at it:
{
"mcpServers": {
"blip": {
"command": "npx",
"args": ["-y", "github:Michaeltsg/mcp-blip"],
"env": { "BLIP_ENV_FILE": "blip.env", "BLIP_ALLOW_WRITES": "false" }
}
}
}Then create blip.env next to it with your credentials. The server also
auto-loads ./blip.env even if you omit BLIP_ENV_FILE. See
.mcp.json.example. (Cursor uses .cursor/mcp.json, same shape.)
Claude Code
Local build (works today):
claude mcp add blip -s user \
-e BLIP_AUTHORIZATION="Key xxxxx" \
-e BLIP_CONTRACT_ID="meu-contrato" \
-e BLIP_ALLOW_WRITES="false" \
-- node /absolute/path/to/mcp-blip/dist/index.jsAfter publishing to npm, the same with npx:
claude mcp add blip -s user \
-e BLIP_AUTHORIZATION="Key xxxxx" \
-e BLIP_CONTRACT_ID="meu-contrato" \
-e BLIP_ALLOW_WRITES="false" \
-- npx -y github:Michaeltsg/mcp-blipClaude Desktop / Cursor (JSON)
Add to mcpServers (Claude Desktop: claude_desktop_config.json):
{
"mcpServers": {
"blip": {
"command": "node",
"args": ["/absolute/path/to/mcp-blip/dist/index.js"],
"env": {
"BLIP_AUTHORIZATION": "Key xxxxx",
"BLIP_CONTRACT_ID": "meu-contrato",
"BLIP_ALLOW_WRITES": "false"
}
}
}
}Once published, swap command/args for "command": "npx", "args": ["-y", "github:Michaeltsg/mcp-blip"].
Validate credentials (self-test)
BLIP_AUTHORIZATION="Key xxxxx" BLIP_CONTRACT_ID="meu-contrato" \
node dist/index.js --self-testIt performs a tiny GET /contacts?$take=1 and prints a masked config
summary plus OK/FAILED. Your token is never printed.
Tools
Read (safe, always available)
Tool | What it does |
| List CRM contacts. Args: |
| Get one contact by |
| Find a contact by phone (tries 55/+/local formats). |
| Read a value from key/value storage by |
| List broadcast/distribution lists. (experimental) |
| List recipients of a broadcast |
| List scheduled messages/commands. (experimental) |
| Ask your bot's AI. |
| Escape hatch: run any |
| Conversation history with a contact (what was said). |
| Recent conversations. |
| A contact's context variables — the values flow rules evaluate against. (experimental) |
| One context variable; |
| The published flow definition (blocks + conditions/rules). (experimental) |
| Event categories your flows track. (experimental) |
| Tracked events for a category (optional date range). (experimental) |
| List configured flows (names/hosts only, never secrets). |
| Read a flow and write componentized docs (index + one file per block) under |
Write (require BLIP_ALLOW_WRITES=true)
Tool | Side effect |
| Sends a message to a real recipient. |
| Writes a value to storage. |
| Creates/updates a contact ( |
| Permanently deletes a contact. |
Examples (natural language to your MCP client)
"List the first 5 Blip contacts that came from WhatsApp." →
blip_list_contacts { take: 5, filter: "substringof('WhatsApp',source)" }"Ask my bot's knowledge base: what are the opening hours?" →
blip_ask_ai { text: "what are the opening hours?", mode: "knowledge" }"Read bucket
onboarding_state." →blip_get_bucket { id: "onboarding_state" }"Run a raw command: get the active message templates." →
blip_command { method: "get", uri: "/templates" }(writes on) "Send 'Hi!' to 5511999999999 on WhatsApp." →
blip_send_message { to: "5511999999999@wa.gw.msging.net", content: "Hi!" }
Experimental / unverified endpoints
These were implemented from Blip's documented patterns and the official C# SDK, but not verified against a live account, so they're marked experimental:
AI / knowledge base (
blip_ask_ai):postmaster@ai.msging.net,SET /content/analysis(knowledge) andSET /analysis(intent), resource typeapplication/vnd.iris.ai.analysis-request+json. The exact content contract can vary per account.Broadcast lists (
blip_list_broadcast_lists,blip_list_recipients):postmaster@broadcast.msging.net,/listsand/lists/{id}/recipients.Schedules (
blip_list_schedules):postmaster@scheduler.msging.net,/schedules.
If any of these don't match your account, use blip_command with the exact
to/uri/resource from your Blip docs.
Buckets note: bucket commands are sent to your bot's own node (no
to/postmaster), which is the correct Blip behavior — this differs from thepostmaster@msging.netmentioned in some notes. Override withblip_commandif your setup needs it.
Debugging "why did this contact take this path?"
Blip's HTTP API does not expose a turn-by-turn condition-evaluation log, but you can reconstruct the decision from a few reads and let your MCP client diff them:
blip_get_flow— the exact condition/rule on the branch in question.blip_get_context { identity }— the contact's actual variable values that the rule evaluated against (andstateid@{flowId}for where they are now).blip_get_thread { identity }— what the user actually said / chose.(optional)
blip_get_event_track— milestones the flow logged.
Then ask, e.g.: "Why did 5511999999999 enter the Support flow instead of Sales?"
Your client reads the rule, sees (say) origem = WhatsApp-Ads in the context and
explains the match — or shows that the variable the rule needed was empty.
These journey tools are experimental and sent to your bot's own node (no postmaster). The richest turn-by-turn view is still the portal's conversation history / Builder debug tool; the API gives you the raw materials to reconstruct it.
Multiple flows & mapping a flow into docs
blip.env (or your MCP env) can hold several flows (Blip bots) — a parent
router plus its subflows, each with its own access key:
BLIP_CONTRACT_ID=mycontract
BLIP_FLOW_NAME=my-router
BLIP_AUTHORIZATION="Key ..." # default flow (the parent / router)
BLIP_FLOW_1_NAME=fila-identificada
BLIP_FLOW_1_AUTHORIZATION="Key ..." # a subflow bot (its own access key)blip_list_flowsshows what's configured (never the secrets).blip_map_flow { flow: "my-router" }reads the flow and writes a componentized doc tree underflows/<flow>/, so a large flow stays browsable:
.mcp-blip/flows/my-router/
index.md overview + routing graph (block -> who it connects to)
index.json machine-readable map
blocks/
inicio.md what the block does (messages, HTTP/script actions) + its rules
roteador-de-mensagem.md
...Re-run after editing the flow in Builder (idempotent). CLI: npm run map-flow -- --flow my-router.
The flows/ folder is gitignored by default (business logic). Mapping a subflow's
internals needs that subflow's own access key configured as an extra flow.
Where blip-mcp writes (.mcp-blip/)
Everything the server discovers or documents goes under a single .mcp-blip/
folder in your project root — e.g. blip_map_flow writes to
.mcp-blip/flows/<flow>/. This keeps blip-mcp's output namespaced and out of
the way when you connect it inside a new or existing repo.
Add it (and blip.env) to your project's .gitignore:
.mcp-blip/
blip.envOverride the base with BLIP_DATA_DIR.
How it works
Commands POST to https://<contract>.http.msging.net/commands with header
Authorization: Key <token> and a LIME-style envelope:
{
"id": "<uuid>",
"to": "postmaster@crm.msging.net",
"method": "get",
"uri": "/contacts?$skip=0&$take=20"
}A response with status: "failure" is converted into a clear error carrying
Blip's reason.code and reason.description. Messages POST to /messages.
Publishing to npm
A GitHub Action (.github/workflows/publish.yml) publishes the package whenever
you create a GitHub Release. One-time setup:
Create an npm account + an automation access token (npmjs.com → Access Tokens → Generate New Token → Automation).
Add it as a repo secret named
NPM_TOKEN:gh secret set NPM_TOKEN # paste the token when prompted(or GitHub → Settings → Secrets and variables → Actions).
Create a release — the Action runs typecheck + tests, builds, and publishes:
gh release create v0.1.0 --generate-notesFor later versions, bump first:
npm version patch && git push --follow-tags, then create the matching release.
The first publish claims the take-blip-mcp name. After that, users install with
npx -y take-blip-mcp. (A ci.yml workflow runs tests on every push/PR.)
Development
npm run dev # run from source via tsx
npm run build # compile to dist/
npm run typecheck # tsc --noEmit (strict)
npm test # vitest (header assembly, sendCommand, failure, guardrails)
npm run self-test # build first, then validate credentialsSecurity notes
Credentials come only from environment variables; nothing is hardcoded.
The authorization header value is never logged. All logs go to stderr (stdout is reserved for the MCP protocol) and pass through a redactor that scrubs the token and any
Key …pattern — even from error bodies.Writes are off by default (
BLIP_ALLOW_WRITES=false).
License
MIT © Michaeltsg. See LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Michaeltsg/mcp-blip'
If you have feedback or need assistance with the MCP directory API, please join our Discord server