Doramagic Project Pack · Human Manual
node804-mcp-toolkit
Shared utilities for building token-efficient, security-conscious MCP 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.
Toolkit Overview and Design Philosophy
Related topics: Permission Gating with ModeGate, Audit Logging and Argument Sanitization, Response Shaping and Shared Parameter Schemas
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Permission Gating with ModeGate, Audit Logging and Argument Sanitization, Response Shaping and Shared Parameter Schemas
Toolkit Overview and Design Philosophy
Purpose and Scope
node804-mcp-toolkit is a shared Python library that supplies the cross-cutting concerns every operations-oriented Model Context Protocol server needs: permission gating, audit logging, response shaping, TLS configuration, and a uniform set of tool-parameter conventions. The toolkit does not implement vendor-specific operations itself; instead, every MCP in the Node804 suite — currently node804-panos-mcp for Palo Alto firewalls and node804-freshservice-mcp for Freshservice ticketing, with PRTG and Veeam MCPs planned — depends on the toolkit so that those concerns are implemented once, identically, and securely. Source: README.md:1-12.
The library is fully typed (ships a py.typed marker and is mypy --strict clean) and targets Python 3.11+. It is published to PyPI as node804-mcp-toolkit and licensed under MIT. Source: README.md:76-82.
Module Map
The toolkit is intentionally narrow. The public API is re-exported from __init__.py so callers typically write from node804_mcp_toolkit import … and never touch the submodules directly. Source: src/node804_mcp_toolkit/__init__.py:1-39.
| Module | Responsibility |
|---|---|
rbac | Hierarchical Mode enum (READ, STANDARD, FULL, ADMIN) and a ModeGate decorator that registers tools with FastMCP only when the active mode qualifies |
audit | JSON-lines AuditEvent model, AuditSink protocol, audit decorator, and open_sink factory wired to an env var |
lean | Pure response-shaping helpers: whitelist, strip_keys, filter_by_pattern, paginate |
tls | Verify-by-default TlsConfig resolved from {PREFIX}_TLS_VERIFY and {PREFIX}_TLS_CA env vars |
params | Shared Pydantic parameter types: VerboseFlag, FieldsList, Pagination, Pattern |
Source: README.md:14-23.
Mode-Based RBAC
Mode is an IntEnum ordered READ < STANDARD < FULL < ADMIN, so if active_mode >= Mode.FULL is the canonical way to express capability checks. Source: src/node804_mcp_toolkit/rbac.py:75-83. ModeGate.from_env reads the operator-supplied env var, parses it case-insensitively, and falls back to READ on any missing or unrecognized value — this is the "default deny on misconfiguration" stance. When the env var is set but invalid, a one-time stderr warning is emitted so the misconfiguration is visible in startup logs. Source: src/node804_mcp_toolkit/rbac.py:33-58.
The gate.tool(mcp, required=Mode.…) decorator records every decorated function in an internal registry. If allows(required) returns False, the function is not passed to mcp.tool(); it remains importable in Python but is invisible to the MCP client. Source: src/node804_mcp_toolkit/rbac.py:120-141.
Audit Logging
Every tool call can emit one AuditEvent — a frozen Pydantic model with ts, request_id, tool, category, mode, sanitized args, success, duration_ms, and optional extra. Source: src/node804_mcp_toolkit/audit.py:24-48. The audit decorator wraps an async function, generates a UUID4 request id, measures wall-clock duration, redacts sensitive keys (e.g. password, secret, token, authorization, x-api-key) at any nesting depth, and elides any string value longer than 2048 characters. Source: src/node804_mcp_toolkit/audit.py:62-86.
open_sink(env_var=…) returns a JsonlSink when the env var is set, or a _NoopSink when it is not — so the default deployment pays nothing for audit. The sink catches and warns on write failures so a broken log file never breaks a tool call. Source: src/node804_mcp_toolkit/audit.py:90-122.
Lean Responses
The lean helpers are deliberately pure: no I/O, no global state, easy to test and compose. The typical assembly order is strip_keys (drop SDK internals like @uuid) → whitelist (project the default field set) → filter_by_pattern (server-side substring filter) → paginate (enforce limit/offset). Source: src/node804_mcp_toolkit/lean.py:1-16. Whitelisting is intentionally shallow; tools that need nested projection compose multiple whitelist calls. Source: src/node804_mcp_toolkit/lean.py:18-37.
Shared Parameter Conventions
VerboseFlag, FieldsList, Pagination, and Pattern are Annotated Pydantic types whose description strings are tuned for AI clients. VerboseFlag defaults to False with a description noting that the lean path typically saves 40–70% of tokens. Source: src/node804_mcp_toolkit/params.py:16-25. Pagination defaults to limit=100, 1 ≤ limit ≤ 1000, with a hard cap that exists because "dumping unbounded inventories can blow the AI's context window." Source: src/node804_mcp_toolkit/params.py:55-70.
TLS Resolution
resolve_tls_config(env, prefix=…) returns a TlsConfig whose verify field defaults to True. A *_TLS_VERIFY=false opt-out emits a stderr warning; *_TLS_CA=/path.pem loads a custom CA bundle for internal PKI. A CA file that fails to read triggers a soft warning and falls back to the system trust store — verification is still on, just against the default roots. Source: src/node804_mcp_toolkit/tls.py:1-30.
Design Philosophy
Four principles, each enforced in code rather than documented as aspiration, shape the toolkit. Source: README.md:60-65.
- One toolkit, one set of patterns. The parameter names
verbose,fields,limit,offset, andpatternmean the same thing in every MCP. A user who learns them once can drive any server in the suite without re-reading docs. - 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 cannot even see them, let alone invoke them.
- Token-lean by default. Responses expose the fields the AI actually reasons over;
verbose=trueopts into the full payload, andfields=[…]projects an arbitrary subset. - Best-effort observability. Audit logging never breaks a tool call. A sink failure logs once to stderr and moves on, so logging is a feature you can turn on without making the service fragile.
Composition Pattern
The toolkit's value is in how the pieces compose. The README's "Quick start" shows the canonical pattern: open_sink and ModeGate.from_env are constructed once at startup, then gate.tool(mcp, required=Mode.…) decorates each tool. The gate wraps the function with audit automatically when a sink is attached, so most call sites never invoke the audit decorator directly. Source: README.md:25-41. A summary() method on the gate returns a stable shape (mode, tools_total, tools_enabled, tools_blocked, enabled_tools, blocked_tools, audit) that powers server_status tools across the suite. Source: src/node804_mcp_toolkit/rbac.py:147-160.
flowchart LR
A[env: PREFIX_MODE] --> B[ModeGate.from_env]
C[env: PREFIX_AUDIT_LOG] --> D[open_sink]
D --> B
B --> E[gate.tool decorator]
E -->|mode qualifies| F[register with FastMCP + audit wrap]
E -->|mode insufficient| G[record blocked, do not register]
H[Tool call] --> F
F --> I[sanitize args]
I --> J[emit AuditEvent JSONL]
F --> K[strip_keys → whitelist → filter → paginate]
K --> L[Token-lean response]See Also
- README.md — installation, module table, and quick-start examples
src/node804_mcp_toolkit/rbac.py—Mode,ModeGate, and registration semanticssrc/node804_mcp_toolkit/audit.py—AuditEventschema, redaction rules, sink lifecyclesrc/node804_mcp_toolkit/lean.py— pure response-shaping helperssrc/node804_mcp_toolkit/params.py— shared Pydantic parameter typessrc/node804_mcp_toolkit/tls.py— env-drivenTlsConfigresolution
Source: https://github.com/Node804/node804-mcp-toolkit / Human Manual
Permission Gating with ModeGate
Related topics: Toolkit Overview and Design Philosophy, Audit Logging and Argument Sanitization
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Toolkit Overview and Design Philosophy, Audit Logging and Argument Sanitization
Permission Gating with ModeGate
Overview
ModeGate is the toolkit's role-based access control primitive for MCP servers. Its central idea is registration-time gating: rather than checking permissions inside every tool call, the gate decides at server startup whether each tool is *registered with the MCP server at all*. Tools that don't qualify are not exposed to the AI client — there is nothing to call, no error to surface, and no path to misuse. (src/node804_mcp_toolkit/rbac.py)
The gate follows a default-deny posture: if the mode env var (e.g. PANOS_MODE) is unset or holds an unrecognized value, the gate resolves to the lowest mode (READ). Operators must explicitly opt in to write capabilities, and the failure mode is intentionally conservative. (README.md)
Mode Hierarchy and Resolution
Mode is an IntEnum with four tiers, ordered so that higher values include all capabilities of lower ones. Comparison is hierarchical out of the box: if active_mode >= Mode.FULL: correctly admits both full and admin. (src/node804_mcp_toolkit/rbac.py)
| Mode | Value | Suggested audit category | Typical use |
|---|---|---|---|
READ | 0 | READ | Read-only — safe default |
STANDARD | 1 | WRITE | Routine writes |
FULL | 2 | WRITE | Broad operational writes |
ADMIN | 3 | ADMIN | Destructive/admin (e.g. commit) |
The class method Mode.parse(raw, default=default) accepts upper- or lower-case strings and falls back to default when the input is empty, None, or unrecognized. ModeGate.from_env builds on top of it. (src/node804_mcp_toolkit/rbac.py)
flowchart TD
A["Server starts"] --> B["Read env var e.g. PANOS_MODE"]
B --> C{"Value valid Mode?"}
C -- Yes --> D["active_mode = parsed"]
C -- No / Missing --> E["Fallback to default e.g. READ"]
D --> F{"Invalid raw was set?"}
E --> F
F -- Yes --> G["One-time stderr warning"]
F -- No --> H["Proceed silently"]
G --> I["ModeGate initialized"]
H --> IWhen the env var is present but invalid and warn_on_invalid=True, the gate prints a one-line stderr message: [node804-mcp-toolkit] WARNING: invalid {env_var}='{raw}'. Falling back to '{default.name.lower()}'. Valid modes: .... (src/node804_mcp_toolkit/rbac.py)
ModeGate Lifecycle and the `gate.tool` Decorator
A ModeGate is constructed with the active mode, the source env_var (for diagnostics), and an optional audit_sink. Internally it maintains _registry: dict[str, tuple[Mode, AuditCategory, bool]] — tool_name → (required_mode, category, registered) — which is populated as decorators fire and later powers summary(). (src/node804_mcp_toolkit/rbac.py)
The gate.tool() decorator is the operational entry point. It accepts:
mcp— the FastMCP server instance,required— minimum mode level needed to expose the tool,category— optional audit-category override (defaults to a sensible value from_MODE_TO_CATEGORY; falls back to"UNKNOWN"when no map entry exists, deliberately loud),tool_name— optional override (defaultfunc.__name__),extra_extractor— forwarded toaudit()to pull MCP-specific fields (e.g.firewall) into the event'sextra,**mcp_tool_kwargs— forwarded tomcp.tool().
The decorator's branching is the heart of the gate: denied tools are recorded with registered=False and returned unchanged — they are not wrapped, not registered with MCP, and invisible to the AI client. Allowed tools are wrapped with audit() (when an enabled sink is present) and then handed to mcp.tool(name=name, **mcp_tool_kwargs). (src/node804_mcp_toolkit/rbac.py)
from mcp.server.fastmcp import FastMCP
from node804_mcp_toolkit import Mode, ModeGate, open_sink
mcp = FastMCP("panos-mcp")
sink = open_sink(env_var="PANOS_AUDIT_LOG")
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
The same pattern applies to every MCP in the suite — node804-panos-mcp, node804-freshservice-mcp, and planned PRTG/Veeam servers — and the public surface is re-exported from the top-level package. (README.md), (src/node804_mcp_toolkit/__init__.py)
Audit Composition and Diagnostics
When the gate is built with an audit_sink, every allowed tool is automatically wrapped by audit(...) without any extra decorator on the user's side. The wrapper records an AuditEvent per call — ISO-8601 timestamp, UUID4 request_id, tool name, category, active mode, sanitized args, success/error, and duration_ms — and writes it to the sink (typically a JSONL file). (src/node804_mcp_toolkit/audit.py)
Sink failures are best-effort: open_sink returns a _NoopSink (enabled=False) and prints a single stderr warning if the log directory cannot be initialized, so audit problems never break a tool call. (src/node804_mcp_toolkit/audit.py)
For diagnostics, ModeGate exposes:
summary()— a dict withmode,env_var,tools_total,tools_enabled,tools_blocked, sorted lists of enabled/blocked tool names, andaudit: enabled|disabled. The shape is stable across MCPs in the suite for cross-server tooling.describe()— a one-line stderr-friendly string, e.g.mode='admin' (12/14 tools enabled, 2 blocked).all_known_tools— afunctools.cached_propertyreturning every decorated tool name in registration order.
These hooks are typically consumed by server_status tools and startup logs so operators can see exactly what is exposed at boot. (src/node804_mcp_toolkit/rbac.py)
See Also
auditmodule — JSON-lines audit logging and argument sanitization. (src/node804_mcp_toolkit/audit.py)paramsmodule — shared Pydantic schemas (VerboseFlag,FieldsList,Pagination,Pattern) so every tool uses the same names, defaults, and descriptions. (src/node804_mcp_toolkit/__init__.py)leanmodule — response-shaping helpers (whitelist,strip_keys,paginate,filter_by_pattern) for token-lean responses. (README.md)tlsmodule — verify-by-default TLS resolution with custom CA bundle support. (README.md)
Source: https://github.com/Node804/node804-mcp-toolkit / Human Manual
Audit Logging and Argument Sanitization
Related topics: Toolkit Overview and Design Philosophy, Permission Gating with ModeGate
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Toolkit Overview and Design Philosophy, Permission Gating with ModeGate
Audit Logging and Argument Sanitization
Purpose and Scope
The audit module gives every MCP tool call a single JSON-lines record of *who called what, when, with which arguments, and whether it succeeded*. It is part of the cross-cutting toolkit that lets a suite of MCP servers (Palo Alto, Freshservice, PRTG, Veeam) share one observability story instead of each implementing its own logger.
The module has two halves that work together:
- Audit logging —
AuditEvent,AuditSink,JsonlSink,_NoopSink,open_sink, and theaudit()decorator. - Argument sanitization —
sanitize_args()and_sanitize_value(), which redact sensitive keys and truncate long strings before they hit the log.
The stated design intent is "best-effort observability": audit logging never breaks a tool call, so sink failures warn once to stderr and degrade silently thereafter (Source: src/node804_mcp_toolkit/audit.py:1-80). It is re-exported through the package's public API alongside ModeGate, whitelist, and the parameter types so downstream MCPs can import node804_mcp_toolkit and get the whole stack (Source: src/node804_mcp_toolkit/__init__.py:1-30).
The AuditEvent Data Model
Every tool call emits exactly one AuditEvent. The model is frozen=True, so event objects are immutable once created (Source: src/node804_mcp_toolkit/audit.py:40-75). The fields are intentionally stable so cross-MCP log tooling can rely on them:
| Field | Type | Purpose | |
|---|---|---|---|
ts | str | ISO-8601 timestamp, millisecond precision, UTC | |
request_id | str | UUID4 correlating one call across logs | |
tool | str | MCP tool name (e.g. get_security_rules) | |
category | AuditCategory | READ / WRITE / ADMIN / UNKNOWN | |
mode | str | Active permission mode at call time | |
args | dict[str, Any] | Sanitized tool arguments | |
success | bool | True for successful calls, False for handler errors | |
duration_ms | int | Wall-clock duration of the call | |
error | `str \ | None` | Error message when success=False |
extra | dict[str, Any] | Per-MCP optional fields (e.g. {'firewall': 'hq-fw'}) |
category is a Literal["READ", "WRITE", "ADMIN", "UNKNOWN"]. The toolkit ships a suggested Mode → AuditCategory mapping (READ → READ, STANDARD → WRITE, FULL → WRITE, ADMIN → ADMIN) so the gate can pick a sensible category when the caller doesn't override it (Source: src/node804_mcp_toolkit/rbac.py:55-75). UNKNOWN is the default for tools that don't pass category to gate.tool() — deliberate so missing mappings show up in code review rather than being silently misclassified.
Sinks and Configuration
AuditSink is a Protocol with one method, write(event), plus an enabled flag. Two concrete implementations ship in the module:
_NoopSink— drops events.enabled=False. Returned when the env var is unset so the audit decorator costs effectively nothing in the default case (Source: src/node804_mcp_toolkit/audit.py:82-95).JsonlSink— appends one JSON object per line to a file path. The parent directory is created on first use. Write failures catchOSError, emit a one-time stderr warning, and never raise — "audit must not break tool calls" (Source: src/node804_mcp_toolkit/audit.py:98-130).
open_sink(env=None, *, env_var="MCP_AUDIT_LOG") is the constructor used by every MCP in the suite. It returns a JsonlSink when the env var is set, a _NoopSink otherwise. Directory-creation failures fall back to no-op with a stderr warning (Source: src/node804_mcp_toolkit/audit.py:132-160).
flowchart LR
A[Tool call] --> B[audit decorator]
B --> C{Sink enabled?}
C -- no --> D[_NoopSink: drop]
C -- yes --> E[JsonlSink]
E --> F[sanitize_args]
F --> G[Append JSONL line]
G --> H{Write OK?}
H -- yes --> I[Done]
H -- no --> J[Warn once to stderr]
J --> IThe decorator is wired into MCP servers through ModeGate.tool(). When the gate accepts a tool and an audit sink is configured, it composes audit(...) on top of the user's function before handing it to mcp.tool() — so a server author writes one decorator call and gets both gating and logging (Source: src/node804_mcp_toolkit/rbac.py:130-180). ModeGate.summary() then reports "audit": "enabled" or "audit": "disabled" for server_status tools and startup logs (Source: src/node804_mcp_toolkit/rbac.py:200-230).
Argument Sanitization
sanitize_args() is called by the audit decorator before emitting the event. It walks the input mapping recursively and:
- Redacts sensitive keys at any nesting depth. The default set is
DEFAULT_SENSITIVE_KEYS = {api_key, apikey, password, passwd, secret, token, auth, authorization, x-api-key}. Match is case-insensitive. The redaction string is the literal"<redacted>"(Source: src/node804_mcp_toolkit/audit.py:160-200). - Elides long strings over
DEFAULT_MAX_VALUE_LEN = 2048chars, replaced with"<elided: N chars>". This stops a singleset_configelement from blowing one audit line to 100K+ chars. - Defensively stringifies non-mapping, non-list values (
bytes,set, custom classes) instead of crashing, so audit never raises inside the wrapping context.
The same defaults are documented as defense in depth — current tool schemas don't accept those keys (credentials live in the keychain, not in tool params), but a future tool that accidentally does will not leak them to the log (Source: src/node804_mcp_toolkit/audit.py:165-175). If args isn't a mapping at all (typical when a tool was called positionally with no kwargs), sanitize_args returns {} — the audit line stays typed and well-formed rather than carrying an oddly-shaped field (Source: src/node804_mcp_toolkit/audit.py:182-195).
Integration With the Rest of the Toolkit
Sanitization is the last step before serialization, but it shares the same defaults philosophy as the rest of the package:
- Shared parameter types — tools that accept a
PatternorPagination(bothAnnotatedPydantic types inparams.py) feed intofilter_by_patternandpaginatefromlean.py, and the sameargsdict is what audit serializes (Source: src/node804_mcp_toolkit/params.py:1-60,Source: src/node804_mcp_toolkit/lean.py:1-30). - Single TLS posture —
tls.pyresolves aTlsConfigfrom env vars with the same "verify-by-default, opt-out via{PREFIX}_TLS_VERIFY=false" pattern thatopen_sinkuses forMCP_AUDIT_LOG. The two are independent — TLS controls outbound traffic, audit controls outbound observability — but they share the convention of "explicit env var to enable, silent default to safe" (Source: src/node804_mcp_toolkit/tls.py:1-40). - Default-deny posture —
ModeGate.from_env()falls back toMode.READon missing or invalid env values, and the README names this as a deliberate design choice: "Default deny. Unset or misconfigured mode env vars fall back to read-only" (Source: README.md:55-80). Audit logs capture the mode that was *actually* active at call time, not the requested one, so post-hoc reviews see the real permission context.
The result is a stack where one decorator on each tool gives you a streaming JSONL audit trail, redacted credentials, bounded line length, and no failure mode that can take down a tool call — exactly the behavior promised in the package overview (Source: README.md:15-40).
See Also
Source: https://github.com/Node804/node804-mcp-toolkit / Human Manual
Response Shaping and Shared Parameter Schemas
Related topics: Toolkit Overview and Design Philosophy
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Toolkit Overview and Design Philosophy
Response Shaping and Shared Parameter Schemas
Overview
node804-mcp-toolkit ships two complementary modules that work together to keep MCP responses small and the parameter surface consistent across every server in the suite. The lean module provides pure response-shaping helpers (whitelist, strip_keys, paginate, filter_by_pattern), while the params module exposes a uniform set of Pydantic-annotated types (VerboseFlag, FieldsList, Pagination, Pattern) that every tool uses for its arguments. Together they form the "token-lean by default" half of the toolkit's design philosophy: tools project only the fields the AI actually reasons over, and the conventions for asking for "more" or "less" are identical regardless of which MCP a caller is using. Source: src/node804_mcp_toolkit/lean.py, src/node804_mcp_toolkit/params.py, README.md.
The public API re-exports both groups from the package root, so downstream MCPs import them with a single statement. Source: src/node804_mcp_toolkit/__init__.py.
Response-Shaping Utilities (`lean.py`)
The lean module is intentionally I/O-free so the helpers compose in any order and are trivial to unit-test. The docstring in lean.py documents a canonical tool-call recipe: strip_keys to drop SDK noise, whitelist to keep only the fields the tool should expose, filter_by_pattern to apply the caller's name filter, then paginate to enforce limit/offset before serialization. Source: src/node804_mcp_toolkit/lean.py.
`whitelist`
whitelist accepts either a single mapping or an iterable of mappings and returns the same shape with non-listed top-level keys removed. Field names that are absent in the input are silently skipped, so callers can pass a generous whitelist. Whitelisting is intentionally shallow — nested dicts pass through unchanged, and tools that need nested filtering should compose multiple calls. Source: src/node804_mcp_toolkit/lean.py.
`strip_keys`
strip_keys removes a configurable set of keys from a mapping, with an optional recursive flag that walks nested dicts and lists. Typical use is dropping SDK internals such as UUIDs, dirty-state flags, or @loc annotations that the AI never needs. Source: src/node804_mcp_toolkit/lean.py.
`paginate`
paginate slices a list with items[offset : offset + limit]. It raises ValueError for negative limit or offset, and returns an empty list (rather than raising) when offset exceeds the list length — pagination is meant to be forgiving. Source: src/node804_mcp_toolkit/lean.py.
`filter_by_pattern`
filter_by_pattern filters items by substring or regex on a configurable name_field (default "name"). The default is case-insensitive substring matching, which matches typical AI intent ("find rules matching 'social'"); passing use_regex=True switches to regex compilation with the same case flag. Items missing name_field are excluded — the docstring explains this is "no implicit pass-through" because a missing name field usually signals the caller used the wrong filter on the wrong list. Source: src/node804_mcp_toolkit/lean.py.
Shared Parameter Schemas (`params.py`)
The params module is the consistency layer for tool signatures. Every tool that accepts a verbose flag, a field whitelist, pagination, or a pattern filter uses the same names, defaults, and descriptions, so a user who learns verbose / fields / limit / offset / pattern in one MCP finds the same conventions in every other MCP. Source: src/node804_mcp_toolkit/params.py.
| Schema | Type | Default | Purpose | |
|---|---|---|---|---|
VerboseFlag | bool | False | Opt into the full underlying response; the tool's default returns only the most relevant fields (typical 40–70% token reduction). | |
FieldsList | `list[str] \ | None` | None | Explicit per-call field projection; overrides the default whitelist and takes precedence over verbose. |
Pattern | `str \ | None` | None | Server-side case-insensitive substring filter on the item's name field; avoids the "dump everything and filter client-side" pattern. |
Pagination | BaseModel | limit=100, offset=0 | limit clamped to [1, 1000]; hard cap exists because unbounded inventories can blow the AI's context window. |
Source: src/node804_mcp_toolkit/params.py.
The Pagination model is a BaseModel with limit constrained to ge=1, le=1000; the 100-item default is tuned for token efficiency, and callers page through larger inventories by incrementing offset between calls. Source: src/node804_mcp_toolkit/params.py.
Composition and End-to-End Flow
The intended pipeline — visible both in the module docstring and in the README's usage example — is: drop SDK internals, optionally project fields, apply a name filter, then paginate. The README demonstrates the exact ordering for get_security_rules: strip_keys → filter_by_pattern → paginate → whitelist. Source: README.md.
flowchart LR
A[Raw SDK response] --> B[strip_keys]
B --> C[filter_by_pattern]
C --> D[paginate]
D --> E[whitelist]
E --> F[Lean MCP response]The schemas in params.py are the inputs the AI client uses to request each step. Pattern controls filter_by_pattern, Pagination.limit/offset control paginate, FieldsList controls the final whitelist, and VerboseFlag short-circuits the pipeline to return the full payload when the caller needs uncommon fields such as UUIDs or audit timestamps. Source: src/node804_mcp_toolkit/params.py, src/node804_mcp_toolkit/lean.py.
In practice, the gating decorator from rbac.py and the audit decorator from audit.py wrap the tool function itself, while lean and params operate on the function's return value. This separation keeps RBAC, audit, response shaping, and parameter typing independently testable. Source: src/node804_mcp_toolkit/rbac.py, src/node804_mcp_toolkit/audit.py.
Common Pitfalls
- Whitelisting is shallow. Nested filtering requires multiple
whitelistcalls; do not assumewhitelistrecurses. Source: src/node804_mcp_toolkit/lean.py. filter_by_patterndrops items missingname_field. If the input list does not use"name", passname_fieldexplicitly. Source: src/node804_mcp_toolkit/lean.py.FieldsListoverridesverbose. A caller that setsfields=[...]gets exactly those keys even ifverbose=True. Source: src/node804_mcp_toolkit/params.py.Pagination.limitis hard-capped at 1000. Tool authors who need a larger page must split it across calls. Source: src/node804_mcp_toolkit/params.py.
See Also
- RBAC and Mode-Based Tool Registration
- Audit Logging
- TLS Configuration for Outbound Clients
Source: https://github.com/Node804/node804-mcp-toolkit / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
Doramagic Pitfall Log
Found 6 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Capability evidence risk - Capability evidence risk requires verification.
1. Capability evidence risk: Capability evidence risk requires verification
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.assumptions | https://github.com/Node804/node804-mcp-toolkit
2. Maintenance risk: Maintenance risk requires verification
- Severity: medium
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/Node804/node804-mcp-toolkit
3. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: downstream_validation.risk_items | https://github.com/Node804/node804-mcp-toolkit
4. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: risks.scoring_risks | https://github.com/Node804/node804-mcp-toolkit
5. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/Node804/node804-mcp-toolkit
6. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/Node804/node804-mcp-toolkit
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using node804-mcp-toolkit with real data or production workflows.
- Capability evidence risk requires verification - GitHub / issue
Source: Project Pack community evidence and pitfall evidence