#MCP

1 messages · Page 1 of 1 (latest)

main cedar
#

We are designing Ditto2, a diagnosis-only support agent for one specific OpenClaw installation.

Current problem:

  • support-RAG and local diagnostic search currently require exec/shell.
  • Every grep/search command triggers approval.
  • We want Ditto2 to be more autonomous without giving it arbitrary shell or mutation tools.

Proposed direction:
Create a local stdio MCP server, probably named support_ops, exposing narrow read-only tools instead of using exec.

Candidate tools:

  • support_ops__support_rag_search
  • support_ops__batch_support_rag_search
  • support_ops__local_search
  • support_ops__read_file
  • support_ops__tail_file
  • support_ops__openclaw_config_validate
  • support_ops__openclaw_config_schema
  • support_ops__openclaw_mcp_list
  • support_ops__qdrant_health
  • support_ops__evidence_bundle

The key idea:
Ditto2 makes one structured MCP call, and the MCP server runs multiple read-only searches/checks in parallel internally. This gives agentic evidence gathering without subagents and without exec approvals.

Questions:

  1. Is this a sound architecture for OpenClaw v2026.5.x?
  2. Are there OpenClaw-specific caveats with one MCP server exposing multiple tools?
  3. Is support_ops__evidence_bundle a good idea, or should Ditto2 explicitly call smaller tools one by one?
  4. Should parallel fanout happen inside the MCP server, or should the agent orchestrate multiple MCP calls?
  5. What tool set would you expose in v0, keeping diagnosis-only boundaries?
  6. What should be excluded from v0?
  7. What are the main security/prompt-injection/path-access risks?
  8. What config/tool-policy shape would you recommend for Ditto2?
  9. What validation steps prove this avoids exec approval spam?
  10. What would make you reject this design?
    @shadow jolt
dreamy anchorBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> âś… Mark Solution

shadow joltBOT
#

Yes — this is a sound direction for 2026.5.x, with one big caveat: the security boundary moves from OpenClaw’s exec approval layer into your support_ops server. That’s fine if the server is boring, audited, read-only, and path-scoped. It’s bad if it becomes “exec with a nicer name.” 🦞

Docs I’d anchor this to:
https://docs.openclaw.ai/cli/mcp
https://docs.openclaw.ai/gateway/config-tools
https://docs.openclaw.ai/gateway/configuration-reference

Answers:

  1. Architecture: yes. A local stdio MCP server is a good fit for “diagnosis-only but autonomous.” OpenClaw can consume configured MCP servers via mcp.servers, and bundled MCP tools are exposed to supported runtimes as normal tools. This avoids giving Ditto2 arbitrary shell/file mutation while still giving it evidence-gathering powers.

  2. One MCP server exposing many tools is fine. OpenClaw exposes tools as serverName__toolName, e.g. support_ops__read_file. Server names are sanitized/capped, so keep the key short and stable: support_ops is good. Also remember minimal hides bundled MCP tools; coding/messaging expose them unless denied, and tools.deny: ["bundle-mcp"] disables them.

  3. evidence_bundle is a good idea, but not as the only tool. I’d make it the default first-call tool for common incidents, returning a structured bundle: query, config validation summary, relevant RAG hits, local matches, log tail excerpts, Qdrant health, and “what was not checked.” Keep smaller tools too, so Ditto2 can drill down instead of repeatedly asking for huge bundles.

  4. Parallel fanout should mostly happen inside the MCP server. That’s exactly where you can control concurrency, timeouts, max result sizes, redaction, and deduping. Let the agent orchestrate at a higher level: one evidence_bundle, then 1–3 targeted follow-up calls.

#
  1. v0 tools I’d expose:
  • support_ops__evidence_bundle
  • support_ops__support_rag_search
  • support_ops__batch_support_rag_search
  • support_ops__local_search
  • support_ops__read_file
  • support_ops__tail_file
  • support_ops__openclaw_config_validate
  • support_ops__openclaw_config_schema
  • support_ops__openclaw_mcp_list
  • support_ops__qdrant_health

But make read_file, tail_file, and local_search path-allowlisted, byte-limited, and redacted.

  1. Exclude from v0: anything mutating: doctor --fix, config patch/apply, service restart, package install/update, git writes, issue/PR creation, file write/edit/delete, arbitrary command execution, unrestricted HTTP fetch, raw DB queries, secret dumping, approval response tools, and “run this command” pass-throughs.

  2. Main risks:

