Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
CF_API_TOKENNoCloudflare API token. Required if not using cf-mcp-setup.
CF_READ_ONLYNoSet false to allow mutating tools (future).true
CF_ACCOUNT_IDNoDefault account ID for account-scoped tools.
CF_ZONE_ALLOWLISTNoComma-separated zone names; zone-scoped tools refuse zones not in the list.

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
cf_list_accountsA

List Cloudflare accounts the configured API token can see.

Calls: GET /accounts (auto-paginated, up to 5 pages).

Returns the envelope (§6.5) with `data` = list of account dicts
(each has at least `id`, `name`, `type`, `created_on`).
cf_list_zonesA

List Cloudflare zones (domains) the token can see.

Args:
    account_id: optional account-ID filter. Defaults to CF_ACCOUNT_ID env
        var when set, otherwise lists across all accessible accounts.
    name_pattern: optional glob filter applied client-side (e.g.
        "*.example.*"). Cloudflare's API does not support glob, so this
        is a post-filter on the API response.
    max_pages: pagination cap (default 5 × per_page 50 = 250 zones).

Calls: GET /zones (auto-paginated).

Returns: envelope with `data = {zones: [...], count, ...}`.

**Compact projection** — each zone is reduced to id, name, status, paused,
type, created_on, modified_on, activated_on, development_mode,
account_id, account_name, plan_name. Full zone config (name_servers,
name_servers_history, owner, permissions, meta, etc.) is dropped to keep
multi-page walks under the 20K-token response ceiling. For full config,
use `cf_get_zone(zone_id)`.
cf_get_zoneA

Get full details for one zone (plan, name servers, settings summary, status).

Args:
    zone_id: 32-char Cloudflare zone ID.

Calls: GET /zones/{zone_id}.

Allowlist enforcement runs AFTER the API call (we need the zone name to
check against the list). If the zone is outside the allowlist, returns
`zone_not_allowed` error — but a CF quota call has been spent.
cf_resolve_zoneA

Look up a zone ID by its name (the canonical DNS name).

Args:
    zone_name: e.g. "example.com". Trailing dots are stripped.

Calls: GET /zones?name=<zone_name>&match=all.

Returns: envelope with `data = {zone_id, zone_name, account_id, ...}`.

Errors:
  - zone_not_allowed when the resolved zone is outside CF_ZONE_ALLOWLIST.
  - not_found when zero zones match.
  - validation when more than one zone matches the same name (rare but
    possible across multiple accounts — agent must disambiguate).
cf_list_rulesetsA

List all rulesets visible at the given scope.

Args:
    scope: 'zone' or 'account'.
    scope_id: matching Cloudflare ID.

Calls: GET /{zones|accounts}/{scope_id}/rulesets.

Returns: envelope with `data = {rulesets: [...], count, scope, scope_id}`.
Each ruleset summary has: id, name, description, kind (managed/custom/zone),
version, last_updated, phase.
cf_get_rulesetA

Fetch a single ruleset including all its rules.

Args:
    scope: 'zone' or 'account'.
    scope_id: matching CF ID.
    ruleset_id: 32-char ruleset ID.

Calls: GET /{zones|accounts}/{scope_id}/rulesets/{ruleset_id}.

Returns: envelope with `data` = full ruleset dict including `rules[]`.
cf_get_entrypoint_rulesetA

Get the ordered list of rules deployed at a zone's entrypoint for a phase.

The "entrypoint ruleset" is the in-line custom ruleset Cloudflare runs
at a given phase. For most WAF/rate-limit investigations this is the
ruleset you want — it shows what's actually executing, in order.

Args:
    zone_id: 32-char Cloudflare zone ID.
    phase: phase name. Common values:
        - http_request_firewall_custom (custom WAF rules)
        - http_request_firewall_managed (managed WAF deployments)
        - http_ratelimit (rate-limiting rules)
        - http_request_sbfm (Super Bot Fight Mode rules)
        - http_request_transform (Transform Rules — request)
        - http_request_origin (Origin Rules)

