A transparent, fail-open observability sidecar for Model Context Protocol (MCP).
Sentinel provides identity, ordering, and integrity guarantees for agent ↔ tool interactions - without modifying execution or coupling to agents.
Sentinel sits invisibly between an LLM client and its MCP tools, acting as a passive, non-blocking tap into live agent traffic. It does not alter requests. It does not gate execution. It does not impose policy.
Instead, Sentinel observes MCP traffic as it flows, reconstructs a canonical event stream, and exposes it to real-time visualization and durable audit logs.
The result:
You can finally see what your agent did, in what order, and trust the record afterward - even when the agent itself is a black box.
# 1. Install Sentinel
curl -fsSL https://raw.githubusercontent.com/EngramAI-io/sentinel/main/install.sh | sh
# 2. Run Sentinel in front of any MCP server
<your-mcp-client> sentinel run -- <your-mcp-server>
# For example:
node mcp_client.js sentinel run --audit-log test_audit.jsonl -- node mcp_server.js
# 3. Open the dashboard
# http://localhost:3000
⚠️ Project Status
Sentinel is under active development. Core architecture and guarantees are implemented, with ongoing work on hardening, UX polish, documentation, and extended verification tooling.
Early adopters and reviewers are encouraged to provide feedback.
Sentinel is:
- A transparent MCP sidecar
- A canonical event recorder
- A real-time observability layer
- A cryptographically verifiable audit tap
Sentinel is not:
- An execution engine
- A policy enforcer
- A tool broker
- A rate limiter
- A replay controller
Agents and tools continue to function exactly the same with or without Sentinel.
| Feature | Official MCP Inspector | Sentinel |
|---|---|---|
| Primary Use | Isolated tool testing | Observing a live agent using tools |
| Integration | Separate web UI | Transparent sidecar in your workflow |
| Ordering | Implicit / undefined | Canonical, monotonic event ordering |
| Correlation | Per-request only | Session, trace, and span continuity |
| Auditability | None | Append-only, signed, optional encrypted logs |
| Failure Mode | Stops visibility | Fail-open: execution continues |
LLM agents reason implicitly.
Tool calls happen asynchronously.
Failures often appear after the cause.
Traditional logging breaks down.
Sentinel exists to provide observability guarantees that agent systems implicitly rely on but rarely formalize.
With Sentinel, you get:
- A single, ordered history of agent activity
- Request → response correlation across tools
- Latency and error visibility by method
- Durable logs you can replay and verify later
- A real-time graph that makes causality visible
Think Chrome DevTools - but for agent toolchains.
Sentinel provides optional, non-invasive guarantees around agent interactions.
When enabled, these guarantees support debugging, auditing, and security analysis.
When absent, agents continue to function normally - but these properties are lost.
Guarantee:
Every observed agent action is causally attributable to a session and execution trace.
Sentinel provides:
- Stable
session_idandtrace_idfor the lifetime of a run - Per-request
span_idwith request ↔ response correlation - Consistent attribution across tools and errors
Without it:
Logs become fragmented and reasoning becomes opaque.
Guarantee:
There exists a single, consistent, replayable history of agent activity.
Sentinel provides:
- A monotonic, globally ordered event stream
- Append-only semantics
- Stable event IDs independent of wall-clock time
Key property:
Ordering is derived from observation at the Sentinel boundary, not timestamps.
Without it:
Events exist, but ordering is ambiguous and trust erodes.
Guarantee:
Observed agent behavior has not been tampered with after the fact.
Sentinel provides:
- Hash-chained, append-only audit records
- Ed25519 digital signatures
- Optional encryption at rest
- Offline verification tooling
Important:
Cryptography applies only to telemetry, never to execution.
| Property | Question Answered |
|---|---|
| Identity | Who did what? |
| Order | In what sequence? |
| Integrity | Can we trust the record? |
Together, these form the minimum foundation required for serious observability - without enforcing policy or constraining agents.
- Observe, never decide
- Record, never enforce
- Fail open, not closed
- Trust comes from visibility, not control
Drop Sentinel in front of any MCP server and instantly get deep visibility - no code changes, no rewrites, no patching.
Sentinel intercepts JSON-RPC traffic without buffering or mangling payloads. True pass-through with <1ms overhead.
Every tool call becomes a glowing edge.
Every response updates node stats.
Errors pulse red.
High-latency calls glow warm.
Sensitive fields are scrubbed only in observability outputs.
Original MCP traffic is never modified.
If the UI crashes or the WebSocket drops, your MCP pipeline continues unfazed.
One command patches Claude Desktop while preserving automatic backups.
Pattern: Transparent Sidecar (T-Tap)
Philosophy: Fail Open
Tech Stack: Rust (Tokio) • TypeScript • React • React Flow • WebSockets
┌──────────────┐
│ LLM Agent │
└──────┬───────┘
│
responses ▲ │ ▼ requests
│
MCP (JSON-RPC over stdio)
│
responses ▲ │ ▼ requests
│
┌──────────────────┐
│ Sentinel │ ← observe only (fail-open)
│ • parse MCP │
│ • order events │
│ • emit telemetry│
└──────┬───────────┘
│
responses ▲ │ ▼ requests
│
unchanged MCP stream
│
responses ▲ │ ▼ requests
│
┌──────────────────┐
│ MCP Server / │
│ Tools │
└──────────────────┘
- Zero-copy stdin/stdout MCP pass-through
- Canonical event sequencing
- Session / trace / span correlation
- WebSocket event bus
- Full JSON-RPC parsing
- Per-method latency & error metrics
- Interactive force-directed graph
- Panic recovery & safe shutdown
- NDJSON audit logs for tooling integration
Linux/macOS:
curl -fsSL https://raw.githubusercontent.com/EngramAI-io/sentinel/main/install.sh | shCustom install directory:
INSTALL_DIR=$HOME/.local/bin curl -fsSL https://raw.githubusercontent.com/EngramAI-io/sentinel/main/install.sh | shiwr https://raw.githubusercontent.com/EngramAI-io/sentinel/main/install.ps1 -UseBasicParsing | iexDownload the latest release for your platform:
After Download (Linux/macOS only):
chmod +x sentinel-*
sudo mv sentinel-* /usr/local/bin/sentinelOnce Sentinel is installed, see the full usage guide for:
- Running Sentinel with MCP servers
- WebSocket authentication
- Audit logging & encryption
- Claude Desktop integration
- Common deployment patterns
- Troubleshooting
👉 Read the full guide:
📄 docs/USAGE.md
On Windows:
- Download and run the Rust installer by following the instructions at https://www.rust-lang.org/tools/install
- Follow the installation prompts (defaults are recommended)
- Restart your terminal/PowerShell after installation
- Verify installation:
You should see versions like
rustc --version cargo --version
rustc 1.70.0or higher, andcargo 1.70.0or higher. - If you're a Windows Subsystem for Linux (WSL) user, run the following in your terminal, then follow the on-screen instructions to install Rust.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shOn macOS:
# Install using Homebrew
brew install rust
# Or use rustup (recommended)
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
# Verify installation
rustc --version
cargo --versionOn Linux:
# Install using rustup (recommended)
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env
# Verify installation
rustc --version
cargo --versionOn Windows:
- Download Node.js from https://nodejs.org/
- Choose the LTS version (18.x or higher recommended)
- Run the installer and follow the prompts
- Verify installation:
You should see
node --version npm --version
v18.x.xor higher for Node.js, and9.x.xor higher for npm.
On macOS:
# Using Homebrew
brew install node
# Verify installation
node --version
npm --versionOn Linux:
# Install nvm (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
# Install Node.js using nvm
nvm install node
# Verify installation
node --version
npm --version# If you haven't already cloned the repository
git clone https://github.com/EngramAI-io/sentinel.git
cd sentinel
# Or if you're already in the project directory, verify you're in the right place
# You should see Cargo.toml and a frontend/ directory-
Navigate to the frontend directory:
cd frontend/my-react-flow-app -
Install frontend dependencies:
npm install
This will download and install all required packages (React, React Flow, Vite, TypeScript, etc.)
-
Build the frontend for production:
npm run build
This compiles TypeScript, bundles the React app, and outputs to
frontend/dist/directory. -
Return to the project root:
cd ..
-
Build the release version (optimized):
cargo build --release
Note: The first build may take 5-10 minutes as it compiles all dependencies. Subsequent builds will be much faster.
-
Verify the binary was created:
- Windows:
target\release\sentinel.exe - macOS/Linux:
target/release/sentinel
- Windows:
-
(Optional) Test that the binary runs:
# Windows .\target\release\sentinel.exe --help # macOS/Linux ./target/release/sentinel --help
-
In one terminal, run the sentinel proxy with an MCP server:
cargo run -- run -- npx -y @modelcontextprotocol/server-filesystem
This will:
- Start the sentinel proxy
- Launch the MCP filesystem server
- Start the HTTP/WebSocket server on port 3000
-
Open your browser and navigate to:
http://localhost:3000 -
You should see the dashboard with:
- A force-directed graph visualization
- An "Agent" node in the center
- Tool nodes appearing as MCP requests are made
-
To test with a different MCP server:
# SQLite server example cargo run -- run -- npx -y @modelcontextprotocol/server-sqlite path/to/database.db # Custom Python server example cargo run -- run -- python -m my_mcp_server
-
Use the release binary you built:
# Windows .\target\release\sentinel.exe run -- npx -y @modelcontextprotocol/server-filesystem # macOS/Linux ./target/release/sentinel run -- npx -y @modelcontextprotocol/server-filesystem
-
Open http://localhost:3000 in your browser
- Check the dashboard loads: You should see the visualization interface
- Check WebSocket connection: The graph should be interactive
- Check logs: Look for
sentinel_debug.jsonlin the project directory for debug logs - Test interactivity: Click on nodes to see detailed JSON-RPC payloads
Issue: cargo: command not found
- Solution: Restart your terminal after installing Rust, or manually add
~/.cargo/binto your PATH
Issue: npm: command not found
- Solution: Restart your terminal after installing Node.js, or verify Node.js is in your PATH
Issue: Frontend build fails
- Solution: Make sure you're in the
frontend/directory and runnpm installfirst
Issue: Port 3000 already in use
- Solution: Kill the process using port 3000, or modify the port in the code
Issue: cargo build fails with linker errors (Windows)
- Solution: Install Microsoft C++ Build Tools from https://visualstudio.microsoft.com/visual-cpp-build-tools/
Issue: Binary not found after build
- Solution: Check that the build completed successfully. Look for
target/release/sentinel(or.exeon Windows)
# Install sentinel for a specific MCP server
./target/release/sentinel install filesystem
# The config is automatically updated and backed up
# Your Claude Desktop will now use sentinel as a proxyTo restore the original config:
# Config backup is at: ~/.config/claude-desktop/claude_desktop_config.json.backup (Unix)
# or %APPDATA%/Claude/claude_desktop_config.json.backup (Windows)sentinel/
├── src/
│ ├── audit.rs # Audit log writer and lifecycle management
│ ├── audit_crypto.rs # Signing, hashing, and encryption logic for tamper-evident logs
│ ├── config.rs # Claude Desktop config helper
│ ├── decrypt_audit_log.rs # Signing, hashing, and encryption logic for tamper-evident logs
│ ├── events.rs # Event logging structures
│ ├── keygen.rs # Offline audit log verification and decryption
│ ├── main.rs # CLI and orchestration
│ ├── panic.rs # Panic recovery
│ ├── proxy.rs # Zero-copy stdio proxy
│ ├── protocol.rs # JSON-RPC structures
│ ├── parser.rs # NDJSON streaming parser
│ ├── session.rs # Request/response correlation
│ ├── server.rs # HTTP/WebSocket server
│ └── redaction.rs # PII redaction
└── frontend/ # React dashboard
└── src/
├── App.tsx
├── components/
│ ├── Graph.tsx
│ └── NodeDetails.tsx
└── hooks/
└── useWebSocket.ts
cd frontend
npm install
npm run devThis runs the frontend in dev mode (not embedded). To connect to a running sentinel instance, update the WebSocket URL in src/hooks/useWebSocket.ts.
cd frontend
npm run build
# Output goes to frontend/dist/ which gets embedded into the binary# Development (no auth)
cargo run -- run -- npx -y @modelcontextprotocol/server-filesystem
# Production (with auth)
cargo run -- run --ws-token "secret123" --ws-bind "127.0.0.1:3000" -- npx -y @modelcontextprotocol/server-filesystemcargo run -- run --ws-token "$SENTINEL_WS_TOKEN" -- npx -y @modelcontextprotocol/server-sqlite path/to/database.db# First generate keys
cargo run -- keygen --out-dir ./keys
cargo run -- recipient-keygen --out-dir ./keys
# Run with full audit logging and encryption
cargo run -- run \
--signing-key-b64-path ./keys/signing_key.b64 \
--encrypt-recipient-pubkey-b64-path ./keys/recipient_pub.b64 \
--audit-log ./audit.jsonl \
--ws-token "secret123" \
-- python -m my_mcp_serverThe dashboard visualizes:
- Agent Node (center): The LLM client
- Tool Nodes (satellites): MCP servers and their methods
- Edges: Active communication paths
- Colors:
- Yellow = Pending request
- Green = Successful response
- Red = Error response
Click on any node to see detailed JSON-RPC payloads.
- Audit logs written to
sentinel_audit.jsonl(configurable via--audit-log) - Panic logs go to
sentinel_panic.log - Config backups are created automatically with
.backupextension - Console output shows:
- ✅ Success indicators (green checkmarks)
- ❌ Error indicators (red X marks)
- 🔒 Security status (lock icons)
⚠️ Warnings (warning triangles)- 📝 Checkpoints and audit events
Sentinel is designed with security-first principles:
- WebSocket Token Authentication: Protect your observability endpoint with token-based auth
- Environment Variable Support: Set
SENTINEL_WS_TOKENto avoid exposing tokens in command history - Automatic Warning: Sentinel warns when running without authentication in production
# Secure mode (recommended)
./sentinel run --ws-token "your-secret-token-here" -- npx @modelcontextprotocol/server-filesystem
# Using environment variable (recommended for production)
export SENTINEL_WS_TOKEN="your-secret-token-here"
./sentinel run -- npx @modelcontextprotocol/server-filesystem
# Connect from browser/client
ws://localhost:3000/ws?token=your-secret-token-here- Custom Bind Address: Control where the WebSocket server listens
- Production-Ready: Bind to specific interfaces or use Unix sockets
# Localhost only (default - most secure)
./sentinel run --ws-bind "127.0.0.1:3000" -- your-mcp-server
# All interfaces (use with authentication!)
./sentinel run --ws-bind "0.0.0.0:3000" --ws-token "secret" -- your-mcp-server
# Custom port
./sentinel run --ws-bind "127.0.0.1:8080" -- your-mcp-server- API keys, tokens, emails automatically scrubbed before visualization
- Original MCP traffic is never modified - redaction only applies to observability data
- Regex-based detection with multiple pattern types:
api_key,apikey,access_token,secret_key- OpenAI-style
sk-*keys - Email addresses
- Bearer tokens
- Ed25519 Digital Signatures: Every checkpoint is cryptographically signed
- ChaCha20-Poly1305 Encryption: Optional end-to-end encryption for audit logs
- Tamper-Evident Chains: Hash-chained events prevent retroactive modification
- Verifiable Logs: Independent verification with
sentinel verifycommand
# Generate signing keypair
./sentinel keygen --out-dir ./keys
# Generate encryption keypair (optional)
./sentinel recipient-keygen --out-dir ./keys
# Run with audit logging
./sentinel run \
--signing-key-b64-path ./keys/signing_key.b64 \
--encrypt-recipient-pubkey-b64-path ./keys/recipient_pub.b64 \
--audit-log ./audit.jsonl \
-- your-mcp-server
# Verify audit log integrity
./sentinel verify \
--log ./audit.jsonl \
--pubkey-b64-path ./keys/signing_pubkey.b64 \
--decrypt-recipient-privkey-b64-path ./keys/recipient_priv.b64- Signal Handling: CTRL+C triggers graceful shutdown
- Flush Guarantees: All audit logs are flushed to disk before exit
- Timeout Protection: 10-second timeout prevents hanging on shutdown
- No Data Loss: Event buffers are drained completely
- Pinned Versions: All dependencies use specific versions (no wildcards)
- Latest Security Patches: tokio-tungstenite 0.24 with all CVEs patched
- Memory Safety: Pure Rust implementation with zero
unsafeblocks - Crypto Libraries: RustCrypto audited implementations
- Detailed Logging: Comprehensive error information for debugging
- User-Friendly Messages: Generic error messages prevent information disclosure
- Fail-Open Proxy: MCP traffic continues even if observability fails
- Panic Recovery: Custom panic handler prevents crashes from affecting MCP pipeline
- Always use authentication in production environments
- Bind to localhost unless you need remote access
- Enable audit log encryption for sensitive environments
- Rotate keys periodically using the keygen commands
- Monitor logs for unauthorized access attempts
- Keep Sentinel updated to get latest security patches
Found a security issue? Please email security@engramai.io (or your contact) instead of opening a public issue.
- Config backups are created automatically before any modifications
- Backup location:
- Linux/macOS:
~/.config/claude-desktop/claude_desktop_config.json.backup - Windows:
%APPDATA%\Claude\claude_desktop_config.json.backup
- Linux/macOS:
MIT
