agentsentinel-cli 0.7.4__tar.gz → 0.7.5__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.
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/PKG-INFO +1 -1
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/cli.py +64 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/pyproject.toml +1 -1
- agentsentinel_cli-0.7.5/tmp/note.md +16 -0
- agentsentinel_cli-0.7.4/tmp/note.md +0 -4
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/.gitignore +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/DOCUMENTATION.md +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/LICENSE +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/README.md +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/__init__.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/a2a_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/a2a_rules.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/a2a_scanner.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/agent_mode.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/agent_mode_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/ai_probe.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/attacks/__init__.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/attacks/library.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/discover.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/discover_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/fingerprint.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/frameworks.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/inspect.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/inspect_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/mcp_client.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/mcp_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/mcp_rules.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/probe.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/probe_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/rules.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/scanner.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/secrets.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/secrets_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/secrets_rules.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/supply_chain_ai.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/supply_chain_report.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/supply_chain_rules.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/suppress.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/target.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/tmp/test-mcp-agent/README.md +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/tmp/test-mcp-agent/langchain_agent.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/tmp/test-mcp-agent/mcp_server.py +0 -0
- {agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/tmp/test-mcp-agent/requirements.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentsentinel-cli
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.5
|
|
4
4
|
Summary: Agentic security CLI — AI analyst with memory, supply chain audit, MCP audit, red-team probing, and agent discovery
|
|
5
5
|
Project-URL: Homepage, https://github.com/jaydenaung/agentsentinel-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/jaydenaung/agentsentinel-cli
|
|
@@ -119,6 +119,60 @@ def _enrich_from_platform(agents, scores_map, connect_url, api_key):
|
|
|
119
119
|
console.print(f" [dim yellow]Warning: could not connect to AgentSentinel: {exc}[/dim yellow]")
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
# ── sentinel discover helpers ────────────────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
def _deep_scan_agents(agents: list, extra_headers: dict | None) -> None:
|
|
125
|
+
"""Run mcp scan rules on every confirmed network MCP server from a discover run."""
|
|
126
|
+
from agentsentinel_cli.discover import DiscoveredAgent
|
|
127
|
+
from agentsentinel_cli.mcp_client import scan_http, McpAuthRequired, McpError
|
|
128
|
+
from agentsentinel_cli.mcp_rules import McpContext, run_mcp_rules, mcp_posture_score
|
|
129
|
+
from agentsentinel_cli.mcp_report import print_mcp_result
|
|
130
|
+
from agentsentinel_cli import suppress as _suppress
|
|
131
|
+
|
|
132
|
+
network_agents = [a for a in agents if a.source == "network"]
|
|
133
|
+
if not network_agents:
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
console.print()
|
|
137
|
+
console.rule("[bold bright_blue]DEEP SCAN[/bold bright_blue]", style="bright_blue")
|
|
138
|
+
|
|
139
|
+
sup_rules = _suppress.load_ignore_file(Path.cwd())
|
|
140
|
+
|
|
141
|
+
for agent in network_agents:
|
|
142
|
+
base = f"http://{agent.location}"
|
|
143
|
+
scan_url = f"{base}/sse" if agent.transport == "sse" else base
|
|
144
|
+
|
|
145
|
+
# Auth-required servers need credentials — skip silently if none provided
|
|
146
|
+
if not agent.tools and not extra_headers:
|
|
147
|
+
console.print(
|
|
148
|
+
f"\n [dim]Skipping {agent.location} — auth required, "
|
|
149
|
+
f"use --auth-header to deep scan[/dim]"
|
|
150
|
+
)
|
|
151
|
+
continue
|
|
152
|
+
|
|
153
|
+
try:
|
|
154
|
+
server = scan_http(scan_url, extra_headers=extra_headers, timeout=15)
|
|
155
|
+
except McpAuthRequired:
|
|
156
|
+
console.print(
|
|
157
|
+
f"\n [dim]Skipping {agent.location} — credentials rejected[/dim]"
|
|
158
|
+
)
|
|
159
|
+
continue
|
|
160
|
+
except (McpError, Exception):
|
|
161
|
+
console.print(
|
|
162
|
+
f"\n [dim]Skipping {agent.location} — could not reconnect[/dim]"
|
|
163
|
+
)
|
|
164
|
+
continue
|
|
165
|
+
|
|
166
|
+
# auth_required: True when the server actually enforces auth (risk LOW/MEDIUM)
|
|
167
|
+
auth_required = agent.risk in ("LOW", "MEDIUM")
|
|
168
|
+
ctx = McpContext(server=server, auth_required=auth_required)
|
|
169
|
+
findings = run_mcp_rules(ctx)
|
|
170
|
+
findings, _ = _suppress.apply(findings, sup_rules)
|
|
171
|
+
score = mcp_posture_score(findings)
|
|
172
|
+
|
|
173
|
+
print_mcp_result(ctx, findings, score, scan_url)
|
|
174
|
+
|
|
175
|
+
|
|
122
176
|
# ── sentinel discover ─────────────────────────────────────────────────────────
|
|
123
177
|
|
|
124
178
|
@main.command()
|
|
@@ -136,6 +190,8 @@ def _enrich_from_platform(agents, scores_map, connect_url, api_key):
|
|
|
136
190
|
help="Custom port range, e.g. 8000-9001. Defaults to common MCP/agent ports.")
|
|
137
191
|
@click.option("--auth-header", "auth_header", default=None, metavar="HEADER",
|
|
138
192
|
help="HTTP auth header for MCP handshakes, e.g. 'Authorization: Bearer token'.")
|
|
193
|
+
@click.option("--scan", "do_scan", is_flag=True, default=False,
|
|
194
|
+
help="Deep-scan every confirmed MCP server with sentinel mcp scan rules.")
|
|
139
195
|
@click.option("--format", "fmt", type=click.Choice(["text", "json"]), default="text",
|
|
140
196
|
help="Output format.")
|
|
141
197
|
@click.option("--verbose", "-v", is_flag=True, default=False,
|
|
@@ -148,17 +204,20 @@ def discover(
|
|
|
148
204
|
subnet: str | None,
|
|
149
205
|
ports: str | None,
|
|
150
206
|
auth_header: str | None,
|
|
207
|
+
do_scan: bool,
|
|
151
208
|
fmt: str,
|
|
152
209
|
verbose: bool,
|
|
153
210
|
) -> None:
|
|
154
211
|
"""Find MCP servers and AI agent processes in your environment.
|
|
155
212
|
|
|
156
213
|
Confirms MCP servers via protocol handshake — not just open ports.
|
|
214
|
+
Add --scan to deep-audit every confirmed server in the same run.
|
|
157
215
|
|
|
158
216
|
\b
|
|
159
217
|
Examples:
|
|
160
218
|
sentinel discover local processes + ports
|
|
161
219
|
sentinel discover --host 10.0.1.45 single remote host
|
|
220
|
+
sentinel discover --host 10.0.1.45 --scan discover + deep audit
|
|
162
221
|
sentinel discover --subnet 10.0.0.0/24 full subnet scan
|
|
163
222
|
sentinel discover --subnet 10.0.0.0/24 \\
|
|
164
223
|
--auth-header 'Authorization: Bearer token' scan with credentials
|
|
@@ -195,6 +254,8 @@ def discover(
|
|
|
195
254
|
click.echo(discover_json(agents))
|
|
196
255
|
return
|
|
197
256
|
print_discover_result(agents, vectors=[f"host ({host})"], verbose=verbose)
|
|
257
|
+
if do_scan:
|
|
258
|
+
_deep_scan_agents(agents, extra_headers or None)
|
|
198
259
|
if any(a.risk == "CRITICAL" for a in agents):
|
|
199
260
|
sys.exit(1)
|
|
200
261
|
return
|
|
@@ -237,6 +298,9 @@ def discover(
|
|
|
237
298
|
|
|
238
299
|
print_discover_result(agents, vectors=vectors, verbose=verbose, subnet_stats=subnet_stats)
|
|
239
300
|
|
|
301
|
+
if do_scan:
|
|
302
|
+
_deep_scan_agents(agents, extra_headers or None)
|
|
303
|
+
|
|
240
304
|
# Exit 1 if any CRITICAL agents found (useful for CI)
|
|
241
305
|
if any(a.risk == "CRITICAL" for a in agents):
|
|
242
306
|
sys.exit(1)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "agentsentinel-cli"
|
|
7
|
-
version = "0.7.
|
|
7
|
+
version = "0.7.5"
|
|
8
8
|
description = "Agentic security CLI — AI analyst with memory, supply chain audit, MCP audit, red-team probing, and agent discovery"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Notes
|
|
2
|
+
ls dist/
|
|
3
|
+
|
|
4
|
+
python3.11 -m build
|
|
5
|
+
twine upload dist/agentsentinel_cli-0.7.3* --username __token__ --password $PYPI_TOKEN
|
|
6
|
+
|
|
7
|
+
lsof -i :8000
|
|
8
|
+
lsof -ti :8000
|
|
9
|
+
|
|
10
|
+
kill $(lsof -ti :8000)
|
|
11
|
+
|
|
12
|
+
kill -9 $(lsof -ti :8000)
|
|
13
|
+
|
|
14
|
+
nsenter -t <PID> -m -u -i -n -p -- /bin/bash
|
|
15
|
+
|
|
16
|
+
ps -p <PID> -o pid,ppid,command
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agentsentinel_cli-0.7.4 → agentsentinel_cli-0.7.5}/agentsentinel_cli/supply_chain_report.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|