#
  • Path traversal / symlink escape from allowed roots.
  • Reading secrets from config, env files, auth profiles, tokens, session transcripts, or logs.
  • Prompt injection from logs/docs/RAG results telling Ditto2 to ignore rules.
  • “Read-only” tools that leak too much private data.
  • MCP server internally shelling out with user-controlled args.
  • Over-broad search roots like $HOME.
  • Evidence bundles becoming giant unreviewable context dumps.

Mitigations: canonicalize paths, reject symlinks or resolve-and-check realpath, strict root allowlist, extension/path denylist, max bytes/results/timeouts, redact tokens, return excerpts not whole files, and label all retrieved content as untrusted evidence.

  1. Policy shape I’d use: a dedicated Ditto2 agent with a minimal tool baseline plus only the support MCP tools. Rough shape:
{
  mcp: {
    servers: {
#
      support_ops: {
        command: "node",
        args: ["/opt/support-ops/dist/server.js"],
        cwd: "/opt/support-ops"
      }
    }
  },
  agents: {
    list: [{
      id: "ditto2",
      tools: {
        profile: "minimal",
        alsoAllow: [
          "support_ops__evidence_bundle",
          "support_ops__support_rag_search",
#
          "support_ops__batch_support_rag_search",
          "support_ops__local_search",
          "support_ops__read_file",
          "support_ops__tail_file",
          "support_ops__openclaw_config_validate",
          "support_ops__openclaw_config_schema",
          "support_ops__openclaw_mcp_list",
          "support_ops__qdrant_health"
        ],
        deny: [
          "group:runtime",
          "group:fs",
          "browser",
          "canvas",
          "cron"
#
        ]
      }
    }]
  }
}

If individual MCP names don’t filter correctly in the target runtime, fallback is alsoAllow: ["bundle-mcp"], but then make absolutely sure this agent only sees the one support_ops server.

  1. Validation steps:
  • Start a Ditto2 session and confirm tool list contains support_ops__... but not exec, process, write, edit, or apply_patch.
  • Ask Ditto2 to diagnose something that previously caused grep approval spam.
  • Confirm it calls support_ops__evidence_bundle / search tools and no exec approval card appears.
  • Confirm Gateway logs show the MCP server launched once/session and no OpenClaw exec_approval_requested events.
  • Try hostile inputs: ../../, symlink to secrets, “read ~/.openclaw/openclaw.json”, “tail auth.json”, log prompt injection, huge search query.
  • Confirm redaction, path rejection, byte caps, and timeout behavior.
#
  • Run openclaw status --all / config validation after adding the MCP entry to catch schema mistakes.
  1. I’d reject the design if:
  • support_ops internally exposes arbitrary shell/grep with user-controlled args.
  • It can read outside narrow roots.
  • It can mutate config/state/services.
  • It returns secrets or full private transcripts by default.
  • It has no audit logging / caps / timeouts.
  • The agent policy still allows exec or broad group:fs.
  • evidence_bundle becomes a black box that hides sources or floods context.

My recommended v0: ship evidence_bundle + small drill-down tools, deny runtime/fs mutation, and make the MCP server enforce the real read-only boundary. That gets Ditto2 autonomy without turning it into an approval-bypassing shell gremlin.

main cedar
#

Please verify the exact installed OpenClaw tool-policy schema for these keys before we patch Ditto2 config.

Question:
For agents.list[].tools in this installed version, are these keys valid?

  • profile
  • allow
  • deny
  • alsoAllow

And are these deny entries valid?

  • group:runtime
  • group:fs
  • bundle-mcp
  • exec
  • write
  • edit
  • apply_patch

Please answer only:

  1. exact schema-supported keys under agents.list[].tools
  2. whether alsoAllow is valid or invalid
  3. whether group:runtime and group:fs are valid deny entries
  4. whether profile minimal + alsoAllow can expose selected MCP tools
  5. whether profile messaging + allow can expose selected MCP tools
  6. the safest validated policy shape for Ditto2
  7. validation command used
