@leadbay/mcp 0.12.0 → 0.13.0
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/CHANGELOG.md +23 -0
- package/README.md +32 -11
- package/dist/bin.js +103 -12
- package/dist/{chunk-J2Y4LCFM.js → chunk-4JLMRGFG.js} +4960 -88
- package/dist/{dist-YYVFSDMH.js → dist-LYTGM7OG.js} +75 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog — @leadbay/mcp
|
|
2
2
|
|
|
3
|
+
## 0.13.0 — 2026-05-21
|
|
4
|
+
|
|
5
|
+
- **Agent memory v1**: added always-on recall/capture/review tools backed by
|
|
6
|
+
local append-only JSONL at `~/.leadbay/memory/{account_id}/`.
|
|
7
|
+
- Leads-touching tool responses now attach `_meta.agent_memory.summary` with
|
|
8
|
+
the consolidated top signals unless `LEADBAY_AGENT_MEMORY=off` is set.
|
|
9
|
+
- Server instructions, prompt descriptions, and workflow prompts now teach the
|
|
10
|
+
memory protocol, including capture of new taste signals and review-gated
|
|
11
|
+
retractions.
|
|
12
|
+
- Added `agent-memory://summary` resource and PostHog events for memory
|
|
13
|
+
capture/recall/prune.
|
|
14
|
+
- **Pin bumps**: every active `@leadbay/mcp@0.12` install/runtime reference in
|
|
15
|
+
docs, generated client config, DXT, MCP Registry metadata, and Claude plugin
|
|
16
|
+
metadata is now `@0.13`.
|
|
17
|
+
|
|
18
|
+
## 0.12.1 — 2026-05-21
|
|
19
|
+
|
|
20
|
+
MCPB hotfix for Claude Desktop.
|
|
21
|
+
|
|
22
|
+
- **Fix packaged-server startup**: the MCPB bundle now injects a Node `createRequire` shim before esbuild's ESM wrapper so CommonJS dependencies can still require Node built-ins such as `perf_hooks`. This fixes the Claude Desktop disconnect where the server exited during initialization.
|
|
23
|
+
- **Packaging guardrail**: `@leadbay/dxt build` now runs the staged `server/index.js --version` before zipping, and the smoke suite extracts the MCPB and completes a real MCP initialize/tools-list handshake.
|
|
24
|
+
- **Manifest refresh**: MCPB manifests now declare `manifest_version: "0.3"` and the smoke assertions match the current MCPB manifest spec.
|
|
25
|
+
|
|
3
26
|
## 0.12.0 — 2026-05-21
|
|
4
27
|
|
|
5
28
|
Campaign and field-sales workflow release.
|
package/README.md
CHANGED
|
@@ -21,10 +21,31 @@ A Model Context Protocol server that lets Claude Desktop, Cursor, Claude Code, a
|
|
|
21
21
|
|
|
22
22
|
> **0.3.0 behavior change** — composite write tools (`refine_prompt`, `report_outreach`, `adjust_audience`, `bulk_qualify_leads`, `enrich_titles`, `answer_clarification`, `import_leads`) are **ON by default**. Set `LEADBAY_MCP_WRITE=0` (or `--no-write` on `install`) to restore the previous read-only behavior. `leadbay-mcp install` now also registers Claude Code at `--scope user` so Leadbay is visible from any project. See [MIGRATION.md](./MIGRATION.md).
|
|
23
23
|
|
|
24
|
+
## Agent memory
|
|
25
|
+
|
|
26
|
+
Leadbay MCP keeps a local, per-account agent memory at
|
|
27
|
+
`~/.leadbay/memory/{account_id}/`. It stores append-only JSONL learnings
|
|
28
|
+
about user taste signals such as preferred sectors, regions, deal size,
|
|
29
|
+
communication style, and qualification rules.
|
|
30
|
+
|
|
31
|
+
The memory tools are always exposed:
|
|
32
|
+
|
|
33
|
+
- `leadbay_agent_memory_recall` reads the consolidated top signals.
|
|
34
|
+
- `leadbay_agent_memory_capture` appends a new learning after the user reveals
|
|
35
|
+
a material preference.
|
|
36
|
+
- `leadbay_agent_memory_review` lists entries and gates retractions or org
|
|
37
|
+
promotion through user confirmation.
|
|
38
|
+
|
|
39
|
+
The main leads-touching tools (`leadbay_account_status`,
|
|
40
|
+
`leadbay_pull_leads`, `leadbay_pull_followups`,
|
|
41
|
+
`leadbay_prepare_outreach`, `leadbay_research_lead_by_id`) also attach
|
|
42
|
+
`_meta.agent_memory.summary` automatically. Set `LEADBAY_AGENT_MEMORY=off`
|
|
43
|
+
to suppress this ambient metadata.
|
|
44
|
+
|
|
24
45
|
## 1. Install (one command)
|
|
25
46
|
|
|
26
47
|
```bash
|
|
27
|
-
npx -y @leadbay/mcp@0.
|
|
48
|
+
npx -y @leadbay/mcp@0.13 install --email you@yourcompany.com --region us
|
|
28
49
|
# (you'll be prompted for your password — it's not echoed)
|
|
29
50
|
```
|
|
30
51
|
|
|
@@ -67,14 +88,14 @@ Claude Desktop 2026 ships the DXT (Desktop Extension) system — the legacy `cla
|
|
|
67
88
|
|
|
68
89
|
If you installed Node from the official [nodejs.org](https://nodejs.org) `.pkg`, `/usr/local/lib/node_modules` is root-owned. Any of these works:
|
|
69
90
|
|
|
70
|
-
- **Use `npx` (recommended, no global install):** all examples above use `npx -y @leadbay/mcp@0.
|
|
91
|
+
- **Use `npx` (recommended, no global install):** all examples above use `npx -y @leadbay/mcp@0.13 ...` — no global install needed.
|
|
71
92
|
- **`sudo npm install -g @leadbay/mcp`** (enter your macOS password).
|
|
72
93
|
- **Use a Node version manager** — [nvm](https://github.com/nvm-sh/nvm), [volta](https://volta.sh), [fnm](https://github.com/Schniz/fnm). They install Node under your home directory, so `npm install -g` works without sudo.
|
|
73
94
|
|
|
74
95
|
### If you'd rather mint a token without auto-install
|
|
75
96
|
|
|
76
97
|
```bash
|
|
77
|
-
npx -y @leadbay/mcp@0.
|
|
98
|
+
npx -y @leadbay/mcp@0.13 login \
|
|
78
99
|
--email you@yourcompany.com \
|
|
79
100
|
--region us
|
|
80
101
|
```
|
|
@@ -92,7 +113,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o
|
|
|
92
113
|
"mcpServers": {
|
|
93
114
|
"leadbay": {
|
|
94
115
|
"command": "npx",
|
|
95
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
116
|
+
"args": ["-y", "@leadbay/mcp@0.13"],
|
|
96
117
|
"env": {
|
|
97
118
|
"LEADBAY_TOKEN": "<paste-token-from-step-1>",
|
|
98
119
|
"LEADBAY_REGION": "us"
|
|
@@ -113,7 +134,7 @@ In Cursor settings, add the MCP server:
|
|
|
113
134
|
"mcp.servers": {
|
|
114
135
|
"leadbay": {
|
|
115
136
|
"command": "npx",
|
|
116
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
137
|
+
"args": ["-y", "@leadbay/mcp@0.13"],
|
|
117
138
|
"env": { "LEADBAY_TOKEN": "<paste-token>", "LEADBAY_REGION": "us" }
|
|
118
139
|
}
|
|
119
140
|
}
|
|
@@ -126,7 +147,7 @@ In Cursor settings, add the MCP server:
|
|
|
126
147
|
claude mcp add leadbay --scope user \
|
|
127
148
|
--env LEADBAY_TOKEN=<paste-token> \
|
|
128
149
|
--env LEADBAY_REGION=us \
|
|
129
|
-
-- npx -y @leadbay/mcp@0.
|
|
150
|
+
-- npx -y @leadbay/mcp@0.13
|
|
130
151
|
```
|
|
131
152
|
|
|
132
153
|
> **`--scope user`** registers Leadbay globally for your account (visible from any project). Without it, `claude mcp add` defaults to project-local scope and the server only appears in conversations opened from the directory where you ran the command.
|
|
@@ -138,7 +159,7 @@ claude mcp add leadbay --scope user \
|
|
|
138
159
|
Before starting Claude, run:
|
|
139
160
|
|
|
140
161
|
```bash
|
|
141
|
-
LEADBAY_TOKEN=<paste-token> npx -y @leadbay/mcp@0.
|
|
162
|
+
LEADBAY_TOKEN=<paste-token> npx -y @leadbay/mcp@0.13 doctor
|
|
142
163
|
```
|
|
143
164
|
|
|
144
165
|
Expected output:
|
|
@@ -366,14 +387,14 @@ The user's literal text replaces `verification.ref` in the outreach record, and
|
|
|
366
387
|
| `No enrichment credits remaining` | Out of quota | Contact Leadbay support to extend quota |
|
|
367
388
|
| Claude Desktop "loading forever" on first use | `npx` cold-start fetching the package | First run takes ~10s. Prefer `npm install -g @leadbay/mcp` for faster startup. |
|
|
368
389
|
| Claude Desktop doesn't show Leadbay tools | Server crashed at startup | Check `~/Library/Logs/Claude/mcp*.log` (macOS) or `%APPDATA%\Claude\logs\mcp*.log` (Windows). |
|
|
369
|
-
| Claude Code can't find Leadbay in a new conversation | MCP server installed at project scope (default before 0.3.0) | Re-run with `--scope user`: `claude mcp remove leadbay && claude mcp add leadbay --scope user --env LEADBAY_TOKEN=… --env LEADBAY_REGION=us -- npx -y @leadbay/mcp@0.
|
|
390
|
+
| Claude Code can't find Leadbay in a new conversation | MCP server installed at project scope (default before 0.3.0) | Re-run with `--scope user`: `claude mcp remove leadbay && claude mcp add leadbay --scope user --env LEADBAY_TOKEN=… --env LEADBAY_REGION=us -- npx -y @leadbay/mcp@0.13` |
|
|
370
391
|
| Agent reports "tool not found" for `refine_prompt` / `adjust_audience` etc. | Pre-0.3.0 install with `LEADBAY_MCP_WRITE` unset (writes were off) | Either re-run `npx @leadbay/mcp install` or remove `LEADBAY_MCP_WRITE=0` from your client config (writes are on by default in 0.3.0+) |
|
|
371
392
|
|
|
372
393
|
## 5. Upgrade & rotation
|
|
373
394
|
|
|
374
|
-
**Upgrade**: change the pinned minor in your config, e.g. `"@leadbay/mcp@0.2"` → `"@leadbay/mcp@0.
|
|
395
|
+
**Upgrade**: change the pinned minor in your config, e.g. `"@leadbay/mcp@0.2"` → `"@leadbay/mcp@0.13"`, then restart the client. **0.3.0 enables composite write tools by default** — see [MIGRATION.md](./MIGRATION.md). See also the [changelog](https://github.com/leadbay/leadclaw/releases).
|
|
375
396
|
|
|
376
|
-
**Rotate token**: re-run `npx -y @leadbay/mcp@0.
|
|
397
|
+
**Rotate token**: re-run `npx -y @leadbay/mcp@0.13 install --email you@yourcompany.com --region us` (or `login`) — the new session token replaces the old one in your MCP client config, and logging in again invalidates the prior session on most session backends.
|
|
377
398
|
|
|
378
399
|
## 6. Advanced
|
|
379
400
|
|
|
@@ -486,7 +507,7 @@ After your first authenticated call, your PostHog `distinctId` is set to your Le
|
|
|
486
507
|
"mcpServers": {
|
|
487
508
|
"leadbay": {
|
|
488
509
|
"command": "npx",
|
|
489
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
510
|
+
"args": ["-y", "@leadbay/mcp@0.13"],
|
|
490
511
|
"env": {
|
|
491
512
|
"LEADBAY_TOKEN": "u.…",
|
|
492
513
|
"LEADBAY_REGION": "us",
|
package/dist/bin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
LeadbayClient,
|
|
4
|
+
agentMemoryTools,
|
|
4
5
|
compositeReadTools,
|
|
5
6
|
compositeWriteTools,
|
|
6
7
|
createClient,
|
|
@@ -8,8 +9,9 @@ import {
|
|
|
8
9
|
formatLoginError,
|
|
9
10
|
granularReadTools,
|
|
10
11
|
granularWriteTools,
|
|
12
|
+
resolveAgentMemorySummary,
|
|
11
13
|
resolveRegion
|
|
12
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-4JLMRGFG.js";
|
|
13
15
|
|
|
14
16
|
// src/bin.ts
|
|
15
17
|
import { realpathSync } from "fs";
|
|
@@ -34,6 +36,11 @@ import {
|
|
|
34
36
|
|
|
35
37
|
// src/prompts.generated.ts
|
|
36
38
|
var leadbay_daily_check_in = `
|
|
39
|
+
## MEMORY
|
|
40
|
+
|
|
41
|
+
Before responding, glance at any \`_meta.agent_memory.summary\` returned by tool calls earlier in this session and reflect its top signals in your reasoning ("Filtering by your stated preference for healthcare"). After any material new taste signal from the user this conversation (sector, region, deal size, communication style, qualification rule, explicit retraction), call \`leadbay_agent_memory_capture\` to persist it: \`source:"user_stated"\` if literal, \`source:"inferred"\` with confidence <=6 if inferred.
|
|
42
|
+
|
|
43
|
+
|
|
37
44
|
Run the Leadbay daily check-in for me. Treat this prompt the same way for any equivalent ask focused on NEW leads from the Discover wishlist: "get me leadbay leads", "best NEW leads to prospect today", "what's new today", "show me my batch", "let's prospect". For follow-up phrasings ("what should I follow up on", "leads I've already worked", "before my trip"), this is the wrong prompt \u2014 route to \`leadbay_followup_check_in\` instead. If the user's intent is ambiguous ("what should I work on?"), ASK once before picking an entry point.
|
|
38
45
|
|
|
39
46
|
# Resilience rules for Leadbay long-running tools
|
|
@@ -411,6 +418,11 @@ If I declined the campaign step, end the turn \u2014 the map + drafts are enough
|
|
|
411
418
|
Done. The map is the surface; the drafts are the action; the campaign is the persistence layer for managerial follow-up after the trip.
|
|
412
419
|
`;
|
|
413
420
|
var leadbay_prospecting_overview = `
|
|
421
|
+
## MEMORY
|
|
422
|
+
|
|
423
|
+
Before responding, glance at any \`_meta.agent_memory.summary\` returned by tool calls earlier in this session and reflect its top signals in your reasoning ("Filtering by your stated preference for healthcare"). After any material new taste signal from the user this conversation (sector, region, deal size, communication style, qualification rule, explicit retraction), call \`leadbay_agent_memory_capture\` to persist it: \`source:"user_stated"\` if literal, \`source:"inferred"\` with confidence <=6 if inferred.
|
|
424
|
+
|
|
425
|
+
|
|
414
426
|
# Leadbay Prospecting \u2014 Orientation
|
|
415
427
|
|
|
416
428
|
You are working with Leadbay through the \`leadbay_*\` MCP tools. This prompt orients you to the user's mental model so you don't re-discover the workflow each session.
|
|
@@ -674,6 +686,11 @@ IRON LAW \u2014 DO NOT ANSWER CLARIFICATIONS ON THE USER'S BEHALF. If the respon
|
|
|
674
686
|
If the response status is \`applied\`, tell me Leadbay is regenerating intelligence and recommend I check back in a few minutes via \`leadbay_account_status\` (\`computing_intelligence\` flips to false when ready). If the status is anything else, name it explicitly.
|
|
675
687
|
`;
|
|
676
688
|
var leadbay_research_a_domain = `
|
|
689
|
+
## MEMORY
|
|
690
|
+
|
|
691
|
+
Before responding, glance at any \`_meta.agent_memory.summary\` returned by tool calls earlier in this session and reflect its top signals in your reasoning ("Filtering by your stated preference for healthcare"). After any material new taste signal from the user this conversation (sector, region, deal size, communication style, qualification rule, explicit retraction), call \`leadbay_agent_memory_capture\` to persist it: \`source:"user_stated"\` if literal, \`source:"inferred"\` with confidence <=6 if inferred.
|
|
692
|
+
|
|
693
|
+
|
|
677
694
|
IRON LAW \u2014 NO FABRICATION. Every lead id, contact email, custom field id, mapping decision, and tool argument must trace to a value you read from the file the user attached or to an output from a leadbay_* tool call in this session. Do not invent values. Do not "fill in" a missing leadId with a name match. Do not synthesize a CRM id from a guess. If a value is missing, leave the field blank and say so.
|
|
678
695
|
|
|
679
696
|
|
|
@@ -1219,6 +1236,7 @@ function getPrompt(name, args = {}) {
|
|
|
1219
1236
|
var LEAD_URI_RE = /^lead:\/\/([0-9a-f-]{36})\/profile$/i;
|
|
1220
1237
|
var LENS_URI_RE = /^lens:\/\/(\d+)\/definition$/;
|
|
1221
1238
|
var ORG_TASTE_URI = "org://taste-profile";
|
|
1239
|
+
var AGENT_MEMORY_SUMMARY_URI = "agent-memory://summary";
|
|
1222
1240
|
function listResources() {
|
|
1223
1241
|
return [
|
|
1224
1242
|
{
|
|
@@ -1226,6 +1244,12 @@ function listResources() {
|
|
|
1226
1244
|
name: "Org taste profile",
|
|
1227
1245
|
description: "The org's qualification questions, intent tags, and ICP signals \u2014 the agent's knowledge base for what makes a lead a fit.",
|
|
1228
1246
|
mimeType: "application/json"
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
uri: AGENT_MEMORY_SUMMARY_URI,
|
|
1250
|
+
name: "Agent memory summary",
|
|
1251
|
+
description: "Consolidated top Leadbay agent-memory signals for this account. Local-file, read-only resource.",
|
|
1252
|
+
mimeType: "text/markdown"
|
|
1229
1253
|
}
|
|
1230
1254
|
];
|
|
1231
1255
|
}
|
|
@@ -1256,11 +1280,29 @@ function jsonContent(uri, value) {
|
|
|
1256
1280
|
]
|
|
1257
1281
|
};
|
|
1258
1282
|
}
|
|
1283
|
+
function textContent(uri, mimeType, text) {
|
|
1284
|
+
return {
|
|
1285
|
+
contents: [
|
|
1286
|
+
{
|
|
1287
|
+
uri,
|
|
1288
|
+
mimeType,
|
|
1289
|
+
text
|
|
1290
|
+
}
|
|
1291
|
+
]
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1259
1294
|
async function readResource(uri, client) {
|
|
1260
1295
|
if (uri === ORG_TASTE_URI) {
|
|
1261
1296
|
const taste = await client.resolveTasteProfile();
|
|
1262
1297
|
return jsonContent(uri, taste);
|
|
1263
1298
|
}
|
|
1299
|
+
if (uri === AGENT_MEMORY_SUMMARY_URI) {
|
|
1300
|
+
const me = await client.resolveMe();
|
|
1301
|
+
const memory = await resolveAgentMemorySummary({
|
|
1302
|
+
accountId: me.organization.id
|
|
1303
|
+
});
|
|
1304
|
+
return textContent(uri, "text/markdown", memory.summary);
|
|
1305
|
+
}
|
|
1264
1306
|
const leadMatch = LEAD_URI_RE.exec(uri);
|
|
1265
1307
|
if (leadMatch) {
|
|
1266
1308
|
const leadId = leadMatch[1];
|
|
@@ -1281,7 +1323,7 @@ async function readResource(uri, client) {
|
|
|
1281
1323
|
return jsonContent(uri, { lensId, filter, scoring });
|
|
1282
1324
|
}
|
|
1283
1325
|
throw new Error(
|
|
1284
|
-
`Unsupported resource URI: ${uri}. Supported schemes: lead://{uuid}/profile, lens://{id}/definition, org://taste-profile.`
|
|
1326
|
+
`Unsupported resource URI: ${uri}. Supported schemes: lead://{uuid}/profile, lens://{id}/definition, org://taste-profile, agent-memory://summary.`
|
|
1285
1327
|
);
|
|
1286
1328
|
}
|
|
1287
1329
|
|
|
@@ -1307,6 +1349,9 @@ var EV_MCP_UPDATE_PROMPTED = "mcp update prompted";
|
|
|
1307
1349
|
var EV_MCP_UPDATE_INSTALL_CLICKED = "mcp update install_clicked";
|
|
1308
1350
|
var EV_MCP_UPDATE_DISMISSED = "mcp update dismissed";
|
|
1309
1351
|
var EV_MCP_VERSION_UPDATED = "mcp version updated";
|
|
1352
|
+
var EV_AGENT_MEMORY_CAPTURED = "agent_memory_captured";
|
|
1353
|
+
var EV_AGENT_MEMORY_RECALLED = "agent_memory_recalled";
|
|
1354
|
+
var EV_AGENT_MEMORY_PRUNED = "agent_memory_pruned";
|
|
1310
1355
|
|
|
1311
1356
|
// src/telemetry.ts
|
|
1312
1357
|
var NOOP_TELEMETRY = {
|
|
@@ -1320,6 +1365,12 @@ var NOOP_TELEMETRY = {
|
|
|
1320
1365
|
},
|
|
1321
1366
|
captureStartup: () => {
|
|
1322
1367
|
},
|
|
1368
|
+
captureAgentMemoryCaptured: () => {
|
|
1369
|
+
},
|
|
1370
|
+
captureAgentMemoryRecalled: () => {
|
|
1371
|
+
},
|
|
1372
|
+
captureAgentMemoryPruned: () => {
|
|
1373
|
+
},
|
|
1323
1374
|
captureException: () => {
|
|
1324
1375
|
},
|
|
1325
1376
|
captureUpdateCheck: () => {
|
|
@@ -1504,6 +1555,15 @@ function initTelemetry(opts) {
|
|
|
1504
1555
|
captureStartup(props) {
|
|
1505
1556
|
emit(EV_STARTUP, { ...props });
|
|
1506
1557
|
},
|
|
1558
|
+
captureAgentMemoryCaptured(props) {
|
|
1559
|
+
emit(EV_AGENT_MEMORY_CAPTURED, { ...props });
|
|
1560
|
+
},
|
|
1561
|
+
captureAgentMemoryRecalled(props) {
|
|
1562
|
+
emit(EV_AGENT_MEMORY_RECALLED, { ...props });
|
|
1563
|
+
},
|
|
1564
|
+
captureAgentMemoryPruned(props) {
|
|
1565
|
+
emit(EV_AGENT_MEMORY_PRUNED, { ...props });
|
|
1566
|
+
},
|
|
1507
1567
|
captureUpdateCheck(props) {
|
|
1508
1568
|
emit(EV_MCP_UPDATE_CHECK, { ...props });
|
|
1509
1569
|
},
|
|
@@ -1867,6 +1927,7 @@ function buildAcknowledgeUpdateTool(opts) {
|
|
|
1867
1927
|
var VERIFICATION_MANDATE = "After every email, call, message, or meeting with a lead's contact, you MUST call leadbay_report_outreach with verification={source, ref} (gmail_message_id from the Gmail send, calendar_event_id from a booking, or user_confirmed='<the user's literal confirmation>'). Skipping or fabricating verification poisons the human team's pipeline.";
|
|
1868
1928
|
var MENTAL_MODEL_PARAGRAPH = "How Leadbay works (mental model): Leadbay is a sales inbox, not a queryable database. Each day the user logs back in, a fresh batch of leads is delivered. Batch size is paced by how many leads the user has actually acted on recently \u2014 some workflows produce a big stream of smaller prospects, others a narrow stream of bigger ones. Pulling more won't produce more; the user acting on leads (outreach, skips, saves) does.";
|
|
1869
1929
|
var QUOTA_AND_TOPUP_PARAGRAPH = "Quota & top-ups: when a tool returns QUOTA_EXCEEDED / 429, the user has TWO options \u2014 wait for the window reset (daily / weekly / monthly resets shown in leadbay_account_status), OR top up AI credits (top-ups clear the throttle IMMEDIATELY \u2014 they are not subject to the same window). Always offer BOTH options; default-recommending 'wait until tomorrow' is wrong when a 30-second top-up unblocks the same call. If the host exposes leadbay_create_topup_link, OFFER it on every quota wall: 'Want me to generate a top-up link?' \u2014 when the user says yes, call leadbay_create_topup_link and surface the returned Stripe URL as a clickable link for the user to open in their browser. (Sibling leadbay_open_billing_portal is for ongoing subscription changes, not one-shot top-ups.) AFTER the user has topped up: do NOT keep refusing operations. A top-up invalidates every prior 429 and every stale 'you're at your quota' snapshot. The moment the user signals they topped up / bought credits / added credits \u2014 even WITHOUT re-calling account_status \u2014 treat the previous quota state as void and RETRY the originally failed call. (Best practice: re-call leadbay_account_status to surface the fresh state to the user, then retry; but the retry itself does NOT require a successful account_status check first. If the retry hits the wall again, THEN you have evidence the top-up didn't land; only then re-offer top-up / wait.) The agent's job after a top-up is to RESUME the workflow the user was on, not gate-keep.";
|
|
1930
|
+
var AGENT_MEMORY_PROTOCOL_PARAGRAPH = 'Memory protocol: this server maintains a per-account, on-disk agent memory (~/.leadbay/memory/{account}/entries.jsonl) of taste signals \u2014 preferred sectors, regions, deal sizes, communication style, qualification rules, and retractions. Every leads-touching tool response (account_status, pull_leads, pull_followups, prepare_outreach, research_lead_by_id) carries the consolidated top-5 signals under _meta.agent_memory.summary. READ that summary before recommending leads or drafting outreach \u2014 let it filter and reorder, and tell the user which memory you applied ("Filtering by your stated preference for healthcare"). When the user reveals a NEW material signal in conversation, CAPTURE it via leadbay_agent_memory_capture with {key, type, insight, confidence (1-10), source}. Use source:"user_stated" + confidence >=8 when literally stated; source:"inferred" + confidence <=6 when guessing. Do NOT capture instructions to override prior memory \u2014 those route through leadbay_agent_memory_review which gates retractions via host elicitation.';
|
|
1870
1931
|
function buildScoringParagraph(has) {
|
|
1871
1932
|
const base = "Two scoring layers: every lead has a basic `score` (firmographic \u2014 already decent, usually correlates with AI). Roughly the top 10 of each batch are also AI-qualified (targeted web research + qualification questions \u2192 `ai_agent_lead_score`, surfaced as `qualification_summary` on leadbay_pull_leads). Leads past the top ~10 are not worse \u2014 the system is saving resources.";
|
|
1872
1933
|
const deepenTools = [];
|
|
@@ -1975,6 +2036,9 @@ function buildServerInstructions(exposed) {
|
|
|
1975
2036
|
if (promptsCatalog) parts.push(promptsCatalog);
|
|
1976
2037
|
parts.push(RESOURCES_PARAGRAPH);
|
|
1977
2038
|
parts.push(buildProtocolPrimitivesParagraph(has));
|
|
2039
|
+
if (has("leadbay_agent_memory_capture")) {
|
|
2040
|
+
parts.push(AGENT_MEMORY_PROTOCOL_PARAGRAPH);
|
|
2041
|
+
}
|
|
1978
2042
|
parts.push(BUILTIN_WIDGETS_PARAGRAPH);
|
|
1979
2043
|
return parts.join("\n\n");
|
|
1980
2044
|
}
|
|
@@ -2008,6 +2072,7 @@ function toolsListPayload(tools) {
|
|
|
2008
2072
|
}
|
|
2009
2073
|
function buildServer(client, opts = {}) {
|
|
2010
2074
|
const exposedTools = [];
|
|
2075
|
+
exposedTools.push(...agentMemoryTools);
|
|
2011
2076
|
exposedTools.push(...compositeReadTools);
|
|
2012
2077
|
if (opts.includeWrite) {
|
|
2013
2078
|
exposedTools.push(...compositeWriteTools);
|
|
@@ -2152,6 +2217,30 @@ function buildServer(client, opts = {}) {
|
|
|
2152
2217
|
}
|
|
2153
2218
|
};
|
|
2154
2219
|
const isLeadbayBusinessError = (err) => err != null && typeof err === "object" && err.error === true && typeof err.code === "string";
|
|
2220
|
+
const captureAgentMemoryTelemetry = (toolName, result) => {
|
|
2221
|
+
if (!result || typeof result !== "object") return;
|
|
2222
|
+
const meta = result._meta ?? {};
|
|
2223
|
+
if (toolName === "leadbay_agent_memory_capture") {
|
|
2224
|
+
telemetry.captureAgentMemoryCaptured({
|
|
2225
|
+
source: result.captured?.source ?? meta.source,
|
|
2226
|
+
scope: result.captured?.scope ?? meta.scope,
|
|
2227
|
+
key: result.captured?.key,
|
|
2228
|
+
type: result.captured?.type,
|
|
2229
|
+
account_id_hash: meta.account_id_hash
|
|
2230
|
+
});
|
|
2231
|
+
} else if (toolName === "leadbay_agent_memory_recall") {
|
|
2232
|
+
telemetry.captureAgentMemoryRecalled({
|
|
2233
|
+
entries_returned: result.entries_returned,
|
|
2234
|
+
total_active: result.total_active,
|
|
2235
|
+
account_id_hash: meta.account_id_hash
|
|
2236
|
+
});
|
|
2237
|
+
} else if (toolName === "leadbay_agent_memory_review" && result.changed === true && (result.action === "retract" || result.action === "prune")) {
|
|
2238
|
+
telemetry.captureAgentMemoryPruned({
|
|
2239
|
+
action: result.action,
|
|
2240
|
+
account_id_hash: meta.account_id_hash
|
|
2241
|
+
});
|
|
2242
|
+
}
|
|
2243
|
+
};
|
|
2155
2244
|
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
2156
2245
|
const callStart = Date.now();
|
|
2157
2246
|
const name = req.params.name;
|
|
@@ -2260,6 +2349,7 @@ function buildServer(client, opts = {}) {
|
|
|
2260
2349
|
format: "markdown",
|
|
2261
2350
|
bytes: mdBytes
|
|
2262
2351
|
});
|
|
2352
|
+
captureAgentMemoryTelemetry(name, env.structured);
|
|
2263
2353
|
if (name === "leadbay_create_topup_link" && typeof env.structured?.url === "string") {
|
|
2264
2354
|
telemetry.captureTopupLink({ tool: name });
|
|
2265
2355
|
}
|
|
@@ -2289,6 +2379,7 @@ function buildServer(client, opts = {}) {
|
|
|
2289
2379
|
format: "json",
|
|
2290
2380
|
bytes: okBytes
|
|
2291
2381
|
});
|
|
2382
|
+
captureAgentMemoryTelemetry(name, result);
|
|
2292
2383
|
if (name === "leadbay_create_topup_link" && typeof result?.url === "string") {
|
|
2293
2384
|
telemetry.captureTopupLink({ tool: name });
|
|
2294
2385
|
}
|
|
@@ -2542,7 +2633,7 @@ async function createDefaultUpdateStateStore(opts = {}) {
|
|
|
2542
2633
|
|
|
2543
2634
|
// src/bin.ts
|
|
2544
2635
|
import { createRequire } from "module";
|
|
2545
|
-
var VERSION = "0.
|
|
2636
|
+
var VERSION = "0.13.0";
|
|
2546
2637
|
var HELP = `
|
|
2547
2638
|
leadbay-mcp ${VERSION} \u2014 Leadbay Model Context Protocol server
|
|
2548
2639
|
|
|
@@ -2591,7 +2682,7 @@ EXAMPLE Claude Desktop config (~/Library/Application Support/Claude/claude_deskt
|
|
|
2591
2682
|
"mcpServers": {
|
|
2592
2683
|
"leadbay": {
|
|
2593
2684
|
"command": "npx",
|
|
2594
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
2685
|
+
"args": ["-y", "@leadbay/mcp@0.13"],
|
|
2595
2686
|
"env": {
|
|
2596
2687
|
"LEADBAY_TOKEN": "lb_...",
|
|
2597
2688
|
"LEADBAY_REGION": "us",
|
|
@@ -2892,7 +2983,7 @@ async function runLogin(args) {
|
|
|
2892
2983
|
let result;
|
|
2893
2984
|
try {
|
|
2894
2985
|
if (pinnedRegion && !allowFallback) {
|
|
2895
|
-
const { REGIONS } = await import("./dist-
|
|
2986
|
+
const { REGIONS } = await import("./dist-LYTGM7OG.js");
|
|
2896
2987
|
const baseUrl = REGIONS[pinnedRegion];
|
|
2897
2988
|
const c = createClient({ region: pinnedRegion });
|
|
2898
2989
|
const token = await loginAt(baseUrl, email, password);
|
|
@@ -2911,7 +3002,7 @@ async function runLogin(args) {
|
|
|
2911
3002
|
mcpServers: {
|
|
2912
3003
|
leadbay: {
|
|
2913
3004
|
command: "npx",
|
|
2914
|
-
args: ["-y", "@leadbay/mcp@0.
|
|
3005
|
+
args: ["-y", "@leadbay/mcp@0.13"],
|
|
2915
3006
|
env: {
|
|
2916
3007
|
LEADBAY_TOKEN: result.token,
|
|
2917
3008
|
LEADBAY_REGION: result.region
|
|
@@ -2951,7 +3042,7 @@ Or for Claude Code (token included \u2014 same warning applies):
|
|
|
2951
3042
|
claude mcp add leadbay --scope user \\
|
|
2952
3043
|
--env LEADBAY_TOKEN=${result.token} \\
|
|
2953
3044
|
--env LEADBAY_REGION=${result.region} \\
|
|
2954
|
-
-- npx -y @leadbay/mcp@0.
|
|
3045
|
+
-- npx -y @leadbay/mcp@0.13
|
|
2955
3046
|
|
|
2956
3047
|
Restart your MCP client to pick up the new server.
|
|
2957
3048
|
`
|
|
@@ -3057,7 +3148,7 @@ For Claude Code, run:
|
|
|
3057
3148
|
claude mcp add leadbay --scope user \\
|
|
3058
3149
|
--env LEADBAY_TOKEN=$(jq -r .mcpServers.leadbay.env.LEADBAY_TOKEN ${quotedPath}) \\
|
|
3059
3150
|
--env LEADBAY_REGION=${result.region} \\
|
|
3060
|
-
-- npx -y @leadbay/mcp@0.
|
|
3151
|
+
-- npx -y @leadbay/mcp@0.13
|
|
3061
3152
|
`
|
|
3062
3153
|
);
|
|
3063
3154
|
}
|
|
@@ -3237,7 +3328,7 @@ function buildClaudeCodeAddArgs(token, region, includeWrite, telemetryEnabled) {
|
|
|
3237
3328
|
`LEADBAY_TELEMETRY_ENABLED=${telemetryEnabled ? "true" : "false"}`
|
|
3238
3329
|
];
|
|
3239
3330
|
if (!includeWrite) args.push("--env", `LEADBAY_MCP_WRITE=0`);
|
|
3240
|
-
args.push("--", "npx", "-y", "@leadbay/mcp@0.
|
|
3331
|
+
args.push("--", "npx", "-y", "@leadbay/mcp@0.13");
|
|
3241
3332
|
return args;
|
|
3242
3333
|
}
|
|
3243
3334
|
async function installInClaudeCode(token, region, includeWrite, telemetryEnabled) {
|
|
@@ -3287,7 +3378,7 @@ async function installInJsonConfig(configPath, token, region, includeWrite, tele
|
|
|
3287
3378
|
if (!includeWrite) env.LEADBAY_MCP_WRITE = "0";
|
|
3288
3379
|
parsed.mcpServers.leadbay = {
|
|
3289
3380
|
command: "npx",
|
|
3290
|
-
args: ["-y", "@leadbay/mcp@0.
|
|
3381
|
+
args: ["-y", "@leadbay/mcp@0.13"],
|
|
3291
3382
|
env
|
|
3292
3383
|
};
|
|
3293
3384
|
const tmp = configPath + ".tmp";
|
|
@@ -3391,7 +3482,7 @@ leadbay-mcp install \u2014 detected MCP clients on this machine:
|
|
|
3391
3482
|
let region;
|
|
3392
3483
|
try {
|
|
3393
3484
|
if (pinnedRegion && !allowFallback) {
|
|
3394
|
-
const { REGIONS } = await import("./dist-
|
|
3485
|
+
const { REGIONS } = await import("./dist-LYTGM7OG.js");
|
|
3395
3486
|
const baseUrl = REGIONS[pinnedRegion];
|
|
3396
3487
|
token = await loginAt(baseUrl, email, password);
|
|
3397
3488
|
region = pinnedRegion;
|
|
@@ -3464,7 +3555,7 @@ leadbay-mcp install \u2014 detected MCP clients on this machine:
|
|
|
3464
3555
|
process.stderr.write(
|
|
3465
3556
|
`
|
|
3466
3557
|
The token was written into client config files but never printed to your terminal.
|
|
3467
|
-
Verify with: LEADBAY_TOKEN=$(...) npx -y @leadbay/mcp@0.
|
|
3558
|
+
Verify with: LEADBAY_TOKEN=$(...) npx -y @leadbay/mcp@0.13 doctor
|
|
3468
3559
|
Restart your MCP client(s) to pick up the new server.
|
|
3469
3560
|
If you ever leak the token, run \`leadbay-mcp login --email <you> --region <us|fr>\` to mint a fresh one (which invalidates the prior session).
|
|
3470
3561
|
`
|