Calls: GET /zones/{zone_id}/rulesets/phases/{phase}/entrypoint.

Returns: envelope with `data` = the entrypoint ruleset dict including
its ordered `rules[]`.
cf_get_ruleA

Look up a single rule by ID.

Cloudflare exposes rule lookup via the parent ruleset; this is a
convenience wrapper that fetches the ruleset and projects the matching
rule. Used heavily for "what does rule X do" resolution when a firewall
event reports an unknown rule ID.

Args:
    scope: 'zone' or 'account'.
    scope_id: matching CF ID.
    ruleset_id: parent ruleset ID.
    rule_id: rule ID to extract.

Calls: GET /{zones|accounts}/{scope_id}/rulesets/{ruleset_id} → project rule.

Errors:
    not_found when the ruleset returns 200 but no rule matches the ID.
cf_list_custom_rulesA

Convenience: list a zone's custom WAF rules (http_request_firewall_custom).

Equivalent to `cf_get_entrypoint_ruleset(zone_id, "http_request_firewall_custom")`
but the return shape is normalized to `{rules: [...], count, zone_id}`.
cf_list_rate_limit_rulesB

Convenience: list a zone's rate-limit rules (http_ratelimit phase).

Same shape as `cf_list_custom_rules` but targets a different phase.
cf_list_managed_rulesetsC

List managed ruleset deployments at a zone's firewall_managed phase.

These are the Cloudflare Managed Ruleset and OWASP Core Ruleset that
are deployed against incoming requests. Each deployment includes
severity overrides, exposed-credentials check, etc.

Calls: GET /zones/{zone_id}/rulesets/phases/http_request_firewall_managed/entrypoint.

Returns: envelope with `data = {rules: [...], count, zone_id}`.
cf_get_managed_rule_detailsA

Look up details of a specific managed-ruleset rule (account-scoped).

Managed rulesets are owned by Cloudflare and live at the account scope;
individual managed rules are referenced from a zone's deployment.
This tool is the bridge: given a managed (ruleset_id, rule_id), it
returns the full rule definition so the agent can determine what the
rule actually matches (used for FP triage on managed-rule hits).

Calls: GET /accounts/{account_id}/rulesets/{ruleset_id} → project rule.
cf_get_bot_management_configA

Get the current Bot Management configuration for a zone.

Args:
    zone_id: 32-char Cloudflare zone ID.

Calls: GET /zones/{zone_id}/bot_management.

Returns: envelope with `data` = the full BM config dict, including:
    - fight_mode (bool)
    - using_latest_model (bool)
    - enable_js (bool)
    - sbfm_definitely_automated (str — block/allow/managed)
    - sbfm_likely_automated (str)
    - sbfm_verified_bots (str)
    - sbfm_static_resource_protection (bool)
    - optimize_wordpress (bool)
    - suppress_session_score (bool)
    - auto_update_model (bool)
    - ai_bots_protection (str — block/disabled)
cf_list_super_bot_fight_mode_configA

Get the Super Bot Fight Mode (SBFM) configuration projection.

Re-uses the same /bot_management endpoint as cf_get_bot_management_config
but projects only the SBFM-relevant fields — convenient when the agent
is specifically investigating bot-blocking behavior.

Args:
    zone_id: 32-char Cloudflare zone ID.

Returns: envelope with `data` = {definitely_automated, likely_automated,
    verified_bots, static_resource_protection, optimize_wordpress,
    ai_bots_protection}.
cf_query_firewall_events_groupedA

Group firewall events by chosen dimensions over a time window.

Calls: POST /graphql, firewallEventsAdaptiveGroups dataset.