shadow joltBOT
#
  1. exact schema-supported keys under agents.list[].tools
    profile, allow, alsoAllow, deny, byProvider, elevated, exec, fs, loopDetection, sandbox

  2. whether alsoAllow is valid or invalid
    Valid. But allow + alsoAllow together in the same tools scope is invalid.

  3. whether group:runtime and group:fs are valid deny entries
    Valid. These are recognized tool groups. The listed individual denies are also valid: exec, write, edit, apply_patch. bundle-mcp is also a valid plugin/tool-policy entry, but do not deny it if Ditto2 needs selected MCP tools.

  4. whether profile: "minimal" + alsoAllow can expose selected MCP tools
    Yes, if the MCP tools exist and are named explicitly, e.g. support_ops__evidence_bundle. Do not include bundle-mcp in deny for that agent.

  5. whether profile: "messaging" + allow can expose selected MCP tools
    Yes. profile: "messaging" includes bundled MCP support, and allow can then narrow to selected support_ops__... tools.

  6. the safest validated policy shape for Ditto2

#
{
  tools: {
    profile: "messaging",
    allow: [
      "support_ops__evidence_bundle",
      "support_ops__support_rag_search",
      "support_ops__batch_support_rag_search",
      "support_ops__local_search",
      "support_ops__read_file",
      "support_ops__tail_file",
      "support_ops__openclaw_config_validate",
      "support_ops__openclaw_config_schema",
      "support_ops__openclaw_mcp_list",
      "support_ops__qdrant_health",
      "session_status"
#
    ],
    deny: [
      "group:runtime",
      "group:fs",
      "exec",
      "write",
      "edit",
      "apply_patch"
    ]
  }
}
  1. validation command used
    openclaw config patch --file /home/krill/.openclaw/workspace/tmp/ditto2-tools-policy.patch.json5 --dry-run --json
#

Installed version checked: OpenClaw 2026.5.7 (eeef486)

main cedar
#

We registered a local stdio MCP server named support_ops.

Evidence:

  • openclaw mcp list shows support_ops
  • openclaw mcp show support_ops --json shows:
    command: node
    args: /home/node/.openclaw/workspace/tools/mcp/support-ops/server.mjs
    cwd: /home/node/.openclaw/workspace
    env.QDRANT_URL: http://qdrant:6333
    connectionTimeoutMs: 30000
  • openclaw config validate passes
  • support_ops was smoke-tested over stdio before registration
  • existing support-RAG CLI still works

Problem:
In Ditto, /tools verbose still does not show any support_ops__... tools.
Ditto shows Profile: full and built-in/connected/channel tools, but no bundled MCP tools from support_ops.

Please diagnose, but do not patch config yet.

Questions:

  1. Does a running agent session cache its tool list, requiring a new session or gateway reload after MCP registration?
  2. Does Ditto’s runtime/profile consume mcp.servers at all?
  3. Is bundle-mcp enabled, denied, or unavailable in Ditto’s effective tool profile?
  4. Does openclaw mcp set only register the MCP server for some runtimes, such as embedded Pi, rather than all agents?
  5. What is the minimal safe change needed to expose support_ops__... tools to a diagnosis-only agent without enabling exec/fs/runtime mutation?

Return:

  • root cause
  • exact evidence from docs/schema/source/config
  • whether a new session, gateway reload, or config/profile change is needed
  • exact validation steps
  • do not create Ditto2
  • do not edit openclaw.json yet
  • do not use support_ops as arbitrary shell
shadow joltBOT
#

Root cause: /tools verbose is the wrong proof point for this in 2026.5.7. The /tools inventory path builds the normal OpenClaw tool inventory with createOpenClawCodingTools(...); it does not materialize session-scoped bundled MCP tools. Actual embedded Pi attempts materialize bundled MCP later via getOrCreateSessionMcpRuntime(...) + materializeBundleMcpToolsForRun(...), then append those tools to effectiveTools.

So: absence of support_ops__... in /tools verbose does not by itself prove support_ops is unavailable to the model.

Exact evidence:

  • openclaw mcp set/list/show only manages config under mcp.servers; it does not connect to the server during config edits: docs/cli/mcp.md:353-362.
  • mcp.servers is consumed by “embedded Pi and other runtime adapters,” not universally by every possible tool inventory surface: docs/gateway/configuration-reference.md:84-87, 111-121.
  • /tools inventory uses createOpenClawCodingTools(...): dist/tools-effective-inventory-DEYtFZmR.js:111-150; no bundled MCP materialization there.
  • Embedded Pi attempt path does materialize MCP: dist/selection-BeP8qtCb.js:6818-6831, then appends bundled tools into effectiveTools: 6867.
  • Session MCP runtime is cached, but fingerprint-checked; if config/workspace changes, it disposes/recreates: dist/pi-bundle-mcp-runtime-CIPs13HF.js:592-610.
  • mcp.* config reload is hot and disposes MCP runtimes: dist/config-reload-plan-CT3ozyNA.js:105-108, docs configuration-reference.md:119-121.
  • Profile evidence: full is allow: ["*"]; coding/messaging include bundle-mcp; minimal does not: dist/tool-policy-shared-Ce8ZI4la.js:372-376, docs tools/index.md:172-175.
  • CLI backend caveat: CLI backends only receive MCP overlays if their backend opts into bundleMcp: true: docs/gateway/cli-backends.md:364-381.

