@leadbay/mcp 0.39.1 → 0.39.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/dist/bin.js CHANGED
@@ -6731,7 +6731,7 @@ prose paragraph. Full recipe below.
6731
6731
 
6732
6732
  Build a single-call mixed-mode itinerary for a field sales tour. Combines \`leadbay_pull_followups\` (Monitor leads in the city \u2014 known accounts) with \`leadbay_pull_leads\` (Discover wishlist \u2014 new prospects, then client-side filtered by city) so the agent can answer the canonical #3630 US1 ask: *"I'm visiting Limoges in 4 days \u2014 propose 3 customers + 3 qualified prospects + 3 new high-potential discoveries."*
6733
6733
 
6734
- **Geo resolution** is identical to \`leadbay_followups_map\`: pass \`city\` (any level from state down to neighborhood \u2014 state, *r\xE9gion*, county, city \u2014 the \`/geo/search\` resolver picks the best match), or a pre-resolved \`city_id\`. Ambiguous matches surface as \`status: "ambiguous_locations"\` + \`location_ambiguities[]\`; pick an id and re-call with \`city_id\`.
6734
+ **Geo resolution** is identical to \`leadbay_followups_map\`: pass \`city\` (any level from state down to neighborhood \u2014 state, *r\xE9gion*, county, city \u2014 the \`/geo/search\` resolver picks the best match), or a pre-resolved \`city_id\`. Ambiguous matches surface as \`status: "ambiguous_locations"\` + \`location_ambiguities[]\`; re-call with \`city_id\` set to the id you pick AND \`city\` set to that candidate's \`name\`. Both are needed: the id scopes the follow-ups, the name scopes the Discover leads, and with \`city_id\` alone \`discover_leads\` comes back empty.
6735
6735
 
6736
6736
  **One workspace = one country \u2014 a country name is NEVER a location filter.** The admin-area index holds no country nodes, so \`"France"\` matches the *commune of Francs* and \`"United States"\` matches *Statesboro*: the call is silently fenced to one village and every conclusion from it is wrong. City AND country named? Keep the city, drop the country.
6737
6737
 
@@ -6761,7 +6761,7 @@ not an itinerary. So for ANY country-level \`city\` \u2014 this workspace's own
6761
6761
  visiting and re-call with that. \`status: "country_level_location"\` carries the
6762
6762
  same instruction in its \`hint\`.
6763
6763
 
6764
- **Counts**: \`followups_count\` (default 6 \u2014 generous so the agent can split into "customers + qualified" client-side) and \`discover_count\` (default 6 after client-side geo filter). The composite over-pulls Discover (30 raw) because the wishlist endpoint has no server-side geo filter \u2014 it then filters by \`location.city/state/country/full\` substring match against the requested city. The \`discover_filter_note\` string in the response tells the agent the match ratio so it can be honest about coverage ("matched 3/30 by city/state" vs. "matched 12/30").
6764
+ **Counts**: \`followups_count\` (default 6 \u2014 generous so the agent can split into "customers + qualified" client-side) and \`discover_count\` (default 6 after client-side geo filter). The composite over-pulls Discover (30 raw) because the wishlist endpoint has no server-side geo filter \u2014 it then keeps the leads whose own \`location.city\` names the requested city, and falls back to \`location.state\` only when no city matched (which is what a regional ask like "Texas" or "\xCEle-de-France" looks like). \`location.country\` is never consulted. \`discover_filter_note\` reports the ratio and which field carried it, so the agent can be honest about coverage. **When it says no Discover lead is in the city, say that** \u2014 return the Monitor half and offer \`leadbay_find_new_leads\` for that city. Never fill the gap with leads from elsewhere.
6765
6765
 
6766
6766
  **What \`tour_plan\` does NOT do**: it doesn't persist the tour as a campaign artifact. To do that \u2014 create a "Limoges Tour \u2013 May 24" campaign and attach the selected accounts \u2014 chain into \`leadbay_create_campaign({lead_ids: [...selected_ids], name: 'Limoges Tour \u2013 <date>'})\` after the user picks. See the \`leadbay_plan_tour_in_city\` prompt for the full end-to-end orchestrator.
6767
6767
 
@@ -14962,13 +14962,33 @@ var init_followups_map = __esm({
14962
14962
  });
14963
14963
 
14964
14964
  // ../core/dist/composite/tour-plan.js
14965
- function cityMatches(lead, cityHint) {
14966
- if (!cityHint)
14967
- return true;
14968
- const hint = cityHint.toLowerCase();
14969
- const loc = lead?.location ?? {};
14970
- const haystacks = [loc.city, loc.state, loc.country, loc.full].filter((v) => typeof v === "string").map((v) => v.toLowerCase());
14971
- return haystacks.some((h) => h.includes(hint) || hint.includes(h));
14965
+ function normalizeGeo(value) {
14966
+ return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
14967
+ }
14968
+ function townName(value) {
14969
+ return normalizeGeo(value).replace(ADMIN_PREFIX, "");
14970
+ }
14971
+ function cityHintCore(cityHint) {
14972
+ const head = cityHint.split(",")[0] ?? "";
14973
+ const expanded = expandAlias(head);
14974
+ return { name: townName(expanded), isCity: expanded !== head };
14975
+ }
14976
+ function stateFieldOf(lead) {
14977
+ const state = lead?.location?.state;
14978
+ return typeof state === "string" ? normalizeGeo(state) : "";
14979
+ }
14980
+ function filterDiscoverByCity(leads, cityHint) {
14981
+ const hint = cityHint ? cityHintCore(cityHint) : { name: "", isCity: false };
14982
+ if (!hint.name)
14983
+ return { leads, matchedOn: null };
14984
+ const cityOf = (l) => typeof l?.location?.city === "string" ? townName(l.location.city) : "";
14985
+ const byCity = leads.filter((l) => cityOf(l) === hint.name);
14986
+ if (byCity.length > 0)
14987
+ return { leads: byCity, matchedOn: "city" };
14988
+ if (hint.isCity)
14989
+ return { leads: [], matchedOn: "city" };
14990
+ const byState = leads.filter((l) => stateFieldOf(l) === hint.name);
14991
+ return { leads: byState, matchedOn: "state" };
14972
14992
  }
14973
14993
  function toMapLocation(lead, mode) {
14974
14994
  const pos = lead?.location?.pos;
@@ -15018,7 +15038,7 @@ function buildMap(monitorLeads, discoverLeads2) {
15018
15038
  }
15019
15039
  };
15020
15040
  }
15021
- var DEFAULT_FOLLOWUPS_COUNT, DEFAULT_DISCOVER_COUNT, DISCOVER_OVER_PULL, tourPlan;
15041
+ var DEFAULT_FOLLOWUPS_COUNT, DEFAULT_DISCOVER_COUNT, DISCOVER_OVER_PULL, ADMIN_PREFIX, tourPlan;
15022
15042
  var init_tour_plan = __esm({
15023
15043
  "../core/dist/composite/tour-plan.js"() {
15024
15044
  "use strict";
@@ -15026,10 +15046,12 @@ var init_tour_plan = __esm({
15026
15046
  init_pull_leads();
15027
15047
  init_interactions();
15028
15048
  init_country_guard();
15049
+ init_geo_helpers();
15029
15050
  init_tool_descriptions_generated();
15030
15051
  DEFAULT_FOLLOWUPS_COUNT = 6;
15031
15052
  DEFAULT_DISCOVER_COUNT = 6;
15032
15053
  DISCOVER_OVER_PULL = 30;
15054
+ ADMIN_PREFIX = /^(?:city|town|village|borough|township|municipality) of /;
15033
15055
  tourPlan = {
15034
15056
  name: "leadbay_tour_plan",
15035
15057
  annotations: {
@@ -15049,7 +15071,7 @@ var init_tour_plan = __esm({
15049
15071
  },
15050
15072
  city_id: {
15051
15073
  type: "string",
15052
- description: "Pre-resolved admin_area id (numeric string). Bypasses the resolver."
15074
+ description: "Pre-resolved admin_area id (numeric string). Bypasses the resolver. Pass `city` alongside it with the NAME of the area you picked: the id scopes the Monitor half, and the name is the only thing that can scope the Discover half, which has no server-side geo filter. With `city_id` alone, `discover_leads` comes back empty."
15053
15075
  },
15054
15076
  followups_count: {
15055
15077
  type: "number",
@@ -15156,7 +15178,13 @@ var init_tour_plan = __esm({
15156
15178
  const discoverCount = params.discover_count ?? DEFAULT_DISCOVER_COUNT;
15157
15179
  const [followupsResult, leadsResult] = await Promise.allSettled([
15158
15180
  pullFollowups.execute(client, {
15159
- city: params.city,
15181
+ // A pre-resolved id bypasses the resolver, which is what its own
15182
+ // schema promises. Forwarding the free text alongside it sends the
15183
+ // name back through /geo/search, and the name is the thing that was
15184
+ // ambiguous — so an agent recovering from `ambiguous_locations` by
15185
+ // picking an id would be handed the same ambiguity again. Here the
15186
+ // free text stays behind and scopes the Discover half instead.
15187
+ city: params.city_id ? void 0 : params.city,
15160
15188
  city_id: params.city_id,
15161
15189
  count: followupsCount
15162
15190
  }, ctx),
@@ -15170,7 +15198,7 @@ var init_tour_plan = __esm({
15170
15198
  location_ambiguities: r.location_ambiguities,
15171
15199
  monitor_leads: [],
15172
15200
  discover_leads: [],
15173
- discover_filter_note: "City was ambiguous; pick an id and re-call to proceed.",
15201
+ discover_filter_note: "City was ambiguous; re-call with `city_id` set to the id you pick AND `city` set to that candidate's `name`. The id scopes the follow-ups; the name is what scopes the Discover leads.",
15174
15202
  map_locations: [],
15175
15203
  map_summary: {
15176
15204
  total_leads: 0,
@@ -15194,13 +15222,27 @@ var init_tour_plan = __esm({
15194
15222
  if (leadsResult.status === "rejected") {
15195
15223
  ctx?.logger?.warn?.(`tour_plan: pull_leads failed: ${leadsResult.reason?.message ?? leadsResult.reason}`);
15196
15224
  }
15197
- const filtered = rawDiscover.filter((l) => cityMatches(l, params.city));
15225
+ const cityName = params.city && !/^\d+$/.test(params.city.trim()) ? params.city : void 0;
15226
+ const knownId = params.city_id ?? (cityName ? void 0 : params.city);
15227
+ const idOnly = Boolean(knownId) && !cityName;
15228
+ const { leads: filtered, matchedOn } = idOnly ? { leads: [], matchedOn: null } : filterDiscoverByCity(rawDiscover, cityName);
15198
15229
  const discoverLeads2 = filtered.slice(0, discoverCount);
15199
15230
  const pulledLensId = leadsResult.status === "fulfilled" ? leadsResult.value?.lens?.id : null;
15200
15231
  if (pulledLensId != null) {
15201
15232
  reportLeadInteractions(client, pulledLensId, discoverLeads2.map((l) => l.id), ["LEAD_SEEN"], ctx?.logger);
15202
15233
  }
15203
- const filterNote = params.city ? `Matched ${filtered.length}/${rawDiscover.length} Discover leads to '${params.city}'; returning top ${discoverLeads2.length}.` : `No city filter applied; returning top ${discoverLeads2.length} Discover leads.`;
15234
+ let filterNote;
15235
+ if (idOnly) {
15236
+ filterNote = `Discover leads need the NAME of the place, and this call passed an area id (${knownId}) and no name. Re-call with \`city\` set to the name of that area, keeping \`city_id\` so the Monitor half stays on the area you picked. The follow-ups below are already scoped to it.`;
15237
+ } else if (!cityName) {
15238
+ filterNote = `No city filter applied; returning top ${discoverLeads2.length} Discover leads.`;
15239
+ } else if (matchedOn === null) {
15240
+ filterNote = `No usable city filter in '${params.city}'; returning top ${discoverLeads2.length} Discover leads.`;
15241
+ } else if (filtered.length === 0) {
15242
+ filterNote = `No Discover lead in the active lens is in '${params.city}' (checked ${rawDiscover.length} candidates by city, then by state/region). Say so; do NOT present leads from elsewhere as if they were in '${params.city}'.`;
15243
+ } else {
15244
+ filterNote = `Matched ${filtered.length}/${rawDiscover.length} Discover leads to '${params.city}' by ${matchedOn === "city" ? "city" : "state/region"}; returning top ${discoverLeads2.length}.`;
15245
+ }
15204
15246
  return {
15205
15247
  city: params.city ?? null,
15206
15248
  city_id: params.city_id ?? null,
@@ -31336,7 +31378,7 @@ var OAUTH_BASE_URLS = {
31336
31378
  fr: "https://staging.api.leadbay.app"
31337
31379
  }
31338
31380
  };
