agentsentinel-cli 0.9.7__tar.gz → 0.9.8__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 (46) hide show
  1. agentsentinel_cli-0.9.8/.claude/settings.local.json +13 -0
  2. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/PKG-INFO +264 -261
  3. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/README.md +263 -260
  4. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/__init__.py +1 -1
  5. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/host_scanner.py +34 -6
  6. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/mcp_client.py +11 -1
  7. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_oauth.py +109 -6
  8. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/transport.py +15 -4
  9. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/pyproject.toml +1 -1
  10. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/.gitignore +0 -0
  11. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/DOCUMENTATION.md +0 -0
  12. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/LICENSE +0 -0
  13. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/a2a_report.py +0 -0
  14. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/a2a_rules.py +0 -0
  15. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/a2a_scanner.py +0 -0
  16. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/cli.py +0 -0
  17. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/discover.py +0 -0
  18. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/discover_report.py +0 -0
  19. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/fingerprint.py +0 -0
  20. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/frameworks.py +0 -0
  21. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/host_report.py +0 -0
  22. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/host_rules.py +0 -0
  23. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/inspect.py +0 -0
  24. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/inspect_report.py +0 -0
  25. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/mcp_report.py +0 -0
  26. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/mcp_rules.py +0 -0
  27. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/__init__.py +0 -0
  28. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_auth.py +0 -0
  29. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_fuzz.py +0 -0
  30. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_inject.py +0 -0
  31. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_poison.py +0 -0
  32. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_preauth.py +0 -0
  33. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/mcp_recon.py +0 -0
  34. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/models.py +0 -0
  35. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/payloads.py +0 -0
  36. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/redteam/report.py +0 -0
  37. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/report.py +0 -0
  38. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/rules.py +0 -0
  39. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/scanner.py +0 -0
  40. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/secrets.py +0 -0
  41. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/secrets_report.py +0 -0
  42. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/secrets_rules.py +0 -0
  43. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/supply_chain_ai.py +0 -0
  44. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/supply_chain_report.py +0 -0
  45. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/supply_chain_rules.py +0 -0
  46. {agentsentinel_cli-0.9.7 → agentsentinel_cli-0.9.8}/agentsentinel_cli/suppress.py +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(python3 -c ' *)",
5
+ "Bash(pip3 show *)",
6
+ "Bash(pip show *)",
7
+ "Bash(python3 -m pip show httpx)",
8
+ "Bash(sentinel --version)",
9
+ "Bash(python -m agentsentinel_cli --version)",
10
+ "Bash(pkill -f \"mcp_server.py --port 8765\")"
11
+ ]
12
+ }
13
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentsentinel-cli
3
- Version: 0.9.7
3
+ Version: 0.9.8
4
4
  Summary: AI agent and MCP server security scanner — discovery, static analysis, supply chain audit, and multi-agent trust analysis
5
5
  Project-URL: Homepage, https://github.com/jaydenaung/agentsentinel-cli
6
6
  Project-URL: Repository, https://github.com/jaydenaung/agentsentinel-cli
@@ -41,59 +41,51 @@ Description-Content-Type: text/markdown
41
41
  **The nmap of AI agents and MCP servers. Deterministic. Protocol-based. No API key required.**
42
42
 
43
43
  ```bash
44
- pipx install agentsentinel-cli
44
+ pipx install "agentsentinel-cli[all]"
45
45
  ```
46
46
 
47
47
  ---
48
48
 
49
49
  ## What it does
50
50
 
51
- `sentinel` discovers and audits AI agents and MCP servers. Every result is deterministicsame input, same output, every time. No cloud dependency, no API key required for any scan.
51
+ `sentinel` actively attacks and audits AI agents and MCP servers. Every result is evidence-confirmedif a traversal finding says it read `/etc/passwd`, it read `/etc/passwd`. No heuristics, no cloud dependency, no API key required for any scan.
52
52
 
53
- | Command | What it answers |
54
- |---------|----------------|
55
- | `sentinel discover` | What MCP servers are running on this host or network? |
56
- | `sentinel mcp scan` | How secure is this specific MCP server? |
57
- | `sentinel supply-chain` | Has this MCP tool manifest been tampered with? |
58
- | `sentinel scan` | What security risks are in this agent's source code? |
59
- | `sentinel secrets` | Are credentials or PII exposed in these files? |
60
- | `sentinel inspect` | What framework, model, and role is this agent? |
61
- | `sentinel a2a` | Are multi-agent trust boundaries safe? |
62
- | `sentinel host-scan` | What is my local AI security posture across all AI tools? |
63
- | `sentinel redteam mcp` | Can I actively exploit this MCP server? |
53
+ | Command | What it does |
54
+ |---------|-------------|
55
+ | `sentinel redteam mcp` | Actively exploit an MCP server confirmed traversal, auth bypass, OAuth attacks, injection |
56
+ | `sentinel host-scan` | Audit your machine's full AI security posture across Claude, Cursor, Windsurf, VS Code, and more |
57
+ | `sentinel a2a` | Build a call graph of your multi-agent system and audit trust boundaries |
58
+ | `sentinel discover` | Find every MCP server on a host or subnet — confirmed via protocol handshake |
59
+ | `sentinel mcp scan` | Deep security audit of a running MCP server |
60
+ | `sentinel supply-chain` | Detect tool manifest tampering, description injection, and schema drift |
61
+ | `sentinel scan` | AST-level static analysis of agent source code |
62
+ | `sentinel secrets` | Find exposed credentials and PII in agent files and AI memory stores |
63
+ | `sentinel inspect` | Fingerprint an agent file or live endpoint |
64
64
 
65
65
  ---
66
66
 
67
67
  ## Quick start
68
68
 
