@clustr-ai/mcp-server 1.0.10 → 1.0.11

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 (66) hide show
  1. package/dist/client.d.ts +20 -14
  2. package/dist/client.js +150 -81
  3. package/dist/client.js.map +1 -1
  4. package/dist/index.js +85 -34
  5. package/dist/index.js.map +1 -1
  6. package/package.json +4 -4
  7. package/dist/tools/create-icp.d.ts +0 -2
  8. package/dist/tools/create-icp.js +0 -26
  9. package/dist/tools/create-icp.js.map +0 -1
  10. package/dist/tools/create-target-accounts.d.ts +0 -2
  11. package/dist/tools/create-target-accounts.js +0 -27
  12. package/dist/tools/create-target-accounts.js.map +0 -1
  13. package/dist/tools/delete-icp.d.ts +0 -2
  14. package/dist/tools/delete-icp.js +0 -9
  15. package/dist/tools/delete-icp.js.map +0 -1
  16. package/dist/tools/delete-target-account.d.ts +0 -2
  17. package/dist/tools/delete-target-account.js +0 -12
  18. package/dist/tools/delete-target-account.js.map +0 -1
  19. package/dist/tools/get-job-status.d.ts +0 -2
  20. package/dist/tools/get-job-status.js +0 -10
  21. package/dist/tools/get-job-status.js.map +0 -1
  22. package/dist/tools/get-network-stats.d.ts +0 -2
  23. package/dist/tools/get-network-stats.js +0 -6
  24. package/dist/tools/get-network-stats.js.map +0 -1
  25. package/dist/tools/import-connectors.d.ts +0 -2
  26. package/dist/tools/import-connectors.js +0 -64
  27. package/dist/tools/import-connectors.js.map +0 -1
  28. package/dist/tools/list-connectors.d.ts +0 -2
  29. package/dist/tools/list-connectors.js +0 -14
  30. package/dist/tools/list-connectors.js.map +0 -1
  31. package/dist/tools/list-icps.d.ts +0 -2
  32. package/dist/tools/list-icps.js +0 -6
  33. package/dist/tools/list-icps.js.map +0 -1
  34. package/dist/tools/list-jobs.d.ts +0 -2
  35. package/dist/tools/list-jobs.js +0 -15
  36. package/dist/tools/list-jobs.js.map +0 -1
  37. package/dist/tools/list-opportunity-statuses.d.ts +0 -2
  38. package/dist/tools/list-opportunity-statuses.js +0 -7
  39. package/dist/tools/list-opportunity-statuses.js.map +0 -1
  40. package/dist/tools/list-target-accounts.d.ts +0 -2
  41. package/dist/tools/list-target-accounts.js +0 -12
  42. package/dist/tools/list-target-accounts.js.map +0 -1
  43. package/dist/tools/search-by-company.d.ts +0 -2
  44. package/dist/tools/search-by-company.js +0 -82
  45. package/dist/tools/search-by-company.js.map +0 -1
  46. package/dist/tools/search-by-connector.d.ts +0 -2
  47. package/dist/tools/search-by-connector.js +0 -56
  48. package/dist/tools/search-by-connector.js.map +0 -1
  49. package/dist/tools/search-companies.d.ts +0 -2
  50. package/dist/tools/search-companies.js +0 -13
  51. package/dist/tools/search-companies.js.map +0 -1
  52. package/dist/tools/search-opportunities.d.ts +0 -2
  53. package/dist/tools/search-opportunities.js +0 -70
  54. package/dist/tools/search-opportunities.js.map +0 -1
  55. package/dist/tools/start-abm-search.d.ts +0 -2
  56. package/dist/tools/start-abm-search.js +0 -30
  57. package/dist/tools/start-abm-search.js.map +0 -1
  58. package/dist/tools/update-icp.d.ts +0 -2
  59. package/dist/tools/update-icp.js +0 -29
  60. package/dist/tools/update-icp.js.map +0 -1
  61. package/dist/tools/update-opportunity.d.ts +0 -2
  62. package/dist/tools/update-opportunity.js +0 -19
  63. package/dist/tools/update-opportunity.js.map +0 -1
  64. package/dist/tools/whats-new.d.ts +0 -3
  65. package/dist/tools/whats-new.js +0 -67
  66. package/dist/tools/whats-new.js.map +0 -1