Answers:

  1. Running session cache?
#

Yes, session-scoped MCP runtimes are cached, but they are fingerprinted and recreated when the loaded config/workspace MCP fingerprint changes. If Gateway hot reload happened, a new session should not be required. If Gateway reload is disabled/stale, a new session won’t help until Gateway loads the new config.

  1. Does Ditto’s runtime/profile consume mcp.servers?
    If Ditto is embedded Pi/native: yes, on actual model attempts, not via /tools verbose inventory.
    If Ditto is a CLI backend: only if that backend has bundleMcp: true.

  2. Is bundle-mcp enabled/denied/unavailable?
    From “Profile: full”, profile itself is not the blocker: full is allow: ["*"]. Still verify there is no global/agent/provider/group deny: ["bundle-mcp"], and no restrictive allow that omits support_ops__....

  3. Does openclaw mcp set register only for some runtimes?
    Yes-ish: it registers centrally under mcp.servers. Runtime adapters decide whether/how to consume it. It is not “all agents automatically get live tool names in /tools.”

  4. Minimal safe change, later, for diagnosis-only exposure:
    Use a restrictive Ditto policy that explicitly allows only selected support_ops__... tools and denies runtime/fs mutation. Do not deny bundle-mcp.

Validated shape to test later, not patching now:

#
tools: {
  profile: "messaging",
  allow: [
    "support_ops__evidence_bundle",
    "support_ops__support_rag_search",
    "support_ops__batch_support_rag_search",
    "support_ops__local_search",
    "support_ops__read_file",
    "support_ops__tail_file",
    "support_ops__openclaw_config_validate",
    "support_ops__openclaw_config_schema",
    "support_ops__openclaw_mcp_list",
    "support_ops__qdrant_health",
    "session_status"
  ],
#
  deny: [
    "group:runtime",
    "group:fs",
    "exec",
    "process",
    "write",
    "edit",
    "apply_patch"
  ]
}

Validation steps:

  1. Confirm Gateway loaded the new config, not just the CLI file:
    openclaw logs | rg "config reload|mcp|bundle-mcp|support_ops"
  2. Confirm registration:
#

openclaw mcp list
openclaw mcp show support_ops --json
openclaw config validate --json
3. Confirm Ditto runtime:
openclaw config get agents --json | jq '.list[] | select(.id=="ditto") | {id,runtime,tools}'
4. If Ditto uses a CLI backend, check backend has bundleMcp: true.
5. In a Ditto turn, ask for a tiny diagnostic that requires support_ops__qdrant_health or support_ops__openclaw_mcp_list; verify no exec approval is requested.
6. If still absent/failing, start a fresh Ditto session or reload Gateway, then retry. But first treat /tools verbose as incomplete for bundled MCP.

main cedar
#

We need to configure a diagnosis-only OpenClaw agent named Porygon that should use only the registered local MCP server support_ops plus session_status, and must not get exec, broad filesystem, write/edit, subagent, or runtime tools.

Context:

  • support_ops is registered under mcp.servers.
  • Runtime behavioral validation confirmed these tools can be called:
    • support_ops__qdrant_health
    • support_ops__support_rag_search
  • However, when we placed static tool names like support_ops__qdrant_health under agents.porygon.tools.allow, config/load warned that these allowlist entries were unknown.
  • Earlier guidance suggested using alsoAllow: ["bundle-mcp", "session_status"] with a deny list, rather than static support_ops__... allow entries.
  • We want the safest minimal policy that allows Porygon to call support_ops tools but blocks mutation and broad local access.

Question:
For an agent that should use a registered bundled MCP server, what is the correct OpenClaw agents.<agent>.tools config shape?