69
69
  ```bash
70
- # Discover MCP servers local and across a network
71
- sentinel discover
72
- sentinel discover --host 10.0.1.45
73
- sentinel discover --subnet 10.0.0.0/24
74
- sentinel discover --subnet 10.0.0.0/24 --scan # discover + deep audit in one pass
70
+ # Active red-teamreal confirmed exploitation
71
+ sentinel redteam mcp full http://localhost:8000
72
+ sentinel redteam mcp full http://localhost:8000 --auth-header "Authorization: Bearer token"
73
+ sentinel redteam mcp preauth http://localhost:8000 # zero credentials — follows MCP 2025 OAuth chain
75
74
 
76
- # Audit a specific MCP server
77
- sentinel mcp scan http://localhost:8000/sse --auth-header "Authorization: Bearer token"
78
- sentinel supply-chain http://localhost:8000/sse
75
+ # Local AI security posture — audits Claude, Cursor, Windsurf, VS Code, and more
76
+ sentinel host-scan
77
+ sentinel host-scan --fail-on HIGH
79
78
 
80
- # Scan agent source code
81
- sentinel scan ./agents/
79
+ # Multi-agent trust analysis
82
80
  sentinel a2a ./agents/
83
81
 
84
- # Secrets and credentials
85
- sentinel secrets .
86
- sentinel secrets ~/.claude/projects/ # scan Claude Code memory
87
-
88
- # Local AI security posture — no network calls
89
- sentinel host-scan
90
- sentinel host-scan --fail-on HIGH
82
+ # Discover and audit MCP servers on a network
83
+ sentinel discover --subnet 10.0.0.0/24 --scan
91
84
 
92
- # Active red-team — real attacks, confirmed exploitation
93
- sentinel redteam mcp full http://localhost:8000
94
- sentinel redteam mcp preauth http://localhost:8000 # works with zero credentials
95
- sentinel redteam mcp inject http://localhost:8000 --type traverse --type ssrf
96
- sentinel redteam mcp auth http://localhost:8000 # credential bypass + OAuth 2.0
85
+ # Static and source-level audits
86
+ sentinel mcp scan http://localhost:8000/sse --auth-header "Authorization: Bearer token"
87
+ sentinel scan ./agents/
88
+ sentinel secrets ~/.claude/projects/
97
89
  ```
98
90
 
99
91
  ---
@@ -101,25 +93,232 @@ sentinel redteam mcp auth http://localhost:8000 # credential bypass +
101
93
  ## Install
102
94
 
103
95
  ```bash
104
- # Zero dependencies — sentinel scan and sentinel a2a
96
+ # Everything (recommended)
97
+ pipx install "agentsentinel-cli[all]"
98
+
99
+ # Zero dependencies — sentinel scan, a2a, secrets, inspect
105
100
  pip install agentsentinel-cli
106
101
 
107
- # + sentinel discover (psutil for process scanning)
102
+ # + network tools (discover, mcp scan, supply-chain, redteam)
103
+ pip install "agentsentinel-cli[mcp]"
104
+
105
+ # + process scanning (discover --local)
108
106
  pip install "agentsentinel-cli[discover]"
107
+ ```
109
108
 
110
- # + sentinel mcp scan, supply-chain, inspect (httpx)
111
- pip install "agentsentinel-cli[mcp]"
109
+ ---
112
110
 
113
- # Everything
114
- pip install "agentsentinel-cli[all]"
111
+ ## Commands
115
112
 
