@coldbirds/mcp-server 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +594 -0
- package/dist/tools.js +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,594 @@
|
|
|
1
|
+
# @coldbirds/mcp-server
|
|
2
|
+
|
|
3
|
+
> **Control your ColdBirds Sequence cold-email workspace from any AI assistant that speaks the [Model Context Protocol](https://modelcontextprotocol.io).**
|
|
4
|
+
|
|
5
|
+
Manage campaigns, contacts, mailboxes, enrollments, events, and webhooks by chatting with Claude Desktop, Cursor, Windsurf, Cline, Continue, or any custom MCP client — no manual API calls, no clicking through the UI.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@coldbirds/mcp-server)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](https://nodejs.org)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
1. [What you get](#what-you-get)
|
|
16
|
+
2. [Prerequisites](#prerequisites)
|
|
17
|
+
3. [Quick start (60 seconds)](#quick-start-60-seconds)
|
|
18
|
+
4. [Integration guides](#integration-guides)
|
|
19
|
+
- [Claude Desktop](#-claude-desktop)
|
|
20
|
+
- [Cursor](#-cursor)
|
|
21
|
+
- [Windsurf](#-windsurf)
|
|
22
|
+
- [Cline (VS Code)](#-cline-vs-code)
|
|
23
|
+
- [Continue (VS Code / JetBrains)](#-continue-vs-code--jetbrains)
|
|
24
|
+
- [Zed](#-zed)
|
|
25
|
+
- [Custom / CLI clients](#-custom--cli-clients)
|
|
26
|
+
5. [Available tools](#available-tools)
|
|
27
|
+
6. [Example prompts](#example-prompts)
|
|
28
|
+
7. [Real-world use cases](#real-world-use-cases)
|
|
29
|
+
8. [Configuration reference](#configuration-reference)
|
|
30
|
+
9. [Troubleshooting](#troubleshooting)
|
|
31
|
+
10. [How it works](#how-it-works)
|
|
32
|
+
11. [Security notes](#security-notes)
|
|
33
|
+
12. [Contributing](#contributing)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## What you get
|
|
38
|
+
|
|
39
|
+
After installing this server, your AI assistant gains **40 typed tools** for ColdBirds Sequence:
|
|
40
|
+
|
|
41
|
+
| Surface | Examples |
|
|
42
|
+
|---|---|
|
|
43
|
+
| **Campaigns** | list, get, pause, resume, duplicate, update settings, intelligence, variables |
|
|
44
|
+
| **Steps** | list / create / update / delete steps in a sequence |
|
|
45
|
+
| **Contacts** | list, get, create, update, delete + lists & list-membership |
|
|
46
|
+
| **Enrollments** | enroll, list, pause/resume per-contact |
|
|
47
|
+
| **Mailboxes** | list, get, create, update, delete sender mailboxes |
|
|
48
|
+
| **Events** | list opens / clicks / replies / bounces / unsubscribes |
|
|
49
|
+
| **Webhooks** | list, get, test |
|
|
50
|
+
| **Account** | who-am-I |
|
|
51
|
+
|
|
52
|
+
Each tool is backed by the official [ColdBirds public REST API](https://sequencer.coldbirds.com/api/docs) and uses the same authentication and rate limits as the dashboard.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Prerequisites
|
|
57
|
+
|
|
58
|
+
- **Node.js 18+** (run `node -v` to check)
|
|
59
|
+
- **A ColdBirds account** — sign up free at [coldbirds.com](https://coldbirds.com)
|
|
60
|
+
- **An API key** — generate one in [Settings → API Keys](https://sequencer.coldbirds.com/settings/api). Format: `sk_live_...`
|
|
61
|
+
|
|
62
|
+
> Keys are workspace-scoped. The MCP server can only see / modify resources owned by the workspace that issued the key.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Quick start (60 seconds)
|
|
67
|
+
|
|
68
|
+
Install globally and verify the server starts:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install -g @coldbirds/mcp-server
|
|
72
|
+
COLDBIRDS_API_KEY="sk_live_..." coldbirds-mcp
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Or run on-demand without installing (recommended for MCP clients — they spawn a fresh process per session):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx -y @coldbirds/mcp-server
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You should see the server idle on stdio. Press `Ctrl+C` to stop. Now wire it into the AI client of your choice — see [Integration guides](#integration-guides).
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Integration guides
|
|
86
|
+
|
|
87
|
+
> Every client below uses the same launch command: `npx -y @coldbirds/mcp-server`, with `COLDBIRDS_API_KEY` injected via environment.
|
|
88
|
+
|
|
89
|
+
### 🤖 Claude Desktop
|
|
90
|
+
|
|
91
|
+
**Config file path:**
|
|
92
|
+
|
|
93
|
+
| OS | Path |
|
|
94
|
+
|---|---|
|
|
95
|
+
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
|
|
96
|
+
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
|
|
97
|
+
| Linux | `~/.config/Claude/claude_desktop_config.json` |
|
|
98
|
+
|
|
99
|
+
Add a `mcpServers` entry:
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"mcpServers": {
|
|
104
|
+
"coldbirds": {
|
|
105
|
+
"command": "npx",
|
|
106
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
107
|
+
"env": {
|
|
108
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Restart Claude Desktop. Click the **🔌 plug icon** in the chat input — you should see `coldbirds` listed with 40 tools available.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### ⚡ Cursor
|
|
120
|
+
|
|
121
|
+
Open **Settings → Cursor Settings → MCP** (or edit `~/.cursor/mcp.json`):
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"coldbirds": {
|
|
127
|
+
"command": "npx",
|
|
128
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
129
|
+
"env": {
|
|
130
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Reload Cursor. In Composer / Chat, type `@coldbirds` to invoke tools manually, or just ask in plain English ("pause the Q3 outreach campaign") — Cursor will pick the right tool automatically.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### 🌊 Windsurf
|
|
142
|
+
|
|
143
|
+
Edit `~/.codeium/windsurf/mcp_config.json`:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"mcpServers": {
|
|
148
|
+
"coldbirds": {
|
|
149
|
+
"command": "npx",
|
|
150
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
151
|
+
"env": {
|
|
152
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Restart Windsurf. Tools appear in Cascade's tool picker.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### 🧩 Cline (VS Code)
|
|
164
|
+
|
|
165
|
+
Install the [Cline extension](https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev), then open the Cline panel → **MCP Servers** → **Edit Config**:
|
|
166
|
+
|
|
167
|
+
```json
|
|
168
|
+
{
|
|
169
|
+
"mcpServers": {
|
|
170
|
+
"coldbirds": {
|
|
171
|
+
"command": "npx",
|
|
172
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
173
|
+
"env": {
|
|
174
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
175
|
+
},
|
|
176
|
+
"disabled": false,
|
|
177
|
+
"autoApprove": []
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
> Leave `autoApprove: []` so destructive tools (`delete_contact`, `pause_campaign`, etc.) require an explicit confirmation click.
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### 🔧 Continue (VS Code / JetBrains)
|
|
188
|
+
|
|
189
|
+
Edit `~/.continue/config.json` and add to the `mcpServers` array:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"mcpServers": [
|
|
194
|
+
{
|
|
195
|
+
"name": "coldbirds",
|
|
196
|
+
"command": "npx",
|
|
197
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
198
|
+
"env": {
|
|
199
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Reload Continue (`Cmd+Shift+P` → **Continue: Reload**).
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### 📝 Zed
|
|
211
|
+
|
|
212
|
+
Open `~/.config/zed/settings.json` and add:
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
{
|
|
216
|
+
"context_servers": {
|
|
217
|
+
"coldbirds": {
|
|
218
|
+
"command": {
|
|
219
|
+
"path": "npx",
|
|
220
|
+
"args": ["-y", "@coldbirds/mcp-server"],
|
|
221
|
+
"env": {
|
|
222
|
+
"COLDBIRDS_API_KEY": "sk_live_..."
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Restart Zed. Use `/coldbirds` in the assistant panel.
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
### 🛠 Custom / CLI clients
|
|
235
|
+
|
|
236
|
+
Any client that supports the MCP **stdio transport** will work. Spawn the server like this:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
import { spawn } from "node:child_process";
|
|
240
|
+
|
|
241
|
+
const server = spawn("npx", ["-y", "@coldbirds/mcp-server"], {
|
|
242
|
+
env: { ...process.env, COLDBIRDS_API_KEY: "sk_live_..." },
|
|
243
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Speak JSON-RPC 2.0 over server.stdin / server.stdout
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Or use the official SDK directly:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
253
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
254
|
+
|
|
255
|
+
const transport = new StdioClientTransport({
|
|
256
|
+
command: "npx",
|
|
257
|
+
args: ["-y", "@coldbirds/mcp-server"],
|
|
258
|
+
env: { COLDBIRDS_API_KEY: process.env.COLDBIRDS_API_KEY! },
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
const client = new Client({ name: "my-app", version: "1.0.0" });
|
|
262
|
+
await client.connect(transport);
|
|
263
|
+
|
|
264
|
+
const tools = await client.listTools();
|
|
265
|
+
console.log(tools.tools.map((t) => t.name)); // 40 tool names
|
|
266
|
+
|
|
267
|
+
const result = await client.callTool({
|
|
268
|
+
name: "list_campaigns",
|
|
269
|
+
arguments: { limit: 10, status: "ACTIVE" },
|
|
270
|
+
});
|
|
271
|
+
console.log(result.content);
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
For interactive exploration, install the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
npx @modelcontextprotocol/inspector npx -y @coldbirds/mcp-server
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
This opens a browser UI where you can call every tool and inspect inputs/outputs.
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Available tools
|
|
285
|
+
|
|
286
|
+
40 tools, grouped by surface. Every tool's `inputSchema` is strict — unknown keys are rejected so your assistant gets accurate validation errors.
|
|
287
|
+
|
|
288
|
+
<details>
|
|
289
|
+
<summary><b>👤 Account (1)</b></summary>
|
|
290
|
+
|
|
291
|
+
| Tool | Method | Path |
|
|
292
|
+
|---|---|---|
|
|
293
|
+
| `get_account` | GET | `/api/v1/me` |
|
|
294
|
+
|
|
295
|
+
</details>
|
|
296
|
+
|
|
297
|
+
<details>
|
|
298
|
+
<summary><b>📣 Campaigns (10)</b></summary>
|
|
299
|
+
|
|
300
|
+
| Tool | Method | Path |
|
|
301
|
+
|---|---|---|
|
|
302
|
+
| `list_campaigns` | GET | `/api/v1/campaigns` |
|
|
303
|
+
| `get_campaign` | GET | `/api/v1/campaigns/{id}` |
|
|
304
|
+
| `update_campaign` | PATCH | `/api/v1/campaigns/{id}` |
|
|
305
|
+
| `pause_campaign` | POST | `/api/v1/campaigns/{id}/pause` |
|
|
306
|
+
| `resume_campaign` | POST | `/api/v1/campaigns/{id}/resume` |
|
|
307
|
+
| `duplicate_campaign` | POST | `/api/v1/campaigns/{id}/duplicate` |
|
|
308
|
+
| `get_campaign_stats` | GET | `/api/v1/campaigns/{id}/stats` |
|
|
309
|
+
| `get_campaign_settings` | GET | `/api/v1/campaigns/{id}/settings` |
|
|
310
|
+
| `update_campaign_settings` | PATCH | `/api/v1/campaigns/{id}/settings` |
|
|
311
|
+
| `get_campaign_intelligence` | GET | `/api/v1/campaigns/{id}/intelligence` |
|
|
312
|
+
| `update_campaign_intelligence` | PATCH | `/api/v1/campaigns/{id}/intelligence` |
|
|
313
|
+
|
|
314
|
+
</details>
|
|
315
|
+
|
|
316
|
+
<details>
|
|
317
|
+
<summary><b>🪜 Steps (4)</b></summary>
|
|
318
|
+
|
|
319
|
+
| Tool | Method | Path |
|
|
320
|
+
|---|---|---|
|
|
321
|
+
| `list_campaign_steps` | GET | `/api/v1/campaigns/{campaignId}/steps` |
|
|
322
|
+
| `create_campaign_step` | POST | `/api/v1/campaigns/{campaignId}/steps` |
|
|
323
|
+
| `update_campaign_step` | PATCH | `/api/v1/campaigns/{campaignId}/steps/{stepId}` |
|
|
324
|
+
| `delete_campaign_step` | DELETE | `/api/v1/campaigns/{campaignId}/steps/{stepId}` |
|
|
325
|
+
|
|
326
|
+
</details>
|
|
327
|
+
|
|
328
|
+
<details>
|
|
329
|
+
<summary><b>👥 Contacts & Lists (9)</b></summary>
|
|
330
|
+
|
|
331
|
+
| Tool | Method | Path |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `list_contacts` | GET | `/api/v1/contacts` |
|
|
334
|
+
| `get_contact` | GET | `/api/v1/contacts/{id}` |
|
|
335
|
+
| `create_contact` | POST | `/api/v1/contacts` |
|
|
336
|
+
| `update_contact` | PATCH | `/api/v1/contacts/{id}` |
|
|
337
|
+
| `delete_contact` | DELETE | `/api/v1/contacts/{id}` |
|
|
338
|
+
| `list_contact_lists` | GET | `/api/v1/lists` |
|
|
339
|
+
| `create_contact_list` | POST | `/api/v1/lists` |
|
|
340
|
+
| `list_contacts_in_list` | GET | `/api/v1/lists/{listId}/contacts` |
|
|
341
|
+
| `remove_contact_from_list` | DELETE | `/api/v1/lists/{listId}/contacts/{contactId}` |
|
|
342
|
+
|
|
343
|
+
</details>
|
|
344
|
+
|
|
345
|
+
<details>
|
|
346
|
+
<summary><b>📬 Enrollments (5)</b></summary>
|
|
347
|
+
|
|
348
|
+
| Tool | Method | Path |
|
|
349
|
+
|---|---|---|
|
|
350
|
+
| `enroll_contacts` | POST | `/api/v1/campaigns/{campaignId}/enrollments` |
|
|
351
|
+
| `list_enrollments` | GET | `/api/v1/campaigns/{campaignId}/enrollments` |
|
|
352
|
+
| `get_enrollment` | GET | `/api/v1/enrollments/{id}` |
|
|
353
|
+
| `pause_enrollment` | POST | `/api/v1/enrollments/{id}/pause` |
|
|
354
|
+
| `resume_enrollment` | POST | `/api/v1/enrollments/{id}/resume` |
|
|
355
|
+
|
|
356
|
+
</details>
|
|
357
|
+
|
|
358
|
+
<details>
|
|
359
|
+
<summary><b>📮 Mailboxes (5)</b></summary>
|
|
360
|
+
|
|
361
|
+
| Tool | Method | Path |
|
|
362
|
+
|---|---|---|
|
|
363
|
+
| `list_mailboxes` | GET | `/api/v1/mailboxes` |
|
|
364
|
+
| `get_mailbox` | GET | `/api/v1/mailboxes/{id}` |
|
|
365
|
+
| `create_mailbox` | POST | `/api/v1/mailboxes` |
|
|
366
|
+
| `update_mailbox` | PATCH | `/api/v1/mailboxes/{id}` |
|
|
367
|
+
| `delete_mailbox` | DELETE | `/api/v1/mailboxes/{id}` |
|
|
368
|
+
|
|
369
|
+
</details>
|
|
370
|
+
|
|
371
|
+
<details>
|
|
372
|
+
<summary><b>📊 Events & Webhooks (4)</b></summary>
|
|
373
|
+
|
|
374
|
+
| Tool | Method | Path |
|
|
375
|
+
|---|---|---|
|
|
376
|
+
| `list_events` | GET | `/api/v1/events` |
|
|
377
|
+
| `list_webhooks` | GET | `/api/v1/webhooks` |
|
|
378
|
+
| `get_webhook` | GET | `/api/v1/webhooks/{id}` |
|
|
379
|
+
| `test_webhook` | POST | `/api/v1/webhooks/{id}/test` |
|
|
380
|
+
|
|
381
|
+
</details>
|
|
382
|
+
|
|
383
|
+
<details>
|
|
384
|
+
<summary><b>🧩 Misc (1)</b></summary>
|
|
385
|
+
|
|
386
|
+
| Tool | Method | Path |
|
|
387
|
+
|---|---|---|
|
|
388
|
+
| `get_campaign_variables` | GET | `/api/v1/campaigns/{campaignId}/variables` |
|
|
389
|
+
|
|
390
|
+
</details>
|
|
391
|
+
|
|
392
|
+
The live, machine-readable tool catalogue lives at **<https://sequencer.coldbirds.com/mcp.json>**.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Example prompts
|
|
397
|
+
|
|
398
|
+
Just talk to your assistant in plain English. It will pick the right tool, ask for confirmation on destructive actions, and chain calls when needed.
|
|
399
|
+
|
|
400
|
+
### 🔎 Insights
|
|
401
|
+
|
|
402
|
+
> "Show me my top 5 campaigns by reply rate this month."
|
|
403
|
+
|
|
404
|
+
> "Which mailboxes had deliverability issues in the last 7 days?"
|
|
405
|
+
|
|
406
|
+
> "Summarise opens, clicks, and replies for the Q3 founder outreach campaign."
|
|
407
|
+
|
|
408
|
+
> "Pull the 10 most recent bounces and group them by mailbox."
|
|
409
|
+
|
|
410
|
+
### ✏️ Campaign management
|
|
411
|
+
|
|
412
|
+
> "Pause all campaigns sending from `dharm@coldbirds.com` — that mailbox needs a break."
|
|
413
|
+
|
|
414
|
+
> "Duplicate the 'SaaS CEOs - Cycle 4' campaign, rename to 'Cycle 5', and update step 2's subject to 'One quick question, {{first_name}}'."
|
|
415
|
+
|
|
416
|
+
> "In the 'Series A Founders' sequence, change the wait between step 3 and step 4 from 3 days to 5 business days."
|
|
417
|
+
|
|
418
|
+
> "Show me the variables available in campaign `cmp_abc123` and tell me which ones are unused in any step."
|
|
419
|
+
|
|
420
|
+
### 👥 Contact ops
|
|
421
|
+
|
|
422
|
+
> "Find every contact at `acme.com` and add them to the list 'ACME — Q3 push'."
|
|
423
|
+
|
|
424
|
+
> "Create a new contact: Jane Doe, jane@example.com, CTO at Example Corp, then enroll her in campaign `cmp_xyz789` starting today."
|
|
425
|
+
|
|
426
|
+
> "Delete contact `con_def456` — they unsubscribed via reply."
|
|
427
|
+
|
|
428
|
+
### 📮 Mailbox ops
|
|
429
|
+
|
|
430
|
+
> "List all mailboxes that aren't currently warming up."
|
|
431
|
+
|
|
432
|
+
> "Update the daily-send-limit on every mailbox tagged `tier-1-senders` to 80."
|
|
433
|
+
|
|
434
|
+
> "Connect a new SMTP mailbox: smtp.fastmail.com:465, user `outreach@mybrand.com`, then send a test."
|
|
435
|
+
|
|
436
|
+
### 🛠 Webhook / integrations
|
|
437
|
+
|
|
438
|
+
> "List my webhooks. For each, run `test_webhook` and report which ones don't return 200."
|
|
439
|
+
|
|
440
|
+
### 🧠 Agentic workflows
|
|
441
|
+
|
|
442
|
+
> "Every Monday at 9am, summarise last week's campaign performance, pause anything with <2% reply rate, and post a one-paragraph standup to my notes."
|
|
443
|
+
|
|
444
|
+
> "I'm replying to a prospect. Pull their enrollment history, last event, and the original cold email I sent so I have full context."
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## Real-world use cases
|
|
449
|
+
|
|
450
|
+
### 1. Morning ops standup (read-only)
|
|
451
|
+
|
|
452
|
+
> "Give me a 5-bullet brief: total sends yesterday, reply rate, any mailbox health alerts, top 3 replied campaigns, and any contacts that bounced more than once this week."
|
|
453
|
+
|
|
454
|
+
The assistant chains `list_campaigns` → `get_campaign_stats` → `list_mailboxes` → `list_events?type=BOUNCED` and assembles a report in seconds.
|
|
455
|
+
|
|
456
|
+
### 2. Reply triage from your inbox
|
|
457
|
+
|
|
458
|
+
Pair the MCP server with a Gmail / Outlook tool in the same client. When a prospect replies, ask:
|
|
459
|
+
|
|
460
|
+
> "@coldbirds find this contact, show their enrollment status, and pause any future steps for them in campaign X."
|
|
461
|
+
|
|
462
|
+
### 3. Bulk campaign edits from spec
|
|
463
|
+
|
|
464
|
+
Paste a markdown spec ("rewrite step 2 to be more concise, change wait to 4 days, add a P.S. line") and let the assistant call `update_campaign_step` to apply the edits — no copy-paste through the UI.
|
|
465
|
+
|
|
466
|
+
### 4. List hygiene
|
|
467
|
+
|
|
468
|
+
> "Find contacts in my workspace that have bounced in the last 30 days and remove them from all active lists."
|
|
469
|
+
|
|
470
|
+
The assistant uses `list_events?type=BOUNCED` → `list_contact_lists` → `remove_contact_from_list` in a loop.
|
|
471
|
+
|
|
472
|
+
### 5. Cross-tool agents (Notion / Linear / GitHub)
|
|
473
|
+
|
|
474
|
+
Combine with other MCP servers — e.g. when a Linear issue tagged `outreach` is created, your agent can run `duplicate_campaign` + `enroll_contacts` based on the issue body.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## Configuration reference
|
|
479
|
+
|
|
480
|
+
| Variable | Required | Default | Description |
|
|
481
|
+
|---|---|---|---|
|
|
482
|
+
| `COLDBIRDS_API_KEY` | ✅ | — | Your `sk_live_...` key from [Settings → API Keys](https://sequencer.coldbirds.com/settings/api). |
|
|
483
|
+
| `COLDBIRDS_API_URL` | ❌ | `https://sequencer.coldbirds.com` | Override only for self-hosted or staging deployments. |
|
|
484
|
+
|
|
485
|
+
The server **fetches its tool catalogue** from `${COLDBIRDS_API_URL}/mcp.json` at startup (5 s timeout). If the live manifest is unreachable or fails validation, it falls back to a snapshot bundled inside this package — so the server always starts even when offline.
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Troubleshooting
|
|
490
|
+
|
|
491
|
+
<details>
|
|
492
|
+
<summary><b>Claude Desktop shows 0 tools or the connector is red.</b></summary>
|
|
493
|
+
|
|
494
|
+
1. Quit Claude Desktop completely (`Cmd+Q` on macOS, not just close the window).
|
|
495
|
+
2. Verify the config JSON parses: `cat ~/Library/Application\ Support/Claude/claude_desktop_config.json | jq .`
|
|
496
|
+
3. Try the command in a terminal:
|
|
497
|
+
```bash
|
|
498
|
+
COLDBIRDS_API_KEY="sk_live_..." npx -y @coldbirds/mcp-server
|
|
499
|
+
```
|
|
500
|
+
It should print nothing and wait for input (that's normal — MCP servers talk over stdio).
|
|
501
|
+
4. Check the log: `~/Library/Logs/Claude/mcp-server-coldbirds.log`.
|
|
502
|
+
</details>
|
|
503
|
+
|
|
504
|
+
<details>
|
|
505
|
+
<summary><b>`npx` can't find <code>@coldbirds/mcp-server</code>.</b></summary>
|
|
506
|
+
|
|
507
|
+
You're behind a registry proxy. Pre-install it once: `npm install -g @coldbirds/mcp-server`, then use `command: "coldbirds-mcp"` (without `npx`) in your client config.
|
|
508
|
+
</details>
|
|
509
|
+
|
|
510
|
+
<details>
|
|
511
|
+
<summary><b>Server starts but every tool returns <code>401 Unauthorized</code>.</b></summary>
|
|
512
|
+
|
|
513
|
+
The API key is wrong, revoked, or missing the `sk_live_` prefix. Regenerate at [Settings → API Keys](https://sequencer.coldbirds.com/settings/api) and update your client config.
|
|
514
|
+
</details>
|
|
515
|
+
|
|
516
|
+
<details>
|
|
517
|
+
<summary><b>I see <code>[coldbirds-mcp] Falling back to bundled manifest</code> on startup.</b></summary>
|
|
518
|
+
|
|
519
|
+
The live `mcp.json` couldn't be reached or didn't match the expected schema. The server still works — it's running off the snapshot bundled with the package version you installed. Run `npm install -g @coldbirds/mcp-server@latest` to get the newest snapshot.
|
|
520
|
+
</details>
|
|
521
|
+
|
|
522
|
+
<details>
|
|
523
|
+
<summary><b>How do I see exactly which HTTP request a tool made?</b></summary>
|
|
524
|
+
|
|
525
|
+
Run via the MCP Inspector:
|
|
526
|
+
```bash
|
|
527
|
+
npx @modelcontextprotocol/inspector npx -y @coldbirds/mcp-server
|
|
528
|
+
```
|
|
529
|
+
The Inspector shows every JSON-RPC request and response in real time. For deeper debugging, set `NODE_OPTIONS=--inspect` and attach Chrome DevTools.
|
|
530
|
+
</details>
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## How it works
|
|
535
|
+
|
|
536
|
+
```
|
|
537
|
+
┌──────────────────┐ stdio (JSON-RPC 2.0) ┌────────────────────┐
|
|
538
|
+
│ AI assistant │ ◀────────────────────────────▶ │ @coldbirds/ │
|
|
539
|
+
│ (Claude, Cursor, │ │ mcp-server │
|
|
540
|
+
│ Cline, …) │ │ │
|
|
541
|
+
└──────────────────┘ └─────────┬──────────┘
|
|
542
|
+
│ HTTPS + Bearer
|
|
543
|
+
▼
|
|
544
|
+
┌────────────────────┐
|
|
545
|
+
│ sequencer. │
|
|
546
|
+
│ coldbirds.com │
|
|
547
|
+
│ /api/v1/* │
|
|
548
|
+
└────────────────────┘
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
- **Single source of truth:** the tool catalogue is published at <https://sequencer.coldbirds.com/mcp.json> and the server registers tools in a loop. New ColdBirds API endpoints become MCP tools automatically — no code change in this package.
|
|
552
|
+
- **Strict validation:** every tool's `inputSchema` is converted to a strict Zod schema before registration. Unknown keys are rejected at the SDK boundary so your assistant gets a clear error instead of a silent strip.
|
|
553
|
+
- **Offline-safe:** a snapshot of the manifest is bundled at build time. If the live fetch fails, the server falls back to the snapshot and logs a one-line stderr warning.
|
|
554
|
+
|
|
555
|
+
Architecture & contribution rules are documented in the root [`AGENTS.md` §21](https://github.com/elitale/coldbirds/blob/main/AGENTS.md#21-mcp-server-package-packagesmcp).
|
|
556
|
+
|
|
557
|
+
---
|
|
558
|
+
|
|
559
|
+
## Security notes
|
|
560
|
+
|
|
561
|
+
- 🔐 **Treat your API key like a password.** Never paste it in chat, never commit it to git, never share it in screenshots.
|
|
562
|
+
- 🛡 **Workspace-scoped:** keys can only see and modify the workspace that issued them. They cannot access other workspaces or platform-level resources.
|
|
563
|
+
- ⚠️ **Destructive tools** (`delete_contact`, `delete_mailbox`, `delete_campaign_step`, `pause_campaign`, etc.) carry the MCP `destructiveHint: true` annotation. Configure your client to require explicit approval for them — do NOT add them to an auto-approve allow-list unless you fully trust the prompts.
|
|
564
|
+
- 🚦 **Rate limits:** the same per-key limits as the dashboard apply (currently 60 req/min). The server doesn't add additional throttling — bursty agentic loops will hit `429` and back off.
|
|
565
|
+
- 🔭 **Audit log:** every API call shows up in your workspace's audit log under the issuing key's name.
|
|
566
|
+
|
|
567
|
+
---
|
|
568
|
+
|
|
569
|
+
## Contributing
|
|
570
|
+
|
|
571
|
+
This package is part of the [coldbirds/sequence](https://github.com/elitale/coldbird-sequncer) monorepo. PRs are welcome.
|
|
572
|
+
|
|
573
|
+
- **Adding a tool** → just edit [`public/mcp.json`](https://github.com/elitale/coldbird-sequncer/blob/main/public/mcp.json) at the repo root; the dispatcher picks it up automatically. Full instructions in [`AGENTS.md` §21.2](https://github.com/elitale/coldbird-sequncer/blob/main/AGENTS.md#212-adding-a-new-tool).
|
|
574
|
+
- **Bug reports / feature requests** → [open an issue](https://github.com/elitale/coldbird-sequncer/issues).
|
|
575
|
+
- **Local dev:**
|
|
576
|
+
```bash
|
|
577
|
+
git clone https://github.com/elitale/coldbird-sequncer.git
|
|
578
|
+
cd coldbird-sequncer
|
|
579
|
+
npm ci
|
|
580
|
+
cd packages/mcp
|
|
581
|
+
npm test # 111 tests
|
|
582
|
+
npm run build
|
|
583
|
+
npm start
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## License
|
|
589
|
+
|
|
590
|
+
[MIT](LICENSE) © Elitale Technologies
|
|
591
|
+
|
|
592
|
+
---
|
|
593
|
+
|
|
594
|
+
<sub>Built with ❤️ for cold-email marketers who would rather chat than click.</sub>
|
package/dist/tools.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__internals=void 0,exports.registerTools=registerTools;const types_js_1=require("@modelcontextprotocol/sdk/types.js"),json_schema_to_zod_1=require("./json-schema-to-zod"),PLACEHOLDER_RE=/\{(\w+)\}/g;function pathParams(t){const
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.__internals=void 0,exports.registerTools=registerTools;const types_js_1=require("@modelcontextprotocol/sdk/types.js"),json_schema_to_zod_1=require("./json-schema-to-zod"),PLACEHOLDER_RE=/\{(\w+)\}/g;function pathParams(t){const e=[];for(const o of t.matchAll(PLACEHOLDER_RE)){const n=o[1];n&&e.push(n)}return e}function stringifyPathValue(t,e){if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return String(e);throw new Error(`Path parameter '${t}' must be a string, number, or boolean (got ${typeof e})`)}function interpolate(t,e){return t.replace(PLACEHOLDER_RE,(o,n)=>{const r=e[n];if(r==null)throw new Error(`Missing required path parameter '${n}'`);return encodeURIComponent(stringifyPathValue(n,r))})}function remainingArgs(t,e){const o={};for(const[n,r]of Object.entries(t))e.includes(n)||(o[n]=r);return o}function asQuery(t){return t}async function dispatch(t,e,o){const{method:n,path:r}=e._http,s=pathParams(r),c=interpolate(r,o),u=remainingArgs(o,s),i=Object.keys(u).length>0;switch(n){case"GET":return t.get(c,i?u:void 0);case"POST":return t.post(c,i?u:void 0);case"PATCH":return t.patch(c,i?u:void 0);case"DELETE":return await t.delete(c)??{ok:!0}}}function ok(t){return{content:[{type:"text",text:JSON.stringify(t,null,2)}]}}function fail(t){return{content:[{type:"text",text:t}],isError:!0}}function isRecord(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}function toStructured(t,e){if(!t.outputSchema||!isRecord(e))return;const o=t.outputSchema.properties;if(isRecord(o)&&"data"in o){const{success:r,...s}=e;return s}return"data"in e&&isRecord(e.data)?e.data:e}function buildHandler(t,e){return async o=>{try{const n=await dispatch(t,e,o),r=toStructured(e,n),s=ok(r??n);return r!==void 0?{...s,structuredContent:r}:s}catch(n){const r=n instanceof Error?n.message:String(n);return fail(`Tool '${e.name}' failed: ${r}`)}}}function buildInputSchema(t){const e=(0,json_schema_to_zod_1.jsonSchemaToZod)(t.inputSchema);if(e._def?.typeName!=="ZodObject")throw new Error(`Tool '${t.name}' inputSchema must be a JSON-Schema object at the root`);return e}function registerTools(t,e,o){for(const n of o.tools){const r={description:n.description,inputSchema:buildInputSchema(n)};n.title&&(r.title=n.title),t.registerTool(n.name,r,buildHandler(e,n))}t.server.setRequestHandler(types_js_1.ListToolsRequestSchema,()=>({tools:o.tools.map(n=>{const{_http:r,...s}=n;return s})}))}exports.__internals={dispatch,pathParams,interpolate,remainingArgs,toStructured};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coldbirds/mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "MCP server for ColdBirds Sequence — control campaigns, contacts, and mailboxes from AI assistants like Claude Desktop, Cursor, and Windsurf.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"coldbirds",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"claude",
|
|
12
12
|
"cursor"
|
|
13
13
|
],
|
|
14
|
-
"homepage": "https://
|
|
14
|
+
"homepage": "https://coldbirds.com",
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"author": "Elitale Technologies",
|
|
17
17
|
"engines": {
|