package/dist/client.d.ts CHANGED
@@ -1,15 +1,21 @@
1
+ /** MCP protocol revision we advertise upstream. */
2
+ export declare const PROTOCOL_VERSION = "2025-06-18";
3
+ /**
4
+ * An upstream failure that already carries a message safe to show a user:
5
+ * unreachable endpoint, rejected key, rate limit, or a JSON-RPC error from the
6
+ * server. Never swallow one into an empty result — an empty tool list reads as
7
+ * "this server has no tools", which is worse than an error.
8
+ */
9
+ export declare class UpstreamError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /** Read CLUSTR_API_KEY and the endpoint config. Exits if the key is missing. */
1
13
  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>;
6
- export declare function put(path: string, body: unknown): Promise<unknown>;
7
- type ToolResult = {
8
- content: {
9
- type: "text";
10
- text: string;
11
- }[];
12
- isError?: boolean;
13
- };
14
- export declare function wrapToolHandler(fn: (params: Record<string, unknown>) => Promise<unknown>): (params: Record<string, unknown>) => Promise<ToolResult>;
15
- export {};
14
+ export declare function getEndpoint(): string;
15
+ /**
16
+ * Send one JSON-RPC request upstream and return its `result` untouched.
17
+ * Throws UpstreamError on any failure, with a message meant for a human.
18
+ */
19
+ export declare function callUpstream(method: string, params?: unknown, overrideTimeoutMs?: number): Promise<unknown>;
20
+ /** Normalise anything thrown by callUpstream into a user-facing string. */
21
+ export declare function errorMessage(error: unknown): string;
package/dist/client.js CHANGED
@@ -1,6 +1,57 @@
1
- const BASE_URL = process.env.CLUSTR_API_URL || "https://api.clustr-ai.com/api/public";
2
- const MAX_RESPONSE_LENGTH = 50_000;
3
- let apiKey;
1
+ // JSON-RPC client for the hosted Clustr MCP endpoint.
2
+ //
3
+ // This package is a transport shim, not a second implementation of the Clustr
4
+ // tool set. Every tool definition and every tool execution lives on the server
5
+ // (POST /mcp). We forward `tools/list` and `tools/call` there and return what
6
+ // comes back, verbatim — which is why a tool added server-side shows up in
7
+ // clients with no npm release.
8
+ //
9
+ // Do not add tool schemas, argument validation or REST calls to this file. If
10
+ // you find yourself needing one, the change belongs on the server.
11
+ const DEFAULT_ENDPOINT = "https://api.clustr-ai.com/mcp";
12
+ const DEFAULT_TIMEOUT_MS = 120_000;
13
+ /** MCP protocol revision we advertise upstream. */
14
+ export const PROTOCOL_VERSION = "2025-06-18";
15
+ let apiKey = "";
16
+ let endpoint = DEFAULT_ENDPOINT;
17
+ let timeoutMs = DEFAULT_TIMEOUT_MS;
18
+ let nextId = 1;
19
+ /**
20
+ * An upstream failure that already carries a message safe to show a user:
21
+ * unreachable endpoint, rejected key, rate limit, or a JSON-RPC error from the
22
+ * server. Never swallow one into an empty result — an empty tool list reads as
23
+ * "this server has no tools", which is worse than an error.
24
+ */
25
+ export class UpstreamError extends Error {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = "UpstreamError";
29
+ }
30
+ }
31
+ /**
32
+ * Resolve the MCP endpoint. Production by default; overridable for staging and
33
+ * local testing.
34
+ *
35
+ * CLUSTR_MCP_URL — full URL of the MCP endpoint (e.g. http://localhost:8080/mcp)
36
+ * CLUSTR_API_URL — legacy REST base of previous versions. Honoured so an
37
+ * existing non-production config does not silently start
38
+ * talking to production.
39
+ */
40
+ function resolveEndpoint() {
41
+ const explicit = process.env.CLUSTR_MCP_URL;
42
+ if (explicit)
43
+ return explicit.replace(/\/+$/, "");
44
+ const legacy = process.env.CLUSTR_API_URL;
45
+ if (legacy) {
46
+ const origin = legacy.replace(/\/+$/, "").replace(/\/api\/public$/, "");
47
+ const derived = `${origin}/mcp`;
48
+ console.error(`[clustr-mcp] CLUSTR_API_URL is set; using ${derived} as the MCP endpoint. ` +
49
+ "Set CLUSTR_MCP_URL to point somewhere else.");
50
+ return derived;
51
+ }
52
+ return DEFAULT_ENDPOINT;
53
+ }
54
+ /** Read CLUSTR_API_KEY and the endpoint config. Exits if the key is missing. */
4
55
  export function initClient() {
5
56
  const key = process.env.CLUSTR_API_KEY;
6
57
  if (!key) {
@@ -9,97 +60,115 @@ export function initClient() {
9
60
  process.exit(1);
10
61
  }
11
62
  apiKey = key;
63
+ endpoint = resolveEndpoint();
64
+ const configured = Number(process.env.CLUSTR_MCP_TIMEOUT_MS);
65
+ timeoutMs = Number.isFinite(configured) && configured > 0 ? configured : DEFAULT_TIMEOUT_MS;
12
66
  }
13
- function headers() {
14
- return {
15
- Authorization: `Bearer ${apiKey}`,
16
- "Content-Type": "application/json",
17
- "User-Agent": "clustr-mcp-server/1.0.0",
18
- };
67
+ export function getEndpoint() {
68
+ return endpoint;
19
69
  }
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
- }
70
+ /**
71
+ * Servers may answer a POST with a single JSON object or with an SSE stream
72
+ * carrying the same object. Accept both so we keep working if the endpoint
73
+ * switches to streaming.
74
+ */
75
+ function parseSSE(body) {
76
+ let last;
77
+ for (const line of body.split("\n")) {
78
+ if (!line.startsWith("data:"))
79
+ continue;
80
+ const payload = line.slice(5).trim();
81
+ if (!payload || payload === "[DONE]")
82
+ continue;
83
+ try {
84
+ last = JSON.parse(payload);
27
85
  }
86
+ catch {
87
+ // Ignore partial/non-JSON events; a later one carries the response.
88
+ }
89
+ }
90
+ if (last === undefined) {
91
+ throw new UpstreamError(`Clustr MCP endpoint (${endpoint}) sent an event stream with no JSON-RPC response`);
28
92
  }
29
- return url.toString();
93
+ return last;
30
94
  }
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."}`);
95
+ function describeHTTPError(status, retryAfter, body) {
96
+ const snippet = body.trim().slice(0, 500);
97
+ if (status === 401 || status === 403) {
98
+ return (`Clustr rejected the API key (HTTP ${status}). Check CLUSTR_API_KEY — ` +
99
+ "you can view or rotate it at https://app.clustr-ai.com/api");
100
+ }
101
+ if (status === 429) {
102
+ return ("Rate limited by the Clustr MCP endpoint." +
103
+ (retryAfter ? ` Retry after ${retryAfter} seconds.` : " Please wait before retrying."));
35
104
  }
36
- let body;
105
+ return `Clustr MCP endpoint (${endpoint}) returned HTTP ${status}${snippet ? `: ${snippet}` : ""}`;
106
+ }
107
+ /**
108
+ * Send one JSON-RPC request upstream and return its `result` untouched.
109
+ * Throws UpstreamError on any failure, with a message meant for a human.
110
+ */
111
+ export async function callUpstream(method, params, overrideTimeoutMs) {
112
+ const payload = {
113
+ jsonrpc: "2.0",
114
+ id: nextId++,
115
+ method,
116
+ ...(params === undefined ? {} : { params }),
117
+ };
118
+ let response;
37
119
  try {
38
- body = await response.json();
120
+ response = await fetch(endpoint, {
121
+ method: "POST",
122
+ headers: {
123
+ Authorization: `Bearer ${apiKey}`,
124
+ "Content-Type": "application/json",
125
+ Accept: "application/json, text/event-stream",
126
+ "MCP-Protocol-Version": PROTOCOL_VERSION,
127
+ "User-Agent": `clustr-mcp-server (proxy; ${method})`,
128
+ },
129
+ body: JSON.stringify(payload),
130
+ signal: AbortSignal.timeout(overrideTimeoutMs ?? timeoutMs),
131
+ });
39
132
  }
40
- catch {
41
- throw new Error(`HTTP ${response.status}: failed to parse response`);
133
+ catch (error) {
134
+ const reason = error instanceof Error ? error.message : String(error);
135
+ throw new UpstreamError(`Cannot reach the Clustr MCP endpoint at ${endpoint} (${reason}). ` +
136
+ "Check your network connection, then https://status.clustr-ai.com");
42
137
  }
138
+ const raw = await response.text();
43
139
  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));
140
+ throw new UpstreamError(describeHTTPError(response.status, response.headers.get("Retry-After"), raw));
48
141
  }
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
- export async function put(path, body) {
78
- const url = buildUrl(path);
79
- const response = await fetch(url, {
80
- method: "PUT",
81
- headers: headers(),
82
- body: JSON.stringify(body),
83
- });
84
- return handleResponse(response);
85
- }
86
- export function wrapToolHandler(fn) {
87
- return async (params) => {
142
+ let envelope;
143
+ const contentType = response.headers.get("Content-Type") ?? "";
144
+ if (contentType.includes("text/event-stream")) {
145
+ envelope = parseSSE(raw);
146
+ }
147
+ else {
88
148
  try {
89
- const result = await fn(params);
90
- return { content: [{ type: "text", text: truncateResult(result) }] };
149
+ envelope = JSON.parse(raw);
91
150
  }
92
- catch (error) {
93
- return {
94
- content: [
95
- {
96
- type: "text",
97
- text: `Error: ${error instanceof Error ? error.message : String(error)}`,
98
- },
99
- ],
100
- isError: true,
101
- };
151
+ catch {
152
+ throw new UpstreamError(`Clustr MCP endpoint (${endpoint}) returned a non-JSON response: ${raw.trim().slice(0, 200)}`);
102
153
  }
103
- };
154
+ }
155
+ const message = envelope;
156
+ if (message?.error) {
157
+ const code = message.error.code;
158
+ throw new UpstreamError(`Clustr MCP endpoint returned an error${code !== undefined ? ` (${code})` : ""}: ` +
159
+ (message.error.message ?? "unknown error"));
160
+ }
161
+ if (message?.result === undefined) {
162
+ throw new UpstreamError(`Clustr MCP endpoint (${endpoint}) returned a response with no result for ${method}`);
163
+ }
164
+ return message.result;
165
+ }
166
+ /** Normalise anything thrown by callUpstream into a user-facing string. */
167
+ export function errorMessage(error) {
168
+ if (error instanceof UpstreamError)
169
+ return error.message;
170
+ if (error instanceof Error)
171
+ return error.message;
172
+ return String(error);
104
173
  }
105
174
  //# sourceMappingURL=client.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,40 +1,91 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ // @clustr-ai/mcp-server — a stdio front door for the hosted Clustr MCP server.
3
+ //
4
+ // It declares no tools of its own. `tools/list` and `tools/call` are forwarded
5
+ // to https://api.clustr-ai.com/mcp and the responses are returned verbatim, so
6
+ // the tool set a client sees is always the one the server is serving right now.
7
+ // The package exists for MCP clients that speak stdio but not remote MCP; every
8
+ // other client should point straight at the URL.
9
+ import { readFileSync } from "node:fs";
10
+ import { dirname, join } from "node:path";
11
+ import { fileURLToPath } from "node:url";
12
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
13
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { initClient } from "./client.js";
5
- import { registerImportConnectors } from "./tools/import-connectors.js";
6
- import { registerStartABMSearch } from "./tools/start-abm-search.js";
7
- import { CURRENT_VERSION, registerWhatsNew } from "./tools/whats-new.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
- import { registerGetJobStatus } from "./tools/get-job-status.js";
12
- import { registerListJobs } from "./tools/list-jobs.js";
13
- import { registerSearchOpportunities } from "./tools/search-opportunities.js";
14
- import { registerSearchCompanies } from "./tools/search-companies.js";
15
- import { registerListConnectors } from "./tools/list-connectors.js";
16
- import { registerGetNetworkStats } from "./tools/get-network-stats.js";
17
- import { registerUpdateOpportunity } from "./tools/update-opportunity.js";
18
- import { registerListOpportunityStatuses } from "./tools/list-opportunity-statuses.js";
19
- const server = new McpServer({
20
- name: "clustr",
21
- version: CURRENT_VERSION,
22
- });
14
+ import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from "@modelcontextprotocol/sdk/types.js";
15
+ import { PROTOCOL_VERSION, callUpstream, errorMessage, getEndpoint, initClient } from "./client.js";
16
+ /** Version of this package, read from the published package.json (never duplicated). */
17
+ function packageVersion() {
18
+ try {
19
+ const here = dirname(fileURLToPath(import.meta.url));
20
+ const pkg = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8"));
21
+ return pkg.version ?? "0.0.0";
22
+ }
23
+ catch {
24
+ return "0.0.0";
25
+ }
26
+ }
27
+ const PROXY_VERSION = packageVersion();
23
28
  initClient();
24
- registerWhatsNew(server);
25
- registerImportConnectors(server);
26
- registerStartABMSearch(server);
27
- registerSearchOpportunities(server);
28
- registerSearchCompanies(server);
29
- registerListConnectors(server);
30
- registerGetNetworkStats(server);
31
- registerGetJobStatus(server);
32
- registerListJobs(server);
33
- registerUpdateOpportunity(server);
34
- registerListOpportunityStatuses(server);
35
- registerCreateTargetAccounts(server);
36
- registerListTargetAccounts(server);
37
- registerDeleteTargetAccount(server);
29
+ // Best-effort handshake so we can advertise the server's own identity and fail
30
+ // loudly (on stderr) if the key or endpoint is wrong. A failure here is NOT
31
+ // fatal: the process still starts, and the first tools/list returns the real
32
+ // reason instead of an empty list.
33
+ async function upstreamIdentity() {
34
+ const fallback = { name: "clustr", version: PROXY_VERSION };
35
+ try {
36
+ const result = (await callUpstream("initialize", {
37
+ protocolVersion: PROTOCOL_VERSION,
38
+ capabilities: {},
39
+ clientInfo: { name: "@clustr-ai/mcp-server", version: PROXY_VERSION },
40
+ }, 10_000));
41
+ return {
42
+ name: result.serverInfo?.name ?? fallback.name,
43
+ version: result.serverInfo?.version ?? fallback.version,
44
+ instructions: result.instructions,
45
+ };
46
+ }
47
+ catch (error) {
48
+ console.error(`[clustr-mcp] Could not reach ${getEndpoint()} at startup: ${errorMessage(error)}\n` +
49
+ "[clustr-mcp] Starting anyway; tool calls will report the error until it recovers.");
50
+ return fallback;
51
+ }
52
+ }
53
+ const identity = await upstreamIdentity();
54
+ const server = new Server({ name: identity.name, version: identity.version }, {
55
+ capabilities: { tools: {} },
56
+ ...(identity.instructions ? { instructions: identity.instructions } : {}),
57
+ });
58
+ // tools/list — fetched fresh on every call. No caching: a tool added server-side
59
+ // must be visible immediately, and a stale list is a support ticket.
60
+ server.setRequestHandler(ListToolsRequestSchema, async (request) => {
61
+ let result;
62
+ try {
63
+ result = await callUpstream("tools/list", request.params ?? {});
64
+ }
65
+ catch (error) {
66
+ throw new McpError(ErrorCode.InternalError, errorMessage(error));
67
+ }
68
+ const tools = result?.tools;
69
+ if (!Array.isArray(tools)) {
70
+ throw new McpError(ErrorCode.InternalError, `Clustr MCP endpoint (${getEndpoint()}) returned a tools/list response without a tool list`);
71
+ }
72
+ return result;
73
+ });
74
+ // tools/call — arguments forwarded untouched, result returned untouched. The
75
+ // server owns validation, so a bad argument comes back as the server's own
76
+ // error rather than one this package invented. A transport failure becomes an
77
+ // isError result so the calling model sees why instead of a silent stall.
78
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
79
+ try {
80
+ return (await callUpstream("tools/call", request.params));
81
+ }
82
+ catch (error) {
83
+ return {
84
+ content: [{ type: "text", text: `Error: ${errorMessage(error)}` }],
85
+ isError: true,
86
+ };
87
+ }
88
+ });
38
89
  const transport = new StdioServerTransport();
