Skip to main content
Glama
naive000

lazy-mcp-router

by naive000

lazy-mcp-router

Safety-first prototype for a local Codex MCP tool gate.

This project does not modify PJ-Monitor and does not modify ~/.codex.

L4 Control Plane Entrypoints

Install from a Git URL:

uv tool install git+https://github.com/<owner>/lazy-mcp-router.git

Product-level commands:

lazy-mcp-router doctor --pretty
lazy-mcp-router doctor --full --pretty
lazy-mcp-router catalog --query git --pretty
lazy-mcp-router onboard --pretty

doctor reports the current L0-L5 level, hard blockers, soft blockers, and next actions. catalog exposes router-visible tools and evidence. onboard previews profile changes by default; onboard --apply is required before any Codex profile config is modified.

Related MCP server: Peta Core

Current Loop

search_tools -> describe_tool -> load_server -> call_tool -> audit trace -> status -> cleanup

Safety Contract

Step 2 uses zero-content evidence receipts:

  • policy defaults to read-only calls

  • missing required env blocks backend startup

  • required env is not automatically injected into child processes

  • receipts store hashes, policy decisions, latency, state, and redaction evidence

  • receipts do not store raw args, raw results, raw stderr, env values, or full schemas

  • receipts stay in memory by default; JSONL persistence is opt-in

Safe observability methods:

  • healthz()

  • status()

  • backends()

  • tools()

  • capabilities()

  • receipts_recent()

  • receipt(receipt_id)

MCP Control Registry