116
- # Recommendedisolated install
117
- pipx install "agentsentinel-cli[all]"
113
+ ### `sentinel redteam mcp` active MCP server exploitation
114
+
115
+ The active red-team module. Every finding is backed by confirmed evidence from the server's actual response — a traversal finding includes the file content, a token finding includes the actual token. If nothing is confirmed, nothing is reported.
116
+
117
+ **Phases 1–2 (`preauth` + OAuth) run with zero credentials** — useful when the target blocks unauthenticated MCP access entirely. `sentinel` follows the full MCP 2025 OAuth discovery chain to find and test the real authorization server, even when it lives on a separate host (Auth0, Okta, Azure AD, Keycloak).
118
+
119
+ Requires `httpx`: `pip install "agentsentinel-cli[mcp]"`
120
+
121
+ ```bash
122
+ # Full run — all 7 phases, unified report
123
+ sentinel redteam mcp full http://localhost:8000
124
+ sentinel redteam mcp full http://localhost:8000 --auth-header "Authorization: Bearer token"
125
+ sentinel redteam mcp full http://localhost:8000 --intensity high --format json
126
+
127
+ # Zero-credential pre-auth probe — follows MCP 2025 OAuth discovery chain
128
+ sentinel redteam mcp preauth http://localhost:8000
129
+ sentinel redteam mcp preauth http://localhost:8000 --skip-oauth # skip external AS if out of scope
130
+
131
+ # Targeted phases
132
+ sentinel redteam mcp recon http://localhost:8000 # enumerate attack surface
133
+ sentinel redteam mcp auth http://localhost:8000 # credential bypass + OAuth 2.0 attacks
134
+ sentinel redteam mcp inject http://localhost:8000 # path traversal, SSRF, cmd, SQLi, LLM injection
135
+ sentinel redteam mcp poison http://localhost:8000 # tool description and result injection
136
+ sentinel redteam mcp fuzz http://localhost:8000 # schema and type boundary fuzzing
137
+
138
+ # Surgical injection — pick techniques, raise intensity
139
+ sentinel redteam mcp inject http://localhost:8000 --type traverse --type ssrf
140
+ sentinel redteam mcp inject http://localhost:8000 --type cmd --type sqli --intensity high
141
+
142
+ # stdio transport (local MCP servers)
143
+ sentinel redteam mcp full --stdio "python my_mcp_server.py"
144
+
145
+ # CI gate — fail if any CRITICAL confirmed
146
+ sentinel redteam mcp full http://localhost:8000 --fail-on CRITICAL
147
+
148
+ # Save full evidence bundle
149
+ sentinel redteam mcp full http://localhost:8000 --output report.json
150
+ ```
151
+
152
+ #### Phases (`full` runs all 7)
153
+
154
+ | Phase | Command | Needs credentials | What it tests |
155
+ |-------|---------|:-----------------:|---------------|
156
+ | 1 — Pre-auth probe | `preauth` | No | CORS policy, version disclosure, unauthenticated paths, SSE stream, error disclosure |
157
+ | 2 — OAuth attack surface | *(auto in `preauth` / `auth` / `full`)* | No | MCP 2025 discovery chain, client registration, token acquisition, PKCE, scope attacks |
158
+ | 3 — Recon | `recon` | Yes | Full tool inventory with input schemas; dangerous capability detection |
159
+ | 4 — Auth bypass | `auth` | Optional | 5 credential scenarios: no creds, empty bearer, garbage token, expired JWT, JWT alg:none |
160
+ | 5 — Injection | `inject` | Yes | Path traversal, SSRF, command injection, SQL injection — evidence-confirmed only |
161
+ | 6 — Poison | `poison` | Yes | Adversarial instructions in tool descriptions; LLM injection via tool result parameters |
162
+ | 7 — Fuzz | `fuzz` | Yes | Stack traces, path disclosure, template injection eval, type confusion, input reflection |
163
+
164
+ #### OAuth 2.0 attack surface — how the discovery chain works
165
+
166
+ The MCP 2025 spec mandates OAuth 2.0. An MCP server is an OAuth **resource server** — it validates tokens but doesn't issue them. The **authorization server** (the service that issues tokens) is often a separate host: Auth0, Okta, Keycloak, AWS Cognito, Azure AD.
167
+
168
+ `sentinel` follows the full RFC 9728 discovery chain automatically:
169
+
170
+ ```
171
+ 1. GET /.well-known/oauth-protected-resource (on the MCP server)
172
+ ↓ authorization_servers: ["https://auth.company.com"]
173
+ 2. GET https://auth.company.com/.well-known/oauth-authorization-server
174
+ ↓ token_endpoint, registration_endpoint, authorization_endpoint
175
+ 3. Run all OAuth attack tests against the real AS endpoints
118
176
  ```
119
177
 
178
+ **Co-located AS** (dev/test): MCP server and AS on the same host. Tests run automatically; the INFO finding says `(co-located)`.
179
+
180
+ **Separate AS** (production): MCP at `api.company.com`, AS at `auth.company.com`. `sentinel` follows the pointer, emits an INFO finding naming the external AS, then runs all OAuth tests against the real AS. Use `--skip-oauth` if the external AS is a third-party service outside your engagement scope.
181
+
182
+ **OAuth tests:**
183
+
184
+ | Test | Severity | What `sentinel` does | Attacker impact if confirmed |
185
+ |------|----------|---------------------|------------------------------|
186
+ | Public client registration | CRITICAL | `POST /registration_endpoint` with no auth | Attacker registers an OAuth client, obtains a valid `client_id`, and can initiate auth flows |
187
+ | Token without `client_secret` | CRITICAL | `POST /token` with only a `client_id` | Any attacker who knows a `client_id` gets a valid access token — no secret required |
188
+ | Token with empty `client_secret` | CRITICAL | Same as above but `client_secret=""` | Empty string accepted — credential check bypassed entirely |
189
+ | PKCE plain method | MEDIUM | `GET /authorize?code_challenge_method=plain` | Code verifier transmitted in cleartext; interceptable via logs or proxies. MCP 2025 requires S256. |
190
+ | Scope escalation | HIGH | Refresh token requesting all supported scopes | Low-privilege token upgrades to higher-privilege scopes — breaks least-privilege enforcement |
191
+ | X-Agent-Scopes forgery | CRITICAL | Authenticated call with forged `X-Agent-Scopes` header | Authenticated agent invokes tools outside its granted scope |
192
+
193
+ #### Pre-auth probes
194
+
195
+ All Phase 1 probes run over plain HTTP before any MCP handshake. No credentials required.
196
+
197
+ | Probe | Sev | What it checks | Why it matters |
198
+ |-------|-----|----------------|----------------|
199
+ | CORS wildcard + credentials | CRITICAL | `Access-Control-Allow-Origin: *` with `Allow-Credentials: true` | Any website can make credentialed requests to MCP endpoints from the victim's browser |
200
+ | CORS wildcard | HIGH | `Access-Control-Allow-Origin: *` | Any website can read MCP tool responses — cross-origin exfiltration |
201
+ | CORS reflected origin | HIGH | Server echoes back the request `Origin` header | Equivalent to wildcard CORS — attacker sets any origin and browser permits the read |
202
+ | Unauthenticated SSE stream | HIGH | `GET /sse` streams without a token | Attacker receives a live feed of all MCP events: tool results, agent responses, notifications |
203
+ | Public client registration | HIGH | `registration_endpoint` reachable unauthenticated | Attacker registers OAuth client without any authorization |
204
+ | Stack trace in error response | HIGH | Malformed request triggers full stack trace | Internal paths, library versions, and code structure exposed to unauthenticated callers |
205
+ | Unauthenticated `/debug` or `/admin` | HIGH | Admin/debug endpoint returns 200 | Admin endpoints frequently expose sensitive operations or config dumps |
206
+ | Server / framework version | MEDIUM | `Server:` header, `X-Powered-By:`, version in error body | Attacker maps exact versions to CVEs without authentication |
207
+ | Unauthenticated `/docs` / `/openapi.json` | MEDIUM | API schema readable without credentials | Every endpoint, parameter, and schema exposed — full attack surface in one request |
208
+ | Unauthenticated `/metrics` | MEDIUM | Prometheus metrics accessible | Runtime internals reveal traffic patterns and anomaly detection thresholds |
209
+ | Implicit grant supported | MEDIUM | `implicit` or `token` in `grant_types_supported` | Access tokens in URL fragments — capturable via browser history or injected scripts |
210
+ | Framework version in error body | MEDIUM | Error body contains a version string | Same CVE-mapping risk as the `Server` header |
211
+ | Security headers missing | LOW | Absent `X-Content-Type-Options`, `Content-Security-Policy`, `X-Frame-Options` | Missing defensive headers expand MIME sniffing, clickjacking, and content injection surface |
212
+
213
+ #### Injection techniques (`--type`)
214
+
215
+ | Technique | What it confirms |
216
+ |-----------|-----------------|
217
+ | `traverse` | Arbitrary file read — evidence: actual `/etc/passwd` content or `.env` key values |
218
+ | `ssrf` | Server-side request forgery — evidence: AWS IMDS tokens, Redis/SSH banners, cloud metadata |
219
+ | `cmd` | OS command injection — evidence: `uid=0(root)` from `id`, sentinel value in output |
220
+ | `sqli` | SQL injection — evidence: DB error messages (`ORA-`, `You have an error in your SQL syntax`) |
221
+ | `llm` | LLM instruction injection via tool result — evidence: sentinel instruction echoed in clean response |
222
+
223
+ #### Intensity levels (`--intensity`)
224
+
225
+ | Level | Payloads per technique | Use case |
226
+ |-------|----------------------|----------|
227
+ | `low` | 5 | Fast CI gate |
228
+ | `medium` | 15 | Standard engagement (default) |
229
+ | `high` | Full library (~20) | Thorough pentest |
230
+
120
231
  ---
