Skip to main content
Glama

strands-sentinel

Autonomous mission-critical systems and AST safety auditor built with the Strands Agents SDK and the Model Context Protocol (MCP). Built for the AWS "Agents for Humans Hackathon" ($40,000 prize pool, Devpost).

strands-sentinel wires a Strands Agent to five deterministic audit tools (AST safety invariants, secret scanning, sandboxed test execution, and remediation guidance) behind an InterventionHandler that requires human confirmation before any remediation action runs. Every finding traces back to a real AST node, regex match, or subprocess result -- nothing is inferred by the model and reported as fact.

Architecture

flowchart TD
    CLI["cli.py<br/>check / watch / mcp"] --> Agent
    MCP["mcp_server.py<br/>MCPServer (mcp&gt;=2.1.0)"] --> Tools
    Agent["agent.py<br/>strands.Agent"] --> Router["Model Router<br/>Bedrock / Anthropic / OpenAI / Gemini / Ollama"]
    Agent --> Tools
    Agent --> Intervention["intervention.py<br/>SentinelInterventionHandler"]
    Tools["Five @tool functions"] --> Invariants["invariants.py<br/>AST/tokenizer engine"]
    Tools --> Secrets["secret_scanner.py<br/>regex + Shannon entropy"]
    Tools --> TestRunner["test_runner.py<br/>bounded subprocess"]
    Intervention -->|Proceed| Tools
    Intervention -->|Confirm| Human["Human approval"]
    Script["scripts/audit_safety_invariants.py"] -.self-audits.-> Invariants

Related MCP server: GitHub Security Agent MCP

Quickstart

uv venv .venv --python python3.12
uv pip install --python .venv/bin/python3 -e ".[dev]"

# One-shot audit of a path, prints a Rich report, exits 1 on any CRITICAL finding
.venv/bin/strands-sentinel check src/strands_sentinel

# Re-audit on every .py file change (bounded via --max-iterations for CI/tests)
.venv/bin/strands-sentinel watch src/strands_sentinel --interval 2

# Run as an MCP server over stdio (Claude Code CLI, Antigravity, Bedrock AgentCore)
.venv/bin/strands-sentinel mcp

Model provider is selected by STRANDS_SENTINEL_MODEL_PROVIDER, or inferred from ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY / OLLAMA_HOST, defaulting to Bedrock (the only provider whose client library -- boto3 -- ships as a strands-agents transitive dependency and is therefore the only one exercised end to end by this test suite; the other four fail fast with an actionable install message when their client library is missing, rather than shipping an untested code path).

What it checks

  • AST safety invariants (invariants.py), a practical subset of Gerard J. Holzmann's Power of 10 rules: function length (<=60 lines), assertion density (>=2 assert per function), bounded loops (while True without a statically reachable break is CRITICAL, with a break is WARNING since runtime boundedness still isn't provable), mutable default arguments, and banned dynamic-execution/deserialization calls (eval, exec, os.system, pickle.load(s), yaml.load). Python is handled by full ast analysis; Rust/TypeScript/JavaScript/Go/C/C++ get a brace-counting length heuristic.

  • Secrets (secret_scanner.py): deterministic regex matches (AWS access keys, GitHub PATs, EVM private keys, 12/24-word mnemonic-shaped phrases) reported at CRITICAL, plus a Shannon-entropy (H >= 3.8) catch-all for everything else reported at WARNING. Findings are always redacted (AKIA****...**OP) before leaving the scanner -- raw secret values are never returned, printed, or logged.

  • Tests: test_runner.py auto-detects cargo test, pytest, or make test from repository markers and runs the resolved command as a bounded subprocess (a real list[str] argv, never a shell string, so there is no command-injection surface), extracting structured per-test failures. The parsers are verified against real pytest -q and cargo test output captured in this environment, not an assumed format.

Intervention policy

SentinelInterventionHandler overrides before_tool_call: the four read-only audit tools always Proceed(); generate_remediation_patch (or any tool call made while a CRITICAL finding is outstanding) requires Confirm(prompt=...) -- human approval before anything that could act on a finding. Confirm takes a prompt field, not message; this is the one place this build corrected a wrong field name that had been assumed rather than verified against the installed SDK.

Quality gate

make lint             # ruff check + mypy --strict, 0 errors
make audit-invariants  # this repo's own scripts/audit_safety_invariants.py, 0 violations
make test              # pytest, 100% pass rate
make demo              # runs the CLI against this package's own src/

