Rune Gurd docs

Known limits: MCP and network

What Rune Guard does not cover, or covers only in part, for MCP servers and tools, and for network egress.

Other device-side limits are in Known limits: devices and agents; Cloud and Console limits are in Known limits: Cloud and Console.

MCP

See MCP for the MCP features.

Inventory and tool checks

  • The inventory reads known config locations in your home directory, projects you name, and with --discover the projects harnesses have recorded plus those under configured search roots. Discovery stops at 256 projects and 4 levels by default (at most 4096 and 8). Projects outside the roots or past a bound are missed. guard mcp-inventory, guard scan and guard mcp-tools say which bound cut discovery short, and the Guard Cloud upload is then marked truncated; guard credentials, guard posture and guard assess don't say. A project with no version control directory, MCP project config or catalog marker file isn't found by the walk.
  • JetBrains AI Assistant's MCP servers are read from the XML layout releases 2025.1 to 2026.2 are known to write. JetBrains doesn't document it, so a release that changes it can drop servers without an error. Its state (turned-off servers, allowed tools) is applied to mcp.json servers of the same scope, but IDE-level state isn't applied to a project's mcp.json, since it isn't known whether the IDE does that. Other IDE-internal settings aren't read.
  • Config files that aren't JSON, JSONC, TOML, YAML or JetBrains settings XML aren't read.
  • The inventory inspects configuration, not traffic. What a server actually reads or sends is seen only through the sensor, harness MCP hooks or the MCP gateway.
  • Tool definitions are compared only when you run guard mcp-tools check. A hostile server can return different definitions to Guard than to the harness, and resources and prompts aren't pinned.
  • Tool poisoning checks are patterns. Paraphrased, translated, encoded or homoglyph instructions, and instructions split across tools, get past them. A finding is suspicion, not proof a model acted on the text.
  • Remote servers are identified by host. --probe-tls names an operator only from an OV or EV certificate's organization when the issuing CA permits that level, from a registry namespace that matches the host's domain, or, with --probe-oauth, from the OAuth issuers the server's metadata names. For the many servers with domain-validated certificates, no such registry entry and no OAuth metadata, the operator is unknown, so a move to another operator isn't noticed. Endpoints are compared only when you run the probe. Unless the catalog pins an endpoint's operator, the first operator seen is trusted. No live OV or EV server has been probed by the automated tests.

Tool access rules

  • In hooks, rules bind to the approved baseline, so a server that changes its tools after approval keeps its allow until the change is approved. The gateway binds to the definitions actually served.
  • Copilot CLI and harnesses without a Guard hook are covered only through the gateway.
  • Cursor servers launched by command without a name in the payload get the policy's default.
  • Resources and prompts aren't covered.

MCP gateway

  • The gateway is opt-in per server, and anyone who can edit the MCP configuration can remove it.
  • It supports stdio and Streamable HTTP only: not the legacy HTTP+SSE transport, WebSocket or OAuth discovery through the gateway.
  • It can't ask the user, so ask blocks.
  • Redaction covers known secret patterns only, and messages over max_message_bytes are dropped.
  • The call log stays on the device. Only bounded daily counts are uploaded. On packaged Linux, each user's running watch queues their counts for root sync; root does not read their raw logs, and a user without a running watch contributes no new counts.
  • Call identity decodes JWT claims without verifying signatures. Opaque tokens and credentials outside the Authorization header are reported as uninspectable. Expired and over-scoped tokens are logged, not blocked.
  • It was tested on macOS with fake clients and servers, not on Linux or Windows or live against each harness.
  • Chrome DevTools MCP has a separate retained macOS run with the published server, real headless Chrome and a direct protocol client. Only routed call observation, tool refusal and known-pattern textual redaction are qualified. This does not qualify a model, agent, extension, personal profile, Linux or Windows.
  • That run used disposable profiles and synthetic loopback pages under an outer OS fence. Chrome's nested sandbox could not start there and was disabled: a qualification constraint, not production guidance. Screenshots, arbitrary DOM behavior and encoded, split or unknown secrets remain unqualified.
  • Browser JavaScript, redirects and network traffic are outside upstream MCP destination policy. Allowed browser tools can cause those effects; unwrapped MCP and direct CDP bypass the gateway. See browser tools.
  • A server Guard didn't wrap counts as wrapped when its entry runs a program named guard with mcp-gateway stdio; Guard can't verify that program.
  • Managed adoption rewrites supported user stdio entries only. Remote servers, project files and unsupported formats/layouts are skipped. An exception or a removed wrapper leaves a path unmediated; inventory and counts do not prove complete traffic coverage.

MCP credentials

  • guard mcp-credentials was tested with the file provider only. Windows has no Credential Manager provider.
  • Continue's YAML, Codex inline-table servers, legacy SSE servers and credentials in arguments or URLs aren't migrated; they are reported.
  • Code running as the same user can use the store through the gateway, and the file key is readable by that user. Old copies of migrated credentials elsewhere aren't touched.