121
232
 
122
- ## Commands
233
+ ### `sentinel host-scan` — local AI security posture audit
234
+
235
+ Audits your machine's AI security posture without any network calls. Discovers and audits MCP server configurations across every major AI coding tool on the host — Claude Code, Claude Desktop, Cursor, Windsurf, Continue.dev, Gemini CLI, and VS Code — then checks shell credentials, macOS privacy permissions, system security settings, and running AI processes.
236
+
237
+ Works on macOS, Linux, and Windows. No API key required.
238
+
239
+ ```bash
240
+ sentinel host-scan
241
+ sentinel host-scan --format json
242
+ sentinel host-scan --fail-on HIGH
243
+ sentinel host-scan --ignore-rule HOST_LARGE_MEMORY
244
+ ```
245
+
246
+ **What it checks:**
247
+
248
+ *Anthropic tools*
249
+ - **Claude Code** — `allowedTools` (shell bypass), MCP server configs, shell hooks
250
+ - **Claude Desktop** — MCP server configs
251
+
252
+ *Third-party AI tools* — MCP server configs audited with the same exfiltration, broad-filesystem, sensitive-path, and sprawl rules as Claude tools
253
+ - **Cursor** — `~/.cursor/mcp.json`
254
+ - **Windsurf** — `~/.codeium/windsurf/mcp_config.json`
255
+ - **Continue.dev** — `~/.continue/config.json`
256
+ - **Gemini CLI** — `~/.gemini/settings.json`
257
+ - **VS Code** — `mcp.servers` in `settings.json` (MCP support added in VS Code 1.99)
258
+
259
+ *Host security*
260
+ - **Shell configs** — hardcoded AI API keys in `.zshrc`, `.bashrc`, `.zprofile`, etc. (macOS/Linux); PowerShell profiles on Windows
261
+ - **macOS TCC permissions** — Full Disk Access, Screen Recording, Accessibility granted to AI apps
262
+ - **macOS system security** — SIP, FileVault, Gatekeeper status
263
+ - **Exposed AI processes** — AI-related processes listening on non-localhost interfaces
264
+ - **Memory footprint** — Claude Code conversation memory size in `~/.claude/projects/`
265
+
266
+ **Rules:**
267
+
268
+ | Rule | Severity | Category | What it catches |
269
+ |------|----------|----------|-----------------|
270
+ | `HOST_SHELL_UNRESTRICTED` | CRITICAL | config | `Bash` in `allowedTools` — shell runs without confirmation prompt |
271
+ | `HOST_SIP_DISABLED` | CRITICAL | system | macOS System Integrity Protection is off |
272
+ | `HOST_API_KEY_IN_SHELL` | HIGH | data_exposure | AI API keys hardcoded in shell config files |
273
+ | `HOST_MCP_EXFIL_PATH` | HIGH | config | Any AI tool's MCP server has both filesystem access and network capability |
274
+ | `HOST_FDA_AI_APP` | HIGH | permissions | Full Disk Access granted to an AI app or its terminal |
275
+ | `HOST_SCREEN_RECORDING_AI` | HIGH | permissions | Screen Recording permission granted to an AI app |
276
+ | `HOST_AI_PROCESS_EXPOSED` | HIGH | network | AI-related process listening on a non-localhost interface |
277
+ | `HOST_FILEVAULT_OFF` | HIGH | system | FileVault disk encryption is disabled |
278
+ | `HOST_ACCESSIBILITY_AI` | MEDIUM | permissions | Accessibility permission granted to an AI app |
279
+ | `HOST_HOOKS_SHELL` | MEDIUM | config | Claude Code shell hooks that could interpolate AI output |
280
+ | `HOST_MCP_BROAD_FS` | MEDIUM | config | Any AI tool's MCP server configured with home-dir or root-level path |
281
+ | `HOST_MCP_SENSITIVE_PATH` | MEDIUM | config | Any AI tool's MCP server has access to `~/.ssh`, `~/.aws`, `~/.kube`, or Keychain |
282
+ | `HOST_MANY_MCP_SERVERS` | MEDIUM | config | 8+ MCP servers across all detected AI tools — large prompt injection attack surface |
283
+ | `HOST_GATEKEEPER_OFF` | MEDIUM | system | Gatekeeper disabled — unsigned binaries run without warning |
284
+ | `HOST_LARGE_MEMORY` | LOW | data_exposure | Claude Code memory files exceed 50 MB of accumulated conversation data |
285
+
286
+ Every finding includes a remediation step. The posture score (0–100) uses CRITICAL −40, HIGH −20, MEDIUM −10, LOW −5.
287
+
288
+ ---
289
+
290
+ ### `sentinel a2a` — multi-agent trust analysis
291
+
292
+ Builds a call graph from Python agent source and audits trust boundaries. Detects injection propagation across agent boundaries, unbounded spawning, and code-execution agents accepting unverified delegations.
293
+
294
+ Supports **LangChain / LangGraph**, **AutoGen**, **CrewAI**, and **MCP client → server connections**.
295
+
296
+ ```bash
297
+ sentinel a2a ./agents/
298
+ sentinel a2a multi_agent.py
299
+ sentinel a2a . --fail-on HIGH
300
+ sentinel a2a . --format json
301
+ ```
302
+
303
+ **Detected patterns:**
304
+ - LangGraph `StateGraph.add_node` / `add_edge` / `add_conditional_edges`
305
+ - AutoGen `initiate_chat`, `GroupChat`, `GroupChatManager`
306
+ - CrewAI `Crew(agents=[...], process=Process.hierarchical)`
307
+ - MCP client connections: `sse_client(url)`, `streamablehttp_client(url)` — surfaces agent → MCP server edges with URL resolution from constants
308
+
309
+ **Rules:**
310
+
311
+ | Rule | Severity | What it catches |
312
+ |------|----------|-----------------|
313
+ | `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no verification |
314
+ | `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
315
+ | `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent instantiated inside a loop — unbounded creation risk |
316
+ | `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
317
+ | `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates full tool set instead of a restricted subset |
318
+
319
+ Covers **ASI07** (Insecure Inter-Agent Communication).
320
+
321
+ ---
123
322
 
124
323
  ### `sentinel discover` — find MCP servers and agent processes
125
324
 
@@ -135,7 +334,6 @@ sentinel discover --host 10.0.1.45 --auth-header "Authorization: Bearer token"
135
334
 
136
335
  # Subnet sweep
137
336
  sentinel discover --subnet 10.0.0.0/24
138
- sentinel discover --subnet 10.0.0.0/24 --auth-header "Authorization: Bearer token"
139
337
 
140
338
  # Discover + deep security audit in one pass
141
339
  sentinel discover --host 10.0.1.45 --scan
@@ -230,7 +428,7 @@ sentinel scan my_agent.py
230
428
  sentinel scan ./agents/
231
429
  sentinel scan ./agents/ --fail-on CRITICAL
232
430
  sentinel scan ./agents/ --format json
233
- sentinel scan ./agents/ --ignore-rule DANGEROUS_GRANTS # suppress accepted finding
431
+ sentinel scan ./agents/ --ignore-rule DANGEROUS_GRANTS
234
432
  ```
