@breaknorm_hu/mcp-server 0.1.5 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +48 -65
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -60,67 +60,51 @@ function str(val) {
60
60
  }
61
61
  var tools = [
62
62
  {
63
- name: "search_contacts",
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!",
63
+ name: "search_leads",
64
+ description: "Search for leads (contacts + company data in one result). This is THE main search tool. Returns contacts with their company info. Use suggest_industry_codes FIRST to get NAICS codes, then pass them here. You can request up to 500 results at once (no need to paginate for small queries). NEVER search by company name one by one!",
65
65
  schema: z.object({
66
- q: z.string().optional().describe("Free text search (name, title, company)"),
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"),
66
+ q: z.string().optional().describe("Free text search (name, title, company name)"),
67
+ naicsCodes: z.array(z.string()).optional().describe("NAICS codes from suggest_industry_codes \u2014 THE way to filter by industry"),
68
+ industry: z.array(z.string()).optional().describe("Industry name filter (use naicsCodes instead when possible)"),
69
69
  city: z.array(z.string()).optional().describe("Filter by city names"),
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"),
70
+ county: z.array(z.string()).optional().describe("Filter by county (megye)"),
71
+ country: z.string().optional().describe("2-letter country code, default: HU"),
72
+ seniority: z.array(z.string()).optional().describe("c_level, vp, director, manager, head, senior, founder, partner, managing_director"),
73
+ department: z.array(z.string()).optional().describe("sales, marketing, it, hr, finance, engineering, c_suite, operations, legal, product"),
74
+ title: z.string().optional().describe("Job title keyword (e.g. '\xFCgyvezet\u0151', 'CEO', 'igazgat\xF3')"),
72
75
  employee_min: z.number().int().optional().describe("Min company employees"),
73
76
  employee_max: z.number().int().optional().describe("Max company employees"),
77
+ revenue_min: z.number().optional().describe("Min annual revenue in HUF"),
78
+ revenue_max: z.number().optional().describe("Max annual revenue in HUF"),
74
79
  has_email: z.enum(["yes", "maybe", "no"]).optional().describe("Filter by email availability"),
75
- page: z.number().int().default(1).describe("Page number"),
76
- limit: z.number().int().max(25).default(25).describe("Results per page (max 25)"),
80
+ has_phone: z.enum(["yes", "maybe", "no"]).optional().describe("Filter by phone availability"),
81
+ is_revealed: z.boolean().optional().describe("Only show already-revealed contacts"),
82
+ icp_score_min: z.number().min(0).max(100).optional().describe("Min ICP score (0-100)"),
83
+ limit: z.number().int().min(1).max(500).default(25).describe("Results to return (max 500, default 25). Use higher values to get more results at once!"),
84
+ page: z.number().int().default(1).describe("Page number (default 1)"),
77
85
  searchToken: z.string().optional().describe("Required for page 2+, from page 1 response")
78
86
  }),
79
87
  handler: async (client, args) => {
80
- return client.get("/contacts/search", {
88
+ return client.get("/leads/search", {
81
89
  q: str(args.q),
82
- industry: arrayParam(args.industry),
83
90
  naicsCodes: arrayParam(args.naicsCodes),
91
+ industry: arrayParam(args.industry),
84
92
  city: arrayParam(args.city),
93
+ county: arrayParam(args.county),
94
+ country: str(args.country),
85
95
  seniority: arrayParam(args.seniority),
86
96
  department: arrayParam(args.department),
97
+ title: str(args.title),
87
98
  employee_min: str(args.employee_min),
88
99
  employee_max: str(args.employee_max),
100
+ revenue_min: str(args.revenue_min),
101
+ revenue_max: str(args.revenue_max),
89
102
  has_email: str(args.has_email),
90
- page: str(args.page),
103
+ has_phone: str(args.has_phone),
104
+ is_revealed: str(args.is_revealed),
105
+ icp_score_min: str(args.icp_score_min),
91
106
  limit: str(args.limit),
92
- searchToken: str(args.searchToken)
93
- });
94
- }
95
- },
96
- {
97
- name: "search_companies",
98
- description: "Search companies with filters. Use suggest_industry_codes FIRST for industry filtering. NEVER search one by one \u2014 use filters!",
99
- schema: z.object({
100
- q: z.string().optional().describe("Company name search"),
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"),
103
- city: z.array(z.string()).optional(),
104
- employee_min: z.number().int().optional(),
105
- employee_max: z.number().int().optional(),
106
- has_website: z.boolean().optional(),
107
- page: z.number().int().default(1),
108
- limit: z.number().int().max(25).default(25),
109
- sort: z.enum(["relevance", "name", "employee_count", "revenue", "icp_score"]).default("relevance"),
110
- searchToken: z.string().optional()
111
- }),
112
- handler: async (client, args) => {
113
- return client.get("/companies/search", {
114
- q: str(args.q),
115
- industry: arrayParam(args.industry),
116
- naicsCodes: arrayParam(args.naicsCodes),
117
- city: arrayParam(args.city),
118
- employee_min: str(args.employee_min),
119
- employee_max: str(args.employee_max),
120
- has_website: str(args.has_website),
121
107
  page: str(args.page),
122
- limit: str(args.limit),
123
- sort: str(args.sort),
124
108
  searchToken: str(args.searchToken)
125
109
  });
126
110
  }
@@ -304,34 +288,33 @@ var SERVER_NAME = "breaknorm";
304
288
  var SERVER_VERSION = "0.1.0";
305
289
  var INSTRUCTIONS = `Breaknorm MCP Server \u2014 B2B contact database for the Hungarian market.
306
290
 
307
- CRITICAL RULES \u2014 READ CAREFULLY:
291
+ CRITICAL RULES:
308
292
 
309
- 1. NEVER search by company name one by one! ALWAYS use filters to get bulk results.
310
- Wrong: search_contacts(q: "Company A"), search_contacts(q: "Company B"), ...
311
- Right: suggest_industry_codes("marketing \xFCgyn\xF6ks\xE9gek") \u2192 search_contacts(naicsCodes: [...], seniority: ["c_level"])
293
+ 1. USE search_leads FOR EVERYTHING \u2014 it returns contacts WITH company data in one call.
294
+ You can request up to 500 results at once (limit: 500). No need to paginate for most queries!
312
295
 
313
- 2. INDUSTRY SEARCH WORKFLOW \u2014 this is how it works:
314
- a. suggest_industry_codes("rekl\xE1m \xE9s m\xE9dia \xFCgyn\xF6ks\xE9gek") \u2192 returns NAICS codes
315
- b. search_companies(naicsCodes: [codes from step a], employee_min: 5) \u2192 returns ALL matching companies at once
316
- c. search_contacts(naicsCodes: [same codes], seniority: ["c_level", "director"]) \u2192 returns ALL decision-makers at once
317
- This gives you hundreds of results in 2-3 API calls instead of searching one by one!
296
+ 2. NEVER search by company name one by one! Use filters:
297
+ Wrong: search_leads(q: "Company A"), search_leads(q: "Company B"), ...
298
+ Right: suggest_industry_codes("marketing") \u2192 search_leads(naicsCodes: [...], seniority: ["c_level"], limit: 200)
318
299
 
319
- 3. Before ANY paid operation (reveal, scoring), call estimate_cost first and get user approval.
300
+ 3. INDUSTRY SEARCH \u2014 always use NAICS codes:
301
+ a. suggest_industry_codes("rekl\xE1m \xE9s m\xE9dia \xFCgyn\xF6ks\xE9gek") \u2192 get NAICS codes ONCE
302
+ b. search_leads(naicsCodes: [codes], employee_min: 5, seniority: ["c_level"], limit: 200)
303
+ c. If you need more pages, reuse the SAME naicsCodes \u2014 NEVER call suggest_industry_codes again!
320
304
 
321
- 4. Recommended workflow for building a lead list:
305
+ 4. WORKFLOW for building a lead list:
322
306
  a. get_credits \u2014 check balance
323
- b. suggest_industry_codes \u2014 convert industry description to NAICS codes
324
- c. search_companies \u2014 find companies with naicsCodes + size + location filters
325
- d. search_contacts \u2014 find decision-makers with naicsCodes + seniority + department filters
326
- e. estimate_cost \u2014 calculate cost
327
- f. [Wait for user approval]
328
- g. bulk_reveal_contacts \u2014 get emails (up to 1000 at once!)
329
- h. create_list + add_contacts_to_list \u2014 organize
330
- i. export_list \u2014 CSV export
307
+ b. suggest_industry_codes \u2014 get NAICS codes (ONCE!)
308
+ c. search_leads \u2014 find leads with all filters, up to 500 at once
309
+ d. estimate_cost \u2014 calculate reveal cost
310
+ e. [Wait for user approval of the cost]
311
+ f. bulk_reveal_contacts \u2014 get emails (up to 1000 at once)
312
+ g. create_list + add_contacts_to_list \u2014 organize
313
+ h. export_list \u2014 CSV export
331
314
 
332
- 5. Credit costs: email=1, phone=10, both=11, ICP scoring=1 per company
333
- 6. Search is FREE and paginated (25/page). Use searchToken for page 2+.
334
- 7. Bulk operations are async \u2014 poll with check_job_status.`;
315
+ 5. Before ANY paid operation (reveal, scoring), call estimate_cost and get user approval.
316
+ 6. Credit costs: email=1, phone=10, both=11, ICP scoring=1 per company.
317
+ 7. Search is FREE. Bulk operations are async \u2014 poll with check_job_status.`;
335
318
  async function main() {
336
319
  const apiKey = process.env.BREAKNORM_API_KEY;
337
320
  if (!apiKey) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@breaknorm_hu/mcp-server",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Breaknorm MCP Server — AI agent interface for B2B contact database",
5
5
  "type": "module",
6
6
  "bin": {