Registry and the Console's MCP page

  • Devices upload their MCP inventory on guard cloud sync when it changed, or on demand. Live upload after config changes needs guard cloud mcp-watch: the Linux package enables a user unit, and the Windows installers register a logon task.
  • Organization-wide blocks, exceptions and actions apply only from a published signed catalog, and only in harness hooks and the MCP gateway. Copilot CLI and the VS Code Copilot target count as harnesses without hooks here, because their hooks can't tell which server a call goes to. A user sensor reports matching launches as observed without stopping them. On Linux, root can use the local launch index authenticated from that same user, without reading their configs. Its freshness depends on their watch; macOS and Windows service sensors have no equivalent channel. Reputation is unknown.
  • On macOS and Windows, the system sensor (root or a service) doesn't report MCP server launches: it never reads users' MCP configs. There, a blocked server is caught only by a harness hook when the agent calls one of its tools, by guard mcp-gateway, or by a sensor run as the user. The Console still lists the server from the inventory upload, but can't show that it ran, and no launch findings is not proof that none started.
  • Tool names, definition digests and poisoning verdicts come from approved baselines only.
  • Servers run through docker, pipx, direct binaries or local paths have no package identity, and downloaded artifacts aren't checked against the registry's hash.
  • Look-alike detection uses edit distance, so a squat that differs by more edits isn't flagged.
  • The Console's block preview and server click-through read each device's newest MCP upload, not live configuration. A device that hasn't reached Guard Cloud in 48 hours is flagged as stale, not left out. Servers uploaded under a registry name before uploads carried the configured name's label stay possible for a label target until the device uploads again. Tool calls link to a server only where the harness writes the configured name unchanged or the way Claude Code rewrites it; a registry-name target links them only on devices whose inventory carries that label. Sessions and findings come from the last 30 days.

Network and egress

  • Egress destination rules are enforced in hooks only, from what a tool call says. Hooks don't resolve names, and run-time redirects are seen only by the sensor.
  • Programs outside the known egress tools, scripts in files and Git remotes named by alias aren't checked at hook time. Copilot CLI's MCP calls aren't covered.
  • Look-alike domains are distinct hosts, so only allowlists stop them.
  • Blocked-destination egress seen by the sensor is observed, never prevented, and needs a host name.
  • On Linux with eBPF, TLS sent through io_uring, sendmmsg or kernel TLS, QUIC handshakes and DNS over HTTPS lookups are missed. An SNI can be spoofed.
  • On macOS, egress comes from polling lsof, so short connections can be missed, until a Network Extension provider is installed. On Windows the sensor sees TCP connections with the bytes they send, and UDP datagrams.
  • The sensor records bytes sent, not what was sent. Correlation is per harness session and time window only.
  • Correlation state survives a sensor restart only when findings are stored, and session state needs the session's root process still running. When it can't be stored, the sensor reports correlation_not_persisted in its health, shown by guard doctor and the Console.
  • A pending credential read outlives its session only for a new run of the same agent started by the same parent process within the window. An agent started again from another terminal or a launcher isn't linked. A run that exited while the sensor was down is noticed only on macOS and Linux. The new run's findings name the earlier run and session rules continue across the restart, but its process tree and hook taint stay its own, and guard assess links its send to the earlier run's access only as a capped chain.
  • A credential read followed by contact with its service (credential_access_then_service_contact) shows only the order of the two steps, never that the credential was sent or used. .env files, .netrc, keychains, password managers and browser stores map to no single service. An SSH key links to a later start of ssh, scp or sftp, whatever server it reached; SSH through a library isn't seen. Environment reads are seen only in a command's arguments, including inline code that looks a variable up by name, never a program reading its own environment. A renamed or wrapped client reading its own credential counts as the agent's read. It hasn't been run live on a host.
  • DNS side channels (dns_side_channel_by_agent_process) are reported on Linux with eBPF only; macOS and Windows don't tie DNS queries to processes. Lookups over DNS over HTTPS or TLS, over TCP or through io_uring aren't seen. Names are judged by shape: data encoded in letters only, spread over fewer than 8 names, or sent slower than 8 names in 2 minutes isn't reported, and a legitimate service that hashes labels under one domain can be. It hasn't been run live on a host.
  • Regular AI API contact by a program that isn't an AI tool is a timing shape from flow metadata. It can't tell a command channel from a scheduled script. Nothing is reported for contact less often than every 15 minutes on average, at very irregular gaps, through a proxy or an unlisted host, or from a new process each time. Counting restarts with the sensor. The name allow list (Postman, Insomnia, Bruno) can be copied by a program that takes the same name.
  • Connections are observed to known AI endpoints only, so an in-process HTTP request isn't automatically treated as new egress.
  • Hosted DeepSeek, Kimi/Moonshot and Qwen API destinations are recognized independently of model names. This is provider metadata, not inference or hook coverage. Regional workspace patterns match one label only; IP-only pollers need an exact catalog host. Custom proxies and unknown hosts need organization catalog entries.

Written from docs/known-gaps.md, docs/mcp-registry.md, docs/mcp-gateway.md, docs/chrome-devtools-mcp.md, docs/hosted-models.md at commit fb79778d02f0. Rune Guard is in early access.