@leadbay/mcp 0.23.8 → 0.23.9
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 +6 -0
- package/dist/bin.js +18 -14
- package/dist/http-server.js +14 -12
- package/dist/installer-electron.js +1 -1
- package/dist/installer-gui.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog — @leadbay/mcp
|
|
2
2
|
|
|
3
|
+
## 0.23.9 — 2026-06-27
|
|
4
|
+
|
|
5
|
+
MCP data plane now targets backend **/1.6** (was /1.5).
|
|
6
|
+
|
|
7
|
+
- **`client`** — every request path is built from a single `API_VERSION = "1.6"` constant (exported as `API_PREFIX`). `LeadbayClient` (request / requestVoid / requestRawBinary + mock-mode paths) and `bin.ts`'s login probe all reference it, so future backend version bumps are a one-line change. Verified live on `api-us` before shipping: `/1.6` mirrors `/1.5` across the full route surface probed (monitor, lenses, auth/login, kpi, geo) — identical status on every call. Tool-description prose and route-doc comments updated to /1.6 to match.
|
|
8
|
+
|
|
3
9
|
## 0.23.8 — 2026-06-26
|
|
4
10
|
|
|
5
11
|
Installer no longer hangs in Claude Cowork / headless terminals (product#3805).
|
package/dist/bin.js
CHANGED
|
@@ -68,7 +68,7 @@ async function resolveRegion(email, password, startWith = "us") {
|
|
|
68
68
|
const baseUrl = REGIONS[region];
|
|
69
69
|
const body = JSON.stringify({ email, password });
|
|
70
70
|
try {
|
|
71
|
-
const res = await httpsRequest("POST", `${baseUrl}/
|
|
71
|
+
const res = await httpsRequest("POST", `${baseUrl}${API_PREFIX}/auth/login`, { "Content-Type": "application/json" }, body);
|
|
72
72
|
if (res.status === 200) {
|
|
73
73
|
const parsed = JSON.parse(res.body);
|
|
74
74
|
if (parsed?.token) {
|
|
@@ -159,7 +159,7 @@ function parseRetryAfter(value) {
|
|
|
159
159
|
}
|
|
160
160
|
return null;
|
|
161
161
|
}
|
|
162
|
-
var LENS_CACHE_TTL_MS, TASTE_CACHE_TTL_MS, ME_CACHE_TTL_MS, MAX_CONCURRENT, REGIONS, _mockFixtures, _mockJournal, LeadbayClient;
|
|
162
|
+
var LENS_CACHE_TTL_MS, TASTE_CACHE_TTL_MS, ME_CACHE_TTL_MS, MAX_CONCURRENT, REGIONS, API_VERSION, API_PREFIX, _mockFixtures, _mockJournal, LeadbayClient;
|
|
163
163
|
var init_client = __esm({
|
|
164
164
|
"../core/dist/client.js"() {
|
|
165
165
|
"use strict";
|
|
@@ -171,6 +171,8 @@ var init_client = __esm({
|
|
|
171
171
|
us: "https://api-us.leadbay.app",
|
|
172
172
|
fr: "https://api-fr.leadbay.app"
|
|
173
173
|
};
|
|
174
|
+
API_VERSION = "1.6";
|
|
175
|
+
API_PREFIX = `/${API_VERSION}`;
|
|
174
176
|
_mockFixtures = null;
|
|
175
177
|
_mockJournal = [];
|
|
176
178
|
LeadbayClient = class {
|
|
@@ -313,7 +315,7 @@ var init_client = __esm({
|
|
|
313
315
|
const retryOn401 = opts?.retryOn401 !== false;
|
|
314
316
|
await this.acquireSemaphore();
|
|
315
317
|
try {
|
|
316
|
-
const url = `${this._baseUrl}
|
|
318
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
317
319
|
const headers = {
|
|
318
320
|
Authorization: `Bearer ${this.token}`
|
|
319
321
|
};
|
|
@@ -348,7 +350,7 @@ var init_client = __esm({
|
|
|
348
350
|
}
|
|
349
351
|
await this.acquireSemaphore();
|
|
350
352
|
try {
|
|
351
|
-
const url = `${this._baseUrl}
|
|
353
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
352
354
|
const headers = {
|
|
353
355
|
Authorization: `Bearer ${this.token}`
|
|
354
356
|
};
|
|
@@ -373,7 +375,7 @@ var init_client = __esm({
|
|
|
373
375
|
// serialized body (string for text payloads such as CSV; Buffer for binary
|
|
374
376
|
// uploads). Auth, semaphore, error mapping, _lastMeta, and mock-mode all
|
|
375
377
|
// mirror request() exactly. Used by leadbay_import_leads to upload CSVs to
|
|
376
|
-
// the wizard at POST /1.
|
|
378
|
+
// the wizard at POST /1.6/imports.
|
|
377
379
|
async requestRawBinary(method, path, contentType, body) {
|
|
378
380
|
if (process.env.LEADBAY_MOCK === "1") {
|
|
379
381
|
return this.mockRequestBinary(method, path, contentType, body);
|
|
@@ -383,7 +385,7 @@ var init_client = __esm({
|
|
|
383
385
|
}
|
|
384
386
|
await this.acquireSemaphore();
|
|
385
387
|
try {
|
|
386
|
-
const url = `${this._baseUrl}
|
|
388
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
387
389
|
const headers = {
|
|
388
390
|
Authorization: `Bearer ${this.token}`,
|
|
389
391
|
"Content-Type": contentType
|
|
@@ -407,7 +409,7 @@ var init_client = __esm({
|
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
411
|
mockRequest(method, path, body) {
|
|
410
|
-
const fullPath =
|
|
412
|
+
const fullPath = `${API_PREFIX}${path}`;
|
|
411
413
|
this._lastMeta = {
|
|
412
414
|
region: this._region,
|
|
413
415
|
endpoint: `${method} ${path}`,
|
|
@@ -430,7 +432,7 @@ var init_client = __esm({
|
|
|
430
432
|
};
|
|
431
433
|
}
|
|
432
434
|
mockRequestBinary(method, path, contentType, body) {
|
|
433
|
-
const fullPath =
|
|
435
|
+
const fullPath = `${API_PREFIX}${path}`;
|
|
434
436
|
this._lastMeta = {
|
|
435
437
|
region: this._region,
|
|
436
438
|
endpoint: `${method} ${path}`,
|
|
@@ -5695,7 +5697,7 @@ WHEN TO USE: at the start of a session to know what the agent can/can't do, afte
|
|
|
5695
5697
|
|
|
5696
5698
|
WHEN NOT TO USE: as a pre-flight gate before bulk ops \u2014 operations themselves return 429; this tool is for context, not gating. And: a recent quota snapshot showing "exhausted" is NOT a reason to refuse a write call when the user has just topped up \u2014 re-call this tool first, then proceed.
|
|
5697
5699
|
`;
|
|
5698
|
-
leadbay_acknowledge_notification = `Acknowledge a Leadbay notification \u2014 i.e. tell the MCP and the backend "I've seen this and acted on it." Wraps \`POST /1.
|
|
5700
|
+
leadbay_acknowledge_notification = `Acknowledge a Leadbay notification \u2014 i.e. tell the MCP and the backend "I've seen this and acted on it." Wraps \`POST /1.6/notifications/{id}/seen\` (default) or \`/archive\` (when \`archive:true\`) and drops the entry from the local inbox so subsequent \`_meta.notifications\` payloads stop carrying it.
|
|
5699
5701
|
|
|
5700
5702
|
**When to call.** After you read an entry from \`_meta.notifications\` or \`account_status.notifications\` and have revised whatever prior output the just-finished background work might have made stale (outreach drafts, lead lists, "available leads" claims, followup plans). Mark-seen tells the human team's pipeline you handled this and prevents the notification from re-surfacing on every subsequent tool response.
|
|
5701
5703
|
|
|
@@ -6305,7 +6307,7 @@ WHEN NOT TO USE: from agent flow \u2014 leadbay_adjust_audience handles the draf
|
|
|
6305
6307
|
|
|
6306
6308
|
This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See \`annotations.destructiveHint\`.
|
|
6307
6309
|
`;
|
|
6308
|
-
leadbay_create_topup_link = `Generate a one-shot Stripe checkout session for an AI-credits top-up. Wraps \`POST /1.
|
|
6310
|
+
leadbay_create_topup_link = `Generate a one-shot Stripe checkout session for an AI-credits top-up. Wraps \`POST /1.6/stripe/topup_checkout\` \u2192 \`{url}\`. Returns a fresh Stripe-hosted URL (~1 hour TTL); creating one does NOT charge the user \u2014 payment happens only after the user opens the URL and completes checkout in their browser.
|
|
6309
6311
|
|
|
6310
6312
|
**When a quota window is hit, offer top-up as the FIRST option.** A top-up clears the throttle immediately (no need to wait for the daily/weekly/monthly window reset). The flow:
|
|
6311
6313
|
|
|
@@ -7489,7 +7491,7 @@ follow-ups. On \`ambiguous_sectors\`, the only move is to pick a sector and re-c
|
|
|
7489
7491
|
If nothing fits, default to "switch to the new lens and pull leads" \u2014 never
|
|
7490
7492
|
invent a tool that doesn't exist.
|
|
7491
7493
|
`;
|
|
7492
|
-
leadbay_open_billing_portal = `Generate a one-shot Stripe customer-portal URL. Wraps \`GET /1.
|
|
7494
|
+
leadbay_open_billing_portal = `Generate a one-shot Stripe customer-portal URL. Wraps \`GET /1.6/stripe/portal\` \u2192 \`{url}\`. Returns a fresh Stripe-hosted URL the user can open to manage their existing Leadbay subscription: change plan tier, swap payment method, view invoices. The agent does NOT make subscription changes itself \u2014 it surfaces the URL and lets the user act.
|
|
7493
7495
|
|
|
7494
7496
|
Sibling of \`leadbay_create_topup_link\`. Use cases differ:
|
|
7495
7497
|
|
|
@@ -7767,7 +7769,7 @@ table. Detail + status priority below.
|
|
|
7767
7769
|
|
|
7768
7770
|
Pull KNOWN leads from the user's Monitor view \u2014 the re-engagement entry point. Use when the user asks "what should I follow up on", "leads I haven't contacted", "leads in [city]", "before my trip", or any phrasing implying pre-existing pipeline context. For NEW leads from Discover, use \`leadbay_pull_leads\`.
|
|
7769
7771
|
|
|
7770
|
-
Backend: wraps \`GET /1.
|
|
7772
|
+
Backend: wraps \`GET /1.6/monitor?personal=&liked=&filtered=&count=&page=\` plus, when \`set_filter\` is supplied, a preceding \`POST /1.6/monitor/filter\`. The Monitor filter is a single \`FilterItem\` per user \u2014 refreshing restores it.
|
|
7771
7773
|
|
|
7772
7774
|
**Filter mechanism \u2014 store-then-apply.** Pass \`set_filter: { criteria: FilterCriterion[] }\` to overwrite the server-stored filter, then the composite re-fetches with \`filtered:true\`. \`FilterCriterion\` is the backend's \`anyOf\` over 10 typed criteria: \`size\`, \`keywords\`, \`sector_ids\`, \`location_ids\`, \`custom_field\`(\`_comparison\`), \`yc\`, \`liked\`, \`last_action\` (MonitorActionType enum), \`last_action_date\` (with \`last_days\`).
|
|
7773
7775
|
|
|
@@ -22669,6 +22671,8 @@ var init_artifact_kit = __esm({
|
|
|
22669
22671
|
// ../core/dist/index.js
|
|
22670
22672
|
var dist_exports = {};
|
|
22671
22673
|
__export(dist_exports, {
|
|
22674
|
+
API_PREFIX: () => API_PREFIX,
|
|
22675
|
+
API_VERSION: () => API_VERSION,
|
|
22672
22676
|
AgentMemoryCaptureInputSchema: () => AgentMemoryCaptureInputSchema,
|
|
22673
22677
|
AgentMemoryEntrySchema: () => AgentMemoryEntrySchema,
|
|
22674
22678
|
AgentMemoryInjectionError: () => AgentMemoryInjectionError,
|
|
@@ -27717,7 +27721,7 @@ var OAUTH_BASE_URLS = {
|
|
|
27717
27721
|
fr: "https://staging.api.leadbay.app"
|
|
27718
27722
|
}
|
|
27719
27723
|
};
|
|
27720
|
-
var VERSION = "0.23.
|
|
27724
|
+
var VERSION = "0.23.9";
|
|
27721
27725
|
var HELP = `
|
|
27722
27726
|
leadbay-mcp ${VERSION} \u2014 Leadbay Model Context Protocol server
|
|
27723
27727
|
|
|
@@ -28518,7 +28522,7 @@ async function loginAt(baseUrl, email, password) {
|
|
|
28518
28522
|
const https2 = await import("https");
|
|
28519
28523
|
return await new Promise((resolve, reject) => {
|
|
28520
28524
|
const body = JSON.stringify({ email, password });
|
|
28521
|
-
const u = new URL(baseUrl +
|
|
28525
|
+
const u = new URL(baseUrl + `${API_PREFIX}/auth/login`);
|
|
28522
28526
|
const r = https2.request(
|
|
28523
28527
|
{
|
|
28524
28528
|
hostname: u.hostname,
|
package/dist/http-server.js
CHANGED
|
@@ -1592,6 +1592,8 @@ var REGIONS = {
|
|
|
1592
1592
|
us: "https://api-us.leadbay.app",
|
|
1593
1593
|
fr: "https://api-fr.leadbay.app"
|
|
1594
1594
|
};
|
|
1595
|
+
var API_VERSION = "1.6";
|
|
1596
|
+
var API_PREFIX = `/${API_VERSION}`;
|
|
1595
1597
|
function httpsRequest(method, url, headers, body) {
|
|
1596
1598
|
return new Promise((resolve, reject) => {
|
|
1597
1599
|
const start = Date.now();
|
|
@@ -1647,7 +1649,7 @@ async function resolveRegion(email, password, startWith = "us") {
|
|
|
1647
1649
|
const baseUrl = REGIONS[region];
|
|
1648
1650
|
const body = JSON.stringify({ email, password });
|
|
1649
1651
|
try {
|
|
1650
|
-
const res = await httpsRequest("POST", `${baseUrl}/
|
|
1652
|
+
const res = await httpsRequest("POST", `${baseUrl}${API_PREFIX}/auth/login`, { "Content-Type": "application/json" }, body);
|
|
1651
1653
|
if (res.status === 200) {
|
|
1652
1654
|
const parsed = JSON.parse(res.body);
|
|
1653
1655
|
if (parsed?.token) {
|
|
@@ -1861,7 +1863,7 @@ var LeadbayClient = class {
|
|
|
1861
1863
|
const retryOn401 = opts?.retryOn401 !== false;
|
|
1862
1864
|
await this.acquireSemaphore();
|
|
1863
1865
|
try {
|
|
1864
|
-
const url = `${this._baseUrl}
|
|
1866
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
1865
1867
|
const headers = {
|
|
1866
1868
|
Authorization: `Bearer ${this.token}`
|
|
1867
1869
|
};
|
|
@@ -1896,7 +1898,7 @@ var LeadbayClient = class {
|
|
|
1896
1898
|
}
|
|
1897
1899
|
await this.acquireSemaphore();
|
|
1898
1900
|
try {
|
|
1899
|
-
const url = `${this._baseUrl}
|
|
1901
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
1900
1902
|
const headers = {
|
|
1901
1903
|
Authorization: `Bearer ${this.token}`
|
|
1902
1904
|
};
|
|
@@ -1921,7 +1923,7 @@ var LeadbayClient = class {
|
|
|
1921
1923
|
// serialized body (string for text payloads such as CSV; Buffer for binary
|
|
1922
1924
|
// uploads). Auth, semaphore, error mapping, _lastMeta, and mock-mode all
|
|
1923
1925
|
// mirror request() exactly. Used by leadbay_import_leads to upload CSVs to
|
|
1924
|
-
// the wizard at POST /1.
|
|
1926
|
+
// the wizard at POST /1.6/imports.
|
|
1925
1927
|
async requestRawBinary(method, path, contentType, body) {
|
|
1926
1928
|
if (process.env.LEADBAY_MOCK === "1") {
|
|
1927
1929
|
return this.mockRequestBinary(method, path, contentType, body);
|
|
@@ -1931,7 +1933,7 @@ var LeadbayClient = class {
|
|
|
1931
1933
|
}
|
|
1932
1934
|
await this.acquireSemaphore();
|
|
1933
1935
|
try {
|
|
1934
|
-
const url = `${this._baseUrl}
|
|
1936
|
+
const url = `${this._baseUrl}${API_PREFIX}${path}`;
|
|
1935
1937
|
const headers = {
|
|
1936
1938
|
Authorization: `Bearer ${this.token}`,
|
|
1937
1939
|
"Content-Type": contentType
|
|
@@ -1955,7 +1957,7 @@ var LeadbayClient = class {
|
|
|
1955
1957
|
}
|
|
1956
1958
|
}
|
|
1957
1959
|
mockRequest(method, path, body) {
|
|
1958
|
-
const fullPath =
|
|
1960
|
+
const fullPath = `${API_PREFIX}${path}`;
|
|
1959
1961
|
this._lastMeta = {
|
|
1960
1962
|
region: this._region,
|
|
1961
1963
|
endpoint: `${method} ${path}`,
|
|
@@ -1978,7 +1980,7 @@ var LeadbayClient = class {
|
|
|
1978
1980
|
};
|
|
1979
1981
|
}
|
|
1980
1982
|
mockRequestBinary(method, path, contentType, body) {
|
|
1981
|
-
const fullPath =
|
|
1983
|
+
const fullPath = `${API_PREFIX}${path}`;
|
|
1982
1984
|
this._lastMeta = {
|
|
1983
1985
|
region: this._region,
|
|
1984
1986
|
endpoint: `${method} ${path}`,
|
|
@@ -6824,7 +6826,7 @@ WHEN TO USE: at the start of a session to know what the agent can/can't do, afte
|
|
|
6824
6826
|
|
|
6825
6827
|
WHEN NOT TO USE: as a pre-flight gate before bulk ops \u2014 operations themselves return 429; this tool is for context, not gating. And: a recent quota snapshot showing "exhausted" is NOT a reason to refuse a write call when the user has just topped up \u2014 re-call this tool first, then proceed.
|
|
6826
6828
|
`;
|
|
6827
|
-
var leadbay_acknowledge_notification = `Acknowledge a Leadbay notification \u2014 i.e. tell the MCP and the backend "I've seen this and acted on it." Wraps \`POST /1.
|
|
6829
|
+
var leadbay_acknowledge_notification = `Acknowledge a Leadbay notification \u2014 i.e. tell the MCP and the backend "I've seen this and acted on it." Wraps \`POST /1.6/notifications/{id}/seen\` (default) or \`/archive\` (when \`archive:true\`) and drops the entry from the local inbox so subsequent \`_meta.notifications\` payloads stop carrying it.
|
|
6828
6830
|
|
|
6829
6831
|
**When to call.** After you read an entry from \`_meta.notifications\` or \`account_status.notifications\` and have revised whatever prior output the just-finished background work might have made stale (outreach drafts, lead lists, "available leads" claims, followup plans). Mark-seen tells the human team's pipeline you handled this and prevents the notification from re-surfacing on every subsequent tool response.
|
|
6830
6832
|
|
|
@@ -7434,7 +7436,7 @@ WHEN NOT TO USE: from agent flow \u2014 leadbay_adjust_audience handles the draf
|
|
|
7434
7436
|
|
|
7435
7437
|
This tool MUTATES state. The caller (agent or human-in-the-loop) is responsible for confirming intent before invocation; the MCP server does not soft-prompt for confirmation. See \`annotations.destructiveHint\`.
|
|
7436
7438
|
`;
|
|
7437
|
-
var leadbay_create_topup_link = `Generate a one-shot Stripe checkout session for an AI-credits top-up. Wraps \`POST /1.
|
|
7439
|
+
var leadbay_create_topup_link = `Generate a one-shot Stripe checkout session for an AI-credits top-up. Wraps \`POST /1.6/stripe/topup_checkout\` \u2192 \`{url}\`. Returns a fresh Stripe-hosted URL (~1 hour TTL); creating one does NOT charge the user \u2014 payment happens only after the user opens the URL and completes checkout in their browser.
|
|
7438
7440
|
|
|
7439
7441
|
**When a quota window is hit, offer top-up as the FIRST option.** A top-up clears the throttle immediately (no need to wait for the daily/weekly/monthly window reset). The flow:
|
|
7440
7442
|
|
|
@@ -8618,7 +8620,7 @@ follow-ups. On \`ambiguous_sectors\`, the only move is to pick a sector and re-c
|
|
|
8618
8620
|
If nothing fits, default to "switch to the new lens and pull leads" \u2014 never
|
|
8619
8621
|
invent a tool that doesn't exist.
|
|
8620
8622
|
`;
|
|
8621
|
-
var leadbay_open_billing_portal = `Generate a one-shot Stripe customer-portal URL. Wraps \`GET /1.
|
|
8623
|
+
var leadbay_open_billing_portal = `Generate a one-shot Stripe customer-portal URL. Wraps \`GET /1.6/stripe/portal\` \u2192 \`{url}\`. Returns a fresh Stripe-hosted URL the user can open to manage their existing Leadbay subscription: change plan tier, swap payment method, view invoices. The agent does NOT make subscription changes itself \u2014 it surfaces the URL and lets the user act.
|
|
8622
8624
|
|
|
8623
8625
|
Sibling of \`leadbay_create_topup_link\`. Use cases differ:
|
|
8624
8626
|
|
|
@@ -8896,7 +8898,7 @@ table. Detail + status priority below.
|
|
|
8896
8898
|
|
|
8897
8899
|
Pull KNOWN leads from the user's Monitor view \u2014 the re-engagement entry point. Use when the user asks "what should I follow up on", "leads I haven't contacted", "leads in [city]", "before my trip", or any phrasing implying pre-existing pipeline context. For NEW leads from Discover, use \`leadbay_pull_leads\`.
|
|
8898
8900
|
|
|
8899
|
-
Backend: wraps \`GET /1.
|
|
8901
|
+
Backend: wraps \`GET /1.6/monitor?personal=&liked=&filtered=&count=&page=\` plus, when \`set_filter\` is supplied, a preceding \`POST /1.6/monitor/filter\`. The Monitor filter is a single \`FilterItem\` per user \u2014 refreshing restores it.
|
|
8900
8902
|
|
|
8901
8903
|
**Filter mechanism \u2014 store-then-apply.** Pass \`set_filter: { criteria: FilterCriterion[] }\` to overwrite the server-stored filter, then the composite re-fetches with \`filtered:true\`. \`FilterCriterion\` is the backend's \`anyOf\` over 10 typed criteria: \`size\`, \`keywords\`, \`sector_ids\`, \`location_ids\`, \`custom_field\`(\`_comparison\`), \`yc\`, \`liked\`, \`last_action\` (MonitorActionType enum), \`last_action_date\` (with \`last_days\`).
|
|
8902
8904
|
|
|
@@ -24014,7 +24016,7 @@ function parseWriteEnv(env = process.env) {
|
|
|
24014
24016
|
}
|
|
24015
24017
|
|
|
24016
24018
|
// src/http-server.ts
|
|
24017
|
-
var VERSION = true ? "0.23.
|
|
24019
|
+
var VERSION = true ? "0.23.9" : "0.0.0-dev";
|
|
24018
24020
|
var PORT = Number(process.env.PORT ?? 8080);
|
|
24019
24021
|
var HOST = process.env.HOST ?? "0.0.0.0";
|
|
24020
24022
|
var sseSessions = /* @__PURE__ */ new Map();
|
package/dist/installer-gui.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leadbay/mcp",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.9",
|
|
4
4
|
"mcpName": "io.github.leadbay/leadbay-mcp",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server for Leadbay — AI lead discovery, qualification, and enrichment for Claude Desktop, Cursor, and Claude Code.",
|
|
6
6
|
"type": "module",
|