235
433
 
236
434
  **Detects tools defined via:**
@@ -269,7 +467,6 @@ sentinel secrets . --format json
269
467
  ```
270
468
 
271
469
  **Detects:**
272
-
273
470
  - Credentials: Anthropic, OpenAI, AWS, GitHub, Stripe, Google, HuggingFace API keys · private keys · database URLs · JWT tokens
274
471
  - PII (global): email addresses · credit cards (Luhn-validated) · US SSN · US phone
275
472
  - PII (Singapore): NRIC/FIN (mod-11 checksum-validated) · passport · mobile · landline · UEN · postal code
@@ -297,200 +494,6 @@ With `ANTHROPIC_API_KEY` set, generates a plain English security summary.
297
494
 
298
495
  ---
299
496
 
300
- ### `sentinel a2a` — multi-agent trust analysis
301
-
302
- Builds a call graph from Python agent source and audits trust boundaries. Detects injection propagation across agent boundaries, unbounded spawning, and code-execution agents accepting unverified delegations.
303
-
304
- Supports **LangChain / LangGraph**, **AutoGen**, **CrewAI**, and **MCP client → server connections**.
305
-
306
- ```bash
307
- sentinel a2a ./agents/
308
- sentinel a2a multi_agent.py
309
- sentinel a2a . --fail-on HIGH
310
- sentinel a2a . --format json
311
- ```
312
-
313
- **Detected patterns:**
314
- - LangGraph `StateGraph.add_node` / `add_edge` / `add_conditional_edges`
315
- - AutoGen `initiate_chat`, `GroupChat`, `GroupChatManager`
316
- - CrewAI `Crew(agents=[...], process=Process.hierarchical)`
317
- - MCP client connections: `sse_client(url)`, `streamablehttp_client(url)` — surfaces agent → MCP server edges with URL resolution from constants
318
-
319
- **Rules:**
320
-
321
- | Rule | Severity | What it catches |
322
- |------|----------|-----------------|
323
- | `A2A03_IMPLICIT_TRUST` | CRITICAL | Code-execution agent accepts calls from other agents with no verification |
324
- | `A2A04_PROMPT_PASSTHROUGH` | HIGH | User input flows directly across an agent boundary without sanitization |
325
- | `A2A02_UNBOUNDED_SPAWNING` | HIGH | Agent instantiated inside a loop — unbounded creation risk |
326
- | `A2A06_CIRCULAR_DELEGATION` | HIGH | Cycle in the call graph — agents can loop indefinitely under injection |
327
- | `A2A05_UNSCOPED_DELEGATION` | MEDIUM | Orchestrator delegates full tool set instead of a restricted subset |
328
-
329
- Covers **ASI07** (Insecure Inter-Agent Communication).
330
-
331
- ---
332
-
333
- ### `sentinel host-scan` — local AI security posture audit
334
-
335
- Audits your machine's AI security posture without any network calls. Discovers and audits MCP server configurations across every major AI coding tool on the host — Claude Code, Claude Desktop, Cursor, Windsurf, Continue.dev, Gemini CLI, and VS Code — then checks shell credentials, macOS privacy permissions, system security settings, and running AI processes.
336
-
337
- Works on macOS, Linux, and Windows. No API key required.
338
-
339
- ```bash
340
- sentinel host-scan
341
- sentinel host-scan --format json
342
- sentinel host-scan --fail-on HIGH
343
- sentinel host-scan --ignore-rule HOST_LARGE_MEMORY
344
- ```
345
-
346
- **What it checks:**
347
-
348
- *Anthropic tools*
349
- - **Claude Code** — `allowedTools` (shell bypass), MCP server configs, shell hooks
350
- - **Claude Desktop** — MCP server configs
351
-
352
- *Third-party AI tools* — MCP server configs audited with the same exfiltration, broad-filesystem, sensitive-path, and sprawl rules as Claude tools
353
- - **Cursor** — `~/.cursor/mcp.json`
354
- - **Windsurf** — `~/.codeium/windsurf/mcp_config.json`
355
- - **Continue.dev** — `~/.continue/config.json`
356
- - **Gemini CLI** — `~/.gemini/settings.json`
357
- - **VS Code** — `mcp.servers` in `settings.json` (MCP support added in VS Code 1.99)
358
-
359
- *Host security*
360
- - **Shell configs** — hardcoded AI API keys in `.zshrc`, `.bashrc`, `.zprofile`, etc.
361
- - **macOS TCC permissions** — Full Disk Access, Screen Recording, Accessibility granted to AI apps
362
- - **macOS system security** — SIP, FileVault, Gatekeeper status
363
- - **Exposed AI processes** — AI-related processes listening on non-localhost network interfaces
364
- - **Memory footprint** — Claude Code conversation memory size in `~/.claude/projects/`
365
-
366
- **Rules:**
367
-
368
- | Rule | Severity | Category | What it catches |
369
- |------|----------|----------|-----------------|
370
- | `HOST_SHELL_UNRESTRICTED` | CRITICAL | config | `Bash` in `allowedTools` — shell runs without confirmation prompt |
371
- | `HOST_SIP_DISABLED` | CRITICAL | system | macOS System Integrity Protection is off |
372
- | `HOST_API_KEY_IN_SHELL` | HIGH | data_exposure | AI API keys hardcoded in shell config files |
373
- | `HOST_MCP_EXFIL_PATH` | HIGH | config | Any AI tool's MCP server has both filesystem access and network capability |
374
- | `HOST_FDA_AI_APP` | HIGH | permissions | Full Disk Access granted to an AI app or its terminal |
375
- | `HOST_SCREEN_RECORDING_AI` | HIGH | permissions | Screen Recording permission granted to an AI app |
376
- | `HOST_AI_PROCESS_EXPOSED` | HIGH | network | AI-related process listening on a non-localhost interface |
377
- | `HOST_FILEVAULT_OFF` | HIGH | system | FileVault disk encryption is disabled |
378
- | `HOST_ACCESSIBILITY_AI` | MEDIUM | permissions | Accessibility permission granted to an AI app |
379
- | `HOST_HOOKS_SHELL` | MEDIUM | config | Claude Code shell hooks that could interpolate AI output |
380
- | `HOST_MCP_BROAD_FS` | MEDIUM | config | Any AI tool's MCP server configured with home-dir or root-level path |
381
- | `HOST_MCP_SENSITIVE_PATH` | MEDIUM | config | Any AI tool's MCP server has access to `~/.ssh`, `~/.aws`, `~/.kube`, or Keychain |
382
- | `HOST_MANY_MCP_SERVERS` | MEDIUM | config | 8+ MCP servers across all detected AI tools — large prompt injection attack surface |
383
- | `HOST_GATEKEEPER_OFF` | MEDIUM | system | Gatekeeper disabled — unsigned binaries run without warning |
384
- | `HOST_LARGE_MEMORY` | LOW | data_exposure | Claude Code memory files exceed 50 MB of accumulated conversation data |
385
-
386
- Every finding includes a **remediation** step. The posture score (0–100) uses the same deduction weights as other sentinel commands: CRITICAL −40, HIGH −20, MEDIUM −10, LOW −5.
387
-
388
- No API key required. No network calls.
389
-
390
- ---
391
-
392
- ### `sentinel redteam mcp` — active MCP server exploitation
393
-
394
- The active red-team module for MCP servers. Every finding is backed by confirmed evidence from the server's actual response — no heuristics, no noise. If a traversal finding says it read `/etc/passwd`, it read `/etc/passwd`.
395
-
396
- **`preauth` and OAuth probing run with zero credentials** — useful when the target server blocks unauthenticated MCP access entirely.
397
-
398
- Requires `httpx`: `pip install "agentsentinel-cli[mcp]"`
399
-
400
- ```bash
401
- # Full run — all 7 phases, unified report
402
- sentinel redteam mcp full http://localhost:8000
403
- sentinel redteam mcp full http://localhost:8000 --intensity high --format json
404
-
405
- # Targeted phases
406
- sentinel redteam mcp preauth http://localhost:8000 # HTTP fingerprint — zero creds required
407
- sentinel redteam mcp recon http://localhost:8000 # enumerate attack surface
408
- sentinel redteam mcp auth http://localhost:8000 # credential bypass + OAuth 2.0 attacks
409
- sentinel redteam mcp inject http://localhost:8000 # all injection techniques
410
- sentinel redteam mcp poison http://localhost:8000 # tool description + result injection
411
- sentinel redteam mcp fuzz http://localhost:8000 # schema and type boundary fuzzing
412
-
413
- # Preauth — works even when server blocks unauthenticated MCP
414
- sentinel redteam mcp preauth http://localhost:8000
415
- sentinel redteam mcp preauth http://locked-server:8000 # CORS, OAuth metadata, version disclosure
416
-
417
- # Surgical injection — pick your techniques
418
- sentinel redteam mcp inject http://localhost:8000 --type traverse
419
- sentinel redteam mcp inject http://localhost:8000 --type traverse --type ssrf
420
- sentinel redteam mcp inject http://localhost:8000 --type cmd --type sqli --intensity high
421
-
422
- # With auth
423
- sentinel redteam mcp full http://localhost:8000 \
424
- --auth-header "Authorization: Bearer token"
425
-
426
- # stdio transport (local MCP servers)
427
- sentinel redteam mcp full --stdio "python my_mcp_server.py"
428
-
429
- # CI gate — fail if any CRITICAL confirmed
430
- sentinel redteam mcp full http://localhost:8000 --fail-on CRITICAL
431
-
432
- # Save report
433
- sentinel redteam mcp full http://localhost:8000 --output report.json
434
- ```
435
-
436
- **Phases (`full` runs all 7):**
437
-
438
- | Phase | Command | Needs credentials | What it tests |
439
- |-------|---------|:-----------------:|---------------|
440
- | 1 — Pre-auth | `preauth` | No | CORS, OAuth metadata, version disclosure, unauthenticated paths, SSE stream, error disclosure |
441
- | 2 — OAuth | *(auto in `auth`/`full`)* | No | Public client registration, token without secret, PKCE downgrade, scope escalation, X-Agent-Scopes forgery |
442
- | 3 — Recon | `recon` | Yes | Tool inventory, resource listing, dangerous capability flags with input schemas |
443
- | 4 — Auth Bypass | `auth` | Optional | 5 credential scenarios: no creds, empty bearer, garbage token, invalid JWT, JWT alg:none |
444
- | 5 — Injection | `inject` | Yes | Path traversal, SSRF, command injection, SQL injection — evidence-confirmed only |
445
- | 6 — Poison | `poison` | Yes | Adversarial instructions in tool descriptions; LLM injection via tool parameters |
446
- | 7 — Fuzz | `fuzz` | Yes | Stack traces, path disclosure, template injection eval, type confusion, input reflection |
447
-
448
- **Pre-auth probes (zero credentials):**
449
-
450
- | Probe | CRITICAL | HIGH | MEDIUM |
451
- |-------|----------|------|--------|
452
- | CORS wildcard + credentials | ✓ | | |
453
- | CORS wildcard / reflected origin | | ✓ | |
454
- | Unauthenticated SSE stream | | ✓ | |
455
- | Public OAuth client registration | | ✓ | |
456
- | Token issued without `client_secret` | ✓ | | |
457
- | X-Agent-Scopes header forgery | ✓ | | |
458
- | PKCE `plain` method accepted | | | ✓ |
459
- | Server/framework version disclosure | | | ✓ |
460
- | Unauthenticated `/docs`, `/metrics` | | | ✓ |
461
-
462
- **Injection techniques (`--type`):**
463
-
464
- | Technique | What it confirms |
465
- |-----------|-----------------|
466
- | `traverse` | Arbitrary file read via path traversal — evidence: `/etc/passwd` content, `.env` keys |
467
- | `ssrf` | Server-side request forgery — evidence: AWS IMDS tokens, Redis/SSH banners, cloud metadata |
468
- | `cmd` | OS command injection — evidence: `uid=0(root)` from `id`, `REDTEAM_CMD_CONFIRMED` sentinel |
469
- | `sqli` | SQL injection — evidence: DB error messages (`ORA-`, `You have an error in your SQL syntax`) |
470
- | `llm` | LLM instruction injection via tool result — evidence: sentinel string echoed in clean response |
471
-
472
- **Intensity levels (`--intensity`):**
473
-
474
- | Level | Payloads per technique | Use case |
475
- |-------|----------------------|----------|
476
- | `low` | 5 | Fast CI gate |
477
- | `medium` | 15 | Standard engagement (default) |
478
- | `high` | Full library (~20) | Thorough pentest |
479
-
480
- **Finding severities:**
481
-
482
- | Severity | Example |
483
- |----------|---------|
484
- | CRITICAL | Path traversal confirmed — `/etc/passwd` content in response; OAuth token issued without secret |
485
- | HIGH | LLM instruction injection — sentinel reflected in clean tool result; CORS wildcard |
486
- | MEDIUM | Input reflected in error message; PKCE plain method accepted; version disclosure |
487
- | LOW | Unexpected content returned on malformed input |
488
- | INFO | Auth enforced on handshake, tool inventory, OAuth metadata discovered |
489
-
490
- Every finding includes a **Fix** line, a **MITRE ATLAS** ID, and an **OWASP ASI** ID. Confirmed multi-step attack chains are synthesized in the report. Use `--verbose` to see full request/response bodies.
491
-
492
- ---
493
-
494
497
  ## Finding suppression
495
498
 
496
499
  Use `--ignore-rule` to suppress findings by rule ID. Suppressed findings are excluded from `--fail-on` evaluation — they don't break CI gates.
@@ -521,10 +524,10 @@ Supported on: `sentinel scan`, `sentinel a2a`, `sentinel mcp scan`, `sentinel su
521
524
  | Agent Goal Hijack | ASI01 | `sentinel scan` (PROMPT_INJECTION_VECTOR), `sentinel supply-chain` (SC01), **`sentinel redteam mcp poison`** (confirmed injection) |
