Skip to main content
Glama
Katalinhorvath-blip

Nura MCP Policy Interceptor

README.md
# Nura MCP Policy Interceptor

A lightweight, deterministic governance and policy enforcement gateway for Model Context Protocol (MCP) servers.

## Install

```bash
npm install mcp-policy-interceptor
```

Requires Node.js 20 or later and `@modelcontextprotocol/sdk` 1.26 or later. npm installs the SDK peer automatically when it is not already present.

Protect an existing MCP `tools/call` handler in three lines:

```typescript
import { createPolicyInterceptor } from "mcp-policy-interceptor";
const protect = await createPolicyInterceptor("./policy.yaml");
server.setRequestHandler(CallToolRequestSchema, protect(callToolHandler));
```

The wrapped handler runs only when the policy returns `ALLOW`. `BLOCK` and `REQUIRE_APPROVAL` requests return MCP errors without invoking application code. Pass a policy object, a `PolicyEngine`, or a path to a `.json`, `.yaml`, or `.yml` file.

## Enterprise Governance & Pilot Program

`mcp-policy-interceptor` is architected as a deterministic, cross-language policy sidecar/proxy for Model Context Protocol (MCP) servers. 

We are currently collaborating with engineering teams and enterprise architects to implement runtime write-path protection, asynchronous Human-in-the-Loop (HITL) approval webhooks, and immutable audit trails.

- 📊 **Take our 60-second survey:** [AI Agent Security Survey](https://tally.so/r/b5M8Ng)
- 📬 **Discuss an Enterprise Pilot:** Open an issue or contact `horvathkit@gmail.com`

## Features
- **Hard Guardrails:** Instantly drop forbidden tool execution requests before hitting systems of record.
- **Dynamic Parameter Bounds:** Intercept requests that exceed numerical thresholds (e.g., discounts, spend limits).
- **Human-in-the-Loop Hooks:** Pause high-risk operations and surface human review requests.
- **Audit Telemetry:** Cryptographic-ready logging for all agent-tool evaluations.

## Demo CLI

```bash
npx mcp-policy-interceptor --policy ./policy.yaml
```

The demo CLI uses MCP stdio transport and is intended to be launched by an MCP client.

## External Policy Files

Pass a JSON or YAML policy at startup to update rules without recompiling TypeScript:

```bash
node dist/cli.js --policy ./policy.json

# The npm equivalent passes arguments after --
npm start -- --policy ./policy.yaml
```

JSON example:

```json
{
	"forbiddenTools": ["delete_database_record", "purge_crm_contacts"],
	"requireApprovalTools": ["issue_refund", "update_deal_stage"],
	"maxParamLimits": {
		"discountPercentage": 20,
		"amount": 1000
	}
}
```

YAML example:

```yaml
forbiddenTools:
	- delete_database_record
	- purge_crm_contacts
requireApprovalTools:
	- issue_refund
	- update_deal_stage
maxParamLimits:
	discountPercentage: 20
	amount: 1000
```

Supported extensions are `.json`, `.yaml`, and `.yml`. Relative paths are resolved from the process working directory. Missing, malformed, or schema-invalid policy files stop startup with an error. If `--policy` is omitted, the built-in policy is used.

## Development

```bash
npm install
npm test
```

## Verification

```bash
npm test
```

The test command builds into `dist/` and verifies:

- Governance decisions use only `ALLOW`, `BLOCK`, and `REQUIRE_APPROVAL`.
- Forbidden tools and out-of-bounds parameters return policy failures without invoking the target executor.
- Every evaluated tool request emits a `[GOVERNANCE AUDIT LOG]` entry with its timestamp, decision, tool name, and reason.
- The compiled stdio server enforces built-in and external policy behavior through an MCP client.

TDQS

B3.3/5.0

Scored across 2 tools

Disambiguation5/5

The two tools are entirely distinct: one applies a discount to a deal, the other deletes a database record. There is no overlap or ambiguity between their purposes.

Naming Consistency5/5

Both tools follow the verb_noun pattern with snake_case: 'apply_deal_discount' and 'delete_database_record'. This is consistent and predictable.

Tool Count3/5

With only 2 tools, the server feels thin for a 'Policy Interceptor' scope. The count is on the low end of borderline, as it may not cover enough operations to be truly useful.

Completeness2/5

The tool surface is sparse and lacks obvious lifecycle operations. For a policy interceptor, one would expect at least read/list functionality alongside the action tools, and the current set leaves significant gaps in typical CRUD or policy management workflows.