Reference policies

Drop-in YAML for every popular MCP server

Five ready-to-use policies you can copy into your repo and adapt today. Each one is a sensible default — read it, adapt it, validate it.

Use the examples below as starting points, adapt them to your repo, and validate them with the Go-based CLI:

eunox-mcp validate ./eunox.policy.yaml
# reference the policy from a route's `policy:` in eunox.yaml, then:
eunox-mcp proxy --config ./eunox.yaml
Policy Upstream What it enforces
filesystem.policy.yaml @modelcontextprotocol/server-filesystem Writes & deletes confined to /data/; executable file types blocked.
postgres.policy.yaml @modelcontextprotocol/server-postgres Non-SELECT SQL blocked; credential and audit tables blocked.
github.policy.yaml @modelcontextprotocol/server-github Write tools rate-limited to prevent runaway automation.
slack.policy.yaml @modelcontextprotocol/server-slack Direct messages restricted to your domain via recipientDomain.
fetch.policy.yaml mcp-server-fetch HTTP blocked; userinfo authority blocked; private RFC-1918 and metadata endpoints blocked (lexical SSRF guard).

Filesystem

Stops the agent from reading sensitive file types and confines writes to a sandbox directory. argumentSchema is a top-level field on the constraint (not a condition); maxCalls uses count.

schemaVersion: "0.1"
name:    filesystem-agent
version: 0.1.0

capabilities:
  - target: tool:read_file
    actions: [call]
    conditions:
      - type: allowedExtensions
        argument: path
        extensions: [".csv", ".json", ".txt", ".md"]

  - target: tool:write_file
    actions: [call]
    argumentSchema:
      type: object
      required: [path, content]
      properties:
        path:    { type: string, pattern: "/data/.*" }
        content: { type: string }
      additionalProperties: false
    conditions:
      - type: allowedExtensions
        argument: path
        extensions: [".csv", ".json", ".txt", ".md"]
      - type: maxCalls
        count: 100
        windowSeconds: 60

  - target: tool:list_directory
    actions: [call]

Postgres

SELECT-only, with a per-session call cap. Table-level protection comes from running the upstream under a read-only database role — the proxy can't reliably pull table names out of free-form SQL, so it doesn't try.

schemaVersion: "0.1"
name:    postgres-agent
version: 0.1.0

capabilities:
  - target: tool:query
    actions: [call]
    conditions:
      - type: allowedOperations
        argument: sql
        operations: [SELECT, EXPLAIN, SHOW]
      - type: maxCalls
        count: 100
        windowSeconds: 60

GitHub

Read-heavy, write-rate-limited — protects against runaway issue or PR creation.

schemaVersion: "0.1"
name:    github-agent
version: 0.1.0

capabilities:
  - target: tool:search_repositories
    actions: [call]
  - target: tool:get_file_contents
    actions: [call]

  - target: tool:create_issue
    actions: [call]
    conditions:
      - type: maxCalls
        count: 10
        windowSeconds: 3600

  - target: tool:create_pull_request
    actions: [call]
    conditions:
      - type: maxCalls
        count: 5
        windowSeconds: 3600

Slack

Restricts DMs to your own domain — a single recipientDomain condition stops agents from leaking conversations. Channel posting (post_message) addresses Slack channel IDs (e.g. C12345), so a domain gate doesn't apply there.

schemaVersion: "0.1"
name:    slack-agent
version: 0.1.0

capabilities:
  - target: tool:send_dm
    actions: [call]
    conditions:
      - type: recipientDomain
        argument: to
        domains: [company.com]
      - type: maxCalls
        count: 20
        windowSeconds: 3600

  - target: tool:post_message
    actions: [call]
    conditions:
      - type: maxCalls
        count: 50
        windowSeconds: 3600

Fetch — lexical SSRF guard

Blocks http://, userinfo authorities, and private RFC-1918 ranges including the cloud metadata endpoint 169.254.169.254. The guard is implemented purely with argumentSchema + maxCalls — no custom condition module required. Read it as a defense-in-depth guard rather than a complete SSRF solution — pair with network-level controls in production.

schemaVersion: "0.1"
name:    fetch-agent
version: 0.1.0

capabilities:
  - target: tool:fetch
    actions: [call]
    argumentSchema:
      type: object
      required: [url]
      additionalProperties: false
      properties:
        url:
          type: string
          # https only; reject userinfo (user@host), loopback,
          # RFC-1918 ranges, and the 169.254/16 metadata endpoint.
          pattern: 'https://(?!(?:[^/]*@|localhost|127\.|10\.|192\.168\.|172\.(?:1[6-9]|2[0-9]|3[01])\.|169\.254\.)).*'
        method:
          type: string
          enum: [GET, HEAD, OPTIONS]
    conditions:
      - type: maxCalls
        count: 60
        windowSeconds: 60
Fail-closed by default. Absent entries are denied for every enforced MCP method — tools/call, resources/read, prompts/get, sampling/createMessage, and unrecognized methods. Only capabilities explicitly listed in the manifest are permitted.

Try one in 60 seconds →   Manifest guide