@coldiq/mcp 0.3.11 → 0.3.13

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 (135) hide show
  1. package/dist/client.d.ts.map +1 -1
  2. package/dist/client.js +4 -0
  3. package/dist/client.js.map +1 -1
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/session-usage.d.ts +59 -0
  7. package/dist/session-usage.d.ts.map +1 -0
  8. package/dist/session-usage.js +96 -0
  9. package/dist/session-usage.js.map +1 -0
  10. package/dist/tools/enrich-company.d.ts +3 -9
  11. package/dist/tools/enrich-company.d.ts.map +1 -1
  12. package/dist/tools/enrich-company.js +3 -16
  13. package/dist/tools/enrich-company.js.map +1 -1
  14. package/dist/tools/enrich-person.d.ts +3 -9
  15. package/dist/tools/enrich-person.d.ts.map +1 -1
  16. package/dist/tools/enrich-person.js +3 -12
  17. package/dist/tools/enrich-person.js.map +1 -1
  18. package/dist/tools/fetch-page-content.d.ts +3 -9
  19. package/dist/tools/fetch-page-content.d.ts.map +1 -1
  20. package/dist/tools/fetch-page-content.js +3 -12
  21. package/dist/tools/fetch-page-content.js.map +1 -1
  22. package/dist/tools/find-email.d.ts +3 -9
  23. package/dist/tools/find-email.d.ts.map +1 -1
  24. package/dist/tools/find-email.js +3 -40
  25. package/dist/tools/find-email.js.map +1 -1
  26. package/dist/tools/find-emails.d.ts +3 -4
  27. package/dist/tools/find-emails.d.ts.map +1 -1
  28. package/dist/tools/find-emails.js +8 -423
  29. package/dist/tools/find-emails.js.map +1 -1
  30. package/dist/tools/find-influencers.d.ts +3 -9
  31. package/dist/tools/find-influencers.d.ts.map +1 -1
  32. package/dist/tools/find-influencers.js +3 -12
  33. package/dist/tools/find-influencers.js.map +1 -1
  34. package/dist/tools/find-people.d.ts +3 -8
  35. package/dist/tools/find-people.d.ts.map +1 -1
  36. package/dist/tools/find-people.js +3 -98
  37. package/dist/tools/find-people.js.map +1 -1
  38. package/dist/tools/find-phone.d.ts +3 -9
  39. package/dist/tools/find-phone.d.ts.map +1 -1
  40. package/dist/tools/find-phone.js +4 -41
  41. package/dist/tools/find-phone.js.map +1 -1
  42. package/dist/tools/find-signals.d.ts +3 -9
  43. package/dist/tools/find-signals.d.ts.map +1 -1
  44. package/dist/tools/find-signals.js +3 -83
  45. package/dist/tools/find-signals.js.map +1 -1
  46. package/dist/tools/get-place-reviews.d.ts +3 -9
  47. package/dist/tools/get-place-reviews.d.ts.map +1 -1
  48. package/dist/tools/get-place-reviews.js +3 -12
  49. package/dist/tools/get-place-reviews.js.map +1 -1
  50. package/dist/tools/get-session-usage.d.ts +10 -0
  51. package/dist/tools/get-session-usage.d.ts.map +1 -0
  52. package/dist/tools/get-session-usage.js +14 -0
  53. package/dist/tools/get-session-usage.js.map +1 -0
  54. package/dist/tools/search-ads.d.ts +3 -9
  55. package/dist/tools/search-ads.d.ts.map +1 -1
  56. package/dist/tools/search-ads.js +3 -12
  57. package/dist/tools/search-ads.js.map +1 -1
  58. package/dist/tools/search-companies.d.ts +3 -9
  59. package/dist/tools/search-companies.d.ts.map +1 -1
  60. package/dist/tools/search-companies.js +3 -24
  61. package/dist/tools/search-companies.js.map +1 -1
  62. package/dist/tools/search-jobs.d.ts +3 -9
  63. package/dist/tools/search-jobs.d.ts.map +1 -1
  64. package/dist/tools/search-jobs.js +3 -27
  65. package/dist/tools/search-jobs.js.map +1 -1
  66. package/dist/tools/search-places.d.ts +3 -15
  67. package/dist/tools/search-places.d.ts.map +1 -1
  68. package/dist/tools/search-places.js +5 -76
  69. package/dist/tools/search-places.js.map +1 -1
  70. package/dist/tools/search-reddit.d.ts +3 -9
  71. package/dist/tools/search-reddit.d.ts.map +1 -1
  72. package/dist/tools/search-reddit.js +3 -12
  73. package/dist/tools/search-reddit.js.map +1 -1
  74. package/dist/tools/search-seo.d.ts +3 -9
  75. package/dist/tools/search-seo.d.ts.map +1 -1
  76. package/dist/tools/search-seo.js +3 -12
  77. package/dist/tools/search-seo.js.map +1 -1
  78. package/dist/tools/search-web.d.ts +3 -9
  79. package/dist/tools/search-web.d.ts.map +1 -1
  80. package/dist/tools/search-web.js +3 -12
  81. package/dist/tools/search-web.js.map +1 -1
  82. package/dist/tools/verify-email.d.ts +3 -10
  83. package/dist/tools/verify-email.d.ts.map +1 -1
  84. package/dist/tools/verify-email.js +3 -68
  85. package/dist/tools/verify-email.js.map +1 -1
  86. package/dist/verb-client.d.ts +35 -0
  87. package/dist/verb-client.d.ts.map +1 -0
  88. package/dist/verb-client.js +57 -0
  89. package/dist/verb-client.js.map +1 -0
  90. package/package.json +1 -1
  91. package/src/client.ts +4 -0
  92. package/src/index.ts +8 -0
  93. package/src/session-usage.ts +130 -0
  94. package/src/tools/enrich-company.ts +3 -16
  95. package/src/tools/enrich-person.ts +3 -12
  96. package/src/tools/fetch-page-content.ts +3 -12
  97. package/src/tools/find-email.ts +3 -42
  98. package/src/tools/find-emails.ts +8 -506
  99. package/src/tools/find-influencers.ts +3 -12
  100. package/src/tools/find-people.ts +3 -107
  101. package/src/tools/find-phone.ts +4 -42
  102. package/src/tools/find-signals.ts +3 -88
  103. package/src/tools/get-place-reviews.ts +3 -12
  104. package/src/tools/get-session-usage.ts +18 -0
  105. package/src/tools/search-ads.ts +3 -12
  106. package/src/tools/search-companies.ts +3 -23
  107. package/src/tools/search-jobs.ts +3 -30
  108. package/src/tools/search-places.ts +5 -72
  109. package/src/tools/search-reddit.ts +3 -12
  110. package/src/tools/search-seo.ts +3 -12
  111. package/src/tools/search-web.ts +3 -12
  112. package/src/tools/verify-email.ts +3 -76
  113. package/src/verb-client.ts +93 -0
  114. package/tests/executor.test.ts +69 -0
  115. package/tests/session-usage.test.ts +130 -0
  116. package/tests/tools/get-session-usage.test.ts +44 -0
  117. package/tests/verb-client.test.ts +152 -0
  118. package/tests/tools/enrich-company.test.ts +0 -92
  119. package/tests/tools/enrich-person.test.ts +0 -140
  120. package/tests/tools/fetch-page-content.test.ts +0 -108
  121. package/tests/tools/find-email.test.ts +0 -137
  122. package/tests/tools/find-emails.test.ts +0 -818
  123. package/tests/tools/find-influencers.test.ts +0 -91
  124. package/tests/tools/find-people.test.ts +0 -621
  125. package/tests/tools/find-phone.test.ts +0 -100
  126. package/tests/tools/find-signals.test.ts +0 -175
  127. package/tests/tools/get-place-reviews.test.ts +0 -73
  128. package/tests/tools/search-ads.test.ts +0 -182
  129. package/tests/tools/search-companies.test.ts +0 -192
  130. package/tests/tools/search-jobs.test.ts +0 -210
  131. package/tests/tools/search-places.test.ts +0 -210
  132. package/tests/tools/search-reddit.test.ts +0 -194
  133. package/tests/tools/search-seo.test.ts +0 -183
  134. package/tests/tools/search-web.test.ts +0 -79
  135. package/tests/tools/verify-email.test.ts +0 -142
