sec-mcp 0.1.1__tar.gz

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.
sec_mcp-0.1.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Luong NGUYEN
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.
sec_mcp-0.1.1/PKG-INFO ADDED
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: sec-mcp
3
+ Version: 0.1.1
4
+ Summary: Python toolkit providing security checks for domains, URLs, IPs, and more.
5
+ Author: Luong NGUYEN
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/Montimage/sec-mcp
8
+ Project-URL: Repository, https://github.com/Montimage/sec-mcp.git
9
+ Project-URL: Documentation, https://github.com/Montimage/sec-mcp#readme
10
+ Keywords: security,blacklist,mcp,phishing,malware
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Topic :: Security
15
+ Requires-Python: >=3.11
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: requests>=2.31.0
19
+ Requires-Dist: httpx>=0.25.0
20
+ Requires-Dist: click>=8.1.7
21
+ Requires-Dist: idna>=3.4
22
+ Requires-Dist: mcp[cli]>=0.1.0
23
+ Requires-Dist: schedule>=1.2.0
24
+ Requires-Dist: tqdm>=4.66.0
25
+ Dynamic: license-file
26
+ Dynamic: requires-python
27
+
28
+ # sec-mcp: Security Checking Toolkit
29
+
30
+ A Python toolkit providing security checks for domains, URLs, IPs, and more. Integrate easily into any Python application, use via terminal CLI, or run as an MCP server to enrich LLM context with real-time threat insights.
31
+
32
+ ## Features
33
+
34
+ - Comprehensive security checks for domains, URLs, IP addresses, and more against multiple blacklist feeds
35
+ - On-demand updates from OpenPhish, PhishStats, URLhaus and custom sources
36
+ - High-performance, thread-safe SQLite storage with in-memory caching for fast lookups
37
+ - Python API via `SecMCP` class for easy integration into your applications
38
+ - Intuitive Click-based CLI for interactive single or batch scans
39
+ - Built-in MCP server support for LLM/AI integrations over JSON/STDIO
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ pip install sec-mcp
45
+ ```
46
+
47
+ ## Usage via CLI
48
+
49
+ 1. Install the package:
50
+ ```bash
51
+ pip install sec-mcp
52
+ ```
53
+ 2. Check a single URL/domain/IP:
54
+ ```bash
55
+ sec-mcp check https://example.com
56
+ ```
57
+ 3. Batch check from a file:
58
+ ```bash
59
+ sec-mcp batch urls.txt
60
+ ```
61
+ 4. View blacklist status:
62
+ ```bash
63
+ sec-mcp status
64
+ ```
65
+ 5. Manually trigger an update:
66
+ ```bash
67
+ sec-mcp update
68
+ ```
69
+
70
+ ## Usage via API (Python)
71
+
72
+ 1. Install in your project:
73
+ ```bash
74
+ pip install sec-mcp
75
+ ```
76
+ 2. Import and initialize:
77
+ ```python
78
+ from sec_mcp import SecMCP
79
+
80
+ client = SecMCP()
81
+ ```
82
+ 3. Single check:
83
+ ```python
84
+ result = client.check("https://example.com")
85
+ print(result.to_json())
86
+ ```
87
+ 4. Batch check:
88
+ ```python
89
+ urls = ["https://example.com", "https://test.com"]
90
+ results = client.check_batch(urls)
91
+ for r in results:
92
+ print(r.to_json())
93
+ ```
94
+ 5. Get status and update:
95
+ ```python
96
+ status = client.get_status()
97
+ print(status.to_json())
98
+
99
+ client.update()
100
+ ```
101
+
102
+ ## Usage via MCP Client
103
+
104
+ To run sec-mcp as an MCP server for AI-driven clients (e.g., Claude):
105
+
106
+ 1. Install in editable mode (for development):
107
+ ```bash
108
+ pip install -e .
109
+ ```
110
+ 2. Start the MCP server:
111
+ ```bash
112
+ sec-mcp-server
113
+ ```
114
+ 3. Configure your MCP client (e.g., Claude) to point at the command:
115
+ ```json
116
+ {
117
+ "mcpServers": {
118
+ "sec-mcp": {
119
+ "command": ".venv/bin/python3",
120
+ "args": ["-m", "sec_mcp.start_server"]
121
+ }
122
+ }
123
+ }
124
+ ```
125
+
126
+ Clients will then use the built-in `check_blacklist` tool over JSON/STDIO for real-time security checks.
127
+
128
+ ## Configuration
129
+
130
+ The client can be configured via `config.json`:
131
+
132
+ - `blacklist_sources`: URLs for blacklist feeds
133
+ - `update_time`: Daily update schedule (default: "00:00")
134
+ - `cache_size`: In-memory cache size (default: 10000)
135
+ - `log_level`: Logging verbosity (default: "INFO")
136
+
137
+ ## Configuring sec-mcp with Claude (MCP Client)
138
+
139
+ To use your MCP Server for security checking (sec-mcp) with an MCP client such as Claude, add it to your Claude configuration as follows:
140
+
141
+ ```json
142
+ {
143
+ "mcpServers": {
144
+ "sec-mcp": {
145
+ "command": ".venv/bin/python3",
146
+ "args": ["-m", "sec_mcp.start_server"]
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ - Ensure you have installed all dependencies in your virtual environment (`.venv`).
153
+ - The `command` should point to your Python executable inside `.venv` for best isolation.
154
+ - The `args` array should launch your MCP server using the provided script.
155
+ - You can add other MCP servers in the same configuration if needed.
156
+
157
+ This setup allows Claude (or any compatible MCP client) to connect to your sec-mcp server and use its `check_blacklist` tool for real-time security checks on URLs, domains, or IP addresses.
158
+
159
+ For more details and advanced configuration, see the [Model Context Protocol examples](https://modelcontextprotocol.io/examples).
160
+
161
+ ## Development
162
+
163
+ Clone the repository and install in development mode:
164
+
165
+ ```bash
166
+ git clone <repository-url>
167
+ cd sec-mcp
168
+ pip install -e .
169
+ ```
170
+
171
+ ## License
172
+
173
+ MIT
@@ -0,0 +1,146 @@
1
+ # sec-mcp: Security Checking Toolkit
2
+
3
+ A Python toolkit providing security checks for domains, URLs, IPs, and more. Integrate easily into any Python application, use via terminal CLI, or run as an MCP server to enrich LLM context with real-time threat insights.
4
+
5
+ ## Features
6
+
7
+ - Comprehensive security checks for domains, URLs, IP addresses, and more against multiple blacklist feeds
8
+ - On-demand updates from OpenPhish, PhishStats, URLhaus and custom sources
9
+ - High-performance, thread-safe SQLite storage with in-memory caching for fast lookups
10
+ - Python API via `SecMCP` class for easy integration into your applications
11
+ - Intuitive Click-based CLI for interactive single or batch scans
12
+ - Built-in MCP server support for LLM/AI integrations over JSON/STDIO
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ pip install sec-mcp
18
+ ```
19
+
20
+ ## Usage via CLI
21
+
22
+ 1. Install the package:
23
+ ```bash
24
+ pip install sec-mcp
25
+ ```
26
+ 2. Check a single URL/domain/IP:
27
+ ```bash
28
+ sec-mcp check https://example.com
29
+ ```
30
+ 3. Batch check from a file:
31
+ ```bash
32
+ sec-mcp batch urls.txt
33
+ ```
34
+ 4. View blacklist status:
35
+ ```bash
36
+ sec-mcp status
37
+ ```
38
+ 5. Manually trigger an update:
39
+ ```bash
40
+ sec-mcp update
41
+ ```
42
+
43
+ ## Usage via API (Python)
44
+
45
+ 1. Install in your project:
46
+ ```bash
47
+ pip install sec-mcp
48
+ ```
49
+ 2. Import and initialize:
50
+ ```python
51
+ from sec_mcp import SecMCP
52
+
53
+ client = SecMCP()
54
+ ```
55
+ 3. Single check:
56
+ ```python
57
+ result = client.check("https://example.com")
58
+ print(result.to_json())
59
+ ```
60
+ 4. Batch check:
61
+ ```python
62
+ urls = ["https://example.com", "https://test.com"]
63
+ results = client.check_batch(urls)
64
+ for r in results:
65
+ print(r.to_json())
66
+ ```
67
+ 5. Get status and update:
68
+ ```python
69
+ status = client.get_status()
70
+ print(status.to_json())
71
+
72
+ client.update()
73
+ ```
74
+
75
+ ## Usage via MCP Client
76
+
77
+ To run sec-mcp as an MCP server for AI-driven clients (e.g., Claude):
78
+
79
+ 1. Install in editable mode (for development):
80
+ ```bash
81
+ pip install -e .
82
+ ```
83
+ 2. Start the MCP server:
84
+ ```bash
85
+ sec-mcp-server
86
+ ```
87
+ 3. Configure your MCP client (e.g., Claude) to point at the command:
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "sec-mcp": {
92
+ "command": ".venv/bin/python3",
93
+ "args": ["-m", "sec_mcp.start_server"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ Clients will then use the built-in `check_blacklist` tool over JSON/STDIO for real-time security checks.
100
+
101
+ ## Configuration
102
+
103
+ The client can be configured via `config.json`:
104
+
105
+ - `blacklist_sources`: URLs for blacklist feeds
106
+ - `update_time`: Daily update schedule (default: "00:00")
107
+ - `cache_size`: In-memory cache size (default: 10000)
108
+ - `log_level`: Logging verbosity (default: "INFO")
109
+
110
+ ## Configuring sec-mcp with Claude (MCP Client)
111
+
112
+ To use your MCP Server for security checking (sec-mcp) with an MCP client such as Claude, add it to your Claude configuration as follows:
113
+
114
+ ```json
115
+ {
116
+ "mcpServers": {
117
+ "sec-mcp": {
118
+ "command": ".venv/bin/python3",
119
+ "args": ["-m", "sec_mcp.start_server"]
120
+ }
121
+ }
122
+ }
123
+ ```
124
+
125
+ - Ensure you have installed all dependencies in your virtual environment (`.venv`).
126
+ - The `command` should point to your Python executable inside `.venv` for best isolation.
127
+ - The `args` array should launch your MCP server using the provided script.
128
+ - You can add other MCP servers in the same configuration if needed.
129
+
130
+ This setup allows Claude (or any compatible MCP client) to connect to your sec-mcp server and use its `check_blacklist` tool for real-time security checks on URLs, domains, or IP addresses.
131
+
132
+ For more details and advanced configuration, see the [Model Context Protocol examples](https://modelcontextprotocol.io/examples).
133
+
134
+ ## Development
135
+
136
+ Clone the repository and install in development mode:
137
+
138
+ ```bash
139
+ git clone <repository-url>
140
+ cd sec-mcp
141
+ pip install -e .
142
+ ```
143
+
144
+ ## License
145
+
146
+ MIT
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sec-mcp"
7
+ version = "0.1.1"
8
+ description = "Python toolkit providing security checks for domains, URLs, IPs, and more."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.11"
12
+ authors = [ { name = "Luong NGUYEN" } ]
13
+ dependencies = [
14
+ "requests>=2.31.0",
15
+ "httpx>=0.25.0",
16
+ "click>=8.1.7",
17
+ "idna>=3.4",
18
+ "mcp[cli]>=0.1.0",
19
+ "schedule>=1.2.0",
20
+ "tqdm>=4.66.0",
21
+ ]
22
+ classifiers = [
23
+ "License :: OSI Approved :: MIT License",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.11",
26
+ "Topic :: Security",
27
+ ]
28
+ keywords = ["security", "blacklist", "mcp", "phishing", "malware"]
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/Montimage/sec-mcp"
32
+ Repository = "https://github.com/Montimage/sec-mcp.git"
33
+ Documentation = "https://github.com/Montimage/sec-mcp#readme"
34
+
35
+ [project.scripts]
36
+ sec-mcp = "sec_mcp.cli:cli"
37
+ sec-mcp-server = "sec_mcp.start_server:main"
38
+
39
+ [tool.setuptools.packages.find]
40
+ where = ["."]
41
+ include = ["sec_mcp*"]
@@ -0,0 +1,10 @@
1
+ """
2
+ MCP Client - A Python library and CLI for checking domains, URLs, and IPs against blacklists.
3
+ """
4
+
5
+ from .sec_mcp import SecMCP, CheckResult, StatusInfo
6
+ from .cli import cli
7
+ from .utility import validate_input, setup_logging
8
+
9
+ __version__ = "0.1.1"
10
+ __all__ = ['SecMCP', 'CheckResult', 'StatusInfo', 'cli', 'validate_input', 'setup_logging']
@@ -0,0 +1,84 @@
1
+ import click
2
+ from .sec_mcp import SecMCP
3
+
4
+ # Global SecMCP instance for CLI
5
+ core = SecMCP()
6
+
7
+ @click.group()
8
+ @click.version_option(version="0.1.1", message="%(version)s (MCP Client)")
9
+ def cli():
10
+ """MCP Client CLI for checking domains, URLs, and IPs against blacklists.
11
+
12
+ Examples:
13
+ mcp check https://example.com
14
+ mcp batch urls.txt --json
15
+ mcp status
16
+ """
17
+ pass
18
+
19
+ @cli.command(help="Check a single domain, URL, or IP against the blacklist.\n\nExample: mcp check https://example.com --json")
20
+ @click.argument('value')
21
+ @click.option('--json', is_flag=True, help='Output in JSON format')
22
+ def check(value: str, json: bool):
23
+ result = core.check(value)
24
+ if json:
25
+ click.echo(result.to_json())
26
+ else:
27
+ if result.blacklisted:
28
+ click.secho(f"Status: Blacklisted", fg="red")
29
+ else:
30
+ click.secho(f"Status: Safe", fg="green")
31
+ click.echo(f"Explanation: {result.explanation}")
32
+
33
+ @cli.command(help="Check multiple inputs from a file against the blacklist.\n\nExample: mcp batch urls.txt --json")
34
+ @click.argument('file', type=click.Path(exists=True))
35
+ @click.option('--json', is_flag=True, help='Output in JSON format')
36
+ def batch(file: str, json: bool):
37
+ with open(file) as f:
38
+ values = [line.strip() for line in f if line.strip()]
39
+ results = core.check_batch(values)
40
+ if json:
41
+ import json as _json
42
+ click.echo(_json.dumps([r.to_json() for r in results], indent=2))
43
+ else:
44
+ for value, result in zip(values, results):
45
+ click.secho(f"{value}:", bold=True)
46
+ if result.blacklisted:
47
+ click.secho(f" Status: Blacklisted", fg="red")
48
+ else:
49
+ click.secho(f" Status: Safe", fg="green")
50
+ click.echo(f" Explanation: {result.explanation}")
51
+
52
+ @cli.command(help="Show blacklist status (entry count, last update, sources).\n\nExample: mcp status --json")
53
+ @click.option('--json', is_flag=True, help='Output in JSON format')
54
+ def status(json):
55
+ status = core.get_status()
56
+ if json:
57
+ import json as _json
58
+ click.echo(_json.dumps(status.to_json(), indent=2))
59
+ else:
60
+ click.secho(f"Total entries: {status.entry_count}", bold=True)
61
+ click.echo(f"Last update: {status.last_update}")
62
+ click.echo("Active sources:")
63
+ for source in status.sources:
64
+ click.echo(f" - {source}")
65
+ click.echo(f"Server status: {status.server_status}")
66
+
67
+ @cli.command(help="Update blacklist feeds immediately.")
68
+ @click.option('--json', is_flag=True, help='Output minimal JSON confirmation')
69
+ def update(json):
70
+ """Force an immediate update of all blacklists."""
71
+ core.update()
72
+ if json:
73
+ import json as _json
74
+ click.echo(_json.dumps({"updated": True}))
75
+ else:
76
+ click.echo("Blacklist update triggered.")
77
+
78
+ @cli.command(help="Sample random blacklist entries for testing.")
79
+ @click.option('-n', '--count', default=10, help='Number of entries to sample')
80
+ def sample(count: int):
81
+ """Output a random sample of blacklist values for quick tests."""
82
+ entries = core.sample(count)
83
+ for value in entries:
84
+ click.echo(value)
@@ -0,0 +1,11 @@
1
+ {
2
+ "blacklist_sources": {
3
+ "OpenPhish": "https://openphish.com/feed.txt",
4
+ "PhishStats": "https://phishstats.info/phish_score.csv",
5
+ "URLhaus": "https://urlhaus.abuse.ch/downloads/text/"
6
+ },
7
+ "update_time": "00:00",
8
+ "cache_size": 10000,
9
+ "log_level": "INFO",
10
+ "db_path": "mcp.db"
11
+ }
@@ -0,0 +1,42 @@
1
+ from mcp.server.fastmcp import FastMCP
2
+ import anyio
3
+ # import SecMCP for server logic
4
+ from .sec_mcp import SecMCP
5
+ from .utility import validate_input
6
+
7
+ # Initialize FastMCP server
8
+ mcp = FastMCP("mcp-blacklist")
9
+
10
+ # Global SecMCP instance for MCP server
11
+ core = SecMCP()
12
+
13
+ @mcp.tool(description="Calculate sum of two numbers. Returns JSON: {sum: number}.")
14
+ async def sum_numbers(a: float, b: float):
15
+ """Sum two numbers."""
16
+ return {"sum": a + b}
17
+
18
+ @mcp.tool(name="check", description="Check if a domain, URL, or IP address is in the blacklist. Returns JSON: {is_safe: bool, explain: str}.")
19
+ async def check_blacklist(value: str):
20
+ """Check a single value against the blacklist."""
21
+ if not validate_input(value):
22
+ return {"is_safe": False, "explain": "Invalid input format. Must be a valid domain, URL, or IP address."}
23
+ result = core.check(value)
24
+ return {"is_safe": not result.blacklisted, "explain": result.explanation}
25
+
26
+ @mcp.tool(description="Get status of the blacklist. Returns JSON: {entry_count: int, last_update: str, sources: List[str], server_status: str}.")
27
+ async def get_blacklist_status():
28
+ """Return current blacklist status."""
29
+ status = core.get_status()
30
+ return {
31
+ "entry_count": status.entry_count,
32
+ "last_update": status.last_update,
33
+ "sources": status.sources,
34
+ "server_status": status.server_status
35
+ }
36
+
37
+ @mcp.tool(description="Force immediate update of all blacklists. Returns JSON: {updated: bool}.")
38
+ async def update_blacklists():
39
+ """Trigger an immediate blacklist refresh."""
40
+ # Offload to thread to avoid nested event loops
41
+ await anyio.to_thread.run_sync(core.update)
42
+ return {"updated": True}
@@ -0,0 +1,70 @@
1
+ from dataclasses import dataclass
2
+ from datetime import datetime
3
+ from typing import List, Optional
4
+ from .storage import Storage
5
+ from .update_blacklist import BlacklistUpdater
6
+
7
+ @dataclass
8
+ class CheckResult:
9
+ blacklisted: bool
10
+ explanation: str
11
+
12
+ def to_json(self):
13
+ return {
14
+ "is_safe": not self.blacklisted,
15
+ "explain": self.explanation
16
+ }
17
+
18
+ @dataclass
19
+ class StatusInfo:
20
+ entry_count: int
21
+ last_update: datetime
22
+ sources: List[str]
23
+ server_status: str
24
+
25
+ def to_json(self):
26
+ return {
27
+ "entry_count": self.entry_count,
28
+ "last_update": self.last_update.isoformat(),
29
+ "sources": self.sources,
30
+ "server_status": self.server_status
31
+ }
32
+
33
+ class SecMCP:
34
+ def __init__(self):
35
+ self.storage = Storage()
36
+ self.updater = BlacklistUpdater(self.storage)
37
+
38
+ def check(self, value: str) -> CheckResult:
39
+ """Check a single value against the blacklist."""
40
+ if self.storage.is_blacklisted(value):
41
+ source = self.storage.get_blacklist_source(value)
42
+ return CheckResult(
43
+ blacklisted=True,
44
+ explanation=f"Blacklisted by {source}"
45
+ )
46
+ return CheckResult(
47
+ blacklisted=False,
48
+ explanation="Not blacklisted"
49
+ )
50
+
51
+ def check_batch(self, values: List[str]) -> List[CheckResult]:
52
+ """Check multiple values against the blacklist."""
53
+ return [self.check(value) for value in values]
54
+
55
+ def get_status(self) -> StatusInfo:
56
+ """Get current status of the blacklist service."""
57
+ return StatusInfo(
58
+ entry_count=self.storage.count_entries(),
59
+ last_update=self.storage.get_last_update(),
60
+ sources=self.storage.get_active_sources(),
61
+ server_status="Running (STDIO)"
62
+ )
63
+
64
+ def update(self) -> None:
65
+ """Force an immediate update of all blacklists."""
66
+ self.updater.force_update()
67
+
68
+ def sample(self, count: int = 10) -> List[str]:
69
+ """Return a random sample of blacklist entries for testing."""
70
+ return self.storage.sample_entries(count)