Metadata-Version: 2.4
Name: node804-mcp-toolkit
Version: 0.1.0
Summary: Shared utilities for token-efficient MCP servers — RBAC, audit logging, lean response shaping, TLS config
Project-URL: Homepage, https://github.com/Node804/node804-mcp-toolkit
Project-URL: Repository, https://github.com/Node804/node804-mcp-toolkit
Project-URL: Issues, https://github.com/Node804/node804-mcp-toolkit/issues
Author-email: Michael Pope <me@michaelpope.cv>
License-Expression: MIT
License-File: LICENSE
Keywords: audit,mcp,model-context-protocol,rbac,tls
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: pydantic>=2.10.6
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# node804-mcp-toolkit

[![CI](https://github.com/Node804/node804-mcp-toolkit/actions/workflows/ci.yml/badge.svg)](https://github.com/Node804/node804-mcp-toolkit/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/node804-mcp-toolkit)](https://pypi.org/project/node804-mcp-toolkit/)
[![Python](https://img.shields.io/pypi/pyversions/node804-mcp-toolkit)](https://pypi.org/project/node804-mcp-toolkit/)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

Shared utilities for building token-efficient, security-conscious [MCP](https://modelcontextprotocol.io) servers for IT operations. Provides the cross-cutting concerns every ops MCP needs — permission gating, audit logging, response shaping, TLS config — so each server in a suite implements them the same way.

## Installation

```bash
pip install node804-mcp-toolkit
```

## What's in here

| Module | Purpose |
|---|---|
| `rbac` | Hierarchical permission modes (`read` / `standard` / `full` / `admin`); a gate decorator that only registers tools with the MCP server when the active mode qualifies — ungated tools are invisible to the AI client, not just blocked |
| `audit` | JSON-lines audit logging of every tool call with timing, success/error state, sensitive-key redaction, and long-value truncation |
| `lean` | Pure response-shaping helpers: field whitelisting, internal-key stripping, pagination, server-side pattern filtering |
| `tls` | Verify-by-default TLS config from env vars, with custom CA bundle support for internal PKI |
| `params` | Shared Pydantic parameter types (`VerboseFlag`, `FieldsList`, `Pagination`, `Pattern`) so every tool uses the same names, defaults, and descriptions |

## Quick start

Gate tools by permission mode, with audit logging composed in:

```python
from mcp.server.fastmcp import FastMCP
from node804_mcp_toolkit import Mode, ModeGate, open_sink

mcp = FastMCP("panos-mcp")

# Audit sink: writes JSONL when PANOS_AUDIT_LOG is set, no-op otherwise.
sink = open_sink(env_var="PANOS_AUDIT_LOG")

# Mode comes from env. Missing or invalid values fail safe to read-only.
gate = ModeGate.from_env(env_var="PANOS_MODE", audit_sink=sink)

@gate.tool(mcp, required=Mode.READ)
async def get_security_rules(...): ...

@gate.tool(mcp, required=Mode.ADMIN)
async def commit(...): ...  # not registered at all unless PANOS_MODE=admin
```

Shape responses for token efficiency:

```python
from node804_mcp_toolkit import filter_by_pattern, paginate, strip_keys, whitelist

rules = strip_keys(raw_rules, ["@uuid", "@loc"])          # drop SDK internals
rules = filter_by_pattern(rules, pattern, name_field="name")
rules = paginate(rules, limit=100, offset=0)
rules = whitelist(rules, ["name", "action", "source", "destination"])
```

Resolve TLS settings from environment (verify-by-default):

```python
from node804_mcp_toolkit import resolve_tls_config
import httpx, os

tls = resolve_tls_config(dict(os.environ), prefix="PRTG")
# PRTG_TLS_VERIFY=false  → verify off, with a loud stderr warning
# PRTG_TLS_CA=/path.pem  → custom CA bundle for internal PKI
client = httpx.Client(verify=str(tls.ca_path) if tls.ca_bundle else tls.verify)
```

## Design philosophy

- **One toolkit, one set of patterns.** A user who learns the parameter conventions in any one MCP — `verbose`, `fields`, `limit`, `offset`, `pattern` — gets the same conventions in all of them.
- **Default deny.** Unset or misconfigured mode env vars fall back to read-only. Tools above the active mode are never registered, so the AI client can't even see them.
- **Token-lean by default.** Responses expose the fields the AI actually reasons over; `verbose=true` opts into the full payload.
- **Best-effort observability.** Audit logging never breaks a tool call — sink failures warn once to stderr and move on.

## Used by

- [`node804-panos-mcp`](https://github.com/Node804) — Palo Alto firewall management
- [`node804-freshservice-mcp`](https://github.com/Node804) — Freshservice ticketing
- Planned: PRTG and Veeam MCPs

## Development

```bash
pip install -e ".[dev]"
pytest
ruff check .
mypy src
```

Requires Python 3.11+. Fully typed (`py.typed` included), `mypy --strict` clean.

## License

[MIT](LICENSE)
