Enable default-deny mode

Problem: you want mcpgw to allow only explicitly listed tools and deny every other tool call.

Solution: set policy.default_action: deny and add allow rules for the tool names, prefixes, globs, or regexes you trust.

Recipe

policy:
  default_action: deny
  rules:
    - id: allow-filesystem-read
      action: allow
      when: { tool_glob: "fs_*read*" }
    - id: allow-git-readonly
      action: allow
      when: { tool_name_in: [git_log, git_diff, git_show] }
    - id: allow-db-readonly
      action: allow
      when: { tool_regex: "db_(select|describe)_.+" }

Reload with SIGHUP:

docker kill --signal=HUP mcpgw

Verify

Call an allowed tool and confirm it reaches the upstream. Then call an unlisted tool and confirm mcpgw returns HTTP 403 with JSON-RPC error -32001 policy_denied.

The audit log records unmatched denials with:

{ "action": "deny", "rule_id": "default_deny", "tool_name": "shell_exec" }

Use those default_deny lines to discover tools that need intentional allow rules:

jq -r 'select(.rule_id == "default_deny") | .tool_name' audit.jsonl | sort | uniq -c | sort -rn

Notes

  • Missing default_action means allow, preserving older configs.
  • Set only one matcher per rule: tool_name, tool_prefix, tool_glob, tool_regex, or tool_name_in.
  • tool_regex is anchored to the full tool name. db_select does not match x_db_select unless the regex says it should.