522
525
  | Tool Misuse & Exploitation | ASI02 | `sentinel mcp scan`, `sentinel scan`, **`sentinel redteam mcp inject`** (confirmed exploitation) |
523
526
  | Agent Identity & Privilege Abuse | ASI03 | `sentinel scan` (PRIVILEGE_EXCESS), `sentinel host-scan` (HOST_SHELL_UNRESTRICTED), **`sentinel redteam mcp auth`** (credential bypass + OAuth scope escalation + X-Agent-Scopes forgery) |
524
- | **Agentic Supply Chain Compromise** | **ASI04** | **`sentinel supply-chain`** (static + AI semantic analysis), **`sentinel redteam mcp poison`** (static description scan) |
527
+ | Agentic Supply Chain Compromise | ASI04 | **`sentinel supply-chain`** (static + AI semantic analysis), **`sentinel redteam mcp poison`** (static description scan) |
525
528
  | Unexpected Code Execution | ASI05 | `sentinel scan` (CODE_EXECUTION_GRANT), `sentinel mcp scan` (CODE_EXECUTION_TOOL), **`sentinel redteam mcp inject --type cmd`** |
526
- | **Memory & Context Poisoning** | **ASI06** | **`sentinel secrets`** (memory contamination, system prompt leakage), `sentinel host-scan` (HOST_LARGE_MEMORY), **`sentinel redteam mcp preauth`** (CORS misconfiguration enabling cross-origin data theft) |
527
- | **Insecure Inter-Agent Communication** | **ASI07** | **`sentinel a2a`** (call graph + trust rules) |
529
+ | Memory & Context Poisoning | ASI06 | **`sentinel secrets`** (memory contamination, system prompt leakage), `sentinel host-scan` (HOST_LARGE_MEMORY), **`sentinel redteam mcp preauth`** (CORS misconfiguration) |
530
+ | Insecure Inter-Agent Communication | ASI07 | **`sentinel a2a`** (call graph + trust rules) |
528
531
  | Cascading Agent Failures | ASI08 | `sentinel discover` (surface unmonitored agents) |