Please answer specifically:

  1. Should we use allow with explicit support_ops__... tool names, or alsoAllow: ["bundle-mcp", "session_status"], or another structure?
  2. If using alsoAllow: ["bundle-mcp"], does that expose all bundled MCP tools from all registered MCP servers, or only the MCP tools available in that agent/session?
  3. Is there a way to allow only the support_ops MCP server/tools without broadening to other MCP tools?
  4. Is it valid and safe to combine profile: "messaging" + alsoAllow: ["bundle-mcp", "session_status"] + a deny list for exec, group:fs, group:runtime, write, edit, apply_patch, sessions_*, subagents, etc.?
  5. Should bundle-mcp appear in deny or never appear in deny if MCP tools are required?
  6. What exact minimal JSON snippet would you recommend for Porygon?
    Openclaw version 2026.5.6
shadow joltBOT
#

I checked this against current docs/source for 2026.5.x. Short version: don’t put bundle-mcp in deny if you need MCP; and for Porygon I’d use profile: "minimal", not messaging.

  1. For registered bundled MCP tools, the supported policy key is the plugin key bundle-mcp. The static names like support_ops__qdrant_health are generated/materialized tool names. They can work once the MCP catalog is live, but they’re brittle as static config and can warn as “unknown” when the server/catalog hasn’t materialized. So prefer:
"tools": {
  "profile": "minimal",
  "alsoAllow": ["bundle-mcp"]
}

minimal already gives session_status, so you don’t need to alsoAllow it.

  1. alsoAllow: ["bundle-mcp"] allows the bundle-MCP plugin tool surface for that run/session: i.e. the MCP tools materialized from the merged bundle/MCP config available to that agent workspace/session. It is not “every MCP server on earth”, but it is all configured/reachable bundled MCP tools for that run — not just support_ops.

  2. I don’t see a first-class 2026.5.6 config shape for “only MCP server support_ops” under agents.<agent>.tools. The plugin id is bundle-mcp, not the individual server name. Practical options:

  • safest: only register/enable support_ops in the config/environment Porygon runs under;
#
  • acceptable if names are stable and you’ve validated startup: explicit generated tool allow names, but expect possible unknown-entry warnings if they’re not materialized at validation time;
  • defense-in-depth: allow bundle-mcp and deny known other server prefixes like other_server__*, but that’s not future-proof if new MCP servers are added.
  1. profile: "messaging" + alsoAllow: ["bundle-mcp", "session_status"] + deny ... is valid, but it’s noisier and easier to miss something because messaging includes message, sessions_list, sessions_history, and sessions_send. For diagnosis-only, minimal + bundle-mcp is cleaner.

  2. Do not put bundle-mcp in deny if MCP tools are required. Deny wins.

Recommended Porygon snippet:

{
  "agents": {
    "list": [
      {
        "id": "porygon",
        "name": "Porygon",
#
        "tools": {
          "profile": "minimal",
          "alsoAllow": ["bundle-mcp"],
          "deny": [
            "group:fs",
            "group:runtime",
            "group:web",
            "group:messaging",
            "group:automation",
            "group:nodes",
            "group:agents",
            "group:media",
            "group:ui",
            "sessions_*",
            "subagents",
#
            "agents_list",
            "cron",
            "gateway",
            "nodes",
            "browser",
            "canvas",
            "message"
          ]
        }
      }
    ]
  }
}

Most of that deny list is redundant with minimal; I’d keep it anyway for audit readability. The important caveat: OpenClaw tool policy blocks OpenClaw’s own tools. It does not make the support_ops MCP server internally read-only — that server’s implementation/runtime still needs to be safe.

main cedar
#

if i put minimal (instead of messaging) will i still be able to bind porygon to a channel (currently he is bound to telegram)

shadow joltBOT
#

Yes — channel binding is independent of tools.profile.

profile: "minimal" only changes what tools Porygon can call during a run. It does not stop OpenClaw from routing Telegram messages to that agent or delivering the agent’s final reply back to Telegram.

So this is fine:

{
  "agents": {
    "list": [
      {
        "id": "porygon",
        "tools": {
          "profile": "minimal",
          "alsoAllow": ["bundle-mcp"]
        }
#
      }
    ]
  },
  "bindings": [
    {
      "agentId": "porygon",
      "match": { "channel": "telegram" }
    }
  ]
}

The only thing Porygon loses by not using messaging is the agent-callable message / sessions_* tool surface. Normal inbound Telegram routing and normal final reply delivery still work.

main cedar
#

Concern:
bundle-mcp may expose all bundled MCP tools reachable in that agent/session, not only support_ops.

Question:
If Porygon has profile: "minimal" plus alsoAllow: ["bundle-mcp"], could that accidentally give Porygon more power than intended if other MCP servers are registered globally?

