@tocharianou/abuseipdb-mcp 1.0.1
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 +306 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +148 -0
- package/dist/index.js.map +1 -0
- package/dist/src/blacklist-tools.d.ts +3 -0
- package/dist/src/blacklist-tools.js +41 -0
- package/dist/src/blacklist-tools.js.map +1 -0
- package/dist/src/block-tools.d.ts +3 -0
- package/dist/src/block-tools.js +38 -0
- package/dist/src/block-tools.js.map +1 -0
- package/dist/src/handlers/blacklist.d.ts +7 -0
- package/dist/src/handlers/blacklist.js +57 -0
- package/dist/src/handlers/blacklist.js.map +1 -0
- package/dist/src/handlers/block.d.ts +7 -0
- package/dist/src/handlers/block.js +34 -0
- package/dist/src/handlers/block.js.map +1 -0
- package/dist/src/handlers/index.d.ts +3 -0
- package/dist/src/handlers/index.js +4 -0
- package/dist/src/handlers/index.js.map +1 -0
- package/dist/src/handlers/ip.d.ts +14 -0
- package/dist/src/handlers/ip.js +106 -0
- package/dist/src/handlers/ip.js.map +1 -0
- package/dist/src/ip-tools.d.ts +3 -0
- package/dist/src/ip-tools.js +79 -0
- package/dist/src/ip-tools.js.map +1 -0
- package/dist/src/types/abuseipdb.d.ts +69 -0
- package/dist/src/types/abuseipdb.js +37 -0
- package/dist/src/types/abuseipdb.js.map +1 -0
- package/dist/src/types.d.ts +18 -0
- package/dist/src/types.js +21 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/api.d.ts +10 -0
- package/dist/src/utils/api.js +30 -0
- package/dist/src/utils/api.js.map +1 -0
- package/dist/src/utils/token-limiter.d.ts +8 -0
- package/dist/src/utils/token-limiter.js +29 -0
- package/dist/src/utils/token-limiter.js.map +1 -0
- package/logos/logo-240.svg +13 -0
- package/logos/logo-48.svg +9 -0
- package/package.json +54 -0
- package/server.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 MCP AbuseIPDB Team
|
|
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,306 @@
|
|
|
1
|
+
# MCP AbuseIPDB Server
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that provides threat intelligence lookups against the AbuseIPDB database. This server enables any MCP-capable client to perform IP reputation checks, CIDR block analysis, and access curated blacklists with intelligent caching and rate limiting.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **IP Reputation Checks**: Single IP address lookups with detailed abuse data
|
|
8
|
+
- **CIDR Block Analysis**: Check entire network ranges for malicious activity
|
|
9
|
+
- **Blacklist Access**: Retrieve current AbuseIPDB blacklist with configurable confidence levels
|
|
10
|
+
- **Bulk Operations**: Check multiple IP addresses efficiently
|
|
11
|
+
- **Log Enrichment**: Extract and analyze IP addresses from log lines
|
|
12
|
+
- **Intelligent Caching**: SQLite-based caching with TTL to minimize API usage
|
|
13
|
+
- **Rate Limiting**: Built-in quota management for AbuseIPDB API limits
|
|
14
|
+
- **Security Focused**: Input validation, private IP filtering, and secure defaults
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
### Prerequisites
|
|
19
|
+
|
|
20
|
+
- Python 3.11 or higher
|
|
21
|
+
- AbuseIPDB API key (get one at [abuseipdb.com](https://www.abuseipdb.com/api))
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
1. Clone the repository:
|
|
26
|
+
```bash
|
|
27
|
+
git clone <repository-url>
|
|
28
|
+
cd AbuseIPDB-MCP
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Install the package:
|
|
32
|
+
```bash
|
|
33
|
+
pip install -e .
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. Set up your environment:
|
|
37
|
+
```bash
|
|
38
|
+
cp .env.example .env
|
|
39
|
+
# Edit .env and add your ABUSEIPDB_API_KEY
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
4. Run the server:
|
|
43
|
+
```bash
|
|
44
|
+
python -m mcp_abuseipdb.server
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### MCP Client Configuration
|
|
48
|
+
|
|
49
|
+
#### Option 1: Using the Enhanced Startup Script (Recommended)
|
|
50
|
+
|
|
51
|
+
Add to your MCP client configuration (e.g., `mcp.json`):
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"mcpServers": {
|
|
56
|
+
"mcp-abuseipdb": {
|
|
57
|
+
"command": "python",
|
|
58
|
+
"args": ["scripts/start_mcp_server.py"],
|
|
59
|
+
"cwd": "/path/to/AbuseIPDB-MCP",
|
|
60
|
+
"env": {
|
|
61
|
+
"ABUSEIPDB_API_KEY": "your_api_key_here"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### Option 2: Direct Module Execution
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"mcpServers": {
|
|
73
|
+
"mcp-abuseipdb": {
|
|
74
|
+
"command": "python",
|
|
75
|
+
"args": ["-m", "mcp_abuseipdb.server"],
|
|
76
|
+
"cwd": "/path/to/AbuseIPDB-MCP",
|
|
77
|
+
"env": {
|
|
78
|
+
"ABUSEIPDB_API_KEY": "your_api_key_here"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Important Notes:**
|
|
86
|
+
- Replace `your_api_key_here` with your actual AbuseIPDB API key
|
|
87
|
+
- Update `/path/to/AbuseIPDB-MCP` to the actual path where you cloned this repository
|
|
88
|
+
- The enhanced startup script (Option 1) provides better error diagnostics
|
|
89
|
+
- Ensure your API key is valid and not expired on the AbuseIPDB website
|
|
90
|
+
|
|
91
|
+
## Available Tools
|
|
92
|
+
|
|
93
|
+
### `check_ip`
|
|
94
|
+
Check the reputation of a single IP address.
|
|
95
|
+
|
|
96
|
+
**Parameters:**
|
|
97
|
+
- `ip_address` (required): IP address to check
|
|
98
|
+
- `max_age_days` (optional): Maximum age of reports (default: 30)
|
|
99
|
+
- `verbose` (optional): Include detailed reports (default: false)
|
|
100
|
+
- `threshold` (optional): Confidence threshold for flagging (default: 75)
|
|
101
|
+
|
|
102
|
+
### `check_block`
|
|
103
|
+
Check the reputation of a CIDR network block.
|
|
104
|
+
|
|
105
|
+
**Parameters:**
|
|
106
|
+
- `network` (required): CIDR network (e.g., "192.168.1.0/24")
|
|
107
|
+
- `max_age_days` (optional): Maximum age of reports (default: 30)
|
|
108
|
+
|
|
109
|
+
### `get_blacklist`
|
|
110
|
+
Retrieve the AbuseIPDB blacklist.
|
|
111
|
+
|
|
112
|
+
**Parameters:**
|
|
113
|
+
- `confidence_minimum` (optional): Minimum confidence level (default: 90)
|
|
114
|
+
- `limit` (optional): Maximum entries to retrieve
|
|
115
|
+
|
|
116
|
+
### `bulk_check`
|
|
117
|
+
Check multiple IP addresses efficiently.
|
|
118
|
+
|
|
119
|
+
**Parameters:**
|
|
120
|
+
- `ip_addresses` (required): List of IP addresses
|
|
121
|
+
- `max_age_days` (optional): Maximum age of reports (default: 30)
|
|
122
|
+
- `threshold` (optional): Confidence threshold for flagging (default: 75)
|
|
123
|
+
|
|
124
|
+
### `enrich_log_line`
|
|
125
|
+
Extract and analyze IP addresses from log entries.
|
|
126
|
+
|
|
127
|
+
**Parameters:**
|
|
128
|
+
- `log_line` (required): Log line containing IP addresses
|
|
129
|
+
- `threshold` (optional): Confidence threshold for flagging (default: 75)
|
|
130
|
+
- `max_age_days` (optional): Maximum age of reports (default: 30)
|
|
131
|
+
|
|
132
|
+
## Available Resources
|
|
133
|
+
|
|
134
|
+
### `cache://info`
|
|
135
|
+
Get current cache statistics and rate limiter status.
|
|
136
|
+
|
|
137
|
+
### `doc://usage`
|
|
138
|
+
Complete API usage documentation and examples.
|
|
139
|
+
|
|
140
|
+
## Available Prompts
|
|
141
|
+
|
|
142
|
+
### `triage_ip`
|
|
143
|
+
Generate security analyst triage notes for an IP address.
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
- `ip_data` (required): IP check data from AbuseIPDB
|
|
147
|
+
|
|
148
|
+
## Configuration
|
|
149
|
+
|
|
150
|
+
All configuration is done via environment variables. Copy `.env.example` to `.env` and customize:
|
|
151
|
+
|
|
152
|
+
### Required Settings
|
|
153
|
+
- `ABUSEIPDB_API_KEY`: Your AbuseIPDB API key
|
|
154
|
+
|
|
155
|
+
### Optional Settings
|
|
156
|
+
- `MAX_AGE_DAYS`: Default report age limit (default: 30)
|
|
157
|
+
- `CONFIDENCE_THRESHOLD`: Default confidence threshold (default: 75)
|
|
158
|
+
- `DAILY_QUOTA`: API request quota (default: 1000)
|
|
159
|
+
- `CACHE_DB_PATH`: SQLite cache file location (default: ./cache.db)
|
|
160
|
+
- `LOG_LEVEL`: Logging level (default: INFO)
|
|
161
|
+
- `ALLOW_PRIVATE_IPS`: Allow checking private IPs (default: false)
|
|
162
|
+
|
|
163
|
+
## Usage Examples
|
|
164
|
+
|
|
165
|
+
### Basic IP Check
|
|
166
|
+
```
|
|
167
|
+
Check the reputation of 8.8.8.8
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Log Analysis
|
|
171
|
+
```
|
|
172
|
+
Analyze this log line for threats:
|
|
173
|
+
192.168.1.100 - - [10/Jan/2024:10:00:00 +0000] "GET /admin/login.php HTTP/1.1" 200 1234
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Bulk Analysis
|
|
177
|
+
```
|
|
178
|
+
Check these IPs for malicious activity:
|
|
179
|
+
- 203.0.113.100
|
|
180
|
+
- 198.51.100.50
|
|
181
|
+
- 192.0.2.25
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Security Investigation
|
|
185
|
+
```
|
|
186
|
+
I'm investigating suspicious activity from 203.0.113.100. Can you:
|
|
187
|
+
1. Check its reputation with detailed reports
|
|
188
|
+
2. Analyze the surrounding network block
|
|
189
|
+
3. Generate triage notes for our security team
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
See `examples/queries.md` for more detailed examples.
|
|
193
|
+
|
|
194
|
+
## Docker Deployment
|
|
195
|
+
|
|
196
|
+
Build and run with Docker:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Build the image
|
|
200
|
+
docker build -f docker/Dockerfile -t mcp-abuseipdb .
|
|
201
|
+
|
|
202
|
+
# Run the container
|
|
203
|
+
docker run -e ABUSEIPDB_API_KEY=your_key_here mcp-abuseipdb
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
### Setup Development Environment
|
|
209
|
+
```bash
|
|
210
|
+
pip install -e ".[dev]"
|
|
211
|
+
pre-commit install
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Run Tests
|
|
215
|
+
```bash
|
|
216
|
+
pytest
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
## Security Considerations
|
|
221
|
+
|
|
222
|
+
- **API Key Protection**: Never commit API keys to version control
|
|
223
|
+
- **Private IP Filtering**: Private IPs are blocked by default
|
|
224
|
+
- **Rate Limiting**: Built-in quota management prevents API abuse
|
|
225
|
+
- **Input Validation**: All inputs are validated and sanitized
|
|
226
|
+
- **Caching**: Reduces API calls and improves performance
|
|
227
|
+
|
|
228
|
+
## Rate Limits
|
|
229
|
+
|
|
230
|
+
AbuseIPDB free tier provides 1,000 requests per day. This server:
|
|
231
|
+
- Implements intelligent caching to minimize API usage
|
|
232
|
+
- Provides rate limiting with configurable quotas
|
|
233
|
+
- Gracefully handles rate limit errors with backoff
|
|
234
|
+
|
|
235
|
+
## Troubleshooting
|
|
236
|
+
|
|
237
|
+
### "Unauthorized API key" Error in Claude App
|
|
238
|
+
|
|
239
|
+
If you're getting unauthorized API key errors when using the MCP server with Claude:
|
|
240
|
+
|
|
241
|
+
1. **Verify API Key Configuration**:
|
|
242
|
+
```bash
|
|
243
|
+
# Test your API key with the diagnostic script
|
|
244
|
+
python diagnostics/api_auth_diagnostic.py
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
2. **Check Claude App Configuration**:
|
|
248
|
+
- Ensure your `mcp.json` has the correct API key in the `env` section
|
|
249
|
+
- Verify the `cwd` path points to your project directory
|
|
250
|
+
- Make sure the API key value matches exactly (no extra spaces)
|
|
251
|
+
|
|
252
|
+
3. **Use Enhanced Startup Script**:
|
|
253
|
+
- Switch to Option 1 configuration (enhanced startup script)
|
|
254
|
+
- Check the server logs in Claude app for diagnostic messages
|
|
255
|
+
- Look for `[MCP AbuseIPDB]` prefixed messages
|
|
256
|
+
|
|
257
|
+
4. **Environment Variable Issues**:
|
|
258
|
+
- Ensure your `.env` file is in the project root directory
|
|
259
|
+
- Verify the API key in `.env` matches your Claude app configuration
|
|
260
|
+
- Check that the API key is valid on the AbuseIPDB website
|
|
261
|
+
|
|
262
|
+
5. **Debug Steps**:
|
|
263
|
+
```bash
|
|
264
|
+
# Test local server startup
|
|
265
|
+
python scripts/start_mcp_server.py
|
|
266
|
+
|
|
267
|
+
# Check environment loading
|
|
268
|
+
python -c "from mcp_abuseipdb.settings import Settings; print('API key loaded:', bool(Settings().abuseipdb_api_key))"
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Common Issues
|
|
272
|
+
|
|
273
|
+
- **"No .env file found"**: Make sure `.env` exists in project root or set API key in Claude app config
|
|
274
|
+
- **"Settings API key: EMPTY"**: API key not properly loaded from environment
|
|
275
|
+
- **"Environment var: EMPTY"**: API key not set in Claude app MCP configuration
|
|
276
|
+
- **Connection timeouts**: Check your internet connection and AbuseIPDB service status
|
|
277
|
+
|
|
278
|
+
## Contributing
|
|
279
|
+
|
|
280
|
+
1. Fork the repository
|
|
281
|
+
2. Create a feature branch
|
|
282
|
+
3. Make your changes with tests
|
|
283
|
+
4. Run the test suite and linting
|
|
284
|
+
5. Submit a pull request
|
|
285
|
+
|
|
286
|
+
## License
|
|
287
|
+
|
|
288
|
+
MIT License — see [LICENSE](LICENSE) for details.
|
|
289
|
+
|
|
290
|
+
## Support
|
|
291
|
+
|
|
292
|
+
- Documentation: See `examples/` directory
|
|
293
|
+
- Issues: Please report bugs and feature requests via GitHub issues
|
|
294
|
+
- API Documentation: [AbuseIPDB API Docs](https://docs.abuseipdb.com/)
|
|
295
|
+
|
|
296
|
+
## Changelog
|
|
297
|
+
|
|
298
|
+
### v0.1.0
|
|
299
|
+
- Initial release
|
|
300
|
+
- Basic IP checking functionality
|
|
301
|
+
- CIDR block analysis
|
|
302
|
+
- Blacklist access
|
|
303
|
+
- Bulk operations
|
|
304
|
+
- Log enrichment
|
|
305
|
+
- Caching and rate limiting
|
|
306
|
+
- Docker support
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import 'dotenv/config';
|
|
3
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
4
|
+
import { AbuseIPDBConfig } from './src/types.js';
|
|
5
|
+
interface ServerCreationOptions {
|
|
6
|
+
name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
config: AbuseIPDBConfig;
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createAbuseIPDBMcpServer(options: ServerCreationOptions): Promise<McpServer>;
|
|
12
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// Copyright (c) 2024 TocharianOU Contributors
|
|
4
|
+
import 'dotenv/config';
|
|
5
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
6
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
7
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
8
|
+
import express from 'express';
|
|
9
|
+
import { randomUUID } from 'crypto';
|
|
10
|
+
import { AbuseIPDBConfigSchema } from './src/types.js';
|
|
11
|
+
import { createAbuseIPDBClient } from './src/utils/api.js';
|
|
12
|
+
import { registerIpTools } from './src/ip-tools.js';
|
|
13
|
+
import { registerBlockTools } from './src/block-tools.js';
|
|
14
|
+
import { registerBlacklistTools } from './src/blacklist-tools.js';
|
|
15
|
+
export async function createAbuseIPDBMcpServer(options) {
|
|
16
|
+
const { name, version, config, description } = options;
|
|
17
|
+
const validatedConfig = AbuseIPDBConfigSchema.parse(config);
|
|
18
|
+
const client = createAbuseIPDBClient(validatedConfig);
|
|
19
|
+
const server = new McpServer({
|
|
20
|
+
name,
|
|
21
|
+
version,
|
|
22
|
+
...(description ? { description } : {}),
|
|
23
|
+
});
|
|
24
|
+
const maxTokenCall = parseInt(process.env.MAX_TOKEN_CALL ?? '20000', 10);
|
|
25
|
+
registerIpTools(server, client, maxTokenCall);
|
|
26
|
+
registerBlockTools(server, client, maxTokenCall);
|
|
27
|
+
registerBlacklistTools(server, client, maxTokenCall);
|
|
28
|
+
registerBlockTools(server, client, maxTokenCall);
|
|
29
|
+
registerBlacklistTools(server, client, maxTokenCall);
|
|
30
|
+
return server;
|
|
31
|
+
}
|
|
32
|
+
async function main() {
|
|
33
|
+
const config = {
|
|
34
|
+
apiKey: process.env.ABUSEIPDB_API_KEY,
|
|
35
|
+
baseUrl: process.env.ABUSEIPDB_BASE_URL,
|
|
36
|
+
authToken: process.env.ABUSEIPDB_AUTH_TOKEN,
|
|
37
|
+
timeout: parseInt(process.env.ABUSEIPDB_TIMEOUT ?? '30000', 10),
|
|
38
|
+
};
|
|
39
|
+
const SERVER_NAME = 'abuseipdb-mcp-server';
|
|
40
|
+
const SERVER_VERSION = '1.0.0';
|
|
41
|
+
const SERVER_DESCRIPTION = 'AbuseIPDB MCP Server – IP reputation, abuse confidence scoring, and threat blacklist';
|
|
42
|
+
const useHttp = process.env.MCP_TRANSPORT === 'http';
|
|
43
|
+
const httpPort = parseInt(process.env.MCP_HTTP_PORT ?? '3000', 10);
|
|
44
|
+
const httpHost = process.env.MCP_HTTP_HOST ?? 'localhost';
|
|
45
|
+
if (useHttp) {
|
|
46
|
+
process.stderr.write(`Starting AbuseIPDB MCP Server in HTTP mode on ${httpHost}:${httpPort}\n`);
|
|
47
|
+
const app = express();
|
|
48
|
+
app.use(express.json());
|
|
49
|
+
const transports = new Map();
|
|
50
|
+
app.get('/health', (_req, res) => {
|
|
51
|
+
res.json({ status: 'ok', transport: 'streamable-http' });
|
|
52
|
+
});
|
|
53
|
+
app.post('/mcp', async (req, res) => {
|
|
54
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
55
|
+
try {
|
|
56
|
+
let transport;
|
|
57
|
+
if (sessionId !== undefined && transports.has(sessionId)) {
|
|
58
|
+
transport = transports.get(sessionId);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
transport = new StreamableHTTPServerTransport({
|
|
62
|
+
sessionIdGenerator: () => randomUUID(),
|
|
63
|
+
onsessioninitialized: async (newSessionId) => {
|
|
64
|
+
transports.set(newSessionId, transport);
|
|
65
|
+
process.stderr.write(`MCP session initialized: ${newSessionId}\n`);
|
|
66
|
+
},
|
|
67
|
+
onsessionclosed: async (closedSessionId) => {
|
|
68
|
+
transports.delete(closedSessionId);
|
|
69
|
+
process.stderr.write(`MCP session closed: ${closedSessionId}\n`);
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const server = await createAbuseIPDBMcpServer({
|
|
73
|
+
name: SERVER_NAME,
|
|
74
|
+
version: SERVER_VERSION,
|
|
75
|
+
config,
|
|
76
|
+
description: SERVER_DESCRIPTION,
|
|
77
|
+
});
|
|
78
|
+
await server.connect(transport);
|
|
79
|
+
}
|
|
80
|
+
await transport.handleRequest(req, res, req.body);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
process.stderr.write(`Error handling MCP request: ${error}\n`);
|
|
84
|
+
if (!res.headersSent) {
|
|
85
|
+
res.status(500).json({
|
|
86
|
+
jsonrpc: '2.0',
|
|
87
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
88
|
+
id: null,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
app.get('/mcp', async (req, res) => {
|
|
94
|
+
const sessionId = req.headers['mcp-session-id'];
|
|
95
|
+
if (sessionId === undefined || !transports.has(sessionId)) {
|
|
96
|
+
res.status(400).json({
|
|
97
|
+
jsonrpc: '2.0',
|
|
98
|
+
error: { code: -32000, message: 'Invalid or missing session ID' },
|
|
99
|
+
id: null,
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
const transport = transports.get(sessionId);
|
|
105
|
+
await transport.handleRequest(req, res);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
process.stderr.write(`Error handling SSE stream: ${error}\n`);
|
|
109
|
+
if (!res.headersSent) {
|
|
110
|
+
res.status(500).json({
|
|
111
|
+
jsonrpc: '2.0',
|
|
112
|
+
error: { code: -32603, message: 'Failed to establish SSE stream' },
|
|
113
|
+
id: null,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
app.listen(httpPort, httpHost, () => {
|
|
119
|
+
process.stderr.write(`AbuseIPDB MCP Server (HTTP mode) started on http://${httpHost}:${httpPort}\n`);
|
|
120
|
+
});
|
|
121
|
+
process.on('SIGINT', async () => {
|
|
122
|
+
for (const [, transport] of transports.entries()) {
|
|
123
|
+
await transport.close();
|
|
124
|
+
}
|
|
125
|
+
process.exit(0);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
process.stderr.write('Starting AbuseIPDB MCP Server in Stdio mode\n');
|
|
130
|
+
const server = await createAbuseIPDBMcpServer({
|
|
131
|
+
name: SERVER_NAME,
|
|
132
|
+
version: SERVER_VERSION,
|
|
133
|
+
config,
|
|
134
|
+
description: SERVER_DESCRIPTION,
|
|
135
|
+
});
|
|
136
|
+
const transport = new StdioServerTransport();
|
|
137
|
+
await server.connect(transport);
|
|
138
|
+
process.on('SIGINT', async () => {
|
|
139
|
+
await server.close();
|
|
140
|
+
process.exit(0);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
main().catch((error) => {
|
|
145
|
+
process.stderr.write(`Fatal error: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { handleGetBlacklist } from './handlers/blacklist.js';
|
|
3
|
+
import { checkTokenLimit } from './utils/token-limiter.js';
|
|
4
|
+
const GetBlacklistSchema = z.object({
|
|
5
|
+
confidence_minimum: z
|
|
6
|
+
.number()
|
|
7
|
+
.int()
|
|
8
|
+
.min(25)
|
|
9
|
+
.max(100)
|
|
10
|
+
.optional()
|
|
11
|
+
.describe('Minimum abuse confidence score to include in blacklist (25–100, default: 90)'),
|
|
12
|
+
limit: z
|
|
13
|
+
.number()
|
|
14
|
+
.int()
|
|
15
|
+
.min(1)
|
|
16
|
+
.max(500000)
|
|
17
|
+
.optional()
|
|
18
|
+
.describe('Maximum number of entries to return (default: all entries up to plan limit)'),
|
|
19
|
+
plain_text: z
|
|
20
|
+
.boolean()
|
|
21
|
+
.optional()
|
|
22
|
+
.describe('Return plain text IP list instead of JSON (default: false)'),
|
|
23
|
+
break_token_rule: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.optional()
|
|
26
|
+
.default(false)
|
|
27
|
+
.describe('Set to true to bypass token limits in critical situations (default: false)'),
|
|
28
|
+
});
|
|
29
|
+
export function registerBlacklistTools(server, client, maxTokenCall = 20000) {
|
|
30
|
+
const registerTool = server.tool.bind(server);
|
|
31
|
+
registerTool('get_blacklist', 'Retrieve the AbuseIPDB blacklist of most-reported malicious IP addresses. Returns confidence distribution, top countries, and sample entries. Requires AbuseIPDB subscription plan.', GetBlacklistSchema.shape, async (args) => {
|
|
32
|
+
const parsed = GetBlacklistSchema.parse(args);
|
|
33
|
+
const text = await handleGetBlacklist(client, parsed);
|
|
34
|
+
const tokenCheck = checkTokenLimit(text, maxTokenCall, parsed.break_token_rule ?? false);
|
|
35
|
+
if (!tokenCheck.allowed) {
|
|
36
|
+
return { content: [{ type: 'text', text: tokenCheck.error }] };
|
|
37
|
+
}
|
|
38
|
+
return { content: [{ type: 'text', text }] };
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=blacklist-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"blacklist-tools.js","sourceRoot":"","sources":["../../src/blacklist-tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAK3D,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,kBAAkB,EAAE,CAAC;SAClB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,EAAE,CAAC;SACP,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,8EAA8E,CAAC;IAC3F,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,MAAM,CAAC;SACX,QAAQ,EAAE;SACV,QAAQ,CAAC,6EAA6E,CAAC;IAC1F,UAAU,EAAE,CAAC;SACV,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,4DAA4D,CAAC;IACzE,gBAAgB,EAAE,CAAC;SAChB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,4EAA4E,CAAC;CAC1F,CAAC,CAAC;AAEH,MAAM,UAAU,sBAAsB,CAAC,MAAiB,EAAE,MAAqB,EAAE,YAAY,GAAG,KAAK;IACnG,MAAM,YAAY,GAAI,MAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAY,CAAC;IAElE,YAAY,CACV,eAAe,EACf,qLAAqL,EACrL,kBAAkB,CAAC,KAAK,EACxB,KAAK,EAAE,IAAa,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtD,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAC;QACzF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,KAAM,EAAE,CAAC,EAAE,CAAC;QAClE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { handleCheckBlock } from './handlers/block.js';
|
|
3
|
+
import { checkTokenLimit } from './utils/token-limiter.js';
|
|
4
|
+
const CheckBlockSchema = z.object({
|
|
5
|
+
network: z.string().describe('CIDR network block to check, e.g. "198.51.100.0/24"'),
|
|
6
|
+
max_age_days: z
|
|
7
|
+
.number()
|
|
8
|
+
.int()
|
|
9
|
+
.min(1)
|
|
10
|
+
.max(365)
|
|
11
|
+
.optional()
|
|
12
|
+
.describe('Look-back window in days for abuse reports (1–365, default: 30)'),
|
|
13
|
+
confidence_threshold: z
|
|
14
|
+
.number()
|
|
15
|
+
.int()
|
|
16
|
+
.min(0)
|
|
17
|
+
.max(100)
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Confidence % to classify addresses as high-confidence threats (default: 75)'),
|
|
20
|
+
break_token_rule: z
|
|
21
|
+
.boolean()
|
|
22
|
+
.optional()
|
|
23
|
+
.default(false)
|
|
24
|
+
.describe('Set to true to bypass token limits in critical situations (default: false)'),
|
|
25
|
+
});
|
|
26
|
+
export function registerBlockTools(server, client, maxTokenCall = 20000) {
|
|
27
|
+
const registerTool = server.tool.bind(server);
|
|
28
|
+
registerTool('check_block', 'Check all reported IP addresses within a CIDR network block against AbuseIPDB. Returns network summary, total reported addresses, and top threats sorted by confidence score. Requires AbuseIPDB subscription plan.', CheckBlockSchema.shape, async (args) => {
|
|
29
|
+
const parsed = CheckBlockSchema.parse(args);
|
|
30
|
+
const text = await handleCheckBlock(client, parsed);
|
|
31
|
+
const tokenCheck = checkTokenLimit(text, maxTokenCall, parsed.break_token_rule ?? false);
|
|
32
|
+
if (!tokenCheck.allowed) {
|
|
33
|
+
return { content: [{ type: 'text', text: tokenCheck.error }] };
|
|
34
|
+
}
|
|
35
|
+
return { content: [{ type: 'text', text }] };
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=block-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"block-tools.js","sourceRoot":"","sources":["../../src/block-tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAK3D,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IACnF,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,iEAAiE,CAAC;IAC9E,oBAAoB,EAAE,CAAC;SACpB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,6EAA6E,CAAC;IAC1F,gBAAgB,EAAE,CAAC;SAChB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,4EAA4E,CAAC;CAC1F,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAqB,EAAE,YAAY,GAAG,KAAK;IAC/F,MAAM,YAAY,GAAI,MAAc,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAY,CAAC;IAElE,YAAY,CACV,aAAa,EACb,qNAAqN,EACrN,gBAAgB,CAAC,KAAK,EACtB,KAAK,EAAE,IAAa,EAAE,EAAE;QACtB,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACpD,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAC;QACzF,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,KAAM,EAAE,CAAC,EAAE,CAAC;QAClE,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { assessRiskLevel } from '../types/abuseipdb.js';
|
|
2
|
+
export async function handleGetBlacklist(client, args) {
|
|
3
|
+
const { confidence_minimum = 90, limit, plain_text = false } = args;
|
|
4
|
+
const params = { confidenceMinimum: confidence_minimum };
|
|
5
|
+
if (limit !== undefined)
|
|
6
|
+
params['limit'] = limit;
|
|
7
|
+
if (plain_text)
|
|
8
|
+
params['plaintext'] = true;
|
|
9
|
+
const { data: resp } = await client.get('/blacklist', { params });
|
|
10
|
+
const entries = resp.data ?? [];
|
|
11
|
+
const generatedAt = resp.meta?.generatedAt ?? 'Unknown';
|
|
12
|
+
const countryStats = {};
|
|
13
|
+
const confidenceDist = { '90-100': 0, '75-89': 0, '50-74': 0, '0-49': 0 };
|
|
14
|
+
for (const e of entries) {
|
|
15
|
+
const cc = e.countryCode ?? 'Unknown';
|
|
16
|
+
countryStats[cc] = (countryStats[cc] ?? 0) + 1;
|
|
17
|
+
const s = e.abuseConfidenceScore;
|
|
18
|
+
if (s >= 90)
|
|
19
|
+
confidenceDist['90-100']++;
|
|
20
|
+
else if (s >= 75)
|
|
21
|
+
confidenceDist['75-89']++;
|
|
22
|
+
else if (s >= 50)
|
|
23
|
+
confidenceDist['50-74']++;
|
|
24
|
+
else
|
|
25
|
+
confidenceDist['0-49']++;
|
|
26
|
+
}
|
|
27
|
+
const topCountries = Object.entries(countryStats)
|
|
28
|
+
.sort(([, a], [, b]) => b - a)
|
|
29
|
+
.slice(0, 10);
|
|
30
|
+
const lines = [
|
|
31
|
+
`Blacklist Retrieved: ${entries.length.toLocaleString()} entries`,
|
|
32
|
+
`Generated: ${generatedAt}`,
|
|
33
|
+
`Minimum Confidence: ${confidence_minimum}%`,
|
|
34
|
+
];
|
|
35
|
+
if (limit !== undefined)
|
|
36
|
+
lines.push(`Limit Applied: ${limit.toLocaleString()}`);
|
|
37
|
+
lines.push('\nConfidence Distribution:', ` • 90-100%: ${confidenceDist['90-100'].toLocaleString()}`, ` • 75-89%: ${confidenceDist['75-89'].toLocaleString()}`, ` • 50-74%: ${confidenceDist['50-74'].toLocaleString()}`, ` • 0-49%: ${confidenceDist['0-49'].toLocaleString()}`);
|
|
38
|
+
if (topCountries.length > 0) {
|
|
39
|
+
lines.push('\nTop Countries:');
|
|
40
|
+
topCountries.forEach(([cc, count]) => {
|
|
41
|
+
lines.push(` • ${cc}: ${count.toLocaleString()}`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
if (entries.length > 0) {
|
|
45
|
+
lines.push('\nSample Entries (top 20 by confidence):');
|
|
46
|
+
const sorted = [...entries].sort((a, b) => b.abuseConfidenceScore - a.abuseConfidenceScore);
|
|
47
|
+
sorted.slice(0, 20).forEach((e) => {
|
|
48
|
+
const level = assessRiskLevel(e.abuseConfidenceScore);
|
|
49
|
+
const last = e.lastReportedAt ? e.lastReportedAt.slice(0, 10) : 'Unknown';
|
|
50
|
+
lines.push(` • ${e.ipAddress} (${e.countryCode ?? '?'}) – ${e.abuseConfidenceScore}% [${level}] – last: ${last}`);
|
|
51
|
+
});
|
|
52
|
+
if (entries.length > 20)
|
|
53
|
+
lines.push(` ... and ${entries.length - 20} more entries`);
|
|
54
|
+
}
|
|
55
|
+
return lines.join('\n');
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=blacklist.js.map
|