@anymailfinder/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.
- package/LICENSE +21 -0
- package/README.md +133 -0
- package/build/api-client.d.ts +8 -0
- package/build/api-client.js +44 -0
- package/build/api-client.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +16 -0
- package/build/index.js.map +1 -0
- package/build/server.d.ts +3 -0
- package/build/server.js +201 -0
- package/build/server.js.map +1 -0
- package/package.json +55 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anymail Finder
|
|
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,133 @@
|
|
|
1
|
+
# @anymailfinder/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP server for the [Anymail Finder](https://anymailfinder.com) API. Lets AI assistants (Claude, Cursor, ChatGPT, etc.) find and verify email addresses natively via the [Model Context Protocol](https://modelcontextprotocol.io).
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- **Node.js 20 or later** -- check with `node --version` ([download](https://nodejs.org))
|
|
8
|
+
- **Anymail Finder API key** -- get one at [anymailfinder.com](https://newapp.anymailfinder.com/settings/api)
|
|
9
|
+
|
|
10
|
+
## Available Tools
|
|
11
|
+
|
|
12
|
+
| Tool | Description | Credits |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| `find_person_email` | Find a person's email by name + company domain | Yes |
|
|
15
|
+
| `find_company_emails` | Find up to 20 emails for a company domain | Yes |
|
|
16
|
+
| `find_email_by_linkedin` | Find email from a LinkedIn profile URL | Yes |
|
|
17
|
+
| `find_decision_maker` | Find a decision maker's email by role category | Yes |
|
|
18
|
+
| `verify_email` | Check if an email is valid, risky, or invalid | Yes |
|
|
19
|
+
| `get_account_info` | Check remaining API credits | No |
|
|
20
|
+
| `report_bad_email` | Report an incorrect email | No |
|
|
21
|
+
|
|
22
|
+
## Setup
|
|
23
|
+
|
|
24
|
+
### Claude Desktop
|
|
25
|
+
|
|
26
|
+
Add to your config file:
|
|
27
|
+
|
|
28
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
29
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
30
|
+
|
|
31
|
+
Open it from a terminal:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# macOS
|
|
35
|
+
open ~/Library/Application\ Support/Claude/claude_desktop_config.json
|
|
36
|
+
|
|
37
|
+
# Windows
|
|
38
|
+
notepad %APPDATA%\Claude\claude_desktop_config.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"mcpServers": {
|
|
44
|
+
"anymailfinder": {
|
|
45
|
+
"command": "npx",
|
|
46
|
+
"args": ["-y", "@anymailfinder/mcp-server"],
|
|
47
|
+
"env": {
|
|
48
|
+
"ANYMAIL_FINDER_API_KEY": "your-api-key"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Fully quit and reopen Claude Desktop after saving (Cmd+Q on macOS).
|
|
56
|
+
|
|
57
|
+
### Cursor
|
|
58
|
+
|
|
59
|
+
Add to `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally:
|
|
60
|
+
|
|
61
|
+
```json
|
|
62
|
+
{
|
|
63
|
+
"mcpServers": {
|
|
64
|
+
"anymailfinder": {
|
|
65
|
+
"command": "npx",
|
|
66
|
+
"args": ["-y", "@anymailfinder/mcp-server"],
|
|
67
|
+
"env": {
|
|
68
|
+
"ANYMAIL_FINDER_API_KEY": "your-api-key"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Restart Cursor after saving.
|
|
76
|
+
|
|
77
|
+
## Troubleshooting
|
|
78
|
+
|
|
79
|
+
### "fetch is not defined" error
|
|
80
|
+
|
|
81
|
+
This means the MCP client is using a Node.js version older than 18. This commonly happens with **nvm** users because Claude Desktop and Cursor don't load your shell profile.
|
|
82
|
+
|
|
83
|
+
**Fix:** replace `"npx"` with the full path to your Node binary:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"mcpServers": {
|
|
88
|
+
"anymailfinder": {
|
|
89
|
+
"command": "/path/to/node",
|
|
90
|
+
"args": ["/path/to/global/node_modules/@anymailfinder/mcp-server/build/index.js"],
|
|
91
|
+
"env": {
|
|
92
|
+
"ANYMAIL_FINDER_API_KEY": "your-api-key"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Find your Node path with:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
which node
|
|
103
|
+
# e.g. /Users/you/.nvm/versions/node/v20.18.1/bin/node
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### "ANYMAIL_FINDER_API_KEY environment variable is required"
|
|
107
|
+
|
|
108
|
+
You didn't set the API key in the `env` block of your MCP config. See setup instructions above.
|
|
109
|
+
|
|
110
|
+
## Environment Variables
|
|
111
|
+
|
|
112
|
+
| Variable | Required | Default | Description |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| `ANYMAIL_FINDER_API_KEY` | Yes | — | Your Anymail Finder API key |
|
|
115
|
+
| `ANYMAIL_FINDER_API_URL` | No | `https://api.anymailfinder.com` | Override API base URL |
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
cd mcp
|
|
121
|
+
yarn install
|
|
122
|
+
yarn build
|
|
123
|
+
|
|
124
|
+
# Test interactively with MCP Inspector
|
|
125
|
+
ANYMAIL_FINDER_API_KEY=your-key npx @modelcontextprotocol/inspector node build/index.js
|
|
126
|
+
|
|
127
|
+
# Run directly (stdio mode)
|
|
128
|
+
ANYMAIL_FINDER_API_KEY=your-key node build/index.js
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const DEFAULT_BASE_URL = "https://api.anymailfinder.com";
|
|
2
|
+
export class AnymailFinderClient {
|
|
3
|
+
apiKey;
|
|
4
|
+
baseUrl;
|
|
5
|
+
constructor() {
|
|
6
|
+
const apiKey = process.env.ANYMAIL_FINDER_API_KEY;
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
console.error("Error: ANYMAIL_FINDER_API_KEY environment variable is required.");
|
|
9
|
+
console.error("Set it in your MCP client config or export it in your shell.");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
this.apiKey = apiKey;
|
|
13
|
+
this.baseUrl = process.env.ANYMAIL_FINDER_API_URL || DEFAULT_BASE_URL;
|
|
14
|
+
}
|
|
15
|
+
async post(path, body) {
|
|
16
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: {
|
|
19
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
},
|
|
22
|
+
body: JSON.stringify(body),
|
|
23
|
+
});
|
|
24
|
+
return this.handleResponse(response);
|
|
25
|
+
}
|
|
26
|
+
async get(path) {
|
|
27
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
28
|
+
method: "GET",
|
|
29
|
+
headers: {
|
|
30
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
return this.handleResponse(response);
|
|
34
|
+
}
|
|
35
|
+
async handleResponse(response) {
|
|
36
|
+
const data = await response.json();
|
|
37
|
+
if (!response.ok) {
|
|
38
|
+
const err = data;
|
|
39
|
+
throw new Error(`${err.error || "unknown"}: ${err.message || `HTTP ${response.status}`}`);
|
|
40
|
+
}
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,+BAA+B,CAAC;AAEzD,MAAM,OAAO,mBAAmB;IACb,MAAM,CAAS;IACf,OAAO,CAAS;IAEjC;QACE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CACX,iEAAiE,CAClE,CAAC;YACF,OAAO,CAAC,KAAK,CACX,8DAA8D,CAC/D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,gBAAgB,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,IAA6B;QACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACvC;SACF,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAkB;QAC7C,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,IAA4C,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,GAAG,GAAG,CAAC,KAAK,IAAI,SAAS,KAAK,GAAG,CAAC,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CACzE,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import { AnymailFinderClient } from "./api-client.js";
|
|
4
|
+
import { createServer } from "./server.js";
|
|
5
|
+
const NODE_MAJOR = parseInt(process.versions.node.split(".")[0], 10);
|
|
6
|
+
if (NODE_MAJOR < 20) {
|
|
7
|
+
console.error(`Error: Node.js 20 or later is required (current: ${process.version}).`);
|
|
8
|
+
console.error("Install Node 20+: https://nodejs.org");
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const client = new AnymailFinderClient();
|
|
12
|
+
const server = createServer(client);
|
|
13
|
+
const transport = new StdioServerTransport();
|
|
14
|
+
await server.connect(transport);
|
|
15
|
+
console.error("Anymail Finder MCP server running on stdio");
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACrE,IAAI,UAAU,GAAG,EAAE,EAAE,CAAC;IACpB,OAAO,CAAC,KAAK,CACX,oDAAoD,OAAO,CAAC,OAAO,IAAI,CACxE,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,MAAM,GAAG,IAAI,mBAAmB,EAAE,CAAC;AACzC,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AACpC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAChC,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC"}
|
package/build/server.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
const formatResult = (data) => ({
|
|
4
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
5
|
+
});
|
|
6
|
+
const formatError = (err) => {
|
|
7
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
8
|
+
return {
|
|
9
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
10
|
+
isError: true,
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export const createServer = (client) => {
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: "anymailfinder",
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
});
|
|
18
|
+
server.registerTool("find_person_email", {
|
|
19
|
+
description: "Find a person's email using their name and company.",
|
|
20
|
+
inputSchema: z.object({
|
|
21
|
+
domain: z
|
|
22
|
+
.string()
|
|
23
|
+
.optional()
|
|
24
|
+
.describe("The company domain (recommended for better accuracy). Either domain or company name is required."),
|
|
25
|
+
company_name: z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("The company name. Used if domain is not provided. Either domain or company name is required."),
|
|
29
|
+
first_name: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("The person's first name. Use with last name if full name is not provided."),
|
|
33
|
+
last_name: z
|
|
34
|
+
.string()
|
|
35
|
+
.optional()
|
|
36
|
+
.describe("The person's last name. Use with first name if full name is not provided."),
|
|
37
|
+
full_name: z
|
|
38
|
+
.string()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("The person's full name. Either full name OR first name + last name is required."),
|
|
41
|
+
}),
|
|
42
|
+
}, async (params) => {
|
|
43
|
+
try {
|
|
44
|
+
const body = {};
|
|
45
|
+
if (params.domain)
|
|
46
|
+
body.domain = params.domain;
|
|
47
|
+
if (params.company_name)
|
|
48
|
+
body.company_name = params.company_name;
|
|
49
|
+
if (params.first_name)
|
|
50
|
+
body.first_name = params.first_name;
|
|
51
|
+
if (params.last_name)
|
|
52
|
+
body.last_name = params.last_name;
|
|
53
|
+
if (params.full_name)
|
|
54
|
+
body.full_name = params.full_name;
|
|
55
|
+
const result = await client.post("/v5.1/find-email/person", body);
|
|
56
|
+
return formatResult(result);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
return formatError(err);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
server.registerTool("find_company_emails", {
|
|
63
|
+
description: "Find all emails at a company.",
|
|
64
|
+
inputSchema: z.object({
|
|
65
|
+
domain: z
|
|
66
|
+
.string()
|
|
67
|
+
.optional()
|
|
68
|
+
.describe("Preferred. The company's domain. If a company name is passed here, we'll attempt to find the domain."),
|
|
69
|
+
company_name: z
|
|
70
|
+
.string()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe("The company name. If a domain is passed here, we'll detect and treat it accordingly."),
|
|
73
|
+
email_type: z
|
|
74
|
+
.enum(["any", "generic", "personal"])
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("Specifies which type of email addresses to return: any (default, returns both generic and personal emails); generic (only role-based emails such as info@, sales@, support@); personal (only personal, individual-specific emails such as jane.doe@company.com)."),
|
|
77
|
+
}),
|
|
78
|
+
}, async (params) => {
|
|
79
|
+
try {
|
|
80
|
+
const body = {};
|
|
81
|
+
if (params.domain)
|
|
82
|
+
body.domain = params.domain;
|
|
83
|
+
if (params.company_name)
|
|
84
|
+
body.company_name = params.company_name;
|
|
85
|
+
if (params.email_type)
|
|
86
|
+
body.email_type = params.email_type;
|
|
87
|
+
const result = await client.post("/v5.1/find-email/company", body);
|
|
88
|
+
return formatResult(result);
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
return formatError(err);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
server.registerTool("find_email_by_linkedin", {
|
|
95
|
+
description: "Find emails using a LinkedIn profile URL.",
|
|
96
|
+
inputSchema: z.object({
|
|
97
|
+
linkedin_url: z
|
|
98
|
+
.string()
|
|
99
|
+
.describe("The LinkedIn profile URL of the person."),
|
|
100
|
+
}),
|
|
101
|
+
}, async (params) => {
|
|
102
|
+
try {
|
|
103
|
+
const result = await client.post("/v5.1/find-email/linkedin-url", {
|
|
104
|
+
linkedin_url: params.linkedin_url,
|
|
105
|
+
});
|
|
106
|
+
return formatResult(result);
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
return formatError(err);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
server.registerTool("find_decision_maker", {
|
|
113
|
+
description: "Find a decision maker's email by company and role.",
|
|
114
|
+
inputSchema: z.object({
|
|
115
|
+
domain: z
|
|
116
|
+
.string()
|
|
117
|
+
.optional()
|
|
118
|
+
.describe("Preferred. The company's domain. If a company name is passed here, we'll attempt to find the domain."),
|
|
119
|
+
company_name: z
|
|
120
|
+
.string()
|
|
121
|
+
.optional()
|
|
122
|
+
.describe("The company name. If a domain is passed here, we'll detect and treat it accordingly."),
|
|
123
|
+
decision_maker_category: z
|
|
124
|
+
.array(z.string())
|
|
125
|
+
.describe("One or more categories of the decision maker(s) to search for. If multiple are provided, they are treated in order of importance and we will return the first category that resolves to a valid email."),
|
|
126
|
+
}),
|
|
127
|
+
}, async (params) => {
|
|
128
|
+
try {
|
|
129
|
+
const body = {
|
|
130
|
+
decision_maker_category: params.decision_maker_category,
|
|
131
|
+
};
|
|
132
|
+
if (params.domain)
|
|
133
|
+
body.domain = params.domain;
|
|
134
|
+
if (params.company_name)
|
|
135
|
+
body.company_name = params.company_name;
|
|
136
|
+
const result = await client.post("/v5.1/find-email/decision-maker", body);
|
|
137
|
+
return formatResult(result);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
return formatError(err);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
server.registerTool("verify_email", {
|
|
144
|
+
description: "Verify if an email address is valid.",
|
|
145
|
+
inputSchema: z.object({
|
|
146
|
+
email: z.string().describe("The email address to validate."),
|
|
147
|
+
}),
|
|
148
|
+
}, async (params) => {
|
|
149
|
+
try {
|
|
150
|
+
const result = await client.post("/v5.1/verify-email", {
|
|
151
|
+
email: params.email,
|
|
152
|
+
});
|
|
153
|
+
return formatResult(result);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
return formatError(err);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
server.registerTool("get_account_info", {
|
|
160
|
+
description: "Check how many search credits are remaining on the Anymail Finder account and the associated email address. Does not consume credits.",
|
|
161
|
+
inputSchema: z.object({}),
|
|
162
|
+
}, async () => {
|
|
163
|
+
try {
|
|
164
|
+
const result = await client.get("/v5.1/account");
|
|
165
|
+
return formatResult(result);
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
return formatError(err);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
server.registerTool("report_bad_email", {
|
|
172
|
+
description: "Report an email address as bad or invalid to Anymail Finder. Use this when you discover an email returned by the API is incorrect or bouncing.",
|
|
173
|
+
inputSchema: z.object({
|
|
174
|
+
email: z.string().describe("The email address to report as bad."),
|
|
175
|
+
additional_info: z
|
|
176
|
+
.string()
|
|
177
|
+
.max(500)
|
|
178
|
+
.describe("Explanation of why the email is bad, e.g. 'Email bounced with permanent failure'."),
|
|
179
|
+
bounce_message: z
|
|
180
|
+
.string()
|
|
181
|
+
.optional()
|
|
182
|
+
.describe("Optional bounce message from the email server."),
|
|
183
|
+
}),
|
|
184
|
+
}, async (params) => {
|
|
185
|
+
try {
|
|
186
|
+
const body = {
|
|
187
|
+
email: params.email,
|
|
188
|
+
additional_info: params.additional_info,
|
|
189
|
+
};
|
|
190
|
+
if (params.bounce_message)
|
|
191
|
+
body.bounce_message = params.bounce_message;
|
|
192
|
+
const result = await client.post("/v5.1/report/bad-email", body);
|
|
193
|
+
return formatResult(result);
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
return formatError(err);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
return server;
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@anymailfinder/mcp-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Anymail Finder API - find and verify email addresses via AI assistants",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Anymail Finder"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"homepage": "https://anymailfinder.com",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"mcp",
|
|
12
|
+
"model-context-protocol",
|
|
13
|
+
"anymailfinder",
|
|
14
|
+
"email",
|
|
15
|
+
"email-finder",
|
|
16
|
+
"email-verification",
|
|
17
|
+
"ai",
|
|
18
|
+
"claude",
|
|
19
|
+
"cursor"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"bin": {
|
|
23
|
+
"anymailfinder-mcp-server": "./build/index.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"build"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc && chmod +x build/index.js",
|
|
30
|
+
"dev": "tsc --watch",
|
|
31
|
+
"lint": "tsc --noEmit && eslint .",
|
|
32
|
+
"lint:fix": "eslint . --fix",
|
|
33
|
+
"prepublishOnly": "npm run build",
|
|
34
|
+
"start": "node build/index.js"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
41
|
+
"zod": "^3.25.76"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^22.10.0",
|
|
45
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
46
|
+
"eslint": "^9.0.0",
|
|
47
|
+
"eslint-config-prettier": "^10.1.8",
|
|
48
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
49
|
+
"eslint-plugin-simple-import-sort": "^12.0.0",
|
|
50
|
+
"globals": "^15.0.0",
|
|
51
|
+
"prettier": "^3.0.0",
|
|
52
|
+
"typescript": "~5.7.0",
|
|
53
|
+
"typescript-eslint": "^8.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|