@coldiq/mcp 0.3.39 → 0.3.41

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.
Files changed (68) hide show
  1. package/dist/registry.d.ts.map +1 -1
  2. package/dist/registry.js +17 -5
  3. package/dist/registry.js.map +1 -1
  4. package/dist/tools/enrich-company-bulk.d.ts +1 -0
  5. package/dist/tools/enrich-company-bulk.d.ts.map +1 -1
  6. package/dist/tools/enrich-company-bulk.js +1 -0
  7. package/dist/tools/enrich-company-bulk.js.map +1 -1
  8. package/dist/tools/enrich-company.d.ts +1 -0
  9. package/dist/tools/enrich-company.d.ts.map +1 -1
  10. package/dist/tools/enrich-company.js +1 -0
  11. package/dist/tools/enrich-company.js.map +1 -1
  12. package/dist/tools/enrich-person-bulk.d.ts +1 -0
  13. package/dist/tools/enrich-person-bulk.d.ts.map +1 -1
  14. package/dist/tools/enrich-person-bulk.js +1 -0
  15. package/dist/tools/enrich-person-bulk.js.map +1 -1
  16. package/dist/tools/enrich-person.d.ts +1 -0
  17. package/dist/tools/enrich-person.d.ts.map +1 -1
  18. package/dist/tools/enrich-person.js +1 -0
  19. package/dist/tools/enrich-person.js.map +1 -1
  20. package/dist/tools/find-email.d.ts +1 -0
  21. package/dist/tools/find-email.d.ts.map +1 -1
  22. package/dist/tools/find-email.js +1 -0
  23. package/dist/tools/find-email.js.map +1 -1
  24. package/dist/tools/find-emails-bulk.d.ts +1 -0
  25. package/dist/tools/find-emails-bulk.d.ts.map +1 -1
  26. package/dist/tools/find-emails-bulk.js +1 -0
  27. package/dist/tools/find-emails-bulk.js.map +1 -1
  28. package/dist/tools/find-emails.d.ts +1 -0
  29. package/dist/tools/find-emails.d.ts.map +1 -1
  30. package/dist/tools/find-emails.js +1 -0
  31. package/dist/tools/find-emails.js.map +1 -1
  32. package/dist/tools/find-phone-bulk.d.ts +1 -0
  33. package/dist/tools/find-phone-bulk.d.ts.map +1 -1
  34. package/dist/tools/find-phone-bulk.js +1 -0
  35. package/dist/tools/find-phone-bulk.js.map +1 -1
  36. package/dist/tools/find-phone.d.ts +1 -0
  37. package/dist/tools/find-phone.d.ts.map +1 -1
  38. package/dist/tools/find-phone.js +1 -0
  39. package/dist/tools/find-phone.js.map +1 -1
  40. package/dist/tools/verify-email.d.ts +1 -1
  41. package/dist/tools/verify-email.d.ts.map +1 -1
  42. package/dist/tools/verify-email.js +1 -1
  43. package/dist/tools/verify-email.js.map +1 -1
  44. package/dist/tools/verify-emails-bulk.d.ts +1 -0
  45. package/dist/tools/verify-emails-bulk.d.ts.map +1 -1
  46. package/dist/tools/verify-emails-bulk.js +2 -0
  47. package/dist/tools/verify-emails-bulk.js.map +1 -1
  48. package/dist/verb-client.d.ts.map +1 -1
  49. package/dist/verb-client.js +4 -1
  50. package/dist/verb-client.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/registry.ts +17 -5
  53. package/src/tools/enrich-company-bulk.ts +1 -0
  54. package/src/tools/enrich-company.ts +1 -0
  55. package/src/tools/enrich-person-bulk.ts +1 -0
  56. package/src/tools/enrich-person.ts +1 -0
  57. package/src/tools/find-email.ts +1 -0
  58. package/src/tools/find-emails-bulk.ts +1 -0
  59. package/src/tools/find-emails.ts +1 -0
  60. package/src/tools/find-phone-bulk.ts +1 -0
  61. package/src/tools/find-phone.ts +1 -0
  62. package/src/tools/verify-email.ts +1 -1
  63. package/src/tools/verify-emails-bulk.ts +2 -0
  64. package/src/verb-client.ts +3 -1
  65. package/tests/gtm/README.md +2 -2
  66. package/tests/gtm/harness.ts +2 -1
  67. package/tests/registry-linkupapi.test.ts +2 -2
  68. package/tests/registry.test.ts +2 -2
