Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,28 @@ To reduce the chance of running in to this issue:
- Try to be specific, keep your queries concise.
- If a single request calls multiple tools, try to to break it into several smaller tool calls to keep the responses short.

## Tool-level policy enforcement

These MCP servers expose tools that can create and delete D1 databases, R2 storage buckets, KV namespaces, and Hyperdrive configurations — as well as execute arbitrary commands in containers. Cloudflare OAuth controls which tools are available, but not how often or how aggressively an agent uses them once access is granted.

You can add rate limits, daily caps, and access control by wrapping the server with [PolicyLayer Intercept](https://github.com/policylayer/intercept), an open-source MCP proxy:

```sh
npx -y @policylayer/intercept \
--policy policies/recommended.yaml \
-- npx mcp-remote https://bindings.mcp.cloudflare.com/mcp
```

Three policy presets are included in [`/policies`](/policies):

| Policy | Description |
|--------|-------------|
| `recommended.yaml` | Rate limits on writes, blocks destructive operations (delete databases, buckets, namespaces), reads allowed freely |
| `strict.yaml` | Default deny — only read and observability tools allowed unless explicitly opted in |
| `permissive.yaml` | Everything allowed, rate limits on destructive and resource-creation operations |

Policies are YAML files you can customise. See the [Intercept docs](https://github.com/policylayer/intercept) for the full policy reference.

## Paid Features

Some features may require a paid Cloudflare Workers plan. Ensure your Cloudflare account has the necessary subscription level for the features you intend to use.
Expand Down
81 changes: 81 additions & 0 deletions policies/permissive.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
version: "1"
description: "Cloudflare MCP — permissive policy. All tools allowed. Rate limits on destructive and resource-creation operations."
default: allow

tools:
# Destructive tools — rate limited even in permissive mode
kv_namespace_delete:
rules:
- name: "rate-limit"
rate_limit: "5/hour"
on_deny: "Max 5 KV namespace deletions per hour"

r2_bucket_delete:
rules:
- name: "rate-limit"
rate_limit: "5/hour"
on_deny: "Max 5 R2 bucket deletions per hour"

d1_database_delete:
rules:
- name: "rate-limit"
rate_limit: "5/hour"
on_deny: "Max 5 D1 database deletions per hour"

hyperdrive_config_delete:
rules:
- name: "rate-limit"
rate_limit: "5/hour"
on_deny: "Max 5 Hyperdrive config deletions per hour"

container_file_delete:
rules:
- name: "rate-limit"
rate_limit: "10/hour"
on_deny: "Max 10 container file deletions per hour"

# Resource creation — rate limited
kv_namespace_create:
rules:
- name: "rate-limit"
rate_limit: "20/hour"
on_deny: "Max 20 KV namespace creations per hour"

r2_bucket_create:
rules:
- name: "rate-limit"
rate_limit: "20/hour"
on_deny: "Max 20 R2 bucket creations per hour"

d1_database_create:
rules:
- name: "rate-limit"
rate_limit: "20/hour"
on_deny: "Max 20 D1 database creations per hour"

hyperdrive_config_create:
rules:
- name: "rate-limit"
rate_limit: "20/hour"
on_deny: "Max 20 Hyperdrive config creations per hour"

# Container execution — rate limited
container_exec:
rules:
- name: "rate-limit"
rate_limit: "120/hour"
on_deny: "Max 120 container commands per hour"

# GraphQL queries — rate limited
graphql_query:
rules:
- name: "rate-limit"
rate_limit: "120/hour"
on_deny: "Max 120 GraphQL queries per hour"

# Global safety net
"*":
rules:
- name: "global-rate-limit"
rate_limit: "120/minute"
on_deny: "Global rate limit — max 120 tool calls per minute"
130 changes: 130 additions & 0 deletions policies/recommended.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
version: "1"
description: "Cloudflare MCP — recommended policy. Rate limits on writes, blocks destructive operations, reads allowed freely."
default: allow

tools:
# Destructive tools — blocked by default
# These permanently destroy databases, storage buckets, and KV namespaces.
# Uncomment and add rate limits if you need them.
kv_namespace_delete:
rules:
- action: deny
on_deny: "KV namespace deletion blocked by policy — remove this rule if you need to delete namespaces"

r2_bucket_delete:
rules:
- action: deny
on_deny: "R2 bucket deletion blocked by policy — remove this rule if you need to delete buckets"

d1_database_delete:
rules:
- action: deny
on_deny: "D1 database deletion blocked by policy — remove this rule if you need to delete databases"

hyperdrive_config_delete:
rules:
- action: deny
on_deny: "Hyperdrive config deletion blocked by policy — remove this rule if you need to delete configs"

container_file_delete:
rules:
- action: deny
on_deny: "Container file deletion blocked by policy"

# Write tools — moderate rate limits
kv_namespace_create:
rules:
- name: "burst-limit"
rate_limit: "5/minute"
on_deny: "Slow down — max 5 KV namespace creations per minute"
- name: "hourly-cap"
rate_limit: "20/hour"
on_deny: "Max 20 KV namespace creations per hour"

r2_bucket_create:
rules:
- name: "burst-limit"
rate_limit: "3/minute"
on_deny: "Slow down — max 3 R2 bucket creations per minute"
- name: "hourly-cap"
rate_limit: "10/hour"
on_deny: "Max 10 R2 bucket creations per hour"

d1_database_create:
rules:
- name: "burst-limit"
rate_limit: "3/minute"
on_deny: "Slow down — max 3 D1 database creations per minute"
- name: "hourly-cap"
rate_limit: "10/hour"
on_deny: "Max 10 D1 database creations per hour"

hyperdrive_config_create:
rules:
- name: "burst-limit"
rate_limit: "3/minute"
on_deny: "Slow down — max 3 Hyperdrive config creations per minute"
- name: "hourly-cap"
rate_limit: "10/hour"
on_deny: "Max 10 Hyperdrive config creations per hour"

hyperdrive_config_edit:
rules:
- name: "rate-limit"
rate_limit: "10/hour"
on_deny: "Max 10 Hyperdrive config edits per hour"

kv_namespace_update:
rules:
- name: "rate-limit"
rate_limit: "20/hour"
on_deny: "Max 20 KV namespace updates per hour"

set_active_account:
rules:
- name: "rate-limit"
rate_limit: "10/hour"
on_deny: "Max 10 account switches per hour"

# Container tools — rate limited
container_exec:
rules:
- name: "burst-limit"
rate_limit: "10/minute"
on_deny: "Slow down — max 10 container commands per minute"
- name: "hourly-cap"
rate_limit: "60/hour"
on_deny: "Max 60 container commands per hour"

container_file_write:
rules:
- name: "rate-limit"
rate_limit: "30/hour"
on_deny: "Max 30 container file writes per hour"

# D1 queries — rate limited to prevent runaway queries
d1_database_query:
rules:
- name: "burst-limit"
rate_limit: "10/minute"
on_deny: "Slow down — max 10 D1 queries per minute"
- name: "hourly-cap"
rate_limit: "120/hour"
on_deny: "Max 120 D1 queries per hour"

# GraphQL queries — rate limited
graphql_query:
rules:
- name: "burst-limit"
rate_limit: "10/minute"
on_deny: "Slow down — max 10 GraphQL queries per minute"
- name: "hourly-cap"
rate_limit: "60/hour"
on_deny: "Max 60 GraphQL queries per hour"

# Global safety net
"*":
rules:
- name: "global-rate-limit"
rate_limit: "60/minute"
on_deny: "Global rate limit — max 60 tool calls per minute across all Cloudflare tools"
Loading