MCP-Sentinel
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Fail
- Hardcoded secret — Potential hardcoded credential in .github/workflows/ci.yml
- rm -rf — Recursive force deletion command in .github/workflows/docs.yml
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
PortunusMCP Sentinel: build-time security scanning for MCP servers.
PortunusMCP Sentinel
Build-time security scanning for MCP servers.
PortunusMCP Sentinel scans local MCP server source before deployment. It combines
deterministic Python and TypeScript analysis, GPT-5.6 semantic review, optional
Docker-isolated runtime probes, OWASP Agentic Top 10 mappings, and validated
SARIF output for GitHub code scanning.
Install
Sentinel supports Python 3.10–3.13 on Linux, macOS, and Windows. Install the
current package with pipx:
pipx install portunusmcp-sentinel
Or use uv:
uv tool install portunusmcp-sentinel
Rules-only commands below require 1.3.0 or newer. Upgrade an existing install
with pipx upgrade portunusmcp-sentinel or uv tool upgrade portunusmcp-sentinel.
Reports expose observed handlers and recognition gaps, actual rule visits,
per-session runtime catalogs and sent attacks, and separate static/dynamic review
activity. Default findings include bounded evidence and repair guidance. Static
surface totals remain unknown; zero findings are not proof of safety. See the
coverage and schema compatibility guide.
TypeScript recognition stays bounded to supported high-level APIs: imported
handlers/schemas, computed registrations, and unsupported forms remain gaps.
Permission sidecars express intended grants; they do not enforce runtime
boundaries. Dynamic probing still makes four fixed attempts, not a campaign
against every discovered tool and field.
Quickstart
From a local Python or TypeScript MCP server repository:
sentinel scan . --rules-only
Rules-only needs no model credentials, review cache, network, Docker, target
configuration, or target execution. It ignores inactive LLM settings even when
credentials and endpoint overrides are present. Installation and dependency
auditing need network access separately.
Optionally run sentinel init afterward to generate a deny-by-defaultsentinel.permissions.yaml; review scopes before granting them. It never imports
or executes source and needs no main guard or launch inference. Existing files
require --force for replacement; symlinks are rejected.
For Python runtime scaffolding, run sentinel init --dynamic, thensentinel scan . --no-rules-only. Adding missing runtime configuration preserves
and validates an existing permissions file. Dynamic scans require Docker,
model credentials, source-context transmission, and model cost; dependency
installation also needs network access. TypeScript does not support --dynamic.
Exit 0 and exit 1 both mean the scan completed: 0 means no finding reached
the configured threshold, while 1 means at least one did. Exit 2 is a target
or configuration error; exit 3 means analysis was incomplete.
Analysis tiers
| Tier | Command | Requirements | Result |
|---|---|---|---|
| Rules-only | sentinel scan . --rules-only |
None beyond Sentinel | Deterministic findings remain needs_review and fail-on eligible |
| Static + GPT review | sentinel scan . --static-only |
OPENAI_API_KEY |
GPT reviews every selected deterministic candidate |
| Full dynamic proof | sentinel scan . |
OPENAI_API_KEY, Docker, and a Python target |
GPT review plus four isolated runtime probes |
--allow-degraded permits unavailable review; it still calls the model when a
key is available. Use --rules-only to disable review explicitly. Completion
describes the selected analysis tier and does not prove a server is secure.
TypeScript support is static-only and covers .ts, .mts, and .cts sources
using the official MCP SDK v1 and server v2 shapes. JavaScript, TSX, declaration
files, workspaces, cross-file dataflow, imported handlers or schemas, and Node
execution are outside the supported boundary. Dynamic targets are local Python
3.10–3.12 MCP servers.
Version 1.3.0 includes Phase 16 static-correctness changes: same-file
named-helper execution flows and value-specific validation, authentication,
integrity, and configured-sanitizer checks. Unsupported flows remain unresolved;
see the rule boundaries and
verification record.
Phase 17 source changes add validated dynamic baselines, explicit probe outcomes,
and proof-preserving review in native JSON 1.6.0. The current replay bundle uses
one approved runtime-review refresh and four unchanged static captures. See the
Phase 17 verification record for gates and acceptance status.
Rules
Every finding uses a stable rule ID and maps to the OWASP Agentic Top 10.
| Rule | Detection | OWASP | Impact |
|---|---|---|---|
| SENT-001 | Overly broad tool permission scope | ASI03:2026 | High |
| SENT-002 | Tool input reaches unsafe execution | ASI05:2026 | Critical |
| SENT-003 | Missing tool input validation | ASI02:2026 | Medium |
| SENT-004 | Unsanitized tool content enters a prompt | ASI01:2026 | High |
| SENT-005 | Hardcoded credential | ASI03:2026 | Critical |
| SENT-006 | Missing or ineffective route authentication | ASI03:2026 | High |
| SENT-007 | Unverified tool manifest | ASI04:2026 | Medium |
| SENT-008 | Out-of-scope tool execution | ASI02:2026 | Critical |
| SENT-009 | Size-limit breach or observed OOM/crash | ASI05:2026 | Medium |
| SENT-010 | Injection payload executed | ASI05:2026 | Critical |
| SENT-011 | Malformed schema input processed | ASI02:2026 | Low |
Published IDs are compatibility contracts: an ID is never renumbered or reused
for a different detection. The rule catalog documents each
engine, boundary, false-positive risk, evidence, and remediation.
GitHub Action
The Marketplace Action runs the full Python pipeline, validates SARIF before
upload, and preserves Sentinel's exit contract.
name: PortunusMCP Sentinel
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
sentinel:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- id: sentinel
uses: BashaarJavaid/MCP-Sentinel@v1
with:
target-path: .
fail-on: high
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
The Action exposes sarif-path, findings-count, and highest-severity.
Forked pull requests, where secrets are withheld, run visibly degraded analysis
and skip upload. High-assurance consumers can replace @v1 with the immutable
commit SHA for the selected release.
Architecture
flowchart LR
A[Untrusted MCP repository] --> B[AST + Semgrep rules]
B --> C[Canonical candidates]
C --> D[GPT-5.6 semantic review]
D --> E[Constrained four-probe plan]
E --> F[Docker sandbox]
F --> G[Reviewed dynamic evidence]
D --> H[Deduplication + provenance merge]
G --> H
H --> I[Console]
H --> J[JSON 1.6.0]
H --> K[SARIF 2.1.0]
K --> L[GitHub code scanning]
Static analysis never imports or executes target code. GPT receives bounded,
redacted context and can only review existing candidates or order four permanent
inert probes. Dynamic analysis mounts local Python source read-only in fresh
containers with no runtime network, resource limits, and forced cleanup. All
stages feed one canonical Finding model consumed by console, JSON, and SARIF.
PortunusMCP Sentinel is the build-time plane of the PortunusMCP family. The
PortunusMCP Gateway provides
runtime enforcement in a separate repository, while PortunusMCP Identity is the
separate short-lived credential-broker plane. Neither is required by Sentinel.
Configuration and adoption
Configuration precedence is CLI → SENTINEL_* environment → target-rootsentinel.toml → built-in defaults. A normal full scan also requiressentinel.target.yaml and sentinel.permissions.yaml; --static-only does not
require launch configuration.
Create a baseline from a complete native JSON report, then compare later scans:
sentinel scan . --allow-degraded --format json --output sentinel-baseline.json
sentinel scan . --allow-degraded --baseline sentinel-baseline.json
Matched findings remain visible but do not affect --fail-on. Sentinel never
updates a baseline automatically.
Suppress a reviewed static source finding with a reason-bearing directive:
# sentinel: ignore[SENT-005] reason=test credential is inert and rotated
api_key = "ghp_example"
Only static SENT-001–SENT-007 findings can be suppressed. Applied
suppressions remain visible in every report; malformed, duplicate, unknown-rule,
or reasonless directives fail configuration validation.
Use Sentinel from pre-commit:
repos:
- repo: https://github.com/BashaarJavaid/MCP-Sentinel
rev: v1.3.0
hooks:
- id: mcp-sentinel
See the configuration guide
for LLM endpoint trust, rule selection, baselines, suppressions, and pre-commit.
CLI and report reference
# Full static, GPT, and Docker analysis
sentinel scan ./path/to/server
# Static analysis with required GPT review
sentinel scan ./path/to/server --static-only
# Validated SARIF
sentinel scan ./path/to/server --format sarif --output results.sarif
# Select rules and change the failure threshold
sentinel scan ./path/to/server --rules SENT-001,SENT-005 --fail-on critical
# Exercise the packaged reference pipeline
sentinel demo --replay-review --verbose
--fail-on accepts critical, high, medium, low, or informational.
Console output is the default; --format json and --format sarif are stable
machine-readable paths. Validate reports offline with:
python -m sentinel.schema check
python -m sentinel.report.validate_sarif results.sarif
The production reviewer uses GPT-5.6 Sol through the Responses API withstore: false, medium reasoning effort, strict Structured Outputs, bounded
context, and host-validated evidence. Sentinel's public OpenAI cost calculation
uses the rates recorded on 2026-09-04: $4/M input, $0.40/M cached input, and
$20/M output, with cache writes at 1.25× input. See the official
GPT-5.6 Sol model and pricing page
and Responses API create reference.
Compatible endpoints retain token usage but report pricing as unavailable.
Project resources
- Scan a real MCP server before release
- Marketplace Action
- Documentation
- Architecture contract
- Roadmap
- Contributing
- SARIF guide
- Changelog
- Security policy
- Project history
PortunusMCP Sentinel is MIT licensed. Dependency licenses and packaged notices
are recorded in THIRD_PARTY_NOTICES.md.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found