agentsentinel-cli 0.7.0__tar.gz → 0.7.2__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.
Files changed (42) hide show
  1. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/.gitignore +3 -0
  2. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/PKG-INFO +62 -6
  3. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/README.md +61 -5
  4. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/cli.py +31 -23
  5. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/discover.py +147 -230
  6. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/discover_report.py +13 -5
  7. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/fingerprint.py +42 -12
  8. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/inspect.py +11 -2
  9. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/inspect_report.py +12 -7
  10. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_client.py +136 -12
  11. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/pyproject.toml +1 -1
  12. agentsentinel_cli-0.7.2/tmp/test-mcp-agent/README.md +134 -0
  13. agentsentinel_cli-0.7.2/tmp/test-mcp-agent/langchain_agent.py +178 -0
  14. agentsentinel_cli-0.7.2/tmp/test-mcp-agent/mcp_server.py +245 -0
  15. agentsentinel_cli-0.7.2/tmp/test-mcp-agent/requirements.txt +16 -0
  16. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/DOCUMENTATION.md +0 -0
  17. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/LICENSE +0 -0
  18. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/__init__.py +0 -0
  19. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_report.py +0 -0
  20. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_rules.py +0 -0
  21. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/a2a_scanner.py +0 -0
  22. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/agent_mode.py +0 -0
  23. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/agent_mode_report.py +0 -0
  24. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/ai_probe.py +0 -0
  25. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/attacks/__init__.py +0 -0
  26. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/attacks/library.py +0 -0
  27. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/frameworks.py +0 -0
  28. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_report.py +0 -0
  29. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/mcp_rules.py +0 -0
  30. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/probe.py +0 -0
  31. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/probe_report.py +0 -0
  32. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/report.py +0 -0
  33. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/rules.py +0 -0
  34. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/scanner.py +0 -0
  35. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets.py +0 -0
  36. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets_report.py +0 -0
  37. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/secrets_rules.py +0 -0
  38. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_ai.py +0 -0
  39. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_report.py +0 -0
  40. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/supply_chain_rules.py +0 -0
  41. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/suppress.py +0 -0
  42. {agentsentinel_cli-0.7.0 → agentsentinel_cli-0.7.2}/agentsentinel_cli/target.py +0 -0
@@ -39,3 +39,6 @@ Thumbs.db
39
39
  .vscode/
40
40
  *.swp
41
41
  ~$*
