@breaknorm_hu/mcp-server 0.1.3 → 0.1.4
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/index.js +47 -27
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -61,13 +61,14 @@ function str(val) {
|
|
|
61
61
|
var tools = [
|
|
62
62
|
{
|
|
63
63
|
name: "search_contacts",
|
|
64
|
-
description: "Search
|
|
64
|
+
description: "Search contacts with filters. Use suggest_industry_codes FIRST to convert industry descriptions to NAICS codes, then pass them here. NEVER search by company name one by one \u2014 always use filters to get bulk results!",
|
|
65
65
|
schema: z.object({
|
|
66
66
|
q: z.string().optional().describe("Free text search (name, title, company)"),
|
|
67
67
|
industry: z.array(z.string()).optional().describe("Filter by industry names"),
|
|
68
|
+
naicsCodes: z.array(z.string()).optional().describe("NAICS codes from suggest_industry_codes \u2014 THIS IS THE BEST WAY TO FILTER BY INDUSTRY"),
|
|
68
69
|
city: z.array(z.string()).optional().describe("Filter by city names"),
|
|
69
|
-
seniority: z.array(z.string()).optional().describe("
|
|
70
|
-
department: z.array(z.string()).optional().describe("
|
|
70
|
+
seniority: z.array(z.string()).optional().describe("c_level, vp, director, manager, head, senior, founder, partner"),
|
|
71
|
+
department: z.array(z.string()).optional().describe("sales, marketing, it, hr, finance, engineering, c_suite"),
|
|
71
72
|
employee_min: z.number().int().optional().describe("Min company employees"),
|
|
72
73
|
employee_max: z.number().int().optional().describe("Max company employees"),
|
|
73
74
|
has_email: z.enum(["yes", "maybe", "no"]).optional().describe("Filter by email availability"),
|
|
@@ -79,6 +80,7 @@ var tools = [
|
|
|
79
80
|
return client.get("/contacts/search", {
|
|
80
81
|
q: str(args.q),
|
|
81
82
|
industry: arrayParam(args.industry),
|
|
83
|
+
naicsCodes: arrayParam(args.naicsCodes),
|
|
82
84
|
city: arrayParam(args.city),
|
|
83
85
|
seniority: arrayParam(args.seniority),
|
|
84
86
|
department: arrayParam(args.department),
|
|
@@ -93,10 +95,11 @@ var tools = [
|
|
|
93
95
|
},
|
|
94
96
|
{
|
|
95
97
|
name: "search_companies",
|
|
96
|
-
description: "Search companies
|
|
98
|
+
description: "Search companies with filters. Use suggest_industry_codes FIRST for industry filtering. NEVER search one by one \u2014 use filters!",
|
|
97
99
|
schema: z.object({
|
|
98
100
|
q: z.string().optional().describe("Company name search"),
|
|
99
101
|
industry: z.array(z.string()).optional(),
|
|
102
|
+
naicsCodes: z.array(z.string()).optional().describe("NAICS codes from suggest_industry_codes \u2014 BEST way to filter by industry"),
|
|
100
103
|
city: z.array(z.string()).optional(),
|
|
101
104
|
employee_min: z.number().int().optional(),
|
|
102
105
|
employee_max: z.number().int().optional(),
|
|
@@ -110,6 +113,7 @@ var tools = [
|
|
|
110
113
|
return client.get("/companies/search", {
|
|
111
114
|
q: str(args.q),
|
|
112
115
|
industry: arrayParam(args.industry),
|
|
116
|
+
naicsCodes: arrayParam(args.naicsCodes),
|
|
113
117
|
city: arrayParam(args.city),
|
|
114
118
|
employee_min: str(args.employee_min),
|
|
115
119
|
employee_max: str(args.employee_max),
|
|
@@ -150,6 +154,21 @@ var tools = [
|
|
|
150
154
|
return { data: trimmed };
|
|
151
155
|
}
|
|
152
156
|
},
|
|
157
|
+
{
|
|
158
|
+
name: "suggest_industry_codes",
|
|
159
|
+
description: "IMPORTANT: Use this BEFORE searching by industry. Converts a natural language industry description (e.g. 'marketing \xFCgyn\xF6ks\xE9gek', 'IT szolg\xE1ltat\xF3k') into NAICS codes that the search endpoints understand. Pass the returned codes as the naicsCodes parameter in search_contacts or search_companies. This is how industry filtering works \u2014 do NOT search by company name one by one!",
|
|
160
|
+
schema: z.object({
|
|
161
|
+
description: z.string().describe("Industry description in natural language, e.g. 'rekl\xE1m \xE9s m\xE9dia \xFCgyn\xF6ks\xE9gek' or 'IT consulting'"),
|
|
162
|
+
precision: z.enum(["strict", "balanced", "broad"]).default("balanced").optional().describe("strict = exact match, balanced = recommended, broad = wider results")
|
|
163
|
+
}),
|
|
164
|
+
handler: async (client, args) => {
|
|
165
|
+
const result = await client.post("/search/naics-suggest", {
|
|
166
|
+
description: args.description,
|
|
167
|
+
precision: args.precision || "balanced"
|
|
168
|
+
});
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
},
|
|
153
172
|
{
|
|
154
173
|
name: "get_contact",
|
|
155
174
|
description: "Get details of a single contact (public fields, no revealed data).",
|
|
@@ -286,33 +305,34 @@ var SERVER_NAME = "breaknorm";
|
|
|
286
305
|
var SERVER_VERSION = "0.1.0";
|
|
287
306
|
var INSTRUCTIONS = `Breaknorm MCP Server \u2014 B2B contact database for the Hungarian market.
|
|
288
307
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
308
|
+
CRITICAL RULES \u2014 READ CAREFULLY:
|
|
309
|
+
|
|
310
|
+
1. NEVER search by company name one by one! ALWAYS use filters to get bulk results.
|
|
311
|
+
Wrong: search_contacts(q: "Company A"), search_contacts(q: "Company B"), ...
|
|
312
|
+
Right: suggest_industry_codes("marketing \xFCgyn\xF6ks\xE9gek") \u2192 search_contacts(naicsCodes: [...], seniority: ["c_level"])
|
|
293
313
|
|
|
294
|
-
2.
|
|
295
|
-
a.
|
|
296
|
-
b.
|
|
297
|
-
c.
|
|
298
|
-
|
|
299
|
-
e. estimate_cost \u2014 calculate total cost for reveals
|
|
300
|
-
f. [Wait for user approval of the cost]
|
|
301
|
-
g. bulk_reveal_contacts \u2014 get email/phone data
|
|
302
|
-
h. create_list + add_contacts_to_list \u2014 organize results
|
|
303
|
-
i. export_list \u2014 export as CSV if needed
|
|
314
|
+
2. INDUSTRY SEARCH WORKFLOW \u2014 this is how it works:
|
|
315
|
+
a. suggest_industry_codes("rekl\xE1m \xE9s m\xE9dia \xFCgyn\xF6ks\xE9gek") \u2192 returns NAICS codes
|
|
316
|
+
b. search_companies(naicsCodes: [codes from step a], employee_min: 5) \u2192 returns ALL matching companies at once
|
|
317
|
+
c. search_contacts(naicsCodes: [same codes], seniority: ["c_level", "director"]) \u2192 returns ALL decision-makers at once
|
|
318
|
+
This gives you hundreds of results in 2-3 API calls instead of searching one by one!
|
|
304
319
|
|
|
305
|
-
3.
|
|
306
|
-
- Email reveal: 1 credit per contact
|
|
307
|
-
- Phone reveal: 10 credits per contact
|
|
308
|
-
- Both (email + phone): 11 credits per contact
|
|
309
|
-
- ICP company scoring: 1 credit per company
|
|
320
|
+
3. Before ANY paid operation (reveal, scoring), call estimate_cost first and get user approval.
|
|
310
321
|
|
|
311
|
-
4.
|
|
312
|
-
|
|
322
|
+
4. Recommended workflow for building a lead list:
|
|
323
|
+
a. get_credits \u2014 check balance
|
|
324
|
+
b. suggest_industry_codes \u2014 convert industry description to NAICS codes
|
|
325
|
+
c. search_companies \u2014 find companies with naicsCodes + size + location filters
|
|
326
|
+
d. search_contacts \u2014 find decision-makers with naicsCodes + seniority + department filters
|
|
327
|
+
e. estimate_cost \u2014 calculate cost
|
|
328
|
+
f. [Wait for user approval]
|
|
329
|
+
g. bulk_reveal_contacts \u2014 get emails (up to 1000 at once!)
|
|
330
|
+
h. create_list + add_contacts_to_list \u2014 organize
|
|
331
|
+
i. export_list \u2014 CSV export
|
|
313
332
|
|
|
314
|
-
5.
|
|
315
|
-
|
|
333
|
+
5. Credit costs: email=1, phone=10, both=11, ICP scoring=1 per company
|
|
334
|
+
6. Search is FREE and paginated (25/page). Use searchToken for page 2+.
|
|
335
|
+
7. Bulk operations are async \u2014 poll with check_job_status.`;
|
|
316
336
|
async function main() {
|
|
317
337
|
const apiKey = process.env.BREAKNORM_API_KEY;
|
|
318
338
|
if (!apiKey) {
|