Args:
    zone_id: zone tag (32-char hex).
    since: RFC 3339 / ISO 8601 start, e.g. '2026-05-28T00:00:00Z'.
    until: ISO 8601 end, must be after `since`.
    group_by: dimensions to group on (e.g. ['action', 'clientCountryName']).
        See _FIREWALL_GROUP_DIMENSIONS for the allowed set.
    filters: extra Cloudflare filter terms (e.g. {'action': 'block',
        'clientCountryName': 'PL'}). Operators like `_in`, `_neq` may be
        appended to the key (e.g. 'action_in': ['block', 'managed_challenge']).
    limit: rows per page, clamped to [1, 500]. Default 50.
    cursor: opaque continuation token from a prior call's `next_cursor`.

Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
cf_query_firewall_events_rawA

Raw firewall events (one row per individual event) over a time window.

Calls: POST /graphql, firewallEventsAdaptive dataset.

Args:
    zone_id: zone tag.
    since, until: ISO-8601 time range.
    filters: extra filter terms.
    limit: rows per page, clamped to [1, 500]. Default 50.
    cursor: continuation token.
    verbose: when True, includes additional fields like userAgent,
        referer, rayName, clientRequestPath. Subject to the same
        ~20K-token response ceiling — narrow `limit` accordingly.

Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
cf_query_http_requests_groupedA

Group HTTP request analytics by chosen dimensions over a time window.

Calls: POST /graphql, httpRequestsAdaptiveGroups dataset.

Args:
    zone_id: zone tag.
    since, until: ISO-8601 time range.
    group_by: dimensions from _HTTP_GROUP_DIMENSIONS.
    filters: extra terms (e.g. {'edgeResponseStatus': 403,
        'clientRequestPath': '/oauth/token'}).
    limit: page size [1, 500].
    cursor: continuation token.

The grouped HTTP dataset also includes a `sum { visits, edgeResponseBytes }`
aggregate block when bytes/visit dimensions aren't already in group_by.

Returns: envelope with `data = {rows, count, page}` and `next_cursor`.
cf_query_http_requests_rawA

Raw HTTP request rows over a time window.

Calls: POST /graphql, httpRequestsAdaptive dataset.

Args, returns: see cf_query_firewall_events_raw — same shape, different
dataset. Use this for unsampled per-request drill-down on traffic patterns
(bot scores, cache statuses, origin response codes).
cf_query_bot_events_groupedA

Group bot-management events by dimensions over a time window.

Internally queries `firewallEventsAdaptiveGroups` with the
`source = "botManagement"` filter pre-applied — Cloudflare doesn't
expose a standalone `botManagementEventsAdaptiveGroups` dataset on
standard plans (verified against the live schema). Bot decisions
flow into the firewall-events dataset with that source tag.

Allowed `group_by` dimensions are the firewall set
(`_FIREWALL_GROUP_DIMENSIONS`). For per-request bot SCORE distribution
(`botScore`, `botScoreSrcName`), use `cf_query_http_requests_grouped`
instead — those fields live on the HTTP requests dataset, not the
firewall-events one.
cf_baseline_traffic_diffA

Compare attack-window traffic vs a prior baseline window on the same path.

Runs two `httpRequestsAdaptiveGroups` queries grouped by
`edgeResponseStatus` and `clientCountryName`, returning a side-by-side
diff suitable for the ATK archetype workflow.

Args:
    zone_id: zone tag.
    match_path: exact `clientRequestPath` to filter (e.g. '/oauth/token').
    attack_since, attack_until: ISO-8601 attack window.
    baseline_lookback_days: how many days before `attack_since` to align
        the baseline window (defaults to 7).

Calls: POST /graphql, two httpRequestsAdaptiveGroups queries.

Returns: envelope with `data = {attack: {...}, baseline: {...},
    window_seconds: N, zone_id, match_path}`.
cf_list_access_appsA

List Cloudflare Access applications configured at the account.

Calls: GET /accounts/{account_id}/access/apps (auto-paginated).

Returns: envelope with `data = {apps: [...], count, account_id}`.

**Compact projection**: each app is reduced to {id, name, domain, type,
session_duration, auto_redirect_to_identity, aud, created_at, updated_at}.
Cloudflare returns a much larger payload per app (policies, allowed_idps,
cors_headers, custom_pages, http_only_cookie_attribute, etc.) — at 50
apps × ~3.7KB this blows the 20K-token response ceiling. For full app
config, call `cf_get_access_app(account_id, app_id)`.
cf_get_access_appA