42
+
43
+ # Local documentation (not for commit)
44
+ doc/
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentsentinel-cli
3
- Version: 0.7.0
3
+ Version: 0.7.2
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
@@ -51,7 +51,7 @@ Description-Content-Type: text/markdown
51
51
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
52
52
  [![Python](https://img.shields.io/pypi/pyversions/agentsentinel-cli)](https://pypi.org/project/agentsentinel-cli/)
53
53
 
54
- **AI agent security — analyst mode, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
54
+ **AI agent security — analyst mode, multi-agent trust analysis, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
55
55
 
56
56
  ```bash
57
57
  pipx install "agentsentinel-cli[all]"
@@ -61,7 +61,7 @@ pipx install "agentsentinel-cli[all]"
61
61
 
62
62
  ## What it does
63
63
 
64
- `sentinel` covers 8 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
64
+ `sentinel` covers 9 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
65
65
 
66
66
  It operates at two levels:
67
67
 
@@ -83,6 +83,10 @@ sentinel agentic ./my-agent/
83
83
  sentinel supply-chain http://localhost:3001
84
84
  sentinel supply-chain http://localhost:3001 --ai # + Claude semantic analysis
85
85
 
86
+ # Multi-agent trust analysis — detect A2A trust violations in your codebase
87
+ sentinel a2a ./agents/
88
+ sentinel a2a multi_agent.py --fail-on HIGH
89
+
86
90
  # Static posture scan
87
91
  sentinel scan my_agent.py
88
92
  sentinel secrets .
@@ -300,6 +304,54 @@ sentinel discover --format json
300
304
 
301
305
  ---
302
306
 
307
+ ### `sentinel a2a` — multi-agent trust analysis
308
+
309
+ Scans Python agent source files and builds a call graph showing which agents call which, then audits the trust boundaries between them. Detects the attack paths that single-agent tools miss entirely: injection that propagates across agent boundaries, unbounded agent spawning, and code-execution agents that accept delegated instructions without verification.
310
+
311
+ Supports **LangChain / LangGraph**, **AutoGen**, and **CrewAI**. No API key required.
312
+
313
+ ```bash
314
+ sentinel a2a ./agents/
315
+ sentinel a2a multi_agent.py
316
+ sentinel a2a . --fail-on HIGH
317
+ sentinel a2a . --format json
318
+ sentinel a2a . --ignore-rule A2A01_UNVERIFIED_ORCHESTRATOR # suppress if handled at infra layer
319
+ ```
320
+
321
+ **Rules:**
322
+
323
+ | Rule | Severity | What it catches |
324
+ |------|----------|-----------------|
325
+ | `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no caller verification |
326
+ | `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
327
+ | `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent is instantiated inside a loop — unbounded agent creation risk |
328
+ | `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
329
+ | `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates its full tool set to a sub-agent instead of a restricted subset |
330
+ | `A2A01_UNVERIFIED_ORCHESTRATOR` | LOW | Agents receive instructions from other agents with no visible trust verification |
331
+
332
+ **Example output:**
333
+
334
+ ```
335
+ 2 agents 1 edges 1 max depth acyclic
336
+
337
+ Agent Framework Role Tools
338
+ planner autogen worker —
339
+ executor autogen orchestrator — ⚠ code exec
340
+
341
+ Call graph:
342
+ executor ──► planner initiate_chat passes input
343
+
344
+ ● HIGH A2A04_PROMPT_PASSTHROUGH ASI01
345
+ User input flows directly from 'executor' to 'planner'
346
+ without sanitization at the agent boundary.
347
+
348
+ Trust Score 75/100 ███████████████░░░░░ WATCH
349
+ ```
350
+
351
+ Covers **ASI07** (Insecure Inter-Agent Communication) from OWASP Top 10 for Agentic Applications 2026.
352
+
353
+ ---
354
+
303
355
  ## Finding suppression
304
356
 
305
357
  Use `--ignore-rule` to suppress specific findings by rule ID. Suppressed findings are excluded from `--fail-on` evaluation and output — they don't break CI gates.
@@ -325,7 +377,7 @@ SC03_HIDDEN_NETWORK_FIELDS # webhook field verified safe — used for audit log
325
377
  NO_AUTH # server is behind an authenticated reverse proxy
326
378
  ```
327
379
 
328
- Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
380
+ Supported on: `sentinel scan`, `sentinel a2a`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
329
381
 
330
382
  ---
331
383
 
@@ -339,7 +391,7 @@ Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `se
339
391
  | **Agentic Supply Chain Compromise** | **ASI04** | **`sentinel supply-chain`** (static + AI), **`sentinel agentic`** |
340
392
  | Unexpected Code Execution | ASI05 | `sentinel scan` (CODE_EXECUTION_GRANT), `sentinel mcp scan` |
341
393
  | **Memory & Context Poisoning** | **ASI06** | **`sentinel secrets`** (memory contamination), **`sentinel agentic`** |
342
- | Insecure Inter-Agent Communication | ASI07 | `sentinel agentic` (reasoning layer) |
394
+ | **Insecure Inter-Agent Communication** | **ASI07** | **`sentinel a2a`** (call graph + trust rules), `sentinel agentic` (semantic reasoning) |
343
395
  | Cascading Agent Failures | ASI08 | `sentinel agentic` (cross-finding chain analysis) |
344
396
  | Human-Agent Trust Exploitation | ASI09 | `sentinel agentic` (narrative + evidence standard) |
345
397
  | Rogue Agents | ASI10 | `sentinel agentic` (drift detection across sessions) |
@@ -373,6 +425,9 @@ jobs:
373
425
 
374
426
  - name: MCP security audit
375
427
  run: sentinel mcp scan http://localhost:3001 --fail-on CRITICAL
428
+
429
+ - name: Multi-agent trust analysis
430
+ run: sentinel a2a ./agents/ --fail-on HIGH
376
431
  ```
377
432
 
378
433
  Use a `.sentinelignore` file at the repo root to suppress known-accepted findings without weakening the gate threshold:
@@ -393,6 +448,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
393
448
  | Investigating a specific server or codebase | `sentinel agentic` |
394
449
  | First assessment of a new MCP server | `sentinel agentic` |
395
450
  | Scheduled nightly security check | `sentinel agentic` (memory tracks drift) |
451
+ | Auditing a multi-agent codebase | `sentinel a2a` (call graph + trust rules) |
396
452
  | Quick local sanity check | `sentinel mcp scan`, `sentinel scan` |
397
453
  | Red-teaming a live agent endpoint | `sentinel ai-probe` |
398
454
 
@@ -402,7 +458,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
402
458
 
403
459
  - Python 3.10+
404
460
  - `ANTHROPIC_API_KEY` required for: `sentinel agentic`, `sentinel ai-probe`, `sentinel supply-chain --ai`, `sentinel inspect` (AI summary)
405
- - No API key required for: `sentinel scan`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
461
+ - No API key required for: `sentinel scan`, `sentinel a2a`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
406
462
 
407
463
  ---
408
464
 
@@ -4,7 +4,7 @@
4
4
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
5
5
  [![Python](https://img.shields.io/pypi/pyversions/agentsentinel-cli)](https://pypi.org/project/agentsentinel-cli/)
6
6
 
7
- **AI agent security — analyst mode, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
7
+ **AI agent security — analyst mode, multi-agent trust analysis, static rules, red-team probing, and MCP auditing. No server. No Docker. One install.**
8
8
 
9
9
  ```bash
10
10
  pipx install "agentsentinel-cli[all]"
@@ -14,7 +14,7 @@ pipx install "agentsentinel-cli[all]"
14
14
 
15
15
  ## What it does
16
16
 
17
- `sentinel` covers 8 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
17
+ `sentinel` covers 9 of the 10 risks in the [OWASP Top 10 for Agentic Applications 2026](https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/).
18
18
 
19
19
  It operates at two levels:
20
20
 
@@ -36,6 +36,10 @@ sentinel agentic ./my-agent/
36
36
  sentinel supply-chain http://localhost:3001
37
37
  sentinel supply-chain http://localhost:3001 --ai # + Claude semantic analysis
38
38
 
39
+ # Multi-agent trust analysis — detect A2A trust violations in your codebase
40
+ sentinel a2a ./agents/
41
+ sentinel a2a multi_agent.py --fail-on HIGH
42
+
39
43
  # Static posture scan
40
44
  sentinel scan my_agent.py
41
45
  sentinel secrets .
@@ -253,6 +257,54 @@ sentinel discover --format json
253
257
 
254
258
  ---
255
259
 
260
+ ### `sentinel a2a` — multi-agent trust analysis
261
+
262
+ Scans Python agent source files and builds a call graph showing which agents call which, then audits the trust boundaries between them. Detects the attack paths that single-agent tools miss entirely: injection that propagates across agent boundaries, unbounded agent spawning, and code-execution agents that accept delegated instructions without verification.
263
+
264
+ Supports **LangChain / LangGraph**, **AutoGen**, and **CrewAI**. No API key required.
265
+
266
+ ```bash
267
+ sentinel a2a ./agents/
268
+ sentinel a2a multi_agent.py
269
+ sentinel a2a . --fail-on HIGH
270
+ sentinel a2a . --format json
271
+ sentinel a2a . --ignore-rule A2A01_UNVERIFIED_ORCHESTRATOR # suppress if handled at infra layer
272
+ ```
273
+
274
+ **Rules:**
275
+
276
+ | Rule | Severity | What it catches |
277
+ |------|----------|-----------------|
278
+ | `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no caller verification |
279
+ | `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
280
+ | `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent is instantiated inside a loop — unbounded agent creation risk |
281
+ | `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
282
+ | `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates its full tool set to a sub-agent instead of a restricted subset |
283
+ | `A2A01_UNVERIFIED_ORCHESTRATOR` | LOW | Agents receive instructions from other agents with no visible trust verification |
284
+
285
+ **Example output:**
286
+
287
+ ```
288
+ 2 agents 1 edges 1 max depth acyclic
289
+
290
+ Agent Framework Role Tools
291
+ planner autogen worker —
292
+ executor autogen orchestrator — ⚠ code exec
293
+
294
+ Call graph:
295
+ executor ──► planner initiate_chat passes input
296
+
297
+ ● HIGH A2A04_PROMPT_PASSTHROUGH ASI01
298
+ User input flows directly from 'executor' to 'planner'
299
+ without sanitization at the agent boundary.
300
+
301
+ Trust Score 75/100 ███████████████░░░░░ WATCH
302
+ ```
303
+
304
+ Covers **ASI07** (Insecure Inter-Agent Communication) from OWASP Top 10 for Agentic Applications 2026.
305
+
306
+ ---
307
+
256
308
  ## Finding suppression
257
309
 
258
310
  Use `--ignore-rule` to suppress specific findings by rule ID. Suppressed findings are excluded from `--fail-on` evaluation and output — they don't break CI gates.
@@ -278,7 +330,7 @@ SC03_HIDDEN_NETWORK_FIELDS # webhook field verified safe — used for audit log
278
330
  NO_AUTH # server is behind an authenticated reverse proxy
279
331
  ```
280
332
 
281
- Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
333
+ Supported on: `sentinel scan`, `sentinel a2a`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel secrets`, `sentinel inspect`.
282
334
 
283
335
  ---
284
336
 
@@ -292,7 +344,7 @@ Supported on: `sentinel scan`, `sentinel mcp scan`, `sentinel supply-chain`, `se
292
344
  | **Agentic Supply Chain Compromise** | **ASI04** | **`sentinel supply-chain`** (static + AI), **`sentinel agentic`** |
293
345
  | Unexpected Code Execution | ASI05 | `sentinel scan` (CODE_EXECUTION_GRANT), `sentinel mcp scan` |
294
346
  | **Memory & Context Poisoning** | **ASI06** | **`sentinel secrets`** (memory contamination), **`sentinel agentic`** |
295
- | Insecure Inter-Agent Communication | ASI07 | `sentinel agentic` (reasoning layer) |
347
+ | **Insecure Inter-Agent Communication** | **ASI07** | **`sentinel a2a`** (call graph + trust rules), `sentinel agentic` (semantic reasoning) |
296
348
  | Cascading Agent Failures | ASI08 | `sentinel agentic` (cross-finding chain analysis) |
297
349
  | Human-Agent Trust Exploitation | ASI09 | `sentinel agentic` (narrative + evidence standard) |
298
350
  | Rogue Agents | ASI10 | `sentinel agentic` (drift detection across sessions) |
@@ -326,6 +378,9 @@ jobs:
326
378
 
327
379
  - name: MCP security audit
328
380
  run: sentinel mcp scan http://localhost:3001 --fail-on CRITICAL
381
+
382
+ - name: Multi-agent trust analysis
383
+ run: sentinel a2a ./agents/ --fail-on HIGH
329
384
  ```
330
385
 
331
386
  Use a `.sentinelignore` file at the repo root to suppress known-accepted findings without weakening the gate threshold:
@@ -346,6 +401,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
346
401
  | Investigating a specific server or codebase | `sentinel agentic` |
347
402
  | First assessment of a new MCP server | `sentinel agentic` |
348
403
  | Scheduled nightly security check | `sentinel agentic` (memory tracks drift) |
404
+ | Auditing a multi-agent codebase | `sentinel a2a` (call graph + trust rules) |
349
405
  | Quick local sanity check | `sentinel mcp scan`, `sentinel scan` |
350
406
  | Red-teaming a live agent endpoint | `sentinel ai-probe` |
351
407
 
@@ -355,7 +411,7 @@ MISSING_RATE_LIMIT # rate limiting handled at infra layer
355
411
 
356
412
  - Python 3.10+
357
413
  - `ANTHROPIC_API_KEY` required for: `sentinel agentic`, `sentinel ai-probe`, `sentinel supply-chain --ai`, `sentinel inspect` (AI summary)
358
- - No API key required for: `sentinel scan`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
414
+ - No API key required for: `sentinel scan`, `sentinel a2a`, `sentinel secrets`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel probe`, `sentinel discover`, `sentinel inspect --no-ai`
359
415
 
360
416
  ---
361
417
 
@@ -123,45 +123,46 @@ def _enrich_from_platform(agents, scores_map, connect_url, api_key):
123
123
 
124
124
  @main.command()
125
125
  @click.option("--process/--no-process", default=True, show_default=True,
126
- help="Scan running processes for LLM API usage.")
126
+ help="Scan running processes for MCP servers and agent signals.")
127
127
  @click.option("--network/--no-network", default=True, show_default=True,
128
- help="Probe local ports for MCP servers and agent APIs.")
128
+ help="Probe local ports confirmed via MCP protocol handshake.")
129
129
  @click.option("--docker/--no-docker", default=False, show_default=True,
130
- help="Inspect running Docker containers.")
131
- @click.option("--path", "scan_path", default=None, type=click.Path(exists=True, path_type=Path),
132
- metavar="DIR", help="Scan a directory for agent source files.")
130
+ help="Inspect running Docker containers for MCP/agent patterns.")
133
131
  @click.option("--subnet", default=None, metavar="CIDR",
134
- help="Scan a CIDR subnet for AI agent endpoints, e.g. 10.0.0.0/24.")
132
+ help="Scan a CIDR subnet for MCP servers, e.g. 10.0.0.0/24.")
135
133
  @click.option("--ports", default=None, metavar="RANGE",
136
- help="Custom port range for network scan, e.g. 8000-9001. Defaults to common agent ports.")
134
+ help="Custom port range, e.g. 8000-9001. Defaults to common MCP/agent ports.")
135
+ @click.option("--auth-header", "auth_header", default=None, metavar="HEADER",
136
+ help="HTTP auth header for MCP handshakes, e.g. 'Authorization: Bearer token'.")
137
137
  @click.option("--format", "fmt", type=click.Choice(["text", "json"]), default="text",
138
138
  help="Output format.")
