🧩🔐
AI infrastructure · security engineering · September 2026

LocalMCP: A Lightweight, Fail-Closed MCP Operations Gateway

Model Context Protocol makes it possible to give agents useful tools. The operational problem is deciding who can use which tool, when a tool service should exist, and how to keep that answer observable without turning a small homelab into a permanent fleet of daemons.

On-demand MCPsLeast privilegeLoopback controlMetadata-only auditNo containers

The problem: useful tools, expanding operational surface

An AI agent can be connected directly to every API, database, script, and remote service it might need. That looks convenient until each agent needs a separate credential path, tool configuration, update path, audit trail, failure mode, and recovery plan.

LocalMCP is an experiment in putting a narrow operational boundary between agents and integrations. It is not a giant all-in-one MCP and it is not a replacement for vendor APIs. It is a small gateway that decides whether an agent may invoke a known tool through a known integration, under a defined policy.

Keep the gateway available. Start integrations only when they are actually needed. Deny unknowns by default.

What stays running

The control plane is intentionally small: a gateway process, a local state store for metadata, policy configuration, and a read-only operations view. It is designed to be boring at idle.

The dashboard is telemetry, not an unauthenticated command shell. It reports unavailable or no-data states instead of painting fictional green indicators.

What does not stay running

Individual MCP integrations are independently managed and launched on demand over standard input/output. A request may cold-start an integration, keep it warm briefly, then stop it after an idle period.

This avoids paying the memory, update, and attack-surface cost of running every possible integration all day.

Request flow

Agent request
   ↓
Authenticated identity check
   ↓
Known agent? Known integration? Known tool?
   ↓
Policy and risk decision
   ├─ deny unknown or destructive-by-default work
   ├─ request human approval for high-risk work
   └─ allow an authorized request
   ↓
Capacity check → start or reuse the integration
   ↓
Tool result + metadata-only audit event
   ↓
Warm briefly, then stop when idle

The boundary matters: an agent identity supplied in a request body is not trusted by itself. Unknown agents, servers, and tools are denied rather than silently admitted.

Four active identities, not an ever-growing registry

The current design has a deliberately fixed active inventory: Hermes, OpenClaw, Claude Code, and Codex. Historical or decommissioned agents are not treated as active just because they appear in an old document, screenshot, or backup.

RuleWhy it matters
Explicit active identity registryPrevents stale identities from reappearing through restore drift.
Authenticated identity requiredPrevents a caller from gaining access just by naming a trusted agent.
Unknown server/tool denialStops accidental expansion from becoming a permission grant.
Approval for higher-risk workKeeps an autonomous request from silently turning into a consequential mutation.

Secrets stay downstream

Agents should ask for a capability, not carry every underlying vendor credential. The gateway and integration layer keep credential material out of agent prompts, tool output, browser telemetry, and normal audit records.

Audit data records operational metadata—identity, tool, policy decision, timing, and outcome—not arguments, results, cookies, tokens, or schemas.

Control API is not a new public service

The administrative gateway binds only to the local host. RyanOS can provide a narrowly scoped, read-only telemetry path through its existing dashboard listener, but the LocalMCP control plane is not exposed directly to the LAN or Internet.

This preserves a useful operator view without converting the dashboard into a remote execution interface.

Resource limits are part of policy

Authorization is only half the decision. A tool may be permitted yet still not be admitted if the host does not have enough memory or concurrency headroom. The project has explicit limits for concurrent running and warm integrations, per-agent concurrency, and pressure protection.

That is a practical lesson from a small VM: reliability is not only about whether code works. It is also about whether the machine can safely absorb the work right now.

An installation lesson: validate effective permissions

The first production install surfaced a mundane but important fault. The service account existed, but its configuration files were too restrictive for that account to read. The result was a restart loop and an operations page correctly reporting the local API as unavailable.

The fix was not to loosen permissions globally. The installer was corrected so the non-secret configuration is readable by the service group while still remaining private. The remediation was then verified as the effective service account, followed by direct health, proxy-health, and dashboard checks.

A service that is enabled is not necessarily healthy. Validate the process, its effective file access, its listener, its API, and the user-facing path.

Backups must fail closed too

LocalMCP configuration is intended to have two independent recovery destinations: a private Git repository and a local SMB snapshot. But a path that merely exists is not proof of an SMB mount. The backup timer remains disabled until the destination is verified as the intended network filesystem and a manual dual-destination backup is checked.

This is deliberately less exciting than declaring a backup complete. It is also much more useful during a real restore.

What is live today

  • A loopback-only LocalMCP gateway with a fixed four-agent inventory.
  • Read-only operational telemetry integrated into the existing RyanOS dashboard.
  • On-demand integration lifecycle design with bounded resource admission.
  • Fail-closed policy defaults, metadata-only audit configuration, and approval gates for higher-risk work.
  • Private source control and a standalone recovery/documentation trail.

What is intentionally not claimed: a catalog entry does not imply a vendor integration is installed, configured, or authorized. Unavailable integrations should remain unavailable until they have a real implementation, policy, and credentials in the proper downstream boundary.

Takeaway

MCP is powerful because it connects models to action. That same property makes operational boundaries non-optional. LocalMCP is my attempt to make those boundaries explicit: start small, identify callers, allow only known tools, preserve human approval where it matters, keep control local, and make missing data honest.

The goal is not more infrastructure. It is a smaller amount of infrastructure that can safely connect a growing agent fleet to the capabilities it actually needs.