39
90
  await server.connect(transport);
40
91
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAC7E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAEvF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,eAAe;CACzB,CAAC,CAAC;AAEH,UAAU,EAAE,CAAC;AAEb,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,2BAA2B,CAAC,MAAM,CAAC,CAAC;AACpC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,yBAAyB,CAAC,MAAM,CAAC,CAAC;AAClC,+BAA+B,CAAC,MAAM,CAAC,CAAC;AACxC,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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clustr-ai/mcp-server",
3
- "version": "1.0.10",
4
- "description": "MCP server for the Clustr API — search referral opportunities, manage target accounts, and import contacts from AI assistants",
3
+ "version": "1.0.11",
4
+ "description": "stdio bridge to the hosted Clustr MCP server — search referral opportunities, monitor competitors, manage target accounts, and import connectors from AI assistants",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -14,6 +14,7 @@
14
14
  "build": "tsc",
15
15
  "dev": "tsx src/index.ts",
16
16
  "start": "node dist/index.js",
17
+ "test": "npm run build && node --test test/*.test.mjs",
17
18
  "prepublishOnly": "npm run build"
18
19
  },
19
20
  "keywords": [
@@ -37,8 +38,7 @@
37
38
  "node": ">=18"
38
39
  },
39
40
  "dependencies": {
40
- "@modelcontextprotocol/sdk": "^1.12.1",
41
- "zod": "^3.24.4"
41
+ "@modelcontextprotocol/sdk": "^1.12.1"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^22.15.3",
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerCreateICP(server: McpServer): void;
@@ -1,26 +0,0 @@
1
- import { z } from "zod";
2
- import { post, wrapToolHandler } from "../client.js";
3
- const inputSchema = {
4
- title: z.string().describe("ICP name (e.g. 'Enterprise SaaS', 'Mid-Market Finance')"),
5
- linkedin_industries: z
6
- .array(z.string())
7
- .optional()
8
- .describe("Target industries (e.g. ['IT', 'Computer Software'])"),
9
- revenue: z
10
- .array(z.string())
11
- .optional()
12
- .describe("Target revenue ranges (e.g. ['$10M-$50M', '$50M-$100M'])"),
13
- employees: z
14
- .array(z.string())
15
- .optional()
16
- .describe("Target employee count ranges (e.g. ['50-200', '201-500'])"),
17
- countries: z
18
- .array(z.string())
19
- .optional()
20
- .describe("Target countries (e.g. ['US', 'UK', 'France'])"),
21
- };
22
- export function registerCreateICP(server) {
23
- server.tool("create_icp", "Create a new Ideal Customer Profile (ICP). " +
24
- "Define target company characteristics for opportunity prioritization.", inputSchema, wrapToolHandler((params) => post("/company-icp", params)));
25
- }
26
- //# sourceMappingURL=create-icp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-icp.js","sourceRoot":"","sources":["../../src/tools/create-icp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;IACrF,mBAAmB,EAAE,CAAC;SACnB,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,sDAAsD,CAAC;IACnE,OAAO,EAAE,CAAC;SACP,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,0DAA0D,CAAC;IACvE,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,2DAA2D,CAAC;IACxE,SAAS,EAAE,CAAC;SACT,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,gDAAgD,CAAC;CAC9D,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,6CAA6C;QAC3C,uEAAuE,EACzE,WAAW,EACX,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAC1D,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerCreateTargetAccounts(server: McpServer): void;
@@ -1,27 +0,0 @@
1
- import { z } from "zod";
2
- import { post, wrapToolHandler } 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, wrapToolHandler((params) => post("/target-accounts", params)));
26
- }
27
- //# sourceMappingURL=create-target-accounts.js.map
@@ -1 +0,0 @@
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,eAAe,EAAE,MAAM,cAAc,CAAC;AAErD,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,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAC9D,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerDeleteICP(server: McpServer): void;
@@ -1,9 +0,0 @@
1
- import { z } from "zod";
2
- import { del, wrapToolHandler } from "../client.js";
3
- const inputSchema = {
4
- id: z.string().describe("ICP ID to delete"),
5
- };
6
- export function registerDeleteICP(server) {
7
- server.tool("delete_icp", "Delete an Ideal Customer Profile (ICP) by its ID.", inputSchema, wrapToolHandler((params) => del(`/company-icp/${encodeURIComponent(String(params.id))}`)));
8
- }
9
- //# sourceMappingURL=delete-icp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"delete-icp.js","sourceRoot":"","sources":["../../src/tools/delete-icp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;CAC5C,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,IAAI,CACT,YAAY,EACZ,mDAAmD,EACnD,WAAW,EACX,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CACzB,GAAG,CAAC,gBAAgB,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAC7D,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerDeleteTargetAccount(server: McpServer): void;
@@ -1,12 +0,0 @@
1
- import { z } from "zod";
2
- import { del, wrapToolHandler } 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, wrapToolHandler((params) => del("/target-accounts", params)));
11
- }
12
- //# sourceMappingURL=delete-target-account.js.map
@@ -1 +0,0 @@
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,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,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,eAAe,CAAC,CAAC,MAAM,EAAE,EAAE,CACzB,GAAG,CAAC,kBAAkB,EAAE,MAA4C,CAAC,CACtE,CACF,CAAC;AACJ,CAAC"}
@@ -1,2 +0,0 @@
1
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
- export declare function registerGetJobStatus(server: McpServer): void;