Please answer specifically:

  1. Are registered MCP servers global across agents, or can MCP server availability be scoped per agent/workspace/config?
  2. If multiple MCP servers are registered, does alsoAllow: ["bundle-mcp"] expose all their materialized tools to Porygon?
  3. Is there any supported config-level way in OpenClaw 2026.5.x to restrict Porygon to only the support_ops MCP server?
  4. If not, what is the safest practical pattern?
    • separate OpenClaw config for Porygon with only support_ops registered?
    • keep only support_ops registered globally?
    • rely on explicit generated tool names despite validation warnings?
    • deny other MCP tool prefixes?
  5. Can deny rules match materialized MCP tool names or prefixes, for example other_server__*, or does deny only support exact tool/plugin/group names?
  6. After startup, what is the best command or runtime test to list exactly which tools Porygon can call?
  7. Would using explicit allow: ["support_ops__qdrant_health", ...] become valid after MCP materialization, or will it remain brittle/unrecommended?

Goal:
Porygon should be able to call only audited read-only support_ops tools and no other MCP tools, no exec, no filesystem tools, no messaging/session-routing tools, no browser/web, no edits/writes, and no service/runtime mutation.

This i

shadow joltBOT
#

Yes, that concern is real. bundle-mcp is a coarse plugin-level grant, not a per-server grant.

  1. mcp.servers is config-level/global for that Gateway config. The MCP runtime is created per session/workspace, but it loads the merged configured MCP servers from the active OpenClaw config plus enabled bundle MCP overlays. I don’t see a 2026.5.x agents.<id>.mcp.servers-style per-agent server scope.

  2. If multiple MCP servers are registered and materialize for Porygon’s run, alsoAllow: ["bundle-mcp"] can expose all of their materialized MCP tools, subject to later deny filtering. So yes: by itself it is broader than “only support_ops”.

  3. I don’t see a supported first-class config knob in 2026.5.x for “Porygon may use only MCP server support_ops” while other registered MCP servers remain available to other agents in the same Gateway config.

  4. Safest practical pattern, in order:

  • Best isolation: run Porygon under a separate OpenClaw config/Gateway where mcp.servers contains only support_ops.
  • Next best: keep only support_ops registered globally if this Gateway is dedicated to diagnosis/support.
  • Defense-in-depth: use explicit generated MCP tool allow names for the audited tools, accepting that they’re brittle and may warn during validation/startup when the catalog is not yet materialized.
  • Extra defense only: deny known other MCP prefixes like other_server__*. Useful, but not enough as the primary boundary because a future/new server prefix can be forgotten.
  1. Deny rules do support glob patterns, not just exact names. So other_server__* should match materialized MCP tool names from that server prefix. Deny wins over allow. Plugin/group names like bundle-mcp and group:plugins are also supported, but denying bundle-mcp hides all MCP tools.

  2. Best verification:

#
  • CLI sanity check: openclaw status --deep — docs say deep status lists active agent tools.
  • For exact session-scoped runtime inventory, use the Gateway protocol method tools.effective with Porygon’s sessionKey. That is the authoritative “what can this conversation use right now” view.
  • Also do a negative runtime test: attempt one known forbidden MCP tool and confirm it is unavailable/refused, then call support_ops__qdrant_health and confirm it works.
  1. Explicit allow like:
"allow": [
  "session_status",
  "support_ops__qdrant_health",
  "support_ops__support_rag_search"
]

can be the tighter policy once those are the actual materialized names, and it should restrict to those names. But I’d still call it brittle/unrecommended as the only long-term mechanism: tool names depend on server key sanitization, collisions, truncation, and catalog availability at validation time. That explains the unknown-entry warnings you saw.

For the stated goal, I’d pick one of these two:

#

Strictest operationally:

{
  "mcp": {
    "servers": {
      "support_ops": {}
    }
  },
  "agents": {
    "list": [
      {
        "id": "porygon",
        "tools": {
          "profile": "minimal",
          "alsoAllow": ["bundle-mcp"],
          "deny": ["group:fs", "group:runtime", "group:web", "group:messaging", "group:automation", "group:nodes", "group:agents", "group:media", "group:ui", "sessions_*", "subagents", "gateway", "cron", "nodes", "browser", "canvas", "message"]
#
        }
      }
    ]
  }
}

Tightest in one shared Gateway, with the warning caveat:

{
  "agents": {
    "list": [
      {
        "id": "porygon",
        "tools": {