Get a single Access app, including its session and CORS configuration.

Calls: GET /accounts/{account_id}/access/apps/{app_id}.
cf_list_access_policiesA

List Access policies — either account-wide or for a specific app.

Args:
    account_id: account ID.
    app_id: when provided, returns policies attached to that app.
        When omitted, returns all account-level reusable policies.

Calls:
    - GET /accounts/{account_id}/access/apps/{app_id}/policies (app-scoped)
    - GET /accounts/{account_id}/access/policies (account-scoped)
cf_list_gateway_rulesA

List Cloudflare Gateway (Zero Trust DNS/network/HTTP) rules.

Args:
    account_id: account ID.
    rule_type: 'dns', 'network', or 'http'. Defaults to 'http'.

Calls: GET /accounts/{account_id}/gateway/rules with filter.
cf_list_warp_devicesB

List WARP-enrolled devices in the account.

Calls: GET /accounts/{account_id}/devices (auto-paginated).
cf_get_warp_deviceB

Get a single WARP device's posture and metadata.

Calls: GET /accounts/{account_id}/devices/{device_id}.
cf_list_service_tokensA

List Access service tokens — METADATA ONLY (never returns the secret).

Cloudflare's API only returns the token secret on creation, so this
endpoint's response is intrinsically metadata-only.

Calls: GET /accounts/{account_id}/access/service_tokens.
cf_list_identity_providersC

List configured Access Identity Providers (Okta, AzureAD, etc.).

Calls: GET /accounts/{account_id}/access/identity_providers.
cf_list_logpush_jobsA

List configured Logpush jobs at a given scope.

Args:
    scope: 'zone' or 'account'.
    scope_id: Cloudflare zone ID or account ID matching the scope.

Calls: GET /{zones|accounts}/{scope_id}/logpush/jobs.

Returns: envelope with `data = {jobs: [...], count: N, scope, scope_id}`.
Each job carries: id, dataset, destination_conf (redacted of secrets by
Cloudflare), enabled, frequency, last_complete, last_error, error_message.
cf_get_logpush_jobA

Get a single Logpush job's configuration + last delivery status.

Args:
    scope: 'zone' or 'account'.
    scope_id: Cloudflare zone ID or account ID matching the scope.
    job_id: Logpush job ID (integer-as-string from CF).

Calls: GET /{zones|accounts}/{scope_id}/logpush/jobs/{job_id}.
cf_build_dashboard_urlA

Construct a deep link into the Cloudflare dashboard for a given view.

Args:
    view_type: one of:
        security_events, waf_custom_rules, rate_limiting_rules,
        bot_management, analytics_traffic, logpush,
        access_apps, gateway_rules.
    account_id: Cloudflare account ID. Required for all views. Falls back
        to CF_ACCOUNT_ID env var when not supplied.
    zone: zone name or zone ID for zone-scoped views (e.g. "example.com").
    filters: optional `?key=value` query-string overrides (e.g.
        `{"action": "block"}` on security_events).

Returns: envelope with `data = {url, view_type, account_id, zone}`.

Errors:
    validation when view_type is unknown, account_id is missing, or a
    zone-scoped view was called without a zone.
cf_validate_wirefilterA

Best-effort syntactic check of a Cloudflare Wirefilter (Rules language) expression.

NOT a full grammar — catches balanced-paren violations, unknown operator
spellings, and obvious typos. A `{valid: true}` response does NOT
guarantee Cloudflare's evaluator will accept the expression at runtime.

Args:
    expression: the wirefilter source, e.g. `(http.request.uri.path
        contains "/admin" and ip.src in {1.2.3.4 5.6.7.8})`.

Returns: envelope with `data = {valid: bool, errors: list, expression}`.
Note: this tool returns success-envelope even when `valid=false`;
the validator's purpose IS to report syntactic issues.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/wojtekkura/cf-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server