Measured on this repository (macOS arm64, Python 3.12.13, in .venv):

Check

Result

Tests

85 passed; 0.87-5.20s wall clock across repeated runs (no fixed number quoted -- see below)

ruff check .

0 errors, 0 warnings (note: ruff has no --strict flag; check plus the [tool.ruff.lint] selection in pyproject.toml is the strictness knob)

mypy --strict src/ scripts/

0 errors across 9 source files

scripts/audit_safety_invariants.py

0 violations (src/ + scripts/, self-inclusive, 9 files)

Invariant scan, src/ only (8 files, 1229 lines)

13.6 ms, 0 violations

Secret scan, same 8 files

2.6 ms, 0 CRITICAL, 7 WARNING (long identifier names crossing the entropy threshold -- the documented false-positive surface of the entropy tier, not the deterministic one)

Repeated pytest runs measured: 1.91s, 5.16s, 5.20s, 1.10s, 0.87s, 0.88s (same machine, no code changes between runs) -- quoted as a range rather than a single number since the variance itself is real and worth being honest about.

Repository layout

src/strands_sentinel/
  invariants.py       AST/tokenizer Power of 10 engine
  secret_scanner.py   regex + entropy secret detection
  test_runner.py      bounded pytest/cargo/make executor
  intervention.py     SentinelInterventionHandler
  agent.py            tools + resilient model router + Agent factory
  mcp_server.py       MCPServer (mcp>=2.1.0) exposing the five tools
  cli.py              check / watch / mcp subcommands
scripts/audit_safety_invariants.py   standalone self-audit entry point
tests/                85 tests across 7 files

Non-negotiable invariants

  • Every function in src/ has <=60 lines and >=2 assert statements, enforced by scripts/audit_safety_invariants.py against its own source.

  • No emojis anywhere in source, docstrings, CLI output, or commit history.

  • Commits are authored as Ishant5436 <ishant.p@somaiya.edu>.

Available Tools

5 tools
sentinel_audit_workspaceA

Run the full sentinel sweep (AST invariants and secret scan) over a workspace path.

Inputs: path (required). Returns: object

sentinel_check_ast_invariantsB

Scan a file or directory for Power of 10 AST safety invariant violations.

Inputs: path (required). Returns: object

sentinel_generate_remediation_patchA

Return structured remediation guidance for a violation previously reported by an audit tool.

Inputs: violation_id (required). Returns: object

sentinel_run_test_suiteB

Run the test suite for a repository. Pass command="" to auto-detect pytest/cargo test/make test.

Inputs: path (required), command (required). Returns: object

sentinel_scan_for_secretsB

Scan a file or directory for hardcoded secrets using deterministic patterns and entropy.

Inputs: path (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 5 tools

    Disambiguation4/5

    The tools are mostly distinct, but sentinel_audit_workspace overlaps with sentinel_check_ast_invariants and sentinel_scan_for_secrets since it runs both checks in one sweep. The descriptions clarify that the audit tool is a combined execution, but an agent might be unsure whether to call the aggregate or individual scanners.

    Naming Consistency5/5

    All tool names follow the consistent pattern sentinel_<verb>_<noun> (audit_workspace, check_ast_invariants, scan_for_secrets, run_test_suite, generate_remediation_patch). The verbs are clear and snake_case is used uniformly.

    Tool Count5/5

    Five tools is well-scoped for a security/quality sentinel server. Each tool covers a distinct operation without bloat, and the count feels appropriate for the stated purpose.

    Completeness4/5

    The surface covers auditing, AST invariant checks, secret scanning, test execution, and remediation guidance. A minor gap is the lack of a dedicated tool to list or query prior violations (though audit results presumably include them), and remediation only provides guidance rather than applying fixes.

    Maintenance

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Enables policy-first defensive security operations for MCP, providing repository and web-security analysis with controlled authorization, scoped execution, and auditability.
      9
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables MCP clients to scan codebases, persist and prioritize security findings against SLAs, retrieve CVE details, propose fixes, and create tickets through its tools. It also supports agent-assisted remediation drafting while enforcing human approval and preventing auto-merge.
      1
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables MCP clients to audit repositories across nine post-code DevSecOps stages, apply verified fixes under assisted, supervised, or hands-off autonomy, ship releases, and produce carbon and receipt outputs.
      MIT