@@ -24,6 +24,7 @@ export const findPhoneBulkSchema = {
24
24
  .max(5000)
25
25
  .describe('People to find phone numbers for (1–5000). Each needs a linkedin_url, or name + company_domain/name.'),
26
26
  webhook_url: z.string().optional().describe('Optional URL POSTed when the whole job completes.'),
27
+ max_credits: z.number().positive().optional().describe('Per-row spend cap: a provider that would return a number but costs more than this is skipped (the row comes back not_found rather than overspending). Phone lookups can be 10+ credits — this bounds them.'),
27
28
  }
28
29
 
29
30
  export async function findPhoneBulkHandler(input: Record<string, unknown>) {
@@ -14,6 +14,7 @@ export const findPhoneSchema = {
14
14
  company_domain: z.string().optional().describe('Company domain, e.g. coldiq.com'),
15
15
  company_name: z.string().optional().describe('Company name (alternative to company_domain)'),
16
16
  use_providers: z.array(z.string()).optional().describe(`Optional ordered list of providers to use. Leave empty to let ColdIQ automatically pick the best tool for your inputs — recommended for most use cases. Available providers: ${getProvidersForCapability('find_phone').join(', ')}. Provider names are matched fuzzily, so minor typos are tolerated.`),
17
+ max_credits: z.number().positive().optional().describe('Per-record spend cap: a provider that would return a number but costs more than this is skipped, so you never pay more than N credits for one phone (returns not_found if nothing answers in budget). Phone lookups can be 10+ credits — this bounds them.'),
17
18
  }
18
19
 
19
20
  export async function findPhoneHandler(input: Record<string, unknown>) {
@@ -5,7 +5,7 @@ import { getProvidersForCapability } from '../utils/provider-resolver.js'
5
5
  export const verifyEmailName = 'verify_email'
6
6
 
7
7
  export const verifyEmailDescription =
8
- 'Check whether an email address is valid and deliverable. Returns a normalized `status` field — one of "valid", "invalid", "catch_all", "risky", "disposable", "unknown" — alongside the raw provider response. Findymail (the default) only distinguishes valid vs invalid; richer status values come from providers like icypeas, instantly, or linkupapi. Use before cold outreach to protect sender reputation. ColdIQ automatically picks the best provider — pass use_providers only if you need a specific tool.'
8
+ 'Check whether an email address is valid and deliverable. Returns a normalized `status` field — one of "valid", "invalid", "catch_all", "risky", "disposable", "unknown" — alongside the raw provider response. BounceBan leads the waterfall: it resolves catch-all and risky addresses without sending (the gap most verifiers leave as "unknown"); if it cannot conclude, the chain falls through to leadmagic, findymail, icypeas, instantly, and linkupapi. Findymail only distinguishes valid vs invalid. Use before cold outreach to protect sender reputation. ColdIQ automatically runs the waterfall — pass use_providers only if you need a specific tool.'
9
9
 
10
10
  export const verifyEmailSchema = {
11
11
  email: z.string().email().describe('Email address to verify'),
@@ -12,10 +12,12 @@ export const verifyEmailsBulkDescription =
12
12
  'means the address was SKIPPED (rate-limited / never checked) and is safe to re-submit — do not discard those contacts; ' +
13
13
  'only `provider_indeterminate` (or no reason) is a real "couldn\'t determine". ' +
14
14
  'The 202 response includes `credits_reserved` (worst-case hold, settled to actual on completion) and a `low_balance_warning` when low. ' +
15
+ 'PROVIDER: runs on BounceBan by default — it resolves catch-all/risky addresses without sending (~0.2 credits per conclusively-verified email). If the BounceBan submit fails, the job AUTOMATICALLY falls back to Icypeas (0.1 credits/verified, no catch-all resolution) — bulk verify survives a single-provider outage. Pinning use_providers:["bounceban"] or ["icypeas"] is STRICT: a pinned backend\'s failure returns an error instead of switching. Any other verifier returns a clear error (never silently ignored). ' +
15
16
  'For a single email use verify_email instead.'
16
17
 
17
18
  export const verifyEmailsBulkSchema = {
18
19
  emails: z.array(z.string()).min(1).max(5000).describe('Emails to verify (1–5000). Invalid/duplicate entries are dropped server-side.'),
20
+ use_providers: z.array(z.string()).optional().describe('Provider pin. Omit for the default: BounceBan (catch-all/risky resolution, ~0.2 cr/verified) with automatic Icypeas failover (0.1 cr/verified). An explicit "bounceban" or "icypeas" pin is strict — its backend\'s failure returns an error, never a silent switch. Any other verifier returns a clear error.'),
19
21
  webhook_url: z.string().optional().describe('Optional URL POSTed when the whole job completes.'),
20
22
  }
21
23
 
@@ -42,7 +42,7 @@ export async function callVerb(
42
42
  }
43
43
  }
44
44
 
45
- const { use_providers, fields, reveal, resolve_current_employer, ...rest } = work
45
+ const { use_providers, fields, reveal, resolve_current_employer, max_credits, ...rest } = work
46
46
 
47
47
  // 2. Resolve the provider pin: explicit use_providers wins; otherwise a
48
48
  // tool-specific provider field (e.g. search_places `provider`).
@@ -68,6 +68,8 @@ export async function callVerb(
68
68
  if (fields !== undefined) envelope.fields = fields
69
69
  if (reveal !== undefined) envelope.reveal = reveal
70
70
  if (resolve_current_employer !== undefined) envelope.resolve_current_employer = resolve_current_employer
71
+ // Top-level (never inside `input`) so it applies to the single OR bulk envelope.
72
+ if (max_credits !== undefined) envelope.max_credits = max_credits
71
73
 
72
74
  const res = await callApi('POST', verbPath, envelope)
73
75
 
@@ -8,8 +8,8 @@ End-to-end scenarios that verify the MCP server routes plain-English prompts to
8
8
  |---|---|
9
9
  | `COLDIQ_API_KEY` | ColdIQ API key (live provider calls) |
10
10
  | `COLDIQ_API_URL` | API base URL (default: `http://localhost:8787`) |
11
- | `ANTHROPIC_API_KEY` | Anthropic API key (Claude agent loop) |
12
- | `AGENT_MODEL` | Override Claude model (default: `claude-sonnet-4-6`) |
11
+ | `ANTHROPIC_API_KEY` | Anthropic API key for this standalone evaluation driver |
12
+ | `GTM_EVAL_MODEL` | Optional evaluation override; defaults to the primary model in `src/agent/model-policy.ts` |
13
13
 
14
14
  ## Run commands
15
15
 
@@ -4,6 +4,7 @@ import * as fs from 'node:fs'
4
4
  import * as path from 'node:path'
5
5
  import * as url from 'node:url'
6
6
 
7
+ import { MODEL_PROFILES } from '../../../src/agent/model-policy.js'
7
8
  import { MCP_TOOLS } from './tools-bridge.js'
8
9
 
9
10
  export interface ToolCall {
@@ -40,7 +41,7 @@ export async function runAgent(options: RunAgentOptions): Promise<AgentResult> {
40
41
  const {
41
42
  prompt,
42
43
  maxToolCalls = 8,
43
- model = process.env.AGENT_MODEL ?? 'claude-sonnet-4-6',
44
+ model = process.env.GTM_EVAL_MODEL ?? MODEL_PROFILES.agent.models[0].model,
44
45
  } = options
45
46
 
46
47
  const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
@@ -181,9 +181,9 @@ describe('linkupapi provider — verify_email', () => {
181
181
  const providers = getProviders('verify_email')
182
182
  const lv = providers.find((p) => p.id === 'linkupapi-validate')!
183
183
 
184
- it('is registered at priority 5 (leadmagic joined at 1)', () => {
184
+ it('is registered at priority 6 (bounceban joined at 1)', () => {
185
185
  expect(lv).toBeDefined()
186
- expect(lv.priority).toBe(5)
186
+ expect(lv.priority).toBe(6)
187
187
  })
188
188
 
189
189
  it('maps email', () => {
@@ -780,8 +780,8 @@ describe('registry', () => {
780
780
  })
781
781
 
782
782
  describe('verify_email', () => {
783
- it('providers are ordered leadmagic → findymail → icypeas → instantly → linkupapi-validate', () => {
784
- expect(getProviders('verify_email').map((p) => p.id)).toEqual(['leadmagic', 'findymail', 'icypeas', 'instantly', 'linkupapi-validate'])
783
+ it('providers are ordered bounceban → leadmagic → findymail → icypeas → instantly → linkupapi-validate', () => {
784
+ expect(getProviders('verify_email').map((p) => p.id)).toEqual(['bounceban', 'leadmagic', 'findymail', 'icypeas', 'instantly', 'linkupapi-validate'])
785
785
  })
786
786
 
787
787
  it('FindyMail hasResult accepts verified field', () => {