MCP Shield Runtime
by samsgates
README.md
# MCP Shield Runtime
**Control every MCP tool call before it executes.**
MCP Shield Runtime is a local-first security gateway for Model Context Protocol clients and servers. It provides parameter-level policies, tool visibility filtering, approval gates, emergency deny rules, secret redaction, tool-contract drift detection, rate limiting, and tamper-evident audit records.
> Project status: production-oriented preview. The core gateway and controls are working and tested, but the project has not yet completed an independent security audit. Use staged rollout and least-privilege upstream credentials for production environments.
## Why this project exists
An allowlist that says an agent may use `read_file` or `send_email` is not enough. Security decisions must consider the concrete path, recipient, repository, branch, URL, command, environment, identity, detected data, and prior approval.
```text
AI client
|
v
MCP Shield Runtime
| policy, approval, DLP, contract lock, audit
v
MCP server
```
### Architecture

## How it works

## Features
- Stdio proxy for local MCP servers
- Streamable HTTP reverse proxy
- MCP 2026 routing-header validation and generation
- Client-independent parameter-level policy decisions
- Built-in emergency blocks for secret paths, private metadata URLs, and destructive commands
- Human approval with retry grants
- Tool discovery filtering
- Tool schema and description lockfile
- Response secret redaction
- Tamper-evident hash-chained audit log with optional HMAC signatures
- Per-user, per-server, per-tool token-bucket rate limiting
- Local dashboard and approval queue
- Zero runtime npm dependencies
- Docker hardening example
- Node built-in test suite and CodeQL workflow
## Requirements
- Node.js 22 or newer
- An existing MCP server
- JSON policy and configuration files
## Quick start
```bash
git clone https://github.com/your-org/mcp-shield-runtime.git
cd mcp-shield-runtime
npm install
npm run check
node src/cli.js init --dir .mcp-shield
```
### Protect a local stdio server
```bash
node src/cli.js run \
--config .mcp-shield/config.json \
-- node examples/risky-demo-server.js
```
Example MCP client configuration:
```json
{
"mcpServers": {
"protected-demo": {
"command": "node",
"args": [
"/absolute/path/mcp-shield-runtime/src/cli.js",
"run",
"--config",
"/absolute/path/mcp-shield-runtime/.mcp-shield/config.json",
"--",
"node",
"/absolute/path/mcp-shield-runtime/examples/risky-demo-server.js"
]
}
}
}
```
### Protect a remote Streamable HTTP server
```bash
node src/cli.js gateway \
--config config/default.config.json \
--upstream https://upstream.example.com/mcp
```
Point the MCP client to `http://127.0.0.1:7777/mcp`. The local dashboard is at `http://127.0.0.1:7777/`.
## Approval flow
When a call requires approval, the gateway returns JSON-RPC error `-32070` with an approval ID.
```bash
node src/cli.js approvals list --config .mcp-shield/config.json
node src/cli.js approvals approve apr_ID \
--config .mcp-shield/config.json \
--ttl 300
```
Retry the identical tool call. The approval is scoped to the request fingerprint and expiration.
## Example policy
```json
{
"version": 1,
"defaults": { "decision": "deny" },
"rules": [
{
"id": "allow-repository-read",
"priority": 100,
"match": {
"methods": ["tools/call"],
"tools": ["read_file"],
"arguments": {
"path": {
"within": ["${workspace}"],
"exclude": ["**/.env", "**/.ssh/**", "**/*.pem"]
}
}
},
"effect": { "decision": "allow" }
},
{
"id": "approve-write",
"priority": 90,
"match": {
"methods": ["tools/call"],
"tools": ["write_file", "push_files"]
},
"effect": {
"decision": "require_approval",
"approvalTtlSeconds": 300
}
}
]
}
```
See [Policy reference](docs/POLICY_REFERENCE.md).
## Security model
The gateway enforces what it can observe at the MCP boundary. A protocol proxy cannot fully constrain a local server process after launch. Strong filesystem and network isolation requires a container, operating-system sandbox, or workload boundary.
Important deployment rules:
1. Keep upstream credentials least-privileged.
2. Bind the dashboard to localhost unless an API token and TLS termination are configured.
3. Enable HMAC audit signing.
4. Use a container or operating-system sandbox for untrusted local servers.
5. Set `allowSseWithoutInspection` to `false` for tools requiring response DLP.
6. Pin upstream package and container versions.
7. Review tool-contract changes before enabling `blockSchemaDrift`.
Read [SECURITY.md](SECURITY.md) and [Threat model](docs/THREAT_MODEL.md).
## Commands
```text
mcp-shield init
mcp-shield gateway
mcp-shield run -- COMMAND
mcp-shield policy test
mcp-shield approvals list|approve|deny
mcp-shield audit list|verify
mcp-shield contracts list|approve
mcp-shield scan
mcp-shield doctor
```
## Protocol compatibility
The proxy is protocol-neutral for JSON-RPC messages and can forward legacy and modern MCP traffic. The HTTP gateway validates or generates modern `Mcp-Method` and `Mcp-Name` routing headers. Stateful legacy HTTP servers may require upstream session handling specific to their deployment.
The project intentionally keeps policy logic separate from the official MCP SDK. SDK-backed client and server adapters can be added without moving the trusted policy core.
## Documentation
- [Architecture](docs/ARCHITECTURE.md)
- [Policy reference](docs/POLICY_REFERENCE.md)
- [Deployment guide](docs/DEPLOYMENT.md)
- [Threat model](docs/THREAT_MODEL.md)
- [Roadmap](docs/ROADMAP.md)
- [Contributing](CONTRIBUTING.md)
## License
Apache License 2.0.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues