@mambalabsdev/mcp-icp-fit-scorer 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mamba Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # ICP Fit Scorer MCP Server
2
+
3
+ An MCP server that scores a company against your ideal customer profile. It wraps the Mamba Labs ICP Fit Scorer actor on Apify and returns a Clay-ready flat JSON row to any MCP client.
4
+
5
+ ## What it does
6
+
7
+ Give it a company domain and a definition of your ICP, and it scores the company on weighted signals, returning a 0 to 100 score, an A to D tier, and a per-signal breakdown. Define your ICP three ways: a prebuilt template, a JSON scoring config, or a plain-English description (which uses your own LLM key). Turn on `fetch_signals` and the actor will gather hiring and tech-stack signals for you before scoring. One flat row, ready for Clay, a CRM, or an AI agent workflow. All of the scoring runs on Apify. This package is a thin client that calls the actor and hands back the result.
8
+
9
+ ## Quick start
10
+
11
+ You need Node.js 18 or newer and an Apify account with an API token.
12
+
13
+ Add this to your Claude Desktop config:
14
+
15
+ ```json
16
+ {
17
+ "mcpServers": {
18
+ "mamba-icp-scorer": {
19
+ "command": "npx",
20
+ "args": ["-y", "@mambalabsdev/mcp-icp-fit-scorer"],
21
+ "env": {
22
+ "APIFY_TOKEN": "your-apify-token"
23
+ }
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ Get your token at https://console.apify.com/account/integrations, paste it in, and restart Claude Desktop. The `score_icp_fit` tool will be available.
30
+
31
+ ## Prerequisites
32
+
33
+ - Node.js 18 or newer
34
+ - An Apify account with an API token
35
+
36
+ ## Example prompts
37
+
38
+ - "Score clay.com against the b2b_saas template and fetch its signals."
39
+ - "How well does stripe.com fit an ICP of mid-market fintech companies? Explain the score."
40
+ - "Score figma.com with my scoring config and include the per-signal breakdown."
41
+ - "Rate openai.com against this ICP description: enterprise AI teams hiring for go-to-market."
42
+
43
+ ## Inputs
44
+
45
+ - `company_domain` (required): the primary domain of the company to score. Example: `clay.com`
46
+ - `company_name` (optional): display name of the company.
47
+ - `template` (optional): name of a prebuilt scoring config.
48
+ - `scoring_config` (optional): a JSON object of scoring weights.
49
+ - `icp_description` (optional): plain-English ICP description. Requires `llm_api_key`.
50
+ - `llm_api_key` (optional): your OpenAI or Anthropic key, used only with `icp_description`.
51
+ - `llm_provider` (optional): `openai` or `anthropic`.
52
+ - `fetch_signals` (optional): let the actor gather hiring and tech-stack signals automatically.
53
+ - `include_explanation` (optional): add a `score_explanation` string to the output.
54
+
55
+ Define your ICP with exactly one of `template`, `scoring_config`, or `icp_description`.
56
+
57
+ This server exposes the single-company scoring path. The actor also supports batch inputs (a dataset or CSV of companies) and a results webhook. For those, run the actor directly on Apify.
58
+
59
+ ## Output
60
+
61
+ The tool returns the actor's flat JSON row for the scored company, including `icp_score` (0 to 100), `icp_tier` (A to D), the per-signal breakdown, and an optional explanation. See the Apify Store page for the full output schema.
62
+
63
+ ## Full actor documentation
64
+
65
+ This server is a thin client and holds no scoring logic. For the complete input and output reference, pricing, and run history, see the Apify Store page:
66
+
67
+ https://apify.com/mambalabs/icp-fit-scorer
68
+
69
+ ## Mamba Labs GTM Suite
70
+
71
+ This is one of six actors in the Mamba Labs GTM Suite, covering hiring signals, tech stack detection, signal aggregation, job board keyword scanning, LinkedIn URL resolution, and ICP scoring. See them all at https://apify.com/mambalabs.
72
+
73
+ ## License
74
+
75
+ MIT
76
+
77
+ Built by Mamba Labs. https://apify.com/mambalabs
package/build/index.js ADDED
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import { dirname, join } from "node:path";
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { z } from "zod";
8
+ const here = dirname(fileURLToPath(import.meta.url));
9
+ const pkg = JSON.parse(readFileSync(join(here, "..", "package.json"), "utf8"));
10
+ const APIFY_TOKEN = process.env.APIFY_TOKEN;
11
+ if (!APIFY_TOKEN) {
12
+ console.error([
13
+ "APIFY_TOKEN is not set.",
14
+ "This server needs an Apify API token to run the ICP Fit Scorer actor.",
15
+ "Create a token at https://console.apify.com/account/integrations and pass it as the APIFY_TOKEN environment variable.",
16
+ ].join("\n"));
17
+ process.exit(1);
18
+ }
19
+ // The tilde between the org name and the actor name is Apify's required separator.
20
+ const ACTOR_ENDPOINT = "https://api.apify.com/v2/acts/mambalabs~icp-fit-scorer/run-sync-get-dataset-items?timeout=300";
21
+ const server = new McpServer({
22
+ name: "mamba-icp-fit-scorer",
23
+ version: pkg.version,
24
+ });
25
+ // This tool exposes the single-company scoring surface. The actor also supports
26
+ // batch inputs (dataset_id, csv_url), a webhook, and ~18 manual signal-override
27
+ // fields; those are intentionally not surfaced here. Use fetch_signals to let the
28
+ // actor gather hiring and tech-stack signals on its own.
29
+ server.tool("score_icp_fit", "Score a company against your ideal customer profile (ICP) using weighted signals. Returns a 0 to 100 icp_score, an A to D icp_tier, and a per-signal breakdown as a flat, Clay-ready JSON row. Define your ICP with a prebuilt template, a JSON scoring_config, or a plain-English icp_description (which requires llm_api_key).", {
30
+ company_domain: z
31
+ .string()
32
+ .describe("The primary domain of the company to score. Example: clay.com"),
33
+ company_name: z.string().optional().describe("Optional display name of the company."),
34
+ template: z
35
+ .string()
36
+ .optional()
37
+ .describe("Name of a prebuilt scoring config. Alternative to scoring_config or icp_description."),
38
+ scoring_config: z
39
+ .record(z.any())
40
+ .optional()
41
+ .describe("JSON object of scoring weights. Alternative to template or icp_description."),
42
+ icp_description: z
43
+ .string()
44
+ .optional()
45
+ .describe("Plain-English description of your target ICP. Requires llm_api_key. Alternative to template or scoring_config."),
46
+ llm_api_key: z
47
+ .string()
48
+ .optional()
49
+ .describe("Your OpenAI or Anthropic API key. Required only when using icp_description."),
50
+ llm_provider: z
51
+ .string()
52
+ .optional()
53
+ .describe("LLM provider to use with icp_description: openai or anthropic."),
54
+ fetch_signals: z
55
+ .boolean()
56
+ .optional()
57
+ .describe("If true, the actor fetches hiring and tech-stack signals for the company automatically before scoring."),
58
+ include_explanation: z
59
+ .boolean()
60
+ .optional()
61
+ .describe("If true, adds a score_explanation string to the output describing how the score was derived."),
62
+ }, async (args) => {
63
+ const input = { company_domain: args.company_domain };
64
+ for (const key of [
65
+ "company_name",
66
+ "template",
67
+ "scoring_config",
68
+ "icp_description",
69
+ "llm_api_key",
70
+ "llm_provider",
71
+ "fetch_signals",
72
+ "include_explanation",
73
+ ]) {
74
+ if (args[key] !== undefined)
75
+ input[key] = args[key];
76
+ }
77
+ let response;
78
+ try {
79
+ response = await fetch(ACTOR_ENDPOINT, {
80
+ method: "POST",
81
+ headers: {
82
+ Authorization: `Bearer ${APIFY_TOKEN}`,
83
+ "Content-Type": "application/json",
84
+ },
85
+ body: JSON.stringify(input),
86
+ });
87
+ }
88
+ catch (err) {
89
+ const message = err instanceof Error ? err.message : String(err);
90
+ return {
91
+ isError: true,
92
+ content: [{ type: "text", text: `Could not reach the Apify API: ${message}` }],
93
+ };
94
+ }
95
+ if (!response.ok) {
96
+ let detail = "";
97
+ try {
98
+ const body = (await response.json());
99
+ if (body?.error?.message)
100
+ detail = ` ${body.error.message}`;
101
+ }
102
+ catch {
103
+ detail = "";
104
+ }
105
+ let message;
106
+ switch (response.status) {
107
+ case 401:
108
+ message = "Invalid Apify token. Check your APIFY_TOKEN environment variable.";
109
+ break;
110
+ case 402:
111
+ message =
112
+ "Insufficient Apify credits. Check your account balance at https://console.apify.com/billing";
113
+ break;
114
+ case 408:
115
+ message =
116
+ "Actor run timed out after 300 seconds. Try again, or run the actor on Apify directly for longer jobs.";
117
+ break;
118
+ default:
119
+ message = `Apify request failed with status ${response.status}.${detail}`;
120
+ }
121
+ return { isError: true, content: [{ type: "text", text: message }] };
122
+ }
123
+ const items = await response.json();
124
+ return {
125
+ content: [{ type: "text", text: JSON.stringify(items, null, 2) }],
126
+ };
127
+ });
128
+ const transport = new StdioServerTransport();
129
+ await server.connect(transport);
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@mambalabsdev/mcp-icp-fit-scorer",
3
+ "version": "1.0.0",
4
+ "description": "MCP server for ICP Fit Scorer. Scores a company against your ideal customer profile with weighted signals via Apify. Returns a 0 to 100 score, a tier, and a per-signal breakdown. Clay-ready output.",
5
+ "type": "module",
6
+ "bin": {
7
+ "mcp-icp-fit-scorer": "./build/index.js"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc && chmod +x build/index.js",
11
+ "prepublishOnly": "npm run build"
12
+ },
13
+ "keywords": [
14
+ "mcp",
15
+ "model-context-protocol",
16
+ "icp",
17
+ "lead-scoring",
18
+ "qualification",
19
+ "apify",
20
+ "clay",
21
+ "lead-generation"
22
+ ],
23
+ "author": "Mamba Labs <labs@mambamindsetgrowth.com>",
24
+ "license": "MIT",
25
+ "homepage": "https://apify.com/mambalabs/icp-fit-scorer",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/mambalabsdev/mcp-icp-fit-scorer"
29
+ },
30
+ "engines": {
31
+ "node": ">=18"
32
+ },
33
+ "dependencies": {
34
+ "@modelcontextprotocol/sdk": "^1.12.0",
35
+ "zod": "^3.23.8"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^20.14.0",
39
+ "typescript": "^5.6.0"
40
+ }
41
+ }