@leadbay/mcp 0.2.2 → 0.4.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 +91 -0
- package/MIGRATION.md +72 -0
- package/README.md +74 -23
- package/dist/bin.js +358 -75
- package/dist/{chunk-FJBO2MY2.js → chunk-O2UOXRZO.js} +778 -12
- package/dist/{dist-FENQ2I7R.js → dist-RONMQBYU.js} +5 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# Changelog — @leadbay/mcp
|
|
2
2
|
|
|
3
|
+
## 0.4.0 — 2026-05-04
|
|
4
|
+
|
|
5
|
+
### `leadbay_import_leads` 0.2.0 — custom field mapping
|
|
6
|
+
|
|
7
|
+
The MCP tool now drives the same CRM-import wizard the web UI exposes — pass arbitrary CSV-shaped records and tell Leadbay which column maps to which `StandardCrmFieldType`.
|
|
8
|
+
|
|
9
|
+
**Two modes** (pass exactly one of `domains` / `records`):
|
|
10
|
+
|
|
11
|
+
- **Mode A (existing, unchanged):** `domains: [{domain, name?}]` — synthesizes a 2-column CSV (LEAD_NAME, LEAD_WEBSITE) and uses the default mapping. Output shape is identical to 0.1.x: `{ leads: [{domain, leadId, name}], not_imported: [{domain, reason}], ... }`.
|
|
12
|
+
- **Mode B (new):** `records: [{Col1, Col2, ...}]` plus `mappings: { fields: { Col1: "LEAD_NAME", Col2: "LEAD_WEBSITE", Col3: "LEAD_SECTOR", ... } }`. The tool synthesizes a CSV from the union of record keys (sorted, deterministic) and POSTs the caller-supplied mapping to `/imports/{id}/update_mappings`. Output shape: `{ leads: [{rowId, domain?, leadId, name}], not_imported: [{rowId, domain?, reason}], ... }`. `rowId` round-trips your input row order; `domain` populated only when `LEAD_WEBSITE` was mapped and the value parsed.
|
|
13
|
+
|
|
14
|
+
Mappings.fields must include `LEAD_NAME` or `LEAD_WEBSITE` — the wizard's resolver needs at least one of those to find a lead. Other CRM fields (`LEAD_SECTOR`, `LEAD_LOCATION`, `LEAD_SIZE`, `EMAIL`, `CRM_ID`, `LEADBAY_ID`, `DEAL_CRM_ID`, `CONTACT_TITLE`, `LEAD_STATUS`, `LEAD_STATUS_DATE`) are passed through verbatim.
|
|
15
|
+
|
|
16
|
+
**Validation (records mode):** new typed error codes — `IMPORT_INPUT_CONFLICT` (both modes supplied), `IMPORT_MAPPING_REQUIRED` (no mappings.fields), `IMPORT_MAPPING_NO_RESOLVER` (no LEAD_NAME or LEAD_WEBSITE in mapping), `IMPORT_MAPPING_KEY_UNKNOWN` (mapping key absent from records), `IMPORT_RESERVED_COLUMN` (record or mapping key matches `MCP_ROW_ID` case-insensitively), `IMPORT_INVALID_COLUMN_NAME` (column name >128 chars or contains control chars), `IMPORT_INVALID_CELL_TYPE` (cell value is array/object — coerce to string before passing). null/undefined cells coerce to "", numbers/booleans coerce via `String(v)`.
|
|
17
|
+
|
|
18
|
+
**Security:** user-supplied column names now flow through the same `escapeCsvCell` (RFC 4180 quoting + formula-injection prefix) that data values use. Header injection vectors (`=`, `+`, `-`, `@`, `,`, `"`, newline) are neutered.
|
|
19
|
+
|
|
20
|
+
**Backward compat:** Mode A output shape unchanged — the new `rowId` field is records-mode only. Existing `domains: [...]` callers see no diff.
|
|
21
|
+
|
|
22
|
+
## 0.3.0 — 2026-04-29
|
|
23
|
+
|
|
24
|
+
Behavior-changing release: closes [product#3504](https://github.com/leadbay/product/issues/3504) end-to-end. Default-installed MCP server now matches its own system prompt out of the box, the `login` command never lands a bearer token in scrollback by default, and `claude mcp add` registers Leadbay at user scope so it's visible from any project.
|
|
25
|
+
|
|
26
|
+
### Coverage — composite write tools default ON
|
|
27
|
+
|
|
28
|
+
- **`LEADBAY_MCP_WRITE` default is now `"1"` (ON).** The composite write tools (`leadbay_bulk_qualify_leads`, `leadbay_enrich_titles`, `leadbay_refine_prompt`, `leadbay_report_outreach`, `leadbay_adjust_audience`, `leadbay_answer_clarification`, `leadbay_import_leads`) are exposed by default. Set `LEADBAY_MCP_WRITE=0` (or `--no-write` on `install`) to disable them.
|
|
29
|
+
- **`SERVER_INSTRUCTIONS` is now dynamic.** The system prompt sent to MCP clients references only the tools actually registered on this instance. Read-only-mode agents receive a different prompt that omits the verification mandate and tells the agent to ask the user to enable writes if they request a config-mutating action.
|
|
30
|
+
- **`leadbay-mcp install --include-write` is a no-op (deprecated).** Writes are on by default. Pass `--no-write` for the inverse. The deprecation warning prints **before** the password prompt so it's not buried.
|
|
31
|
+
- **`LEADBAY_MCP_WRITE` value-vocabulary expanded.** In 0.2.x only `"1"` was ON; `"true"` / `"yes"` / `"on"` were treated as OFF. In 0.3.0 the parser accepts all of those as ON, and `"0"` / `"false"` / `"no"` / `"off"` as OFF. Unrecognized values default to ON with a one-shot stderr warning. **Existing operators using `=true` / `=yes` / `=on` will see writes flip ON.** See [MIGRATION.md](./MIGRATION.md).
|
|
32
|
+
|
|
33
|
+
### Login — no token in stdout
|
|
34
|
+
|
|
35
|
+
- **`leadbay-mcp login` default writes a 0600-mode credentials file.** The path resolves to `$XDG_CONFIG_HOME/leadbay/credentials.json` if set, else `~/Library/Application Support/leadbay/credentials.json` on macOS, `%APPDATA%\leadbay\credentials.json` on Windows, else `~/.config/leadbay/credentials.json`. Existing `~/.leadbay-mcp.json` files (0.2.x) are still honored on this run with a deprecation note pointing at the new path (no automatic file move).
|
|
36
|
+
- **`--unsafe-print-token`** restores the previous "print JSON config to stdout" behavior. The deprecated `--print-token` alias still works for one release with a deprecation warning.
|
|
37
|
+
- **Collision detection** — if the target credentials file already exists with a different `LEADBAY_TOKEN` or `LEADBAY_REGION`, `login` refuses without `--force` and tells the operator how to keep both files.
|
|
38
|
+
- **EACCES / EROFS / ENOENT** errors on the file write print actionable remediation pointing at `--write-config /tmp/...` or `--unsafe-print-token`.
|
|
39
|
+
|
|
40
|
+
### Scope — visible from any project
|
|
41
|
+
|
|
42
|
+
- **`leadbay-mcp install` now passes `--scope user` to `claude mcp add`.** This was Ludo's third complaint in #3504: the default `claude mcp add` is project-local, so a freshly-opened conversation from a different directory can't see the server. README §2 (Claude Code), §1 (install), and §4 (troubleshooting table) all reflect the user-scope recommendation.
|
|
43
|
+
|
|
44
|
+
### Migration
|
|
45
|
+
|
|
46
|
+
- Read [MIGRATION.md](./MIGRATION.md) for the value-vocabulary flip, the login default, and the install scope change.
|
|
47
|
+
- The legacy DXT manifest key (`leadbay_mcp_write`) is unchanged in shape — it now defaults `true` (ON) and feeds the same `LEADBAY_MCP_WRITE` env var. Users who explicitly set the toggle to `false` keep their read-only behavior; users who never touched it (the bug case Ludo hit) now get the new default ON.
|
|
48
|
+
- Tests: dropped the `SERVER_INSTRUCTIONS` const re-export. Tests now exercise `buildServerInstructions(exposedSet)` directly across the default/read-only/advanced matrices. New unit suites: `parse-write-env.test.ts`, `login-default.test.ts`, `install-flags.test.ts`.
|
|
49
|
+
|
|
50
|
+
### Known follow-up (0.4.0)
|
|
51
|
+
|
|
52
|
+
- `compositeWriteTools` will split into safer-tier (credit-spending: bulk_qualify_leads, enrich_titles, report_outreach, answer_clarification) and config-mutating-tier (refine_prompt, adjust_audience, import_leads), with audit-log + one-click undo on the config-mutating side. Tracked separately.
|
|
53
|
+
|
|
54
|
+
## 0.2.5 — 2026-04-28
|
|
55
|
+
|
|
56
|
+
New `leadbay_import_leads` composite write tool.
|
|
57
|
+
|
|
58
|
+
- **New tool: [`leadbay_import_leads`](https://github.com/leadbay/product/issues/3537)** — accepts a list of `{ domain, name? }` and returns Leadbay `leadId`s for the ones the crawler already knows. Output is naturally chainable into `leadbay_bulk_qualify_leads({ leadIds })` and `leadbay_research_lead`. Gated behind `LEADBAY_MCP_WRITE=1` (MCP) and `exposeWrite=true` (OpenClaw).
|
|
59
|
+
|
|
60
|
+
**⚠️ Writes user state.** Internally wraps Leadbay's CRM-import wizard (the only domain-import primitive the backend ships today). Each call:
|
|
61
|
+
- creates a row in the user's CRM-imports list (visible in the web UI)
|
|
62
|
+
- touches onboarding state (`startFileless`, onboarding step → PROCESSING)
|
|
63
|
+
|
|
64
|
+
Suitable for occasional automation. **Not** suitable for high-cadence (>5 calls/day) — the right primitive is a clean async-import-with-crawl backend endpoint, tracked as a follow-up issue (`leadbay/backend` — prolonged async import jobs).
|
|
65
|
+
|
|
66
|
+
**Surface:**
|
|
67
|
+
- Input: `{ domains: [{domain, name?}], dry_run?: boolean, per_phase_budget_ms?, total_budget_ms? }`.
|
|
68
|
+
- Output: `{ leads: [{domain, leadId, name}], not_imported: [{domain, reason}], importIds, region, _meta }` where `reason ∈ malformed | no_match | uncrawled | ambiguous | internal_error | dry_run`.
|
|
69
|
+
- `dry_run: true` runs preprocess only — skips the lead-CRM linking. The CRM-imports row still appears (the wedge can't fully eliminate it without backend changes), but the heavier side effect of committing matches is skipped.
|
|
70
|
+
- 8 typed error codes (`IMPORT_PREPROCESS_FAILED`, `IMPORT_PROCESSING_FAILED`, `IMPORT_BUDGET_EXHAUSTED`, `IMPORT_NOT_TERMINAL`, `IMPORT_ADMIN_REQUIRED`, `IMPORT_BILLING_REQUIRED`, `IMPORT_PAGINATION_RUNAWAY`, `IMPORT_EMPTY_INPUT`) — every one carries `{ code, message, hint }`. Per-domain `not_imported.reason="internal_error"` covers irreconcilable rows from the wizard.
|
|
71
|
+
|
|
72
|
+
**Limitations (v1):** uncrawled domains land in `not_imported` with `reason: "uncrawled"` — the tool does NOT create new Leadbay leads for unknown websites; the caller decides what to do. The backend follow-up will lift this.
|
|
73
|
+
|
|
74
|
+
**Implementation notes:** preflight admin check (fails in <500ms instead of after a 30s wizard timeout), MCP_ROW_ID-based reconciliation (resilient to wizard URL canonicalization), client-side chunking at 100 domains per CSV upload, stabilization loop after `processing.finished` to avoid races where some records are still in `MATCHING|IMPORTING`, RFC 4180 quoting + formula-injection (`=`/`+`/`-`/`@`) prefix on every cell, AbortSignal plumbing returns `{cancelled: true, importIds, ...}` so callers can recover. New helper `LeadbayClient.requestRawBinary()` for the CSV upload — mirrors `request()` exactly (auth, semaphore, error mapping, `_lastMeta`, `LEADBAY_MOCK=1` mock-mode parity).
|
|
75
|
+
|
|
76
|
+
- **README**: new `## Write tools (LEADBAY_MCP_WRITE=1)` section with the import quickstart.
|
|
77
|
+
|
|
78
|
+
## 0.2.4 — 2026-04-22
|
|
79
|
+
|
|
80
|
+
Claude Desktop 2026 compatibility + install UX polish. Also publishes the `refine_prompt` `/user_prompt` wire-key fix that landed on `main` in 0.2.3 but never reached npm.
|
|
81
|
+
|
|
82
|
+
- **Fix [product#3504](https://github.com/leadbay/product/issues/3504)** — `install --target claude-desktop` no longer silently no-ops on Claude Desktop 2026. The app moved to the DXT (Desktop Extension) system; the legacy `claude_desktop_config.json` is UI-prefs-only there and gets overwritten on every prefs save, so a block written to it disappears a few minutes later. `install` now detects DXT (via `Claude Extensions/`, `extensions-installations.json`, or `dxt:*` keys in `config.json`), prints a loud warning pointing at the `.dxt` bundle, and default-skips the legacy write. Pass `--force-legacy` to override.
|
|
83
|
+
- **New: shipping a `.dxt` bundle** — drag-drop into Claude Desktop 2026 → Settings → Extensions. Uploaded to each [GitHub Release](https://github.com/leadbay/leadclaw/releases). Dialog asks for token + region + write-toggle; no terminal required. Manifest is DXT 0.2 (`dxt_version: "0.2"`, `user_config.leadbay_token.sensitive: true`). Source for the build lives in `packages/dxt/`.
|
|
84
|
+
- **Fix**: `login` 401 errors no longer end with a dangling `:` when the backend returns an empty body. Messages now read `login failed (401) at <url> (wrong email or password?)`. 429/5xx get their own hints too. The core helper `formatLoginError` is exported from `@leadbay/core` so the MCP and ClawHub surfaces stay in sync.
|
|
85
|
+
- **README**: new section on `npm install -g` EACCES (sudo / npx / nvm workarounds — common on the official nodejs.org `.pkg`), and a pointer to the `.dxt` install for Claude Desktop 2026.
|
|
86
|
+
- **Also shipping** (previously merged but not yet published to npm) — `leadbay_refine_prompt` / `leadbay_set_user_prompt` now send `{ user_prompt }` instead of `{ prompt }` to `POST /user_prompt` ([product#3508](https://github.com/leadbay/product/issues/3508)). Fixes the JSON deserialization 400 Ludo hit during the 0.2.2 install session.
|
|
87
|
+
|
|
88
|
+
## 0.2.3 — 2026-04-21
|
|
89
|
+
|
|
90
|
+
Bug fix release.
|
|
91
|
+
|
|
92
|
+
- **Fix [product#3508](https://github.com/leadbay/product/issues/3508)**: `leadbay_refine_prompt` (and the granular `leadbay_set_user_prompt`) now send the correct `{ user_prompt }` body key to `POST /organizations/{orgId}/user_prompt`. Previous versions sent `{ prompt }`, which the backend's strict kotlinx.serialization rejected with a JSON deserialization error (400). The `dry_run` preview for both tools was printing the wrong shape too, which hid the mismatch from anyone inspecting it. New unit tests pin the wire key so this contract can't silently regress again.
|
|
93
|
+
|
|
3
94
|
## 0.2.2 — 2026-04-21
|
|
4
95
|
|
|
5
96
|
Bug fix + contract correction + mental-model docs release.
|
package/MIGRATION.md
CHANGED
|
@@ -1,3 +1,75 @@
|
|
|
1
|
+
# Migration: leadbay-mcp 0.2.x → 0.3.0
|
|
2
|
+
|
|
3
|
+
This release fixes [product#3504](https://github.com/leadbay/product/issues/3504): the default-installed MCP server's system prompt told the agent to call tools that the server didn't actually expose. Three behavior changes you need to know about.
|
|
4
|
+
|
|
5
|
+
## 1. `LEADBAY_MCP_WRITE` defaults to ON
|
|
6
|
+
|
|
7
|
+
In 0.2.x the composite write tools (`leadbay_bulk_qualify_leads`, `leadbay_enrich_titles`, `leadbay_refine_prompt`, `leadbay_report_outreach`, `leadbay_adjust_audience`, `leadbay_answer_clarification`, `leadbay_import_leads`) were gated behind `LEADBAY_MCP_WRITE=1`. The `SERVER_INSTRUCTIONS` referenced them anyway → users got an agent system prompt that lied about what was available.
|
|
8
|
+
|
|
9
|
+
**0.3.0**: `LEADBAY_MCP_WRITE` defaults to `"1"` (ON). The system prompt is built from the actual exposed tool set, so it stops lying. To restore the previous read-only behavior, set `LEADBAY_MCP_WRITE=0` (or `--no-write` on `leadbay-mcp install`).
|
|
10
|
+
|
|
11
|
+
### Value-vocabulary flip
|
|
12
|
+
|
|
13
|
+
In 0.2.x the parser was strict: only `LEADBAY_MCP_WRITE === "1"` turned writes on. So `=true`, `=yes`, `=on` were treated as OFF (probably accidentally — the user clearly meant "on"). The 0.3.0 parser accepts all of these as ON:
|
|
14
|
+
|
|
15
|
+
| Value | 0.2.x meaning | 0.3.0 meaning |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| unset | OFF | **ON** |
|
|
18
|
+
| `""` | OFF | **ON** |
|
|
19
|
+
| `"1"` / `"true"` / `"yes"` / `"on"` | OFF (only `"1"`) / OFF (the rest) | **ON** |
|
|
20
|
+
| `"0"` / `"false"` / `"no"` / `"off"` | OFF | OFF |
|
|
21
|
+
| anything else | OFF | ON + stderr warning |
|
|
22
|
+
|
|
23
|
+
If you were relying on `LEADBAY_MCP_WRITE=true` to mean OFF (unlikely but possible), switch to `LEADBAY_MCP_WRITE=0`.
|
|
24
|
+
|
|
25
|
+
## 2. `leadbay-mcp login` no longer prints the token to stdout
|
|
26
|
+
|
|
27
|
+
In 0.2.x `login` printed the bearer token (inside an MCP-config JSON blob) to stdout by default, with a stderr warning. Real users (Ludo's incident) had tokens leak into terminal scrollback / agent chat / CI logs.
|
|
28
|
+
|
|
29
|
+
**0.3.0**: `login` writes a `0600`-mode credentials file by default. The path resolves per-platform:
|
|
30
|
+
|
|
31
|
+
| Platform | Default path |
|
|
32
|
+
|---|---|
|
|
33
|
+
| Linux (or anywhere `XDG_CONFIG_HOME` is set) | `$XDG_CONFIG_HOME/leadbay/credentials.json` (or `~/.config/leadbay/credentials.json`) |
|
|
34
|
+
| macOS | `~/Library/Application Support/leadbay/credentials.json` |
|
|
35
|
+
| Windows | `%APPDATA%\leadbay\credentials.json` |
|
|
36
|
+
|
|
37
|
+
If `~/.leadbay-mcp.json` (the 0.2.x default) already exists, `login` writes to that path with a one-shot deprecation note pointing at the new location.
|
|
38
|
+
|
|
39
|
+
### `--unsafe-print-token` (legacy CI use)
|
|
40
|
+
|
|
41
|
+
Pass `--unsafe-print-token` to restore the old "print to stdout" behavior. The deprecated `--print-token` alias still works for one release with a warning. Use only if you have to — the token will end up in scrollback / logs.
|
|
42
|
+
|
|
43
|
+
### Collision detection
|
|
44
|
+
|
|
45
|
+
If the target file already exists with a different `LEADBAY_TOKEN` or `LEADBAY_REGION`, `login` refuses without `--force` and tells you how to keep both files. Toggling between accounts no longer silently overwrites the prior token.
|
|
46
|
+
|
|
47
|
+
### File-write errors
|
|
48
|
+
|
|
49
|
+
`EACCES` / `EROFS` / `ENOENT` print actionable remediation pointing at `--write-config /tmp/...` or `--unsafe-print-token`.
|
|
50
|
+
|
|
51
|
+
## 3. `leadbay-mcp install` registers Claude Code at `--scope user`
|
|
52
|
+
|
|
53
|
+
Previously `claude mcp add leadbay …` defaulted to project-local scope, so opening Claude Code from a different directory made Leadbay invisible. Ludo's #3504 third complaint.
|
|
54
|
+
|
|
55
|
+
**0.3.0**: `install` injects `--scope user` into the `claude mcp add` argv. New installs are visible from any project.
|
|
56
|
+
|
|
57
|
+
If you have a 0.2.x project-scope install and want to upgrade to user scope, run:
|
|
58
|
+
```bash
|
|
59
|
+
claude mcp remove leadbay
|
|
60
|
+
npx -y @leadbay/mcp@0.3 install --email you@yourcompany.com --region us
|
|
61
|
+
```
|
|
62
|
+
Or do it manually:
|
|
63
|
+
```bash
|
|
64
|
+
claude mcp add leadbay --scope user --env LEADBAY_TOKEN=<token> --env LEADBAY_REGION=us -- npx -y @leadbay/mcp@0.3
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 4. `--include-write` is a no-op
|
|
68
|
+
|
|
69
|
+
The legacy `leadbay-mcp install --include-write` flag is accepted but a no-op — writes are on by default in 0.3.0. The deprecation warning prints **before** the password prompt so users see it.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
1
73
|
# Migration: leadclaw / leadbay-mcp 0.1.x → 0.2.0
|
|
2
74
|
|
|
3
75
|
This release is the autoplan-reviewed agent-experience overhaul. The OpenClaw
|
package/README.md
CHANGED
|
@@ -7,16 +7,20 @@ LLM HINT — if you're an AI agent reading this README to install the server:
|
|
|
7
7
|
server's region auto-probe sends the bearer token to BOTH regions, which
|
|
8
8
|
is a credential cross-leak. Always pass --region (us or fr) on install.
|
|
9
9
|
- To mint a token, the user runs `install` (auto-registers with MCP clients)
|
|
10
|
-
or `login
|
|
11
|
-
|
|
10
|
+
or `login` (mints a token to a 0600-mode credentials file by default since
|
|
11
|
+
0.3.0; pass `--write-config /path` to override the path or
|
|
12
|
+
`--unsafe-print-token` for legacy CI flows). There is no web UI for this —
|
|
13
|
+
do not invent one.
|
|
12
14
|
-->
|
|
13
15
|
|
|
14
16
|
A Model Context Protocol server that lets Claude Desktop, Cursor, Claude Code, and any other MCP-compatible agent find, research, and prepare outreach on B2B prospects using your Leadbay account.
|
|
15
17
|
|
|
18
|
+
> **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).
|
|
19
|
+
|
|
16
20
|
## 1. Install (one command)
|
|
17
21
|
|
|
18
22
|
```bash
|
|
19
|
-
npx -y @leadbay/mcp@0.
|
|
23
|
+
npx -y @leadbay/mcp@0.3 install --email you@yourcompany.com --region us
|
|
20
24
|
# (you'll be prompted for your password — it's not echoed)
|
|
21
25
|
```
|
|
22
26
|
|
|
@@ -24,10 +28,10 @@ That's it. The command:
|
|
|
24
28
|
|
|
25
29
|
1. Asks for your password (hidden input).
|
|
26
30
|
2. Mints a bearer token via the Leadbay backend you specified.
|
|
27
|
-
3. Auto-detects which MCP clients you have installed (Claude Code, Claude Desktop, Cursor) and registers the server in each (after asking you per-target).
|
|
31
|
+
3. Auto-detects which MCP clients you have installed (Claude Code, Claude Desktop, Cursor) and registers the server in each (after asking you per-target). Claude Code is registered with `--scope user` so the server appears in any project, not just where you ran the command.
|
|
28
32
|
4. The token is written into the client config files — **never to your terminal scrollback**.
|
|
29
33
|
|
|
30
|
-
Add `--
|
|
34
|
+
Add `--no-write` to disable the composite write tools (`refine_prompt`, `report_outreach`, `adjust_audience`, etc. — ON by default since 0.3.0; pass `--no-write` for a read-only agent). Add `--yes` for non-interactive runs (CI / scripts). Add `--target claude-code,cursor` to scope to specific clients. The legacy `--include-write` flag is accepted but is now a no-op.
|
|
31
35
|
|
|
32
36
|
`--region us|fr` is required by default — it pins which Leadbay backend gets your password and avoids a silent cross-region credential leak. If you really don't know your region, opt in with `--allow-region-fallback` (your password will hit BOTH backends if the first 401s).
|
|
33
37
|
|
|
@@ -35,16 +39,27 @@ The token is **session-scoped** (full account access, password-equivalent). Trea
|
|
|
35
39
|
|
|
36
40
|
**Don't have a Leadbay account?** [Register here](https://wow.leadbay.ai/?register=true).
|
|
37
41
|
|
|
42
|
+
### Claude Desktop 2026 (DXT)
|
|
43
|
+
|
|
44
|
+
Claude Desktop 2026 ships the DXT (Desktop Extension) system — the legacy `claude_desktop_config.json` is UI-prefs-only there and gets overwritten by the app. If you're on 2026, **install the `.dxt` bundle** from [Releases](https://github.com/leadbay/leadclaw/releases/latest) (drag-drop into Settings → Extensions). `leadbay-mcp install` detects this and skips the legacy write automatically.
|
|
45
|
+
|
|
46
|
+
### `npm install -g` says "EACCES" / "permission denied"
|
|
47
|
+
|
|
48
|
+
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:
|
|
49
|
+
|
|
50
|
+
- **Use `npx` (recommended, no global install):** all examples above use `npx -y @leadbay/mcp@0.3 ...` — no global install needed.
|
|
51
|
+
- **`sudo npm install -g @leadbay/mcp`** (enter your macOS password).
|
|
52
|
+
- **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.
|
|
53
|
+
|
|
38
54
|
### If you'd rather mint a token without auto-install
|
|
39
55
|
|
|
40
56
|
```bash
|
|
41
|
-
npx -y @leadbay/mcp@0.
|
|
57
|
+
npx -y @leadbay/mcp@0.3 login \
|
|
42
58
|
--email you@yourcompany.com \
|
|
43
|
-
--region us
|
|
44
|
-
--write-config ~/.leadbay-mcp.json
|
|
59
|
+
--region us
|
|
45
60
|
```
|
|
46
61
|
|
|
47
|
-
|
|
62
|
+
Default writes a `0600`-mode JSON file at the platform-correct credentials path (`$XDG_CONFIG_HOME/leadbay/credentials.json` on Linux, `~/Library/Application Support/leadbay/credentials.json` on macOS, `%APPDATA%\leadbay\credentials.json` on Windows). Pass `--write-config /some/path.json` to override the path. Pass `--unsafe-print-token` for legacy CI flows that scrape stdout (the token will end up in scrollback / logs — only use this if you have to). Pass `--force` to overwrite an existing file from a different account.
|
|
48
63
|
|
|
49
64
|
## 2. Quickstart
|
|
50
65
|
|
|
@@ -57,7 +72,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) o
|
|
|
57
72
|
"mcpServers": {
|
|
58
73
|
"leadbay": {
|
|
59
74
|
"command": "npx",
|
|
60
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
75
|
+
"args": ["-y", "@leadbay/mcp@0.3"],
|
|
61
76
|
"env": {
|
|
62
77
|
"LEADBAY_TOKEN": "<paste-token-from-step-1>",
|
|
63
78
|
"LEADBAY_REGION": "us"
|
|
@@ -78,7 +93,7 @@ In Cursor settings, add the MCP server:
|
|
|
78
93
|
"mcp.servers": {
|
|
79
94
|
"leadbay": {
|
|
80
95
|
"command": "npx",
|
|
81
|
-
"args": ["-y", "@leadbay/mcp@0.
|
|
96
|
+
"args": ["-y", "@leadbay/mcp@0.3"],
|
|
82
97
|
"env": { "LEADBAY_TOKEN": "<paste-token>", "LEADBAY_REGION": "us" }
|
|
83
98
|
}
|
|
84
99
|
}
|
|
@@ -88,20 +103,22 @@ In Cursor settings, add the MCP server:
|
|
|
88
103
|
### Claude Code
|
|
89
104
|
|
|
90
105
|
```bash
|
|
91
|
-
claude mcp add leadbay \
|
|
106
|
+
claude mcp add leadbay --scope user \
|
|
92
107
|
--env LEADBAY_TOKEN=<paste-token> \
|
|
93
108
|
--env LEADBAY_REGION=us \
|
|
94
|
-
-- npx -y @leadbay/mcp@0.
|
|
109
|
+
-- npx -y @leadbay/mcp@0.3
|
|
95
110
|
```
|
|
96
111
|
|
|
97
|
-
>
|
|
112
|
+
> **`--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.
|
|
113
|
+
|
|
114
|
+
> To **disable** the composite write tools (refine_prompt, report_outreach, adjust_audience, etc.), add `--env LEADBAY_MCP_WRITE=0`. They are ON by default since 0.3.0. The legacy `LEADBAY_MCP_WRITE=1` opt-in is now a no-op.
|
|
98
115
|
|
|
99
116
|
### Verify it works
|
|
100
117
|
|
|
101
118
|
Before starting Claude, run:
|
|
102
119
|
|
|
103
120
|
```bash
|
|
104
|
-
LEADBAY_TOKEN=<paste-token> npx -y @leadbay/mcp@0.
|
|
121
|
+
LEADBAY_TOKEN=<paste-token> npx -y @leadbay/mcp@0.3 doctor
|
|
105
122
|
```
|
|
106
123
|
|
|
107
124
|
Expected output:
|
|
@@ -131,28 +148,30 @@ Leadbay connection OK.
|
|
|
131
148
|
| `No enrichment credits remaining` | Out of quota | Contact Leadbay support to extend quota |
|
|
132
149
|
| 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. |
|
|
133
150
|
| 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). |
|
|
151
|
+
| 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.3` |
|
|
152
|
+
| 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+) |
|
|
134
153
|
|
|
135
154
|
## 5. Upgrade & rotation
|
|
136
155
|
|
|
137
|
-
**Upgrade**: change the pinned minor in your config, e.g. `"@leadbay/mcp@0.
|
|
156
|
+
**Upgrade**: change the pinned minor in your config, e.g. `"@leadbay/mcp@0.2"` → `"@leadbay/mcp@0.3"`, 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).
|
|
138
157
|
|
|
139
|
-
**Rotate token**: re-run `npx -y @leadbay/mcp@0.
|
|
158
|
+
**Rotate token**: re-run `npx -y @leadbay/mcp@0.3 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.
|
|
140
159
|
|
|
141
160
|
## 6. Advanced
|
|
142
161
|
|
|
143
|
-
### Exposing the granular tools and write tools
|
|
162
|
+
### Exposing the granular tools and disabling write tools
|
|
144
163
|
|
|
145
|
-
By default the server exposes the **composite workflow tools** (`leadbay_pull_leads`, `leadbay_research_lead`, `leadbay_account_status`, `leadbay_recall_ordered_titles`,
|
|
164
|
+
By default the server exposes the **composite workflow tools** — both reads (`leadbay_pull_leads`, `leadbay_research_lead`, `leadbay_account_status`, `leadbay_recall_ordered_titles`, `leadbay_research_company`, `leadbay_prepare_outreach`) and writes (`leadbay_bulk_qualify_leads`, `leadbay_enrich_titles`, `leadbay_refine_prompt`, `leadbay_report_outreach`, `leadbay_adjust_audience`, `leadbay_answer_clarification`, `leadbay_import_leads`). These work well with most prompts.
|
|
146
165
|
|
|
147
|
-
To
|
|
166
|
+
To **disable the write tools** (run a strictly read-only agent), set `LEADBAY_MCP_WRITE=0`. The server's system prompt will adapt to omit references to those tools.
|
|
148
167
|
|
|
149
|
-
To unlock the **
|
|
168
|
+
To unlock the **granular API tools** (`leadbay_list_lenses`, `leadbay_discover_leads`, `leadbay_get_lead_profile`, `leadbay_get_contacts`, `leadbay_get_quota`, `leadbay_get_taste_profile`, `leadbay_get_lens_filter`, `leadbay_list_sectors`, …), set `LEADBAY_MCP_ADVANCED=1`.
|
|
150
169
|
|
|
151
170
|
```json
|
|
152
171
|
"env": {
|
|
153
172
|
"LEADBAY_TOKEN": "<token>",
|
|
154
173
|
"LEADBAY_MCP_ADVANCED": "1",
|
|
155
|
-
"LEADBAY_MCP_WRITE": "
|
|
174
|
+
"LEADBAY_MCP_WRITE": "0"
|
|
156
175
|
}
|
|
157
176
|
```
|
|
158
177
|
|
|
@@ -160,6 +179,38 @@ To unlock the **write tools** (`leadbay_bulk_qualify_leads`, `leadbay_enrich_tit
|
|
|
160
179
|
|
|
161
180
|
**Note**: `leadbay_login` is intentionally not exposed over MCP — see [Security](#security) below.
|
|
162
181
|
|
|
182
|
+
### Importing domains from external systems → leadIds
|
|
183
|
+
|
|
184
|
+
`leadbay_import_leads` is a **write tool** (exposed by default since 0.3.0; set `LEADBAY_MCP_WRITE=0` to hide it) for the case where you have a list of company domains from another system (CRM, analytics, email correspondents, etc.) and want stable Leadbay `leadId`s to chain into qualification:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# 1. Set up
|
|
188
|
+
export LEADBAY_TOKEN="<your-token>"
|
|
189
|
+
export LEADBAY_REGION="us"
|
|
190
|
+
# LEADBAY_MCP_WRITE defaults to "1" (ON) since 0.3.0 — no need to set it.
|
|
191
|
+
|
|
192
|
+
# 2. Wire in your MCP client per §2 above. Then ask the agent:
|
|
193
|
+
# "Import these domains: apple.com, microsoft.com, salesforce.com.
|
|
194
|
+
# Then qualify the matched leads."
|
|
195
|
+
#
|
|
196
|
+
# The agent calls leadbay_import_leads({ domains: [...] }), gets back
|
|
197
|
+
# { leads: [{domain, leadId, name}], not_imported: [{domain, reason}], importIds, _meta },
|
|
198
|
+
# then chains leads.map(l => l.leadId) into leadbay_bulk_qualify_leads.
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**⚠️ Writes user state.** Internally wraps Leadbay's CRM-import wizard (the only domain-import primitive the backend ships today). Each call:
|
|
202
|
+
|
|
203
|
+
- creates a row in your CRM-imports list (visible in the web UI)
|
|
204
|
+
- touches onboarding state (`startFileless`, onboarding step → `PROCESSING`)
|
|
205
|
+
|
|
206
|
+
Suitable for **occasional automation**. **Not** suitable for high-cadence (>5 calls/day) — the right primitive is a clean async-import-with-crawl backend endpoint, tracked as a follow-up in `leadbay/backend`.
|
|
207
|
+
|
|
208
|
+
**Limitation:** the wedge maps domains to leads the crawler already knows. Uncrawled domains land in `not_imported` with `reason: "uncrawled"` — the tool does **not** create new leads for unknown websites; the caller decides what to do (skip, queue for the backend follow-up, etc.).
|
|
209
|
+
|
|
210
|
+
**Requires:** `LEADBAY_MCP_WRITE` not set to `0` (it's ON by default since 0.3.0; or `exposeWrite: true` in OpenClaw); admin role on your Leadbay account; active billing.
|
|
211
|
+
|
|
212
|
+
Use `dry_run: true` to validate domain formatting and wizard reachability without committing the lead-CRM linking. (The CRM-imports row still appears — only a backend change can remove that.)
|
|
213
|
+
|
|
163
214
|
### Environment variables
|
|
164
215
|
|
|
165
216
|
| Var | Required | Default | Purpose |
|
|
@@ -168,7 +219,7 @@ To unlock the **write tools** (`leadbay_bulk_qualify_leads`, `leadbay_enrich_tit
|
|
|
168
219
|
| `LEADBAY_REGION` | **strongly recommended** | (auto-probe — see warning below) | `us` or `fr` |
|
|
169
220
|
| `LEADBAY_BASE_URL` | no | derived from region | Override for staging/dev |
|
|
170
221
|
| `LEADBAY_MCP_ADVANCED` | no | unset | `"1"` exposes the granular API tools |
|
|
171
|
-
| `LEADBAY_MCP_WRITE` | no |
|
|
222
|
+
| `LEADBAY_MCP_WRITE` | no | `"1"` (ON) | Default ON since 0.3.0. Set to `"0"` / `"false"` / `"no"` / `"off"` to hide the composite write tools (refine_prompt, report_outreach, adjust_audience, etc.) and the system prompt that mentions them. Note: 0.2.x treated `"true"` / `"yes"` / `"on"` as OFF; 0.3.0+ treats them as ON. |
|
|
172
223
|
| `LEADBAY_MOCK` | no | unset | `"1"` serves all reads from on-disk fixtures (dev only) |
|
|
173
224
|
| `LEADBAY_MOCK_DIR` | no | `./.context/leadbay-live-shapes/` | Fixture dir for mock mode |
|
|
174
225
|
| `LEADBAY_LOG_LEVEL` | no | `error` | `debug` \| `info` \| `error`, logs to stderr |
|