@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.
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -0
- package/dist/client.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/session-usage.d.ts +59 -0
- package/dist/session-usage.d.ts.map +1 -0
- package/dist/session-usage.js +96 -0
- package/dist/session-usage.js.map +1 -0
- package/dist/tools/enrich-company.d.ts +3 -9
- package/dist/tools/enrich-company.d.ts.map +1 -1
- package/dist/tools/enrich-company.js +3 -16
- package/dist/tools/enrich-company.js.map +1 -1
- package/dist/tools/enrich-person.d.ts +3 -9
- package/dist/tools/enrich-person.d.ts.map +1 -1
- package/dist/tools/enrich-person.js +3 -12
- package/dist/tools/enrich-person.js.map +1 -1
- package/dist/tools/fetch-page-content.d.ts +3 -9
- package/dist/tools/fetch-page-content.d.ts.map +1 -1
- package/dist/tools/fetch-page-content.js +3 -12
- package/dist/tools/fetch-page-content.js.map +1 -1
- package/dist/tools/find-email.d.ts +3 -9
- package/dist/tools/find-email.d.ts.map +1 -1
- package/dist/tools/find-email.js +3 -40
- package/dist/tools/find-email.js.map +1 -1
- package/dist/tools/find-emails.d.ts +3 -4
- package/dist/tools/find-emails.d.ts.map +1 -1
- package/dist/tools/find-emails.js +8 -423
- package/dist/tools/find-emails.js.map +1 -1
- package/dist/tools/find-influencers.d.ts +3 -9
- package/dist/tools/find-influencers.d.ts.map +1 -1
- package/dist/tools/find-influencers.js +3 -12
- package/dist/tools/find-influencers.js.map +1 -1
- package/dist/tools/find-people.d.ts +3 -8
- package/dist/tools/find-people.d.ts.map +1 -1
- package/dist/tools/find-people.js +3 -98
- package/dist/tools/find-people.js.map +1 -1
- package/dist/tools/find-phone.d.ts +3 -9
- package/dist/tools/find-phone.d.ts.map +1 -1
- package/dist/tools/find-phone.js +4 -41
- package/dist/tools/find-phone.js.map +1 -1
- package/dist/tools/find-signals.d.ts +3 -9
- package/dist/tools/find-signals.d.ts.map +1 -1
- package/dist/tools/find-signals.js +3 -83
- package/dist/tools/find-signals.js.map +1 -1
- package/dist/tools/get-place-reviews.d.ts +3 -9
- package/dist/tools/get-place-reviews.d.ts.map +1 -1
- package/dist/tools/get-place-reviews.js +3 -12
- package/dist/tools/get-place-reviews.js.map +1 -1
- package/dist/tools/get-session-usage.d.ts +10 -0
- package/dist/tools/get-session-usage.d.ts.map +1 -0
- package/dist/tools/get-session-usage.js +14 -0
- package/dist/tools/get-session-usage.js.map +1 -0
- package/dist/tools/search-ads.d.ts +3 -9
- package/dist/tools/search-ads.d.ts.map +1 -1
- package/dist/tools/search-ads.js +3 -12
- package/dist/tools/search-ads.js.map +1 -1
- package/dist/tools/search-companies.d.ts +3 -9
- package/dist/tools/search-companies.d.ts.map +1 -1
- package/dist/tools/search-companies.js +3 -24
- package/dist/tools/search-companies.js.map +1 -1
- package/dist/tools/search-jobs.d.ts +3 -9
- package/dist/tools/search-jobs.d.ts.map +1 -1
- package/dist/tools/search-jobs.js +3 -27
- package/dist/tools/search-jobs.js.map +1 -1
- package/dist/tools/search-places.d.ts +3 -15
- package/dist/tools/search-places.d.ts.map +1 -1
- package/dist/tools/search-places.js +5 -76
- package/dist/tools/search-places.js.map +1 -1
- package/dist/tools/search-reddit.d.ts +3 -9
- package/dist/tools/search-reddit.d.ts.map +1 -1
- package/dist/tools/search-reddit.js +3 -12
- package/dist/tools/search-reddit.js.map +1 -1
- package/dist/tools/search-seo.d.ts +3 -9
- package/dist/tools/search-seo.d.ts.map +1 -1
- package/dist/tools/search-seo.js +3 -12
- package/dist/tools/search-seo.js.map +1 -1
- package/dist/tools/search-web.d.ts +3 -9
- package/dist/tools/search-web.d.ts.map +1 -1
- package/dist/tools/search-web.js +3 -12
- package/dist/tools/search-web.js.map +1 -1
- package/dist/tools/verify-email.d.ts +3 -10
- package/dist/tools/verify-email.d.ts.map +1 -1
- package/dist/tools/verify-email.js +3 -68
- package/dist/tools/verify-email.js.map +1 -1
- package/dist/verb-client.d.ts +35 -0
- package/dist/verb-client.d.ts.map +1 -0
- package/dist/verb-client.js +57 -0
- package/dist/verb-client.js.map +1 -0
- package/package.json +1 -1
- package/src/client.ts +4 -0
- package/src/index.ts +8 -0
- package/src/session-usage.ts +130 -0
- package/src/tools/enrich-company.ts +3 -16
- package/src/tools/enrich-person.ts +3 -12
- package/src/tools/fetch-page-content.ts +3 -12
- package/src/tools/find-email.ts +3 -42
- package/src/tools/find-emails.ts +8 -506
- package/src/tools/find-influencers.ts +3 -12
- package/src/tools/find-people.ts +3 -107
- package/src/tools/find-phone.ts +4 -42
- package/src/tools/find-signals.ts +3 -88
- package/src/tools/get-place-reviews.ts +3 -12
- package/src/tools/get-session-usage.ts +18 -0
- package/src/tools/search-ads.ts +3 -12
- package/src/tools/search-companies.ts +3 -23
- package/src/tools/search-jobs.ts +3 -30
- package/src/tools/search-places.ts +5 -72
- package/src/tools/search-reddit.ts +3 -12
- package/src/tools/search-seo.ts +3 -12
- package/src/tools/search-web.ts +3 -12
- package/src/tools/verify-email.ts +3 -76
- package/src/verb-client.ts +93 -0
- package/tests/executor.test.ts +69 -0
- package/tests/session-usage.test.ts +130 -0
- package/tests/tools/get-session-usage.test.ts +44 -0
- package/tests/verb-client.test.ts +152 -0
- package/tests/tools/enrich-company.test.ts +0 -92
- package/tests/tools/enrich-person.test.ts +0 -140
- package/tests/tools/fetch-page-content.test.ts +0 -108
- package/tests/tools/find-email.test.ts +0 -137
- package/tests/tools/find-emails.test.ts +0 -818
- package/tests/tools/find-influencers.test.ts +0 -91
- package/tests/tools/find-people.test.ts +0 -621
- package/tests/tools/find-phone.test.ts +0 -100
- package/tests/tools/find-signals.test.ts +0 -175
- package/tests/tools/get-place-reviews.test.ts +0 -73
- package/tests/tools/search-ads.test.ts +0 -182
- package/tests/tools/search-companies.test.ts +0 -192
- package/tests/tools/search-jobs.test.ts +0 -210
- package/tests/tools/search-places.test.ts +0 -210
- package/tests/tools/search-reddit.test.ts +0 -194
- package/tests/tools/search-seo.test.ts +0 -183
- package/tests/tools/search-web.test.ts +0 -79
- 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
|
-
})
|