Step 3 adds a read-only registry layer for local Codex MCP inventory:

  • scans ~/.codex/config.toml, ~/.codex/*.config.toml, and ~/.codex/mcp-auto.tsv

  • reads only; it does not start servers, inject env values, or modify global config

  • builds proof-carrying backend receipts with trust tier and activation level

  • uses repo-local router.config.toml or LAZY_MCP_ROUTER_CONFIG for allowlist overlay

  • keeps capability output zero-content: no raw args, raw config, env values, or secret tokens

Trust tiers:

  • T0_BLOCKED

  • T1_OBSERVED

  • T2_LOCAL_CANDIDATE

  • T3_TRUSTED_REMOTE_CANDIDATE

  • T4_CONFIGURED_BACKEND

  • T5_RUNTIME_APPROVED

Optional read-only HTTP surface:

  • GET /healthz

  • GET /status

  • GET /backends

  • GET /tools

  • GET /capabilities

  • GET /receipts/recent

  • GET /receipts/{id}

The HTTP server binds to 127.0.0.1:7791 by default, supports an optional bearer token, and exposes no write/control routes.

Router Runtime

Step 4 adds the runtime bridge from proof receipts to lazy-startable backends.

Runtime approval is stricter than configuration:

  • T4_CONFIGURED_BACKEND means the backend is configured and visible in /capabilities, but it is not startable.

  • T5_RUNTIME_APPROVED means the backend passed the runtime gates and is the only tier compiled into LazyMcpRouter.registry.

  • runtime_enabled=true is not enough by itself; the configured runtime_fingerprint must match the current canonical runtime contract.

  • factory construction, search_tools(), and capabilities() do not spawn backend processes.

Runtime gates:

  • remote MCP uses https only, allowlisted hosts, exact allowlisted paths, and rejects userinfo, query strings, and fragments

  • direct stdio uses MCP stdio only and requires command/argv allowlisting

  • required env is injectable only when the key is both required and env_allowlisted

  • env values are resolved only at T5 compile/start boundaries and are never included in receipts, status, capabilities, or HTTP responses

  • allowed tools can be declared with tool_risks; undeclared risk remains unknown and is denied unless explicitly allowed

Observability contract:

Endpoint

Scope

Includes

Excludes

GET /capabilities

all T0-T5 inventory

proof, diagnostics, runtime overlay, expected fingerprint hash

raw command, raw URL path/query, env values, allowed tool names

GET /backends

compiled T5 runtime registry only

runtime state, pid, startup latency, call count, missing env keys

T0-T4 candidates

GET /status

aggregate only

capability counts, runtime state counts, audit stats

per-backend detail

GET /tools

declared/loaded tools from compiled T5 backends

tool ids, names, risk, source

raw schemas unless described/loaded

Step 4 keeps HTTP read-only. Control routes such as load_tool and call_tool remain Step 5 work.

Control Plane

Step 5 adds a transport-neutral control core plus HTTP as the first adapter.

Control commands:

  • status

  • capabilities

  • list_backends

  • search_tools

  • describe_tool

  • load_server

  • call_tool

All control responses use a safe envelope:

{
  "schema_version": "step5.v1",
  "ok": true,
  "command": "search_tools",
  "result": {},
  "error": null,
  "receipt_id": null,
  "ts": 0.0
}

HTTP control routes:

  • POST /control/list_backends

  • POST /control/search_tools

  • POST /control/describe_tool

  • POST /control/load_server

  • POST /control/call_tool

  • POST /control/status

  • POST /control/capabilities

The HTTP adapter reuses the optional bearer token. GET observability routes stay unchanged. Control errors are returned as safe envelopes; raw command args, env values, raw URLs, stderr, and unredacted tool arguments are not returned.

CLI Adapter

Step 5.5 adds a local debug CLI over the same ControlPlane:

lazy-mcp-router status
lazy-mcp-router capabilities
lazy-mcp-router backends
lazy-mcp-router search echo --limit 10
lazy-mcp-router describe '<tool_id>' --no-load
lazy-mcp-router load 'default::server'
lazy-mcp-router call '<tool_id>' --arguments-json '{"message":"hello"}'
lazy-mcp-router call '<tool_id>' --arguments-file args.json
lazy-mcp-router call '<tool_id>' --arguments-stdin

Global flags:

  • --codex-dir PATH

  • --config PATH

  • --pretty

  • --no-npx-check

  • --env KEY=VALUE

The CLI always prints a step5.v1 JSON envelope. It does not persist daemon state between invocations and does not add policy rules beyond the existing control plane, policy gate, and T5 runtime gates.

MCP Server Adapter

Step 7 adds a stdio MCP server over the same ControlPlane:

lazy-mcp-router-mcp --no-npx-check

It exposes only router meta-tools:

  • list_backends

  • search_tools

  • load_tool

  • call_tool

The adapter does not expose backend tools directly, does not mutate router.config.toml, does not inject env values from tool payloads, and does not relax T5 runtime gates. Tool results include the same step5.v1 envelope in MCP structuredContent; content[0].text contains compact JSON for clients that only read text tool output.

For the canonical local runtime, run the MCP adapter as a thin client to the PM2-owned HTTP daemon:

lazy-mcp-router-mcp --proxy-url http://127.0.0.1:7791 --caller codex-mcp

Proxy mode does not construct a direct LazyMcpRouter and does not spawn backend child processes. It forwards the four router meta-tools to POST /control/*, adds safe caller metadata for attribution, and keeps backend runtime state, cooldown, pids, and receipts in the HTTP daemon that PJ-Monitor observes. Direct mode remains available for tests and local development.

Clean-room Codex Smoke

Step 10.10.5 verifies the proxy-mode MCP adapter with an isolated CODEX_HOME instead of codex exec --ignore-user-config. On Codex 0.138.0, the --ignore-user-config path can enumerate the injected MCP server but cancels MCP tool calls during execution. The isolated-home smoke avoids that CLI edge case while still avoiding the user's base ~/.codex/config.toml.

scripts/step10_10_clean_room_smoke

The smoke writes state/step10.10.5-clean-room-smoke.json, isolates config in a temporary Codex home, and uses a temporary auth.json symlink to the existing Codex auth file when available. If that auth file is unavailable, it falls back to codex login --with-api-key from OPENAI_API_KEY. The temporary home is deleted after the run, and token values are never written into the artifact.

Lifecycle Hardening

Step 8 hardens lazy backend runtime behavior:

  • state transitions are recorded as receipts

  • failed backends enter cooldown before another start attempt

  • call timeout clears stale pids and stops router-owned child processes

  • backend health probes reconcile dead HOT children during runtime snapshots

  • audit receipts are protected by a lock for concurrent control requests

  • HTTP control on non-loopback hosts requires a bearer token

Backend runtime rows now include trust tier, activation level, tool count, failure count, cooldown, last transition, and last health probe metadata. They still exclude raw command args, env values, stderr, raw input, and raw output.

PJ-Monitor Observability

Step 9 is consumed by PJ-Monitor through read-only router endpoints:

  • /healthz

  • /status

  • /backends

  • /capabilities

  • /receipts/recent

The PJ-Monitor MCP Lazy v2 payload can distinguish profile inventory health from router runtime availability. It includes per-endpoint latency/error summaries, read-only path proof, health metadata, backend state/tier/latency/failure rows, and recent receipt summaries. PJ-Monitor does not call router /control/* routes and does not add start/stop buttons for router backends.

Activation Pipeline

Step 10 adds an activation compiler for repo-local rollout checks. It reads router.activation.toml by default. If that file is missing, the compiler returns a safe blocked default instead of touching global Codex config.

Dry-run:

lazy-mcp-router activate --dry-run
lazy-mcp-router activate --dry-run --manifest router.activation.toml --pretty

The dry-run prints a step10.activation.v1 JSON envelope with:

  • manifest summary

  • router config plan

  • shadow profile plan

  • capability and T5 readiness

  • blocked reasons

  • secret redaction proof

Write a repo-local router config plan:

lazy-mcp-router activate --dry-run --write-router-config --config router.config.toml

The generated router.config.toml includes allowlists, runtime fingerprints, env key names, and tool risk metadata. It does not write env values or token values.

Secret values are resolved from the router process environment only. Activation manifests should list env_keys, required_env, and env_allowlist; legacy env = { KEY = "value" } rows are ignored and reported as diagnostics.

Minimal synthetic canary manifest:

[activation]
name = "synthetic-canary"

[[backends]]
profile = "synthetic"
server = "canary"
kind = "synthetic"
command = "/path/to/python"
args = ["tests/fixtures/fake_mcp_server.py", "--scenario", "normal"]
allowed_tools = ["echo"]
tool_risks = { echo = "read" }

Python callers can run the synthetic activation smoke without external GitHub or token dependencies:

from pathlib import Path
from lazy_mcp_router.activation import activation_report

report = activation_report(Path("router.activation.toml"))

The report uses the local fake backend flow search_tools -> load_tool -> call_tool and returns step10.activation_report.v1 JSON-compatible data.

HTTP Daemon

Step 10 also adds a daemon entrypoint over the existing HTTP server:

lazy-mcp-router-http --manifest router.activation.toml --config router.config.toml --host 127.0.0.1 --port 7791 --no-npx-check

Options:

  • --manifest PATH

  • --config PATH

  • --host HOST

  • --port PORT

  • --token TOKEN

  • --no-npx-check

Loopback hosts can run without a token. Non-loopback hosts still require a bearer token through the existing HTTP guardrail.

Real Backend Dual Canary

Step 10.11 adds the first real runtime backend while keeping the synthetic canary as a baseline. The repo-local router.activation.toml now compiles:

  • synthetic::canary

  • repo-ops::git-mcp

repo-ops::git-mcp is a no-secret remote MCP backend at https://gitmcp.io/docs and is limited to the read-risk fetch_generic_url_content tool. The real canary calls that tool with {"url":"https://gitmcp.io/docs"}.

Local MCP candidates are still discovery-only in Step 10.11. Run:

scripts/step10_11_local_discovery

This writes state/step10.11-local-discovery.json with command names, argument counts, env key names, and recommendations. It does not start or call local MCP servers.

Persistent Shadow Profile Smoke

Step 10.13 turns the persistent lazy-router-shadow profile into a repeatable acceptance check. It reads /home/crazy/.codex/lazy-router-shadow.config.toml, verifies that the profile exposes only lazy-mcp-router, and blocks before running Codex if direct MCP servers such as git-mcp reappear.

scripts/step10_13_shadow_profile_smoke

The smoke runs Codex with the real shadow profile:

codex exec -p lazy-router-shadow -s read-only -C /home/crazy/lazy-mcp-router --skip-git-repo-check

It then exercises the router meta-tool path list_backends -> search_tools -> load_tool -> call_tool against the repo-ops::git-mcp canary and writes state/step10.13-shadow-profile-smoke.json. The artifact records profile server names, router/PJ-Monitor postflight status, backend call evidence, and sanitized Codex command output. It does not set CODEX_HOME, does not modify ~/.codex, and does not store token or env values.

Fake Backend Scenarios

  • normal_backend

  • slow_start_backend

  • crash_on_start_backend

  • hang_on_call_backend

  • duplicate_tool_backend

  • secret_leak_backend

Real Smoke

Phase 3 uses GitMCP through the documented mcp-remote stdio bridge:

npx -y mcp-remote https://gitmcp.io/docs

Run the live smoke test explicitly:

RUN_GIT_MCP_SMOKE=1 uv run pytest -q tests/test_phase3_mcp_stdio.py::test_git_mcp_docs_real_smoke -s

Step 4 factory/runtime tests cover the local T5 bridge. A future live load-only smoke can use the same GitMCP bridge without calling tools.

Verification

uv run pytest -q
uv run ruff check .

Available Tools

4 tools
call_toolC

Call a router tool through lazy lifecycle, policy, timeout, and audit gates.

ParametersJSON Schema
NameRequiredDescriptionDefault
tool_idYes
argumentsNo

TDQS

C2.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must fully disclose behavior. It mentions gates (lazy lifecycle, policy, timeout, audit) but does not explain what these imply for the caller, such as side effects, authentication needs, or error handling. This is insufficient for a tool that likely executes actions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence, which is appropriately concise, but it lacks structure and depth. It is not front-loaded with critical details beyond the basic action, and it does not earn its place by conveying essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an object parameter (arguments), no output schema, and no annotations, the description is severely under-specified. It fails to explain what a router tool is, how the gates affect execution, or what the expected outcome is, leaving the agent with substantial uncertainty.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage and the description does not mention the parameters (tool_id, arguments) at all. An agent has no way to understand what tool_id refers to or how to structure the arguments object, making correct invocation nearly impossible.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb ('Call') and a specific resource type ('router tool'), which is distinct from siblings like list_backends or search_tools. However, it does not clarify which specific router tool or what makes it unique beyond the mention of gates, leaving some ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives such as list_backends, search_tools, or load_tool. No conditions, prerequisites, or exclusions are mentioned, leaving the agent to infer the appropriate context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_backendsA

List lazy MCP router runtime backends without starting them.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states that backends are not started, which implies a read-only intent, but does not mention potential side effects, output format, or error behavior. For a zero-parameter list operation this is adequate but not rich in context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence, front-loaded with the verb and object, and every word earns its place. No filler or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple zero-parameter tool with no output schema, the description conveys the essential action and a key behavioral qualifier. It does not describe the return value (a list), but the tool's purpose implies it; given the low complexity, this is a near-complete definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so schema coverage is vacuously 100%. The description adds no parameter-specific meaning, but none is needed since the tool takes no arguments. Baseline 3 applies per the rubric for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'list' with a clear resource ('lazy MCP router runtime backends') and adds a qualifier ('without starting them') that distinguishes it from siblings like load_tool and call_tool. The purpose is unambiguous and immediate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'without starting them' provides clear context that this tool is for inspection only, implying alternatives exist for starting backends (e.g., load_tool). However, it does not name specific alternatives or provide explicit when-not conditions, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

load_toolC

Load the backend that owns a tool and return its safe tool detail.

ParametersJSON Schema
NameRequiredDescriptionDefault
tool_idYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. The word 'safe' hints the operation is non-destructive, but it never states side effects, whether it's read-only, what 'safe tool detail' actually returns, or error behavior. The transparency is thin and leaves the agent to infer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. The action verb leads and the rest is compact, though brevity comes at the cost of explanatory detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotations, the description must explain both inputs and expected returns. 'Safe tool detail' is never defined, and there's no guidance on when loading is appropriate versus calling. The description is too thin for a 1-param tool that could easily be more explicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for the parameter. It implies tool_id identifies a tool, but doesn't explain the ID's format, how to obtain it (e.g., via search_tools), or its relationship to backends. The description only partially bridges the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Load') and resource ('the backend that owns a tool') and notes it returns 'safe tool detail'. It's clear about the core action, but 'safe tool detail' is ambiguous and the description doesn't explicitly distinguish itself from siblings like call_tool or search_tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this tool versus its siblings (list_backends, search_tools, call_tool). The description doesn't mention alternatives, prerequisites, or exclusions, leaving an agent to guess whether it should load, call, or search a tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_toolsA

Search declared and loaded router tools without starting cold backends.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryNo

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral disclosure burden. It does disclose a meaningful behavior (it avoids cold-starting backends), but it says nothing about return format, result ordering, pagination, or the precise meaning of 'declared' vs 'loaded'. Useful but incomplete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, compact sentence with the core action front-loaded and the qualifier placed right after. There is no unnecessary wording, and every word contributes meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no annotations, no output schema, and no parameter descriptions, the description is too thin to fully equip an agent. It omits return value structure, default behavior, and any detail about what 'declared' versus 'loaded' means, leaving significant gaps for a search tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the description does not explain either parameter. While 'query' and 'limit' are somewhat self-explanatory from their names and schema constraints, the description does not clarify what fields query searches against or exactly how limit affects results, so the agent is left without crucial semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Search') and resource ('declared and loaded router tools'), and adds a distinguishing qualifier ('without starting cold backends') that sets it apart from siblings like list_backends, load_tool, and call_tool. An agent can clearly understand what this tool does and how it differs at a high level.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The qualifier 'without starting cold backends' implies a lightweight search context, but the description does not explicitly say when to use this tool over alternatives such as list_backends or load_tool, nor does it provide exclusions or conditions. Usage guidance is only implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.1.0
    • First observedcall_tool
    • First observedlist_backends
    • First observedload_tool
    • First observedsearch_tools

TDQS

A3.5/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a distinct role: listing backends, searching tools, loading a specific tool, and invoking a tool. No overlap in purpose, and the descriptions clearly differentiate the lifecycle stages.

Naming Consistency5/5

All tool names follow the verb_noun pattern in snake_case: list_backends, search_tools, load_tool, call_tool. The naming is uniform and predictable.

Tool Count5/5

Four tools is a focused, well-scoped set for a router server. Each tool serves a necessary part of the workflow without redundancy or bloat.

Completeness4/5

The core router lifecycle is covered: inspect, search, load, and call. A minor gap is the lack of an explicit unload or backend status operation, but the essential functionality is complete.

Maintenance

ActivityInactive
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCPGate aggregates multiple MCP servers into a single unified endpoint, enabling centralized tool management with granular filtering, automatic namespacing, and observability. Features a real-time web dashboard and optional PostgreSQL-backed audit trails for monitoring and controlling AI tool access across local and remote deployments.
    5 npm
    Apache 2.0
  • F
    license
    Not graded
    quality
    A
    maintenance
    A production-ready MCP gateway and control plane that provides credential vault, policy engine, audit logging, and managed runtime for routing tool calls between AI agents and downstream MCP servers.
    58
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Self-hosted MCP gateway that applies deterministic, compiled policy to tool discovery, invocation, and outbound data flow, with no model in the enforcement path. Every decision emits a hash-chained receipt sealed with Ed25519 and verifiable using public keys only.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP Shield Runtime is a local-first security gateway that controls MCP tool calls with parameter-level policies, approval gates, secret redaction, rate limiting, contract drift detection, and tamper-evident auditing before they reach the upstream MCP server.
    1
    Apache 2.0