139
139
  @click.option("--verbose", "-v", is_flag=True, default=False,
140
- help="Show full details per discovered agent.")
140
+ help="Show full details per discovered server.")
141
141
  def discover(
142
142
  process: bool,
143
143
  network: bool,
144
144
  docker: bool,
145
- scan_path: Path | None,
146
145
  subnet: str | None,
147
146
  ports: str | None,
147
+ auth_header: str | None,
148
148
  fmt: str,
149
149
  verbose: bool,
150
150
  ) -> None:
151
- """Find AI agents running in your environment.
151
+ """Find MCP servers and AI agent processes in your environment.
152
152
 
153
- Scans running processes, local network ports, source files, and Docker
154
- containers to surface AI agents including unmonitored ones.
153
+ Confirms MCP servers via protocol handshake not just open ports.
154
+ Use --subnet to scan across a network range.
155
155
 
156
156
  \b
157
157
  Examples:
158
- sentinel discover scan processes + network
159
- sentinel discover --docker include Docker containers
160
- sentinel discover --path ./agents scan a source directory
161
- sentinel discover --subnet 10.0.0.0/24 scan internal subnet
162
- sentinel discover --no-process network scan only
163
- sentinel discover --ports 8000-9001 custom port range
164
- sentinel discover --format json machine-readable output
158
+ sentinel discover local processes + ports
159
+ sentinel discover --subnet 10.0.0.0/24 scan internal network
160
+ sentinel discover --subnet 10.0.0.0/24 \\
161
+ --auth-header 'Authorization: Bearer token' scan with credentials
162
+ sentinel discover --no-process network only
163
+ sentinel discover --docker include containers
164
+ sentinel discover --ports 8000-9001 custom port range
165
+ sentinel discover --format json machine-readable output
165
166
  """
166
167
  from agentsentinel_cli.discover import run_discovery, as_json as discover_json
167
168
  from agentsentinel_cli.discover_report import print_discover_result, print_subnet_progress
@@ -169,6 +170,15 @@ def discover(
169
170
  # Parse port range
170
171
  port_list = _parse_ports(ports) if ports else None
171
172
 
173
+ # Parse auth header
174
+ extra_headers: dict[str, str] = {}
175
+ if auth_header:
176
+ if ":" not in auth_header:
177
+ console.print("[red]Error:[/red] --auth-header must be 'Header-Name: value' format.")
178
+ sys.exit(1)
179
+ key, _, val = auth_header.partition(":")
180
+ extra_headers[key.strip()] = val.strip()
181
+
172
182
  # Collect active scan vectors for the header
173
183
  vectors = []
174
184
  if process:
@@ -177,14 +187,12 @@ def discover(
177
187
  vectors.append("network")
178
188
  if subnet:
179
189
  vectors.append(f"subnet ({subnet})")
180
- if scan_path:
181
- vectors.append(f"files ({scan_path})")
182
190
  if docker:
183
191
  vectors.append("docker")
184
192
 
185
193
  if not vectors:
186
194
  console.print("[yellow]No scan vectors selected — use at least one of: "
187
- "--process, --network, --subnet, --path, --docker[/yellow]")
195
+ "--process, --network, --subnet, --docker[/yellow]")
188
196
  sys.exit(1)
189
197
 
190
198
  if fmt == "text":
@@ -197,9 +205,9 @@ def discover(
197
205
  do_process=process,
198
206
  do_network=network,
199
207
  do_docker=docker,
200
- scan_path=scan_path,
201
208
  ports=port_list,
202
209
  subnet=subnet,
210
+ extra_headers=extra_headers or None,
203
211
  subnet_progress_cb=progress_cb,
204
212
  )
205
213