@clustr-ai/mcp-server 1.0.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.
@@ -0,0 +1,5 @@
1
+ export declare function initClient(): void;
2
+ export declare function truncateResult(data: unknown): string;
3
+ export declare function get(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<unknown>;
4
+ export declare function post(path: string, body: unknown): Promise<unknown>;
5
+ export declare function del(path: string, params?: Record<string, string | number | boolean | undefined>): Promise<unknown>;
package/dist/client.js ADDED
@@ -0,0 +1,77 @@
1
+ const BASE_URL = "https://api.clustr-ai.com/api/public";
2
+ const MAX_RESPONSE_LENGTH = 50_000;
3
+ let apiKey;
4
+ export function initClient() {
5
+ const key = process.env.CLUSTR_API_KEY;
6
+ if (!key) {
7
+ console.error("[clustr-mcp] CLUSTR_API_KEY environment variable is required.\n" +
8
+ "Get your API key from https://app.clustr-ai.com/api");
9
+ process.exit(1);
10
+ }
11
+ apiKey = key;
12
+ }
13
+ function headers() {
14
+ return {
15
+ Authorization: `Bearer ${apiKey}`,
16
+ "Content-Type": "application/json",
17
+ "User-Agent": "clustr-mcp-server/1.0.0",
18
+ };
19
+ }
20
+ function buildUrl(path, params) {
21
+ const url = new URL(`${BASE_URL}${path}`);
22
+ if (params) {
23
+ for (const [key, value] of Object.entries(params)) {
24
+ if (value !== undefined && value !== "") {
25
+ url.searchParams.set(key, String(value));
26
+ }
27
+ }
28
+ }
29
+ return url.toString();
30
+ }
31
+ async function handleResponse(response) {
32
+ if (response.status === 429) {
33
+ const retryAfter = response.headers.get("Retry-After");
34
+ throw new Error(`Rate limited by Clustr API.${retryAfter ? ` Retry after ${retryAfter} seconds.` : " Please wait before retrying."}`);
35
+ }
36
+ let body;
37
+ try {
38
+ body = await response.json();
39
+ }
40
+ catch {
41
+ throw new Error(`HTTP ${response.status}: failed to parse response`);
42
+ }
43
+ if (!response.ok) {
44
+ const b = body;
45
+ const err = b?.error;
46
+ const errorMsg = err?.message || b?.message || `HTTP ${response.status}`;
47
+ throw new Error(String(errorMsg));
48
+ }
49
+ return body.data ?? body;
50
+ }
51
+ export function truncateResult(data) {
52
+ const json = JSON.stringify(data, null, 2);
53
+ if (json.length <= MAX_RESPONSE_LENGTH)
54
+ return json;
55
+ return (json.slice(0, MAX_RESPONSE_LENGTH) +
56
+ `\n\n... [truncated — response was ${json.length} chars. Use page/page_size params to get smaller pages]`);
57
+ }
58
+ export async function get(path, params) {
59
+ const url = buildUrl(path, params);
60
+ const response = await fetch(url, { method: "GET", headers: headers() });
61
+ return handleResponse(response);
62
+ }
63
+ export async function post(path, body) {
64
+ const url = buildUrl(path);
65
+ const response = await fetch(url, {
66
+ method: "POST",
67
+ headers: headers(),
68
+ body: JSON.stringify(body),
69
+ });
70
+ return handleResponse(response);
71
+ }
72
+ export async function del(path, params) {
73
+ const url = buildUrl(path, params);
74
+ const response = await fetch(url, { method: "DELETE", headers: headers() });
75
+ return handleResponse(response);
76
+ }
77
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { initClient } from "./client.js";
5
+ import { registerImportContacts } from "./tools/import-contacts.js";
6
+ import { registerSearchByCompany } from "./tools/search-by-company.js";
7
+ import { registerSearchByContact } from "./tools/search-by-contact.js";
8
+ import { registerCreateTargetAccounts } from "./tools/create-target-accounts.js";
9
+ import { registerListTargetAccounts } from "./tools/list-target-accounts.js";
10
+ import { registerDeleteTargetAccount } from "./tools/delete-target-account.js";
11
+ const server = new McpServer({
12
+ name: "clustr",
13
+ version: "1.0.0",
14
+ });
15
+ initClient();
16
+ registerImportContacts(server);
17
+ registerSearchByCompany(server);
18
+ registerSearchByContact(server);
19
+ registerCreateTargetAccounts(server);
20
+ registerListTargetAccounts(server);
21
+ registerDeleteTargetAccount(server);
22
+ const transport = new StdioServerTransport();
23
+ await server.connect(transport);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAE/E,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,UAAU,EAAE,CAAC;AAEb,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,4BAA4B,CAAC,MAAM,CAAC,CAAC;AACrC,0BAA0B,CAAC,MAAM,CAAC,CAAC;AACnC,2BAA2B,CAAC,MAAM,CAAC,CAAC;AAEpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerCreateTargetAccounts(server: McpServer): void;
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { post, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ company_name: z
5
+ .string()
6
+ .optional()
7
+ .describe("Company name (single account format — adds one, does not affect existing)"),
8
+ linkedin_url: z
9
+ .string()
10
+ .optional()
11
+ .describe("Company LinkedIn URL (single account format)"),
12
+ target_companies: z
13
+ .array(z.object({
14
+ name: z.string().describe("Company name"),
15
+ linkedin_url: z.string().optional().describe("Company LinkedIn URL"),
16
+ }))
17
+ .optional()
18
+ .describe("Batch format — WARNING: this REPLACES ALL existing target accounts. " +
19
+ "Only use this when the user wants to set the complete list."),
20
+ };
21
+ export function registerCreateTargetAccounts(server) {
22
+ server.tool("create_target_accounts", "Add target accounts for opportunity prioritization. " +
23
+ "Two formats: (1) Single — provide company_name and/or linkedin_url to ADD one account. " +
24
+ "(2) Batch — provide target_companies array to REPLACE ALL existing accounts. " +
25
+ "WARNING: Batch format is destructive — it replaces the entire target account list.", inputSchema, async (params) => {
26
+ try {
27
+ const result = await post("/target-accounts", params);
28
+ return {
29
+ content: [{ type: "text", text: truncateResult(result) }],
30
+ };
31
+ }
32
+ catch (error) {
33
+ return {
34
+ content: [
35
+ {
36
+ type: "text",
37
+ text: `Error creating target accounts: ${error instanceof Error ? error.message : String(error)}`,
38
+ },
39
+ ],
40
+ isError: true,
41
+ };
42
+ }
43
+ });
44
+ }
45
+ //# sourceMappingURL=create-target-accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-target-accounts.js","sourceRoot":"","sources":["../../src/tools/create-target-accounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,2EAA2E,CAAC;IACxF,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,gBAAgB,EAAE,CAAC;SAChB,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;QACzC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;KACrE,CAAC,CACH;SACA,QAAQ,EAAE;SACV,QAAQ,CACP,sEAAsE;QACpE,6DAA6D,CAChE;CACJ,CAAC;AAEF,MAAM,UAAU,4BAA4B,CAAC,MAAiB;IAC5D,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,sDAAsD;QACpD,yFAAyF;QACzF,+EAA+E;QAC/E,oFAAoF,EACtF,WAAW,EACX,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,mCAAmC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBAClG;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerDeleteTargetAccount(server: McpServer): void;
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import { del, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ id: z.string().optional().describe("Target account ID"),
5
+ account_name: z.string().optional().describe("Account name (exact match)"),
6
+ linkedin_url: z.string().optional().describe("Account LinkedIn URL"),
7
+ };
8
+ export function registerDeleteTargetAccount(server) {
9
+ server.tool("delete_target_account", "Delete a target account by ID, name, or LinkedIn URL. " +
10
+ "Provide at least one parameter to identify the account to delete.", inputSchema, async (params) => {
11
+ try {
12
+ const result = await del("/target-accounts", params);
13
+ return {
14
+ content: [{ type: "text", text: truncateResult(result) }],
15
+ };
16
+ }
17
+ catch (error) {
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: `Error deleting target account: ${error instanceof Error ? error.message : String(error)}`,
23
+ },
24
+ ],
25
+ isError: true,
26
+ };
27
+ }
28
+ });
29
+ }
30
+ //# sourceMappingURL=delete-target-account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete-target-account.js","sourceRoot":"","sources":["../../src/tools/delete-target-account.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IACvD,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IAC1E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;CACrE,CAAC;AAEF,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,wDAAwD;QACtD,mEAAmE,EACrE,WAAW,EACX,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,kBAAkB,EAClB,MAA4C,CAC7C,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACjG;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerImportContacts(server: McpServer): void;
@@ -0,0 +1,73 @@
1
+ import { z } from "zod";
2
+ import { post, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ contacts: z
5
+ .array(z.object({
6
+ linkedin_url: z.string().describe("LinkedIn profile URL"),
7
+ record_id: z.string().optional().describe("Your CRM record ID"),
8
+ owner_email: z.string().optional().describe("CRM owner email"),
9
+ connector_tag: z
10
+ .string()
11
+ .optional()
12
+ .describe('Tag for this connector (e.g. "Employee", "Friend")'),
13
+ }))
14
+ .optional()
15
+ .describe("Contacts with metadata (1-50). Use this OR linkedin_urls."),
16
+ linkedin_urls: z
17
+ .array(z.string())
18
+ .optional()
19
+ .describe("Simple list of LinkedIn URLs (1-50). Use this OR contacts."),
20
+ webhook_url: z.string().describe("URL to receive results when processing completes"),
21
+ completion_email: z
22
+ .string()
23
+ .optional()
24
+ .describe("Email to notify when processing completes"),
25
+ max_opportunities: z
26
+ .number()
27
+ .optional()
28
+ .describe("Max opportunities to return per contact"),
29
+ full_history: z
30
+ .boolean()
31
+ .optional()
32
+ .describe("Include full engagement history in webhook response"),
33
+ custom: z
34
+ .record(z.unknown())
35
+ .optional()
36
+ .describe("Custom data passed through to webhook response"),
37
+ filters: z
38
+ .object({
39
+ confidence_score_ranges: z.array(z.string()).optional(),
40
+ seniority_levels: z.array(z.string()).optional(),
41
+ employee_ranges: z.array(z.string()).optional(),
42
+ revenue_ranges: z.array(z.string()).optional(),
43
+ prospect_job_titles: z.array(z.string()).optional(),
44
+ industries: z.array(z.string()).optional(),
45
+ countries: z.array(z.string()).optional(),
46
+ })
47
+ .optional()
48
+ .describe("Filters to apply to discovered opportunities"),
49
+ };
50
+ export function registerImportContacts(server) {
51
+ server.tool("import_contacts", "Import LinkedIn contacts for referral opportunity discovery. " +
52
+ "Processing is ASYNCHRONOUS — results are delivered via the webhook_url you provide, not in this response. " +
53
+ "Provide contacts via 'contacts' array (with CRM metadata) or simpler 'linkedin_urls' array. Max 50 per request.", inputSchema, async (params) => {
54
+ try {
55
+ const result = await post("/network/import/contacts", params);
56
+ return {
57
+ content: [{ type: "text", text: truncateResult(result) }],
58
+ };
59
+ }
60
+ catch (error) {
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: `Error importing contacts: ${error instanceof Error ? error.message : String(error)}`,
66
+ },
67
+ ],
68
+ isError: true,
69
+ };
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=import-contacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-contacts.js","sourceRoot":"","sources":["../../src/tools/import-contacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerListTargetAccounts(server: McpServer): void;
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ import { get, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ id: z.string().optional().describe("Target account ID (returns single account)"),
5
+ search: z.string().optional().describe("Search by account name (partial match)"),
6
+ linkedin_url: z.string().optional().describe("Search by LinkedIn URL"),
7
+ };
8
+ export function registerListTargetAccounts(server) {
9
+ server.tool("list_target_accounts", "List all target accounts, or search by ID, name, or LinkedIn URL. " +
10
+ "Call with no parameters to list all accounts.", inputSchema, async (params) => {
11
+ try {
12
+ const result = await get("/target-accounts", params);
13
+ return {
14
+ content: [{ type: "text", text: truncateResult(result) }],
15
+ };
16
+ }
17
+ catch (error) {
18
+ return {
19
+ content: [
20
+ {
21
+ type: "text",
22
+ text: `Error listing target accounts: ${error instanceof Error ? error.message : String(error)}`,
23
+ },
24
+ ],
25
+ isError: true,
26
+ };
27
+ }
28
+ });
29
+ }
30
+ //# sourceMappingURL=list-target-accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-target-accounts.js","sourceRoot":"","sources":["../../src/tools/list-target-accounts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4CAA4C,CAAC;IAChF,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wCAAwC,CAAC;IAChF,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;CACvE,CAAC;AAEF,MAAM,UAAU,0BAA0B,CAAC,MAAiB;IAC1D,MAAM,CAAC,IAAI,CACT,sBAAsB,EACtB,oEAAoE;QAClE,+CAA+C,EACjD,WAAW,EACX,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,kBAAkB,EAClB,MAA4C,CAC7C,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACjG;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerSearchByCompany(server: McpServer): void;
@@ -0,0 +1,97 @@
1
+ import { z } from "zod";
2
+ import { get, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ // Company identifiers
5
+ linkedin_urls: z.string().optional().describe("Comma-separated company LinkedIn URLs"),
6
+ numeric_ids: z.string().optional().describe("Comma-separated LinkedIn numeric IDs"),
7
+ domains: z.string().optional().describe("Comma-separated company domains"),
8
+ vanity_names: z.string().optional().describe("Comma-separated LinkedIn vanity names"),
9
+ // Filters
10
+ seniority_levels: z
11
+ .string()
12
+ .optional()
13
+ .describe("Comma-separated seniority levels: high, mid, low"),
14
+ industries: z.string().optional().describe("Comma-separated industries"),
15
+ employee_ranges: z
16
+ .string()
17
+ .optional()
18
+ .describe("Comma-separated employee count ranges (e.g. 51-200,501-1000)"),
19
+ revenue_ranges: z.string().optional().describe("Comma-separated revenue ranges"),
20
+ countries: z.string().optional().describe("Comma-separated countries"),
21
+ confidence_ranges: z
22
+ .string()
23
+ .optional()
24
+ .describe("Comma-separated confidence score ranges (e.g. 80-100,60-79)"),
25
+ // Client/prospect filters
26
+ client_names: z.string().optional().describe("Comma-separated client names"),
27
+ client_linkedin_urls: z.string().optional().describe("Comma-separated client LinkedIn URLs"),
28
+ client_public_identifiers: z
29
+ .string()
30
+ .optional()
31
+ .describe("Comma-separated client LinkedIn public identifiers"),
32
+ client_companies: z.string().optional().describe("Comma-separated client company names"),
33
+ prospect_names: z.string().optional().describe("Comma-separated prospect names"),
34
+ prospect_linkedin_urls: z
35
+ .string()
36
+ .optional()
37
+ .describe("Comma-separated prospect LinkedIn URLs"),
38
+ prospect_positions: z
39
+ .string()
40
+ .optional()
41
+ .describe("Comma-separated prospect job titles"),
42
+ prospect_companies: z
43
+ .string()
44
+ .optional()
45
+ .describe("Comma-separated prospect company names"),
46
+ owners: z.string().optional().describe("Comma-separated owner emails"),
47
+ statuses: z.string().optional().describe("Comma-separated opportunity statuses"),
48
+ engagement_types: z.string().optional().describe("Comma-separated engagement types"),
49
+ crm_statuses: z.string().optional().describe("Comma-separated CRM statuses"),
50
+ // Date filters
51
+ created_after: z.string().optional().describe("Filter opportunities created after this date (YYYY-MM-DD)"),
52
+ created_before: z
53
+ .string()
54
+ .optional()
55
+ .describe("Filter opportunities created before this date (YYYY-MM-DD)"),
56
+ // Boolean filters
57
+ exclude_client_companies: z
58
+ .boolean()
59
+ .optional()
60
+ .describe("Exclude prospects at the same company as the client"),
61
+ include_unengaged: z
62
+ .boolean()
63
+ .optional()
64
+ .describe("Include opportunities with no engagement"),
65
+ full_history: z.boolean().optional().describe("Include full engagement history"),
66
+ force_refresh: z.boolean().optional().describe("Bypass cache and fetch fresh results"),
67
+ // Other
68
+ job_id: z.string().optional().describe("Filter by import job ID"),
69
+ page: z.number().optional().describe("Page number (default: 1)"),
70
+ page_size: z.number().optional().describe("Results per page (default: 25)"),
71
+ sort_field: z.string().optional().describe("Field to sort by"),
72
+ sort_direction: z.enum(["asc", "desc"]).optional().describe("Sort direction"),
73
+ };
74
+ export function registerSearchByCompany(server) {
75
+ server.tool("search_opportunities_by_company", "Search referral opportunities filtered by company identifiers (LinkedIn URL, domain, numeric ID) and other criteria. " +
76
+ "Returns paginated results grouped by client with their opportunities. " +
77
+ "Provide at least one company identifier (linkedin_urls, domains, numeric_ids, or vanity_names).", inputSchema, async (params) => {
78
+ try {
79
+ const result = await get("/network/search/opportunities/by-company", params);
80
+ return {
81
+ content: [{ type: "text", text: truncateResult(result) }],
82
+ };
83
+ }
84
+ catch (error) {
85
+ return {
86
+ content: [
87
+ {
88
+ type: "text",
89
+ text: `Error searching opportunities: ${error instanceof Error ? error.message : String(error)}`,
90
+ },
91
+ ],
92
+ isError: true,
93
+ };
94
+ }
95
+ });
96
+ }
97
+ //# sourceMappingURL=search-by-company.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-by-company.js","sourceRoot":"","sources":["../../src/tools/search-by-company.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerSearchByContact(server: McpServer): void;
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+ import { get, truncateResult } from "../client.js";
3
+ const inputSchema = {
4
+ linkedin_public_id: z
5
+ .string()
6
+ .optional()
7
+ .describe("LinkedIn public identifier (e.g. john-doe). Provide this OR linkedin_url."),
8
+ linkedin_url: z
9
+ .string()
10
+ .optional()
11
+ .describe("Full LinkedIn URL (e.g. https://www.linkedin.com/in/john-doe). Provide this OR linkedin_public_id."),
12
+ full_history: z.boolean().optional().describe("Include full engagement history"),
13
+ seniority_levels: z
14
+ .string()
15
+ .optional()
16
+ .describe("Comma-separated seniority levels: high, mid, low"),
17
+ industries: z.string().optional().describe("Comma-separated industries"),
18
+ employee_ranges: z
19
+ .string()
20
+ .optional()
21
+ .describe("Comma-separated employee count ranges"),
22
+ revenue_ranges: z.string().optional().describe("Comma-separated revenue ranges"),
23
+ countries: z.string().optional().describe("Comma-separated countries"),
24
+ confidence_ranges: z
25
+ .string()
26
+ .optional()
27
+ .describe("Comma-separated confidence score ranges"),
28
+ page: z.number().optional().describe("Page number (default: 1)"),
29
+ page_size: z.number().optional().describe("Results per page (default: 25)"),
30
+ sort_field: z.string().optional().describe("Field to sort by"),
31
+ sort_direction: z.enum(["asc", "desc"]).optional().describe("Sort direction"),
32
+ };
33
+ export function registerSearchByContact(server) {
34
+ server.tool("search_opportunities_by_contact", "Get referral opportunities for a specific contact. " +
35
+ "Provide exactly one of linkedin_public_id OR linkedin_url to identify the contact.", inputSchema, async (params) => {
36
+ try {
37
+ const result = await get("/network/search/opportunities/by-contact", params);
38
+ return {
39
+ content: [{ type: "text", text: truncateResult(result) }],
40
+ };
41
+ }
42
+ catch (error) {
43
+ return {
44
+ content: [
45
+ {
46
+ type: "text",
47
+ text: `Error searching opportunities: ${error instanceof Error ? error.message : String(error)}`,
48
+ },
49
+ ],
50
+ isError: true,
51
+ };
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=search-by-contact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-by-contact.js","sourceRoot":"","sources":["../../src/tools/search-by-contact.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,MAAM,WAAW,GAAG;IAClB,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,2EAA2E,CAAC;IACxF,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,oGAAoG,CACrG;IACH,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAChF,gBAAgB,EAAE,CAAC;SAChB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,kDAAkD,CAAC;IAC/D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,4BAA4B,CAAC;IACxE,eAAe,EAAE,CAAC;SACf,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uCAAuC,CAAC;IACpD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAChF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IACtE,iBAAiB,EAAE,CAAC;SACjB,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,yCAAyC,CAAC;IACtD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;IAC3E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC9D,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;CAC9E,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,iCAAiC,EACjC,qDAAqD;QACnD,oFAAoF,EACtF,WAAW,EACX,KAAK,EAAE,MAAM,EAAE,EAAE;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,GAAG,CACtB,0CAA0C,EAC1C,MAA+D,CAChE,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;aAC1D,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,kCAAkC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACjG;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@clustr-ai/mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for the Clustr API — search referral opportunities, manage target accounts, and import contacts from AI assistants",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "clustr-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "dev": "tsx src/index.ts",
16
+ "start": "node dist/index.js",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "clustr",
23
+ "ai",
24
+ "referral",
25
+ "crm",
26
+ "linkedin"
27
+ ],
28
+ "author": "Clustr <support@clustr-ai.com> (https://clustr-ai.com)",
29
+ "license": "MIT",
30
+ "homepage": "https://docs.clustr-ai.com/mcp",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/arthu/clustr_app",
34
+ "directory": "mcp"
35
+ },
36
+ "engines": {
37
+ "node": ">=18"
38
+ },
39
+ "dependencies": {
40
+ "@modelcontextprotocol/sdk": "^1.12.1",
41
+ "zod": "^3.24.4"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.15.3",
45
+ "tsx": "^4.19.4",
46
+ "typescript": "^5.8.3"
47
+ }
48
+ }