31339
- var VERSION = "0.39.1";
31381
+ var VERSION = "0.39.2";
31340
31382
  var HELP = `
31341
31383
  leadbay-mcp ${VERSION} \u2014 Leadbay Model Context Protocol server
31342
31384
 
@@ -9679,7 +9679,7 @@ prose paragraph. Full recipe below.
9679
9679
 
9680
9680
  Build a single-call mixed-mode itinerary for a field sales tour. Combines \`leadbay_pull_followups\` (Monitor leads in the city \u2014 known accounts) with \`leadbay_pull_leads\` (Discover wishlist \u2014 new prospects, then client-side filtered by city) so the agent can answer the canonical #3630 US1 ask: *"I'm visiting Limoges in 4 days \u2014 propose 3 customers + 3 qualified prospects + 3 new high-potential discoveries."*
9681
9681
 
9682
- **Geo resolution** is identical to \`leadbay_followups_map\`: pass \`city\` (any level from state down to neighborhood \u2014 state, *r\xE9gion*, county, city \u2014 the \`/geo/search\` resolver picks the best match), or a pre-resolved \`city_id\`. Ambiguous matches surface as \`status: "ambiguous_locations"\` + \`location_ambiguities[]\`; pick an id and re-call with \`city_id\`.
9682
+ **Geo resolution** is identical to \`leadbay_followups_map\`: pass \`city\` (any level from state down to neighborhood \u2014 state, *r\xE9gion*, county, city \u2014 the \`/geo/search\` resolver picks the best match), or a pre-resolved \`city_id\`. Ambiguous matches surface as \`status: "ambiguous_locations"\` + \`location_ambiguities[]\`; re-call with \`city_id\` set to the id you pick AND \`city\` set to that candidate's \`name\`. Both are needed: the id scopes the follow-ups, the name scopes the Discover leads, and with \`city_id\` alone \`discover_leads\` comes back empty.
9683
9683
 
9684
9684
  **One workspace = one country \u2014 a country name is NEVER a location filter.** The admin-area index holds no country nodes, so \`"France"\` matches the *commune of Francs* and \`"United States"\` matches *Statesboro*: the call is silently fenced to one village and every conclusion from it is wrong. City AND country named? Keep the city, drop the country.
9685
9685
 
@@ -9709,7 +9709,7 @@ not an itinerary. So for ANY country-level \`city\` \u2014 this workspace's own
9709
9709
  visiting and re-call with that. \`status: "country_level_location"\` carries the
9710
9710
  same instruction in its \`hint\`.
9711
9711
 
9712
- **Counts**: \`followups_count\` (default 6 \u2014 generous so the agent can split into "customers + qualified" client-side) and \`discover_count\` (default 6 after client-side geo filter). The composite over-pulls Discover (30 raw) because the wishlist endpoint has no server-side geo filter \u2014 it then filters by \`location.city/state/country/full\` substring match against the requested city. The \`discover_filter_note\` string in the response tells the agent the match ratio so it can be honest about coverage ("matched 3/30 by city/state" vs. "matched 12/30").
9712
+ **Counts**: \`followups_count\` (default 6 \u2014 generous so the agent can split into "customers + qualified" client-side) and \`discover_count\` (default 6 after client-side geo filter). The composite over-pulls Discover (30 raw) because the wishlist endpoint has no server-side geo filter \u2014 it then keeps the leads whose own \`location.city\` names the requested city, and falls back to \`location.state\` only when no city matched (which is what a regional ask like "Texas" or "\xCEle-de-France" looks like). \`location.country\` is never consulted. \`discover_filter_note\` reports the ratio and which field carried it, so the agent can be honest about coverage. **When it says no Discover lead is in the city, say that** \u2014 return the Monitor half and offer \`leadbay_find_new_leads\` for that city. Never fill the gap with leads from elsewhere.
9713
9713
 
9714
9714
  **What \`tour_plan\` does NOT do**: it doesn't persist the tour as a campaign artifact. To do that \u2014 create a "Limoges Tour \u2013 May 24" campaign and attach the selected accounts \u2014 chain into \`leadbay_create_campaign({lead_ids: [...selected_ids], name: 'Limoges Tour \u2013 <date>'})\` after the user picks. See the \`leadbay_plan_tour_in_city\` prompt for the full end-to-end orchestrator.
9715
9715
 
@@ -17373,13 +17373,34 @@ var followupsMap = {
17373
17373
  var DEFAULT_FOLLOWUPS_COUNT = 6;
17374
17374
  var DEFAULT_DISCOVER_COUNT = 6;
17375
17375
  var DISCOVER_OVER_PULL = 30;
17376
- function cityMatches(lead, cityHint) {
17377
- if (!cityHint)
17378
- return true;
17379
- const hint = cityHint.toLowerCase();
17380
- const loc = lead?.location ?? {};
17381
- const haystacks = [loc.city, loc.state, loc.country, loc.full].filter((v) => typeof v === "string").map((v) => v.toLowerCase());
17382
- return haystacks.some((h) => h.includes(hint) || hint.includes(h));
17376
+ function normalizeGeo(value) {
17377
+ return value.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, " ").trim();
17378
+ }
17379
+ var ADMIN_PREFIX = /^(?:city|town|village|borough|township|municipality) of /;
17380
+ function townName(value) {
17381
+ return normalizeGeo(value).replace(ADMIN_PREFIX, "");
17382
+ }
17383
+ function cityHintCore(cityHint) {
17384
+ const head = cityHint.split(",")[0] ?? "";
17385
+ const expanded = expandAlias(head);
17386
+ return { name: townName(expanded), isCity: expanded !== head };
17387
+ }
17388
+ function stateFieldOf(lead) {
17389
+ const state = lead?.location?.state;
17390
+ return typeof state === "string" ? normalizeGeo(state) : "";
17391
+ }
17392
+ function filterDiscoverByCity(leads, cityHint) {
17393
+ const hint = cityHint ? cityHintCore(cityHint) : { name: "", isCity: false };
17394
+ if (!hint.name)
17395
+ return { leads, matchedOn: null };
17396
+ const cityOf = (l) => typeof l?.location?.city === "string" ? townName(l.location.city) : "";
17397
+ const byCity = leads.filter((l) => cityOf(l) === hint.name);
17398
+ if (byCity.length > 0)
17399
+ return { leads: byCity, matchedOn: "city" };
17400
+ if (hint.isCity)
17401
+ return { leads: [], matchedOn: "city" };
17402
+ const byState = leads.filter((l) => stateFieldOf(l) === hint.name);
17403
+ return { leads: byState, matchedOn: "state" };
17383
17404
  }
17384
17405
  function toMapLocation(lead, mode) {
17385
17406
  const pos = lead?.location?.pos;
@@ -17448,7 +17469,7 @@ var tourPlan = {
17448
17469
  },
17449
17470
  city_id: {
17450
17471
  type: "string",
17451
- description: "Pre-resolved admin_area id (numeric string). Bypasses the resolver."
17472
+ description: "Pre-resolved admin_area id (numeric string). Bypasses the resolver. Pass `city` alongside it with the NAME of the area you picked: the id scopes the Monitor half, and the name is the only thing that can scope the Discover half, which has no server-side geo filter. With `city_id` alone, `discover_leads` comes back empty."
17452
17473
  },
17453
17474
  followups_count: {
17454
17475
  type: "number",
@@ -17555,7 +17576,13 @@ var tourPlan = {
17555
17576
  const discoverCount = params.discover_count ?? DEFAULT_DISCOVER_COUNT;
17556
17577
  const [followupsResult, leadsResult] = await Promise.allSettled([
17557
17578
  pullFollowups.execute(client, {
17558
- city: params.city,
17579
+ // A pre-resolved id bypasses the resolver, which is what its own
17580
+ // schema promises. Forwarding the free text alongside it sends the
17581
+ // name back through /geo/search, and the name is the thing that was
17582
+ // ambiguous — so an agent recovering from `ambiguous_locations` by
17583
+ // picking an id would be handed the same ambiguity again. Here the
17584
+ // free text stays behind and scopes the Discover half instead.
17585
+ city: params.city_id ? void 0 : params.city,
17559
17586
  city_id: params.city_id,
17560
17587
  count: followupsCount
17561
17588
  }, ctx),
@@ -17569,7 +17596,7 @@ var tourPlan = {
17569
17596
  location_ambiguities: r.location_ambiguities,
17570
17597
  monitor_leads: [],
17571
17598
  discover_leads: [],
17572
- discover_filter_note: "City was ambiguous; pick an id and re-call to proceed.",
17599
+ discover_filter_note: "City was ambiguous; re-call with `city_id` set to the id you pick AND `city` set to that candidate's `name`. The id scopes the follow-ups; the name is what scopes the Discover leads.",
17573
17600
  map_locations: [],
17574
17601
  map_summary: {
17575
17602
  total_leads: 0,
@@ -17593,13 +17620,27 @@ var tourPlan = {
17593
17620
  if (leadsResult.status === "rejected") {
17594
17621
  ctx?.logger?.warn?.(`tour_plan: pull_leads failed: ${leadsResult.reason?.message ?? leadsResult.reason}`);
17595
17622
  }
17596
- const filtered = rawDiscover.filter((l) => cityMatches(l, params.city));
17623
+ const cityName = params.city && !/^\d+$/.test(params.city.trim()) ? params.city : void 0;
17624
+ const knownId = params.city_id ?? (cityName ? void 0 : params.city);
17625
+ const idOnly = Boolean(knownId) && !cityName;
17626
+ const { leads: filtered, matchedOn } = idOnly ? { leads: [], matchedOn: null } : filterDiscoverByCity(rawDiscover, cityName);
17597
17627
  const discoverLeads2 = filtered.slice(0, discoverCount);
17598
17628
  const pulledLensId = leadsResult.status === "fulfilled" ? leadsResult.value?.lens?.id : null;
17599
17629
  if (pulledLensId != null) {
17600
17630
  reportLeadInteractions(client, pulledLensId, discoverLeads2.map((l) => l.id), ["LEAD_SEEN"], ctx?.logger);
17601
17631
  }
17602
- const filterNote = params.city ? `Matched ${filtered.length}/${rawDiscover.length} Discover leads to '${params.city}'; returning top ${discoverLeads2.length}.` : `No city filter applied; returning top ${discoverLeads2.length} Discover leads.`;
17632
+ let filterNote;
17633
+ if (idOnly) {
17634
+ filterNote = `Discover leads need the NAME of the place, and this call passed an area id (${knownId}) and no name. Re-call with \`city\` set to the name of that area, keeping \`city_id\` so the Monitor half stays on the area you picked. The follow-ups below are already scoped to it.`;
17635
+ } else if (!cityName) {
17636
+ filterNote = `No city filter applied; returning top ${discoverLeads2.length} Discover leads.`;
17637
+ } else if (matchedOn === null) {
17638
+ filterNote = `No usable city filter in '${params.city}'; returning top ${discoverLeads2.length} Discover leads.`;
17639
+ } else if (filtered.length === 0) {
17640
+ filterNote = `No Discover lead in the active lens is in '${params.city}' (checked ${rawDiscover.length} candidates by city, then by state/region). Say so; do NOT present leads from elsewhere as if they were in '${params.city}'.`;
17641
+ } else {
17642
+ filterNote = `Matched ${filtered.length}/${rawDiscover.length} Discover leads to '${params.city}' by ${matchedOn === "city" ? "city" : "state/region"}; returning top ${discoverLeads2.length}.`;
17643
+ }
17603
17644
  return {
17604
17645
  city: params.city ?? null,
17605
17646
  city_id: params.city_id ?? null,
@@ -28619,7 +28660,7 @@ function parseWriteEnv(env = process.env) {
28619
28660
  }
28620
28661
 
28621
28662
  // src/http-server.ts
28622
- var VERSION = true ? "0.39.1" : "0.0.0-dev";
28663
+ var VERSION = true ? "0.39.2" : "0.0.0-dev";
28623
28664
  var PORT = Number(process.env.PORT ?? 8080);
28624
28665
  var HOST = process.env.HOST ?? "0.0.0.0";
28625
28666
  var logger = {
@@ -1805,7 +1805,7 @@ var init_installer_gui = __esm({
1805
1805
  init_install_dxt();
1806
1806
  init_install_shared();
1807
1807
  init_oauth();
1808
- VERSION = true ? "0.39.1" : "0.0.0-dev";
1808
+ VERSION = true ? "0.39.2" : "0.0.0-dev";
1809
1809
  MESSAGES = {
1810
1810
  en: {
1811
1811
  installer: {
@@ -1068,7 +1068,7 @@ async function oauthLogin(opts) {
1068
1068
  }
1069
1069
 
1070
1070
  // installer/installer-gui.ts
1071
- var VERSION = true ? "0.39.1" : "0.0.0-dev";
1071
+ var VERSION = true ? "0.39.2" : "0.0.0-dev";
1072
1072
  var MESSAGES = {
1073
1073
  en: {
1074
1074
  installer: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leadbay/mcp",
3
- "version": "0.39.1",
3
+ "version": "0.39.2",
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",