fracta.yaml that filters which tools agents see in tools/list and which they can invoke via tools/call. Enforcement happens twice — at visibility build time (tools the agent can’t see don’t appear in their tool list) and at request time (a denied tool call returns a structured error).
This page covers the policy shape, where it sits in your config, and the workflow for verifying enforcement end-to-end.
For the CLI ref, see fracta debug gateway policy. For the broader catalog narrative, see MCP Catalog Workflow.
The policy shape
Atool_policy block under any mcp_servers.servers.<id> entry carries two optional lists:
| Field | Behaviour | When to use |
|---|---|---|
allow_only | Whitelist. Only tools matching one of these names are visible. Everything else on the backend is denied. | When you know the small set of tools agents should use. |
deny | Blacklist. Tools matching one of these names are denied; everything else is allowed. | When the backend has a few risky tools but most are fine. |
<server>. namespace prefix the gateway adds when proxying. So ping matches fracta-test-server.ping.
Both lists support exact names, * as wildcard, and prefix* glob matching (spec-47 §2A). allow_only: [read_*] lets read_file, read_url, etc. through and denies everything else.
You can combine them: allow_only runs first, then deny narrows further.
Default behaviour without a policy
Omittool_policy entirely (or leave both lists empty) and the gateway makes every tool the backend exposes visible to every agent. The default is permissive — policy is opt-in per server.
Where the policy lives
Two files matter:- Project
fracta.yaml— the source of truth operators commit and review. Edit thetool_policyblock here. - Gateway ConfigMap (k8s:
deployment/k8s/manifests/fracta-gateway.yaml; compose:deployment/configs/gateway.yaml) — what the running gateway pod actually reads.
tool_policy block to both locations until the live-sync command lands.
After editing the gateway ConfigMap on k8s:
Verifying enforcement
The verification workflow is the same in any deployment mode: ask the gateway what it sees, and confirm the visible/denied counts match what your policy declares.Snapshot the policy state
fracta debug gateway policy --verbose prints a per-tool breakdown:
+and-prefix every tool in the catalog.+is visible to agents;-is filtered out.[denied_by_policy]— yourallow_only/denyrules excluded the tool.[disabled_by_registry]— an operator turned the tool off explicitly viafracta config mcp tool disable.- The summary line counts (
Visible,Denied by policy,Disabled by registry) must add up toCatalog size.
--direct --gateway-url <url> bypasses the controlplane API and hits the gateway’s own debug endpoint directly. Use it from any directory — no fracta project required (spec-49 §1.4).
If Has policies: false, the gateway never received a tool_policy block. Either it’s missing from the ConfigMap or the pod hasn’t restarted to pick it up.
Confirm at request time
The visibility check is one side of enforcement. The other is what happens when an agent (or a curl-wielding human) tries to call a denied tool. Drive an MCP request through the gateway and look at the response:isError: true flag plus the (blocked by policy or disabled) suffix are the gateway’s request-time signal that policy intervened. Agents see this just like any other tool error.
tools/list over the same connection returns only the visible tools — the denied ones never reach the agent at all, so well-behaved clients won’t even attempt the call.
Common patterns
Read-only access to a write-capable backend
A backend exposing bothread_* and write_* tools, where agents should only read:
Block a specific destructive tool, allow everything else
Block destructive tools but only allow a narrow set
deny always wins over allow_only — useful when a prefix glob would otherwise let through a tool you specifically want blocked.
Per-tool disable vs policy
tool_policy is the declarative approach (committed in YAML, reviewed in PRs, applies to every agent). For one-off operator overrides — disabling a specific tool while you investigate a misbehaving backend, for example — use the imperative fracta config mcp tool disable <server> <tool> which writes to the registry store.
Both gate the same visibility computation:
| Source | Persistence | Use for |
|---|---|---|
tool_policy in fracta.yaml | Git-tracked, ConfigMap-deployed | Long-lived per-environment rules |
fracta config mcp tool disable | Registry store (postgres/sqlite) | Operator-driven incident response or experimentation |
fracta debug gateway policy --verbose with the appropriate [denied_by_policy] or [disabled_by_registry] reason.
What’s next
fracta debug gateway policy— CLI ref for the verification command.fracta config mcp tool— imperative per-tool enable/disable.- MCP Server Examples —
tool_policyblock alongside the rest of an MCP server config. - Troubleshooting — what to check when agents report “tool not available” unexpectedly.