@@ -1,108 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
- import { initClient } from '../../src/client.js'
3
- import { fetchPageContentHandler } from '../../src/tools/fetch-page-content.js'
4
-
5
- describe('fetch_page_content handler', () => {
6
- const originalFetch = globalThis.fetch
7
-
8
- beforeEach(() => {
9
- initClient('http://test-api.local', 'test-key')
10
- })
11
-
12
- afterEach(() => {
13
- globalThis.fetch = originalFetch
14
- })
15
-
16
- it('single URL — exa-contents returns results', async () => {
17
- globalThis.fetch = vi.fn(async (url: string | URL | Request) => {
18
- const u = url.toString()
19
- if (u.includes('/exa/contents')) {
20
- return new Response(JSON.stringify({
21
- results: [{ url: 'https://coldiq.com', text: 'ColdIQ page text' }],
22
- }), { status: 200 })
23
- }
24
- return new Response(JSON.stringify({ error: 'unexpected' }), { status: 500 })
25
- }) as typeof fetch
26
-
27
- const result = await fetchPageContentHandler({ urls: ['https://coldiq.com'] })
28
-
29
- expect(result.isError).toBeFalsy()
30
- const parsed = JSON.parse(result.content[0].text)
31
- expect(parsed._meta.provider).toBe('exa-contents')
32
- expect(parsed.data.results).toHaveLength(1)
33
- expect(parsed.data.results[0].text).toBe('ColdIQ page text')
34
- })
35
-
36
- it('batch URLs — all returned in one call', async () => {
37
- globalThis.fetch = vi.fn(async (url: string | URL | Request, opts?: RequestInit) => {
38
- const u = url.toString()
39
- if (u.includes('/exa/contents')) {
40
- const body = JSON.parse((opts?.body as string) ?? '{}')
41
- return new Response(JSON.stringify({
42
- results: body.urls.map((pageUrl: string) => ({ url: pageUrl, text: `text for ${pageUrl}` })),
43
- }), { status: 200 })
44
- }
45
- return new Response(JSON.stringify({ error: 'unexpected' }), { status: 500 })
46
- }) as typeof fetch
47
-
48
- const urls = ['https://coldiq.com', 'https://hubspot.com', 'https://salesforce.com']
49
- const result = await fetchPageContentHandler({ urls })
50
-
51
- expect(result.isError).toBeFalsy()
52
- const parsed = JSON.parse(result.content[0].text)
53
- expect(parsed._meta.provider).toBe('exa-contents')
54
- expect(parsed.data.results).toHaveLength(3)
55
- })
56
-
57
- it('include_summary=true — summary flag forwarded to exa', async () => {
58
- let capturedBody: Record<string, unknown> | null = null
59
-
60
- globalThis.fetch = vi.fn(async (url: string | URL | Request, opts?: RequestInit) => {
61
- const u = url.toString()
62
- if (u.includes('/exa/contents')) {
63
- capturedBody = JSON.parse((opts?.body as string) ?? '{}')
64
- return new Response(JSON.stringify({
65
- results: [{ url: 'https://coldiq.com', text: 'text', summary: 'summary text' }],
66
- }), { status: 200 })
67
- }
68
- return new Response(JSON.stringify({ error: 'unexpected' }), { status: 500 })
69
- }) as typeof fetch
70
-
71
- await fetchPageContentHandler({ urls: ['https://coldiq.com'], include_summary: true })
72
-
73
- expect(capturedBody).not.toBeNull()
74
- expect(capturedBody!.summary).toEqual({})
75
- })
76
-
77
- it('include_summary=false (default) — no summary field in request', async () => {
78
- let capturedBody: Record<string, unknown> | null = null
79
-
80
- globalThis.fetch = vi.fn(async (url: string | URL | Request, opts?: RequestInit) => {
81
- const u = url.toString()
82
- if (u.includes('/exa/contents')) {
83
- capturedBody = JSON.parse((opts?.body as string) ?? '{}')
84
- return new Response(JSON.stringify({
85
- results: [{ url: 'https://coldiq.com', text: 'text' }],
86
- }), { status: 200 })
87
- }
88
- return new Response(JSON.stringify({ error: 'unexpected' }), { status: 500 })
89
- }) as typeof fetch
90
-
91
- await fetchPageContentHandler({ urls: ['https://coldiq.com'] })
92
-
93
- expect(capturedBody).not.toBeNull()
94
- expect(capturedBody!.summary).toBeUndefined()
95
- })
96
-
97
- it('provider fails — returns isError', async () => {
98
- globalThis.fetch = vi.fn(async () => {
99
- return new Response(JSON.stringify({ error: 'upstream error' }), { status: 502 })
100
- }) as typeof fetch
101
-
102
- const result = await fetchPageContentHandler({ urls: ['https://coldiq.com'] })
103
-
104
- expect(result.isError).toBe(true)
105
- const parsed = JSON.parse(result.content[0].text)
106
- expect(parsed.error).toBeTruthy()
107
- })
108
- })
@@ -1,137 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
2
- import { initClient } from '../../src/client.js'
3
- import { findEmailHandler } from '../../src/tools/find-email.js'
4
-
5
- describe('find_email handler (waterfall)', () => {
6
- const originalFetch = globalThis.fetch
7
-
8
- beforeEach(() => {
9
- initClient('http://test-api.local', 'test-key')
10
- })
11
-
12
- afterEach(() => {
13
- globalThis.fetch = originalFetch
14
- })
15
-
16
- it('returns email from first provider that finds one', async () => {
17
- globalThis.fetch = vi.fn(async () =>
18
- new Response(JSON.stringify({ email: 'michel@coldiq.com' }), { status: 200 })
19
- ) as typeof fetch
20
-
21
- const result = await findEmailHandler({
22
- first_name: 'Michel',
23
- last_name: 'Lieben',
24
- domain: 'coldiq.com',
25
- })
26
-
27
- const parsed = JSON.parse(result.content[0].text)
28
- expect(parsed._meta.provider).toBe('findymail')
29
- expect(parsed.data.email).toBe('michel@coldiq.com')
30
- })
31
-
32
- it('falls through to IcyPeas when FindyMail has no result', async () => {
33
- let callCount = 0
34
- globalThis.fetch = vi.fn(async () => {
35
- callCount++
36
- if (callCount === 1) {
37
- // FindyMail — no email found
38
- return new Response(JSON.stringify({ email: null }), { status: 200 })
39
- }
40
- // IcyPeas — found
41
- return new Response(JSON.stringify({ email: 'michel@coldiq.com' }), { status: 200 })
42
- }) as typeof fetch
43
-
44
- const result = await findEmailHandler({
45
- first_name: 'Michel',
46
- last_name: 'Lieben',
47
- domain: 'coldiq.com',
48
- })
49
-
50
- const parsed = JSON.parse(result.content[0].text)
51
- expect(parsed._meta.provider).toBe('icypeas')
52
- })
53
-
54
- it('falls through to Prospeo when FindyMail and IcyPeas both fail', async () => {
55
- let callCount = 0
56
- globalThis.fetch = vi.fn(async () => {
57
- callCount++
58
- if (callCount <= 2) {
59
- return new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })
60
- }
61
- // Prospeo success response — email is nested under person.email.email
62
- return new Response(
63
- JSON.stringify({ error: false, person: { email: { email: 'michel@coldiq.com', status: 'VERIFIED' } } }),
64
- { status: 200 },
65
- )
66
- }) as typeof fetch
67
-
68
- const result = await findEmailHandler({
69
- first_name: 'Michel',
70
- last_name: 'Lieben',
71
- domain: 'coldiq.com',
72
- })
73
-
74
- const parsed = JSON.parse(result.content[0].text)
75
- expect(parsed._meta.provider).toBe('prospeo')
76
- })
77
-
78
- it('returns error when all providers fail', async () => {
79
- globalThis.fetch = vi.fn(async () =>
80
- new Response(JSON.stringify({ error: 'Not found' }), { status: 404 })
81
- ) as typeof fetch
82
-
83
- const result = await findEmailHandler({
84
- first_name: 'Unknown',
85
- last_name: 'Person',
86
- domain: 'unknown.xyz',
87
- })
88
-
89
- expect(result.isError).toBe(true)
90
- const parsed = JSON.parse(result.content[0].text)
91
- // No linkedin_url → blitzapi and limadata-work-email-linkedin are skipped via isApplicable
92
- expect(parsed.providers_tried.length).toBe(6) // findymail, icypeas, limadata-work-email, prospeo, fullenrich, linkupapi
93
- })
94
-
95
- describe('use_providers', () => {
96
- it('Scenario A — pinned provider succeeds', async () => {
97
- globalThis.fetch = vi.fn(async () =>
98
- new Response(JSON.stringify({ email: 'michel@coldiq.com' }), { status: 200 })
99
- ) as typeof fetch
100
-
101
- const result = await findEmailHandler({
102
- first_name: 'Michel',
103
- domain: 'coldiq.com',
104
- use_providers: ['findymail'],
105
- })
106
-
107
- expect(result.isError).toBeUndefined()
108
- const parsed = JSON.parse(result.content[0].text)
109
- expect(parsed._meta.provider).toBe('findymail')
110
- })
111
-
112
- it('Scenario C — gated provider without required input returns helpful error', async () => {
113
- const result = await findEmailHandler({
114
- first_name: 'Michel',
115
- domain: 'coldiq.com',
116
- use_providers: ['blitzapi'],
117
- })
118
-
119
- expect(result.isError).toBe(true)
120
- const parsed = JSON.parse(result.content[0].text)
121
- expect(parsed.error).toContain("'blitzapi' requires")
122
- expect(parsed.error).toContain('ColdIQ will automatically pick the best tool')
123
- })
124
-
125
- it('Scenario E — unrecognized provider returns isError', async () => {
126
- const result = await findEmailHandler({
127
- first_name: 'Michel',
128
- domain: 'coldiq.com',
129
- use_providers: ['apollo'],
130
- })
131
-
132
- expect(result.isError).toBe(true)
133
- const parsed = JSON.parse(result.content[0].text)
134
- expect(parsed.error).toContain("'apollo' is not a recognized provider")
135
- })
136
- })
137
- })