529
532
  | Rogue Agents | ASI10 | `sentinel discover` (find agents that shouldn't exist), `sentinel host-scan` (HOST_AI_PROCESS_EXPOSED) |
530
533
 
@@ -546,29 +549,29 @@ jobs:
546
549
  - name: Install sentinel
547
550
  run: pip install "agentsentinel-cli[mcp]"
548
551
 
549
- - name: Posture scan
550
- run: sentinel scan ./agents/ --fail-on CRITICAL
551
-
552
- - name: Secrets scan
553
- run: sentinel secrets . --fail-on HIGH
552
+ - name: Active red-team (zero credentials)
553
+ run: sentinel redteam mcp preauth http://localhost:8000 --fail-on HIGH
554
554
 
555
- - name: MCP supply chain audit
556
- run: sentinel supply-chain http://localhost:8000/sse --fail-on CRITICAL
555
+ - name: Active red-team (full exploitation check)
556
+ run: sentinel redteam mcp full http://localhost:8000 --fail-on CRITICAL
557
557
 
558
- - name: MCP security audit
559
- run: sentinel mcp scan http://localhost:8000/sse --fail-on CRITICAL
558
+ - name: Host AI security posture
559
+ run: sentinel host-scan --fail-on HIGH
560
560
 
561
561
  - name: Multi-agent trust analysis
562
562
  run: sentinel a2a ./agents/ --fail-on HIGH
563
563
 
564
- - name: Host AI security posture
565
- run: sentinel host-scan --fail-on HIGH
564
+ - name: MCP security audit
565
+ run: sentinel mcp scan http://localhost:8000/sse --fail-on CRITICAL
566
566
 
567
- - name: MCP pre-auth probe (zero credentials needed)
568
- run: sentinel redteam mcp preauth http://localhost:8000 --fail-on HIGH
567
+ - name: MCP supply chain audit
568
+ run: sentinel supply-chain http://localhost:8000/sse --fail-on CRITICAL
569
569
 
570
- - name: MCP red-team (active exploitation check)
571
- run: sentinel redteam mcp full http://localhost:8000 --fail-on CRITICAL
570
+ - name: Posture scan
571
+ run: sentinel scan ./agents/ --fail-on CRITICAL
572
+
573
+ - name: Secrets scan
574
+ run: sentinel secrets . --fail-on HIGH
572
575
  ```
573
576
 
574
577
  Use `.sentinelignore` at the repo root to suppress accepted risks without weakening the gate:
@@ -583,7 +586,7 @@ NO_AUTH # server is behind an authenticated reverse proxy
583
586
  ## Requirements
584
587
 
585
588
  - Python 3.10+
586
- - No API key required for: `sentinel discover`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel scan`, `sentinel secrets`, `sentinel inspect --no-ai`, `sentinel a2a`, `sentinel host-scan`, `sentinel redteam mcp`
589
+ - No API key required for: `sentinel redteam mcp`, `sentinel host-scan`, `sentinel a2a`, `sentinel discover`, `sentinel mcp scan`, `sentinel supply-chain`, `sentinel scan`, `sentinel secrets`, `sentinel inspect --no-ai`
587
590
  - `ANTHROPIC_API_KEY` required for: `sentinel supply-chain --ai`, `sentinel inspect` (AI summary)
588
591
 
589
592
  ---