From 9729a655b9704b8c1a1f2f73fdc8081d143f671f Mon Sep 17 00:00:00 2001 From: Liam Ilan Date: Wed, 14 Oct 2026 18:41:01 -0700 Subject: [PATCH] feat(third_party): add WhatsApp Business plugin --- .cursor-plugin/marketplace.json | 5 ++ README.md | 1 + .../.cursor-plugin/plugin.json | 63 ++++++++++++++ third_party/whatsapp-business/CHANGELOG.md | 11 +++ third_party/whatsapp-business/LICENSE | 21 +++++ third_party/whatsapp-business/README.md | 77 ++++++++++++++++++ third_party/whatsapp-business/assets/logo.png | Bin 0 -> 9738 bytes 7 files changed, 178 insertions(+) create mode 100644 third_party/whatsapp-business/.cursor-plugin/plugin.json create mode 100644 third_party/whatsapp-business/CHANGELOG.md create mode 100644 third_party/whatsapp-business/LICENSE create mode 100644 third_party/whatsapp-business/README.md create mode 100644 third_party/whatsapp-business/assets/logo.png diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json index 4c2f963ff..b8b863993 100644 --- a/.cursor-plugin/marketplace.json +++ b/.cursor-plugin/marketplace.json @@ -518,6 +518,11 @@ "source": "third_party/workday", "description": "Look up workers, organizations, time off, payroll, and recruiting data in Workday." }, + { + "name": "whatsapp-business", + "source": "third_party/whatsapp-business", + "description": "Send messages and manage templates, contacts, and phone numbers in WhatsApp Business." + }, { "name": "square", "source": "third_party/square", diff --git a/README.md b/README.md index 61eca8baf..b42a64469 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,7 @@ Official Cursor plugins for popular developer tools, frameworks, and SaaS produc | `shopify-store` | [Shopify](third_party/shopify-store/) | Cursor | Integrations | Connect your Shopify store so Grok can answer questions about products, orders, customers, inventory, and sales. | | `quickbooks-online` | [QuickBooks Online](third_party/quickbooks-online/) | Cursor | Integrations | Read invoices, bills, expenses, customers, accounts, and financial reports. | | `workday` | [Workday](third_party/workday/) | Cursor | Integrations | Look up workers, organizations, time off, payroll, and recruiting data in Workday. | +| `whatsapp-business` | [WhatsApp Business](third_party/whatsapp-business/) | Cursor | Integrations | Send messages and manage templates, contacts, and phone numbers in WhatsApp Business. | | `square` | [Square](third_party/square/) | Cursor | Integrations | Work with payments, orders, catalog, customers, and invoices. | | `tailscale` | [Tailscale](third_party/tailscale/) | Cursor | Integrations | Let Grok Bot reach MCP servers on your private Tailscale network. Sign in to Tailscale to connect your tailnet; Grok Bot joins it as one tagged device and only reaches the hosts you grant to tag:grokbot. | | `highlevel` | [HighLevel](third_party/highlevel/) | Cursor | Integrations | Work with contacts, conversations, opportunities, calendars, and payments. | diff --git a/third_party/whatsapp-business/.cursor-plugin/plugin.json b/third_party/whatsapp-business/.cursor-plugin/plugin.json new file mode 100644 index 000000000..373917f4b --- /dev/null +++ b/third_party/whatsapp-business/.cursor-plugin/plugin.json @@ -0,0 +1,63 @@ +{ + "name": "whatsapp-business", + "displayName": "WhatsApp Business", + "version": "1.0.0", + "minClientVersions": { + "cursor": "3.19.0" + }, + "description": "Send messages and manage templates, contacts, and phone numbers in WhatsApp Business.", + "author": { + "name": "Cursor", + "email": "plugins@cursor.com" + }, + "homepage": "https://github.com/cursor/plugins/tree/main/third_party/whatsapp-business", + "repository": "https://github.com/cursor/plugins", + "license": "MIT", + "logo": "assets/logo.png", + "keywords": [ + "whatsapp", + "whatsapp business", + "meta", + "messaging", + "mcp" + ], + "category": "integrations", + "tags": [ + "whatsapp", + "whatsapp business", + "meta", + "messaging", + "mcp" + ], + "variables": { + "type": "object", + "additionalProperties": false, + "required": [ + "WHATSAPP_BUSINESS_ACCOUNT_ID", + "WHATSAPP_BUSINESS_PHONE_NUMBER_ID", + "WHATSAPP_BUSINESS_ACCESS_TOKEN" + ], + "properties": { + "WHATSAPP_BUSINESS_ACCOUNT_ID": { + "type": "string", + "title": "WhatsApp Business Account ID", + "description": "Shown next to your account name in WhatsApp Manager.", + "minLength": 1 + }, + "WHATSAPP_BUSINESS_PHONE_NUMBER_ID": { + "type": "string", + "title": "Phone number ID", + "description": "The long numeric ID under Account tools > Phone numbers in WhatsApp Manager, not the phone number itself.", + "minLength": 1 + }, + "WHATSAPP_BUSINESS_ACCESS_TOKEN": { + "type": "string", + "title": "Access token", + "description": "A system user token with the whatsapp_business_messaging and whatsapp_business_management permissions.", + "writeOnly": true, + "format": "password", + "minLength": 1 + } + } + } +} diff --git a/third_party/whatsapp-business/CHANGELOG.md b/third_party/whatsapp-business/CHANGELOG.md new file mode 100644 index 000000000..eb7206e79 --- /dev/null +++ b/third_party/whatsapp-business/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog + +All notable changes to this plugin will be documented here. + +## 1.0.0 — initial release + +- Added the `whatsapp-business` plugin, the opt-in for the WhatsApp Business MCP server that Cursor hosts. +- Carries no MCP server definition: the server is Cursor-side, so installing the plugin is the whole configuration. +- Each member enters their own `WHATSAPP_BUSINESS_ACCOUNT_ID`, `WHATSAPP_BUSINESS_PHONE_NUMBER_ID`, and `WHATSAPP_BUSINESS_ACCESS_TOKEN`. These are per-member values, not team settings. +- The access token is a Meta system user token with the `whatsapp_business_messaging` and `whatsapp_business_management` permissions. +- Logo: WhatsApp's official mark, from `whatsapp.com`. diff --git a/third_party/whatsapp-business/LICENSE b/third_party/whatsapp-business/LICENSE new file mode 100644 index 000000000..ca2bba771 --- /dev/null +++ b/third_party/whatsapp-business/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Cursor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/third_party/whatsapp-business/README.md b/third_party/whatsapp-business/README.md new file mode 100644 index 000000000..b4e4e9ea5 --- /dev/null +++ b/third_party/whatsapp-business/README.md @@ -0,0 +1,77 @@ +# WhatsApp Business + +Cursor plugin that connects agents to [WhatsApp Business](https://business.whatsapp.com) — Meta's messaging platform for businesses — through a [Model Context Protocol](https://modelcontextprotocol.io/) server that Cursor hosts. + +Work with a WhatsApp Business Account: send messages from your business phone number, manage message templates, and look up contacts and phone numbers. + +## Install + +1. Open **Cursor Settings → Plugins**. +2. Search for **WhatsApp Business** and click **Install**. +3. Enter your WhatsApp Business Account ID, phone number ID, and access token (see [Before you connect](#before-you-connect)). + +Or run `/add-plugin whatsapp-business` in chat. + +## MCP + +This plugin ships no `mcp.json`, and that is deliberate. + +Every other connector in this repository either points at a vendor's hosted endpoint or runs a package locally over stdio, so it carries its own server definition. WhatsApp Business does not: Cursor runs the server, and the plugin exists only as the opt-in that turns it on for your account. There is no command to run and no MCP endpoint to configure. + +One consequence worth knowing: because the server is not declared here, you will not find it in a local `mcp.json` and you cannot point another MCP client at it. It is reachable from Cursor only. + +## Before you connect + +Each person who installs the plugin enters their own three values. These are per-member settings, so a team admin cannot set them for everyone. + +### 1. Create a system user token in Meta + +1. In [Meta Business Suite](https://business.facebook.com), open **Business settings → Users → System users** and add a system user, or pick an existing one. +2. Under **Assign assets**, give the system user access to your WhatsApp Business Account. +3. Click **Generate new token**, choose the Meta app connected to your WhatsApp Business Account, and select the `whatsapp_business_messaging` and `whatsapp_business_management` permissions. +4. Copy the token. Meta shows it only once. + +### 2. Find your IDs in WhatsApp Manager + +- **WhatsApp Business Account ID:** shown next to your account name in [WhatsApp Manager](https://business.facebook.com/wa/manage/home/). +- **Phone number ID:** the long numeric ID under **Account tools → Phone numbers**. Use the ID, not the phone number itself. + +### 3. Enter the values in Cursor + +All three fields are required: + +| Field | Value | +| --- | --- | +| `WHATSAPP_BUSINESS_ACCOUNT_ID` | WhatsApp Business Account ID from WhatsApp Manager. | +| `WHATSAPP_BUSINESS_PHONE_NUMBER_ID` | Phone number ID from **Account tools → Phone numbers**. Agents send messages from this number. | +| `WHATSAPP_BUSINESS_ACCESS_TOKEN` | The system user token from step 1. Treated as a secret and never shown back. | + +## What agents can do + +| Category | Capabilities | +| --- | --- | +| Messages | Send text and template messages from your business phone number | +| Templates | List and manage message templates | +| Contacts | Look up the contacts your business messages | +| Phone numbers | Read the phone numbers on your WhatsApp Business Account | + +The server is the source of truth for tool names and schemas. + +## Notes + +- Access follows the system user token. The connector can reach only the WhatsApp Business Accounts assigned to that system user, within the token's permissions. +- WhatsApp only allows free-form messages within 24 hours of a customer's last message. Outside that window, agents must send an approved template. +- Messages go out from your real business number and can incur Meta's messaging charges. Review what agents send. +- Disconnecting the connector in Cursor deletes your saved account ID, phone number ID, and access token. Revoking the token in Meta Business Settings ends Cursor's access to your account. + +## Docs + +- WhatsApp Business Platform: https://business.whatsapp.com +- WhatsApp Cloud API: https://developers.facebook.com/docs/whatsapp/cloud-api +- Model Context Protocol: https://modelcontextprotocol.io + +Logo is WhatsApp's official mark, from `whatsapp.com`. + +## License + +MIT diff --git a/third_party/whatsapp-business/assets/logo.png b/third_party/whatsapp-business/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..aca3c0ef0e00b624fb3f63cc5eb1ffbd5cb134a9 GIT binary patch literal 9738 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