diff --git a/apps/docs/content/docs/integrations/cloudflare.mdx b/apps/docs/content/docs/integrations/cloudflare.mdx index 51f989bf172..cb154831a76 100644 --- a/apps/docs/content/docs/integrations/cloudflare.mdx +++ b/apps/docs/content/docs/integrations/cloudflare.mdx @@ -11,807 +11,5883 @@ import { BlockInfoCard } from "@/components/ui/block-info-card" /> {/* MANUAL-CONTENT-START:intro */} -Use [Cloudflare](https://cloudflare.com/) in Sim to manage zones, DNS records, cache, zone settings, WAF rules, rate limits, and Cloudflare Access. The actions also list SSL/TLS certificates and inspect R2 buckets, Workers, and Tunnels. +Use [Cloudflare](https://cloudflare.com/) in Sim to manage zones, DNS, cache, WAF rules, rate limits, and Zero Trust Access. Manage Worker routes and tunnels, configure R2 CORS and lifecycle rules, and read certificates, analytics, and Worker settings. + +Create a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) with the read or write permissions for the resources you use. Zone operations need a zone ID; Access, R2, Workers scripts, and tunnels need an account ID. + +For structured inputs, enter JSON or connect an upstream block output. DNS record data supports record-specific fields such as SRV priority, weight, port, and target. Cache purge files also accept JSON entries with a URL and cache-key headers. DNS tags and Access application tags and identity-provider IDs also accept JSON string arrays; use `[]` to clear these lists during an update. + +Read a resource before replacing it and resend the fields you want to keep. Access applications and policies, rules, tunnel configuration, R2 policies, and Worker routes have replacement semantics. Rulesets operations that expose `dry_run` can validate a request without saving it; successful validation may return empty resource fields. List operations return one page; use page numbers or the returned cursor to continue. {/* MANUAL-CONTENT-END */} ## Use the block [#usage-instructions] -Manage zones (domains), DNS records, SSL/TLS certificates, zone settings, DNS analytics, and cache purging. Configure WAF rulesets, managed rule overrides, and rate limiting rules through the current Rulesets engine. Administer Cloudflare Access (Zero Trust) applications, policies, groups, identity providers, and service tokens, and inspect R2 buckets, Workers scripts and routes, and Cloudflare Tunnels. +Manage Cloudflare DNS, zones, SSL, cache, and analytics. Configure WAF rulesets and rate limiting; administer Access applications, policies, groups, and service tokens; manage Worker routes and tunnels; and configure R2 buckets, CORS, and lifecycle rules. ## Actions -### Cloudflare List Zones +### Cloudflare Create Access Application -Lists all zones (domains) in the Cloudflare account. +Creates a Cloudflare Access (Zero Trust) application that puts an identity check in front of a hostname. Until at least one policy is attached the application denies everyone, so pair this with "Create Access Policy". Requires an API token with Account Access: Apps and Policies Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `name` | string | No | Filter zones by domain name \(e.g., "example.com"\) | -| `status` | string | No | Filter by zone status: "initializing", "pending", "active", or "moved" | -| `page` | number | No | Page number for pagination \(default: 1\) | -| `per_page` | number | No | Number of zones per page \(default: 20, max: 50\) | -| `accountId` | string | No | Filter zones by account ID | -| `order` | string | No | Sort field \(name, status, account.id, account.name, plan.id\) | -| `direction` | string | No | Sort direction \(asc, desc\) | -| `match` | string | No | Match logic for filters \(any, all\). Default: all | +| `destinations` | json | No | JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id. | +| `oauth_configuration` | json | No | JSON object. Required for end_user applications. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support \[RFC 8707\]\(https://datatracker.ietf.org/doc/html/rfc8707) \(Resource Indicators for OAuth 2.0\). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant. | +| `self_hosted_domains` | json | No | JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| `user_populations` | json | No | JSON array. Required for end_user applications. The single user population associated with this application. | +| `allow_authenticate_via_warp` | boolean | No | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| `allow_iframe` | boolean | No | Enables loading application content in an iFrame. | +| `cors_headers` | json | No | JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age. | +| `custom_non_identity_deny_url` | string | No | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| `custom_pages` | json | No | JSON array. The custom pages that will be displayed when applicable for this application | +| `eager_redirect_cookie_setting` | boolean | No | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| `enable_binding_cookie` | boolean | No | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| `http_only_cookie_attribute` | boolean | No | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| `mfa_config` | json | No | JSON object. Configures multi-factor authentication \(MFA\) settings. Fields: allowed_authenticators, mfa_disabled, session_duration. | +| `options_preflight_bypass` | boolean | No | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| `path_cookie_attribute` | boolean | No | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| `read_service_tokens_from_header` | string | No | Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the \(CF-Access-Client-Id, CF-Access-Client-Secret\) pair of headers. The header value will be interpreted as a json object similar to: \{ "cf-access-client-id": "<CLIENT_ID>", "cf-access-client-secret": "<CLIENT_SECRET>" \} | +| `same_site_cookie_attribute` | string | No | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| `scim_config` | json | No | JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri. | +| `service_auth_401_redirect` | boolean | No | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| `skip_interstitial` | boolean | No | Enables automatic authentication through cloudflared. | +| `use_clientless_isolation_app_launcher_url` | boolean | No | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| `app_launcher_logo_url` | string | No | The image URL of the logo shown in the App Launcher header. | +| `bg_color` | string | No | The background color of the App Launcher page. | +| `footer_links` | json | No | JSON array. The links in the App Launcher footer. Fields: name, url. | +| `header_bg_color` | string | No | The background color of the App Launcher header. | +| `landing_page_design` | json | No | JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title. | +| `skip_app_launcher_login_page` | boolean | No | Determines when to skip the App Launcher landing page. | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `type` | string | Yes | Application type: self_hosted, end_user, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be created through the API | +| `domain` | string | No | The primary hostname and path secured by Access, e.g. internal.example.com or example.com/admin. Required for the self_hosted, ssh, vnc, and rdp types; optional for bookmark and mcp_portal; read-only for app_launcher, warp, biso, and proxy_endpoint; and absent from the saas, infrastructure, and mcp variants | +| `name` | string | No | Friendly name shown in the dashboard and App Launcher | +| `sessionDuration` | string | No | How long an Access session stays valid, e.g. 24h or 30m | +| `allowedIdps` | string | No | Comma-separated identity provider IDs users may authenticate with. Leave empty to allow all configured providers | +| `appLauncherVisible` | boolean | No | Whether the application is shown in the App Launcher | +| `autoRedirectToIdentity` | boolean | No | Whether users skip the identity provider picker | +| `customDenyMessage` | string | No | Message shown to users who are denied access | +| `customDenyUrl` | string | No | URL denied users are redirected to | +| `logoUrl` | string | No | Logo image URL shown in the dashboard and App Launcher | +| `tags` | string | No | Comma-separated tag names categorizing the application | +| `policies` | string | No | JSON array of policies to attach. Entries may be reusable policy IDs or inline policy objects, e.g. \["<POLICY_ID>"\] | +| `saasApp` | string | No | JSON SaaS configuration, required for the saas type and rejected on every other type. SAML, e.g. \{ "auth_type": "saml", "consumer_service_url": "https://example.com/acs", "sp_entity_id": "https://example.com" \}; OIDC, e.g. \{ "auth_type": "oidc", "client_id": "...", "redirect_uris": \[ "https://example.com/callback" \] \} | +| `targetCriteria` | string | No | JSON array of infrastructure target criteria, required for the infrastructure and rdp types and rejected on every other type, e.g. \[\{"port":22,"protocol":"SSH","target_attributes":\{"hostname":\["production"\]\}\}\] | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `zones` | array | List of zones/domains | -| ↳ `id` | string | Zone ID | -| ↳ `name` | string | Domain name | -| ↳ `status` | string | Zone status \(initializing, pending, active, moved\) | -| ↳ `paused` | boolean | Whether the zone is paused | -| ↳ `type` | string | Zone type \(full, partial, secondary, or internal\) | -| ↳ `name_servers` | array | Assigned Cloudflare name servers | -| ↳ `original_name_servers` | array | Original name servers before moving to Cloudflare | -| ↳ `created_on` | string | ISO 8601 date when the zone was created | -| ↳ `modified_on` | string | ISO 8601 date when the zone was last modified | -| ↳ `activated_on` | string | ISO 8601 date when the zone was activated | -| ↳ `development_mode` | number | Seconds remaining in development mode \(0 = off\) | -| ↳ `plan` | object | Zone plan information | -| ↳ `id` | string | Plan identifier | -| ↳ `name` | string | Plan name | -| ↳ `price` | number | Plan price | -| ↳ `is_subscribed` | boolean | Whether the zone is subscribed to the plan | -| ↳ `frequency` | string | Plan billing frequency | -| ↳ `currency` | string | Plan currency | -| ↳ `legacy_id` | string | Legacy plan identifier | -| ↳ `account` | object | Account the zone belongs to | -| ↳ `id` | string | Account identifier | -| ↳ `name` | string | Account name | -| ↳ `owner` | object | Zone owner information | -| ↳ `id` | string | Owner identifier | -| ↳ `name` | string | Owner name | -| ↳ `type` | string | Owner type | -| ↳ `meta` | object | Zone metadata | -| ↳ `cdn_only` | boolean | Whether the zone is CDN only | -| ↳ `custom_certificate_quota` | number | Custom certificate quota | -| ↳ `dns_only` | boolean | Whether the zone is DNS only | -| ↳ `foundation_dns` | boolean | Whether foundation DNS is enabled | -| ↳ `page_rule_quota` | number | Page rule quota | -| ↳ `phishing_detected` | boolean | Whether phishing was detected | -| ↳ `step` | number | Current setup step | -| ↳ `vanity_name_servers` | array | Custom vanity name servers | -| ↳ `permissions` | array | User permissions for the zone | -| `total_count` | number | Total number of zones matching the query | +| `aud` | string | Audience tag. | +| `created_at` | string | created at | +| `id` | string | UUID. | +| `updated_at` | string | updated at | +| `allowed_idps` | array | The identity providers your users can select when connecting to this application. Defaults to all IdPs configured in your account. | +| `destinations` | array | List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| ↳ `overrides` | array | Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. Overrides are supported for public destinations and Worker destinations. | +| ↳ `behavior` | string | The behavior to apply to matching requests. Values: public. | +| ↳ `path_pattern` | string | The request path pattern to match. Wildcards \(`*`\) are supported, but each path segment may have at most one wildcard. Unlike the `uri` in public destinations, override path patterns do not implicitly cover subpaths; to do that, use a wildcard. | +| ↳ `type` | string | type Values: public, private, via_mcp_server_portal, worker, preview_worker, all_workers, all_preview_workers. | +| ↳ `uri` | string | The URI of the destination. Public destinations' URIs can include a domain and path with \[wildcards\]\(https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/). | +| ↳ `cidr` | string | The CIDR range of the destination. Single IPs will be computed as /32. | +| ↳ `hostname` | string | The hostname of the destination. Matches a valid SNI served by an HTTPS origin. | +| ↳ `l4_protocol` | string | The L4 protocol of the destination. When omitted, both UDP and TCP traffic will match. Values: tcp, udp. | +| ↳ `port_range` | string | The port range of the destination. Can be a single port or a range of ports. When omitted, all ports will match. | +| ↳ `vnet_id` | string | The VNET ID to match the destination. When omitted, all VNETs will match. | +| ↳ `mcp_server_id` | string | The MCP server id configured in ai-controls. | +| ↳ `worker_id` | string | The ID of the Cloudflare Worker whose preview deployments to protect with Access. | +| `domain` | string | The primary hostname and path secured by Access. This domain will be displayed if the app is visible in the App Launcher. | +| `name` | string | The name of the application. | +| `oauth_configuration` | json | **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. | +| ↳ `dynamic_client_registration` | json | Settings for OAuth dynamic client registration. | +| ↳ `allow_any_on_localhost` | boolean | Allows any client with redirect URIs on localhost. | +| ↳ `allow_any_on_loopback` | boolean | Allows any client with redirect URIs on 127.0.0.1. | +| ↳ `allowed_uris` | array | The URIs that are allowed as redirect URIs for dynamically registered clients. HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs must be explicitly configured and match exactly. | +| ↳ `enabled` | boolean | Whether dynamic client registration is enabled. | +| ↳ `enabled` | boolean | Whether the OAuth configuration is enabled for this application. When set to `false`, Access will not handle OAuth for this application. Defaults to `true` if omitted. Values: True. | +| ↳ `grant` | json | Settings for OAuth grant behavior. | +| ↳ `access_token_lifetime` | string | The lifetime of the access token. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| ↳ `session_duration` | string | The duration of the OAuth session. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| `self_hosted_domains` | array | List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| `type` | string | The application type. Values: end_user, self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, dash_sso, infrastructure, rdp, mcp, mcp_portal, proxy_endpoint. | +| `user_populations` | array | The single user population associated with this application. | +| `allow_authenticate_via_warp` | boolean | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| `allow_iframe` | boolean | Enables loading application content in an iFrame. | +| `app_launcher_visible` | boolean | Displays the application in the App Launcher. | +| `auto_redirect_to_identity` | boolean | When set to `true`, users skip the identity provider selection step during login. You must specify only one identity provider in allowed_idps. | +| `cors_headers` | json | cors headers | +| ↳ `allow_all_headers` | boolean | Allows all HTTP request headers. | +| ↳ `allow_all_methods` | boolean | Allows all HTTP request methods. | +| ↳ `allow_all_origins` | boolean | Allows all origins. | +| ↳ `allow_credentials` | boolean | When set to `true`, includes credentials \(cookies, authorization headers, or TLS client certificates\) with requests. | +| ↳ `allowed_headers` | array | Allowed HTTP request headers. | +| ↳ `allowed_methods` | array | Allowed HTTP request methods. | +| ↳ `allowed_origins` | array | Allowed origins. | +| ↳ `max_age` | number | The maximum number of seconds the results of a preflight request can be cached. | +| `custom_deny_message` | string | The custom error message shown to a user when they are denied access to the application. | +| `custom_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing identity-based rules. | +| `custom_non_identity_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| `custom_pages` | array | The custom pages that will be displayed when applicable for this application | +| `eager_redirect_cookie_setting` | boolean | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| `enable_binding_cookie` | boolean | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| `http_only_cookie_attribute` | boolean | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| `logo_url` | string | The image URL for the logo shown in the App Launcher dashboard. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| `options_preflight_bypass` | boolean | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| `path_cookie_attribute` | boolean | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| `read_service_tokens_from_header` | string | Allows matching Access Service Tokens passed HTTP in a single header with this name. | +| `same_site_cookie_attribute` | string | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| `scim_config` | json | Configuration for provisioning to this application via SCIM. This is currently in closed beta. | +| ↳ `authentication` | json | Multiple authentication schemes | +| ↳ `password` | string | Password used to authenticate with the remote SCIM service. | +| ↳ `scheme` | string | The authentication scheme to use when making SCIM requests to this application. Values: httpbasic, oauthbearertoken, oauth2, access_service_token. | +| ↳ `user` | string | User name used to authenticate with the remote SCIM service. | +| ↳ `token` | string | Token used to authenticate with the remote SCIM service. | +| ↳ `authorization_url` | string | URL used to generate the auth code used during token generation. | +| ↳ `client_id` | string | Client ID of the Access service token used to authenticate with the remote service. | +| ↳ `client_secret` | string | Client secret of the Access service token used to authenticate with the remote service. | +| ↳ `scopes` | array | The authorization scopes to request when generating the token used to authenticate with the remove SCIM service. | +| ↳ `token_url` | string | URL used to generate the token used to authenticate with the remote SCIM service. | +| ↳ `deactivate_on_delete` | boolean | If false, propagates DELETE requests to the target application for SCIM resources. If true, sets 'active' to false on the SCIM resource. Note: Some targets do not support DELETE operations. | +| ↳ `enabled` | boolean | Whether SCIM provisioning is turned on for this application. | +| ↳ `idp_uid` | string | The UID of the IdP to use as the source for SCIM resources to provision to this application. | +| ↳ `mappings` | array | A list of mappings to apply to SCIM resources before provisioning them in this application. These can transform or filter the resources to be provisioned. | +| ↳ `enabled` | boolean | Whether or not this mapping is enabled. | +| ↳ `filter` | string | A \[SCIM filter expression\]\(https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2) that matches resources that should be provisioned to this application. | +| ↳ `operations` | json | Whether or not this mapping applies to creates, updates, or deletes. | +| ↳ `create` | boolean | Whether or not this mapping applies to create \(POST\) operations. | +| ↳ `delete` | boolean | Whether or not this mapping applies to DELETE operations. | +| ↳ `update` | boolean | Whether or not this mapping applies to update \(PATCH/PUT\) operations. | +| ↳ `schema` | string | Which SCIM resource type this mapping applies to. | +| ↳ `strictness` | string | The level of adherence to outbound resource schemas when provisioning to this mapping. ‘Strict’ removes unknown values, while ‘passthrough’ passes unknown values to the target. Values: strict, passthrough. | +| ↳ `transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms the resource before provisioning it in the application. | +| ↳ `remote_uri` | string | The base URI for the application's SCIM-compatible API. | +| `service_auth_401_redirect` | boolean | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| `session_duration` | string | The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `skip_interstitial` | boolean | Enables automatic authentication through cloudflared. | +| `tags` | array | The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. | +| `use_clientless_isolation_app_launcher_url` | boolean | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| `policies` | array | policies | +| ↳ `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| ↳ `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| ↳ `connection_rules` | json | The rules that define how users may connect to targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| ↳ `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| ↳ `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| ↳ `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `created_at` | string | created at | +| ↳ `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | The UUID of the policy | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access policy. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| ↳ `account_id` | string | Identifier. | +| ↳ `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | +| `saas_app` | json | saas app | +| ↳ `auth_type` | string | Identifier of the authentication protocol used for the saas app. Required for OIDC. Values: saml, oidc. | +| ↳ `consumer_service_url` | string | The service provider's endpoint that is responsible for receiving and parsing a SAML assertion. | +| ↳ `created_at` | string | created at | +| ↳ `custom_attributes` | array | custom attributes | +| ↳ `friendly_name` | string | The SAML FriendlyName of the attribute. | +| ↳ `name` | string | The name of the attribute. | +| ↳ `name_format` | string | A globally unique name for an identity or service provider. Values: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified, urn:oasis:names:tc:SAML:2.0:attrname-format:basic, urn:oasis:names:tc:SAML:2.0:attrname-format:uri. | +| ↳ `required` | boolean | If the attribute is required when building a SAML assertion. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP attribute. | +| ↳ `name_by_idp` | array | A mapping from IdP ID to attribute name. | +| ↳ `idp_id` | string | The UID of the IdP. | +| ↳ `source_name` | string | The name of the IdP provided attribute. | +| ↳ `default_relay_state` | string | The URL that the user will be redirected to after a successful login for IDP initiated logins. | +| ↳ `idp_entity_id` | string | The unique identifier for your SaaS application. | +| ↳ `name_id_format` | string | The format of the name identifier sent to the SaaS application. Values: id, email. | +| ↳ `name_id_transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms an application's user identities into a NameID value for its SAML assertion. This expression should evaluate to a singular string. The output of this expression can override the `name_id_format` setting. | +| ↳ `public_key` | string | The Access public certificate that will be used to verify your identity. | +| ↳ `saml_attribute_transform_jsonata` | string | A \[JSONata\] \(https://jsonata.org/) expression that transforms an application's user identities into attribute assertions in the SAML response. | +| ↳ `sp_entity_id` | string | A globally unique name for an identity or service provider. | +| ↳ `sso_endpoint` | string | The endpoint where your SaaS application will send login requests. | +| ↳ `updated_at` | string | updated at | +| ↳ `access_token_lifetime` | string | The lifetime of the OIDC Access Token after creation. Valid units are m,h. Must be greater than or equal to 1m and less than or equal to 24h. | +| ↳ `allow_pkce_without_client_secret` | boolean | If client secret should be required on the token endpoint when authorization_code_with_pkce grant is used. | +| ↳ `app_launcher_url` | string | The URL where this applications tile redirects users | +| ↳ `client_id` | string | The application client id | +| ↳ `client_secret` | string | The application client secret, only returned on POST request. | +| ↳ `custom_claims` | array | custom claims | +| ↳ `name` | string | The name of the claim. | +| ↳ `required` | boolean | If the claim is required when building an OIDC token. | +| ↳ `scope` | string | The scope of the claim. Values: groups, profile, email, openid. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP claim. | +| ↳ `name_by_idp` | json | A mapping from IdP ID to claim name. | +| ↳ `grant_types` | array | The OIDC flows supported by this application | +| ↳ `group_filter_regex` | string | A regex to filter Cloudflare groups returned in ID token and userinfo endpoint | +| ↳ `hybrid_and_implicit_options` | json | hybrid and implicit options | +| ↳ `return_access_token_from_authorization_endpoint` | boolean | If an Access Token should be returned from the OIDC Authorization endpoint | +| ↳ `return_id_token_from_authorization_endpoint` | boolean | If an ID Token should be returned from the OIDC Authorization endpoint | +| ↳ `redirect_uris` | array | The permitted URL's for Cloudflare to return Authorization codes and Access/ID tokens | +| ↳ `refresh_token_options` | json | refresh token options | +| ↳ `lifetime` | string | How long a refresh token will be valid for after creation. Valid units are m,h,d. Must be longer than 1m. | +| ↳ `scopes` | array | Define the user information shared with access, "offline_access" scope will be automatically enabled if refresh tokens are enabled | +| `app_launcher_logo_url` | string | The image URL of the logo shown in the App Launcher header. | +| `bg_color` | string | The background color of the App Launcher page. | +| `footer_links` | array | The links in the App Launcher footer. | +| ↳ `name` | string | The hypertext in the footer link. | +| ↳ `url` | string | the hyperlink in the footer link. | +| `header_bg_color` | string | The background color of the App Launcher header. | +| `landing_page_design` | json | The design of the App Launcher landing page shown to users when they log in. | +| ↳ `button_color` | string | The background color of the log in button on the landing page. | +| ↳ `button_text_color` | string | The color of the text in the log in button on the landing page. | +| ↳ `image_url` | string | The URL of the image shown on the landing page. | +| ↳ `message` | string | The message shown on the landing page. | +| ↳ `title` | string | The title shown on the landing page. | +| `skip_app_launcher_login_page` | boolean | Determines when to skip the App Launcher landing page. | +| `target_criteria` | array | target criteria | +| ↳ `exclude` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `include` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `port` | number | The port that the targets use for the chosen communication protocol. A port cannot be assigned to multiple protocols. | +| ↳ `require` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `target_attributes` | json | Contains a map of target attribute keys to target attribute values. | +| ↳ `protocol` | string | The communication protocol your application secures. Values: RDP. | + +### Cloudflare Create Access Group + +Creates a new Access group. -### Cloudflare Get Zone +#### Input -Gets details for a specific zone (domain) by its ID. +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `apiKey` | string | Yes | Cloudflare API token | +| `exclude` | json | No | JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | +| `include` | json | Yes | JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | +| `is_default` | boolean | No | Whether this is the default group | +| `name` | string | Yes | The name of the Access group. | +| `require` | json | No | JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `created_at` | string | created at | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | UUID. | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `is_default` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access group. | +| `require` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | + +### Cloudflare Create Access Policy + +Creates a Cloudflare Access (Zero Trust) policy on an application, deciding who may reach it. A policy takes effect on live traffic as soon as it is created — an allow policy with a broad include rule grants access immediately. Requires an API token with Account Access: Apps and Policies Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to retrieve details for | +| `approval_groups` | json | No | JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid. | +| `connection_rules` | json | No | JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh. | +| `mfa_config` | json | No | JSON object. Configures multi-factor authentication \(MFA\) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration. | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID to attach the policy to | +| `name` | string | Yes | Name of the policy | +| `decision` | string | Yes | What the policy does when it matches: allow, deny, non_identity \(service tokens and other non-identity rules\), or bypass \(skip Access entirely\) | +| `include` | string | Yes | JSON array of Access rules evaluated with OR logic — matching any one selects the policy. Example: \[\{"email":\{"email":"user@example.com"\}\}\] or \[\{"email_domain":\{"domain":"example.com"\}\}\] | +| `exclude` | string | No | JSON array of Access rules evaluated with NOT logic — matching any one rejects the request | +| `require` | string | No | JSON array of Access rules evaluated with AND logic — all of them must match | +| `precedence` | number | No | Evaluation order of the policy within the application | +| `sessionDuration` | string | No | How long a session granted by this policy stays valid, e.g. 24h. Leave it unset on a policy attached to an infrastructure-typed application — Cloudflare rejects those with error 12130 | +| `approvalRequired` | boolean | No | Whether an approver must grant each access request | +| `isolationRequired` | boolean | No | Whether the session must run in a remote isolated browser | +| `purposeJustificationRequired` | boolean | No | Whether users must state a reason for access | +| `purposeJustificationPrompt` | string | No | Prompt shown when a justification is required | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Zone ID | -| `name` | string | Domain name | -| `status` | string | Zone status \(initializing, pending, active, moved\) | -| `paused` | boolean | Whether the zone is paused | -| `type` | string | Zone type \(full, partial, secondary, or internal\) | -| `name_servers` | array | Assigned Cloudflare name servers | -| `original_name_servers` | array | Original name servers before moving to Cloudflare | -| `created_on` | string | ISO 8601 date when the zone was created | -| `modified_on` | string | ISO 8601 date when the zone was last modified | -| `activated_on` | string | ISO 8601 date when the zone was activated | -| `development_mode` | number | Seconds remaining in development mode \(0 = off\) | -| `plan` | object | Zone plan information | -| ↳ `id` | string | Plan identifier | -| ↳ `name` | string | Plan name | -| ↳ `price` | number | Plan price | -| ↳ `is_subscribed` | boolean | Whether the zone is subscribed to the plan | -| ↳ `frequency` | string | Plan billing frequency | -| ↳ `currency` | string | Plan currency | -| ↳ `legacy_id` | string | Legacy plan identifier | -| `account` | object | Account the zone belongs to | -| ↳ `id` | string | Account identifier | -| ↳ `name` | string | Account name | -| `owner` | object | Zone owner information | -| ↳ `id` | string | Owner identifier | -| ↳ `name` | string | Owner name | -| ↳ `type` | string | Owner type | -| `meta` | object | Zone metadata | -| ↳ `cdn_only` | boolean | Whether the zone is CDN only | -| ↳ `custom_certificate_quota` | number | Custom certificate quota | -| ↳ `dns_only` | boolean | Whether the zone is DNS only | -| ↳ `foundation_dns` | boolean | Whether foundation DNS is enabled | -| ↳ `page_rule_quota` | number | Page rule quota | -| ↳ `phishing_detected` | boolean | Whether phishing was detected | -| ↳ `step` | number | Current setup step | -| `vanity_name_servers` | array | Custom vanity name servers | -| `permissions` | array | User permissions for the zone | +| `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| `connection_rules` | json | The rules that define how users may connect to the targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `ssh` | json | The SSH-specific rules that define how users may connect to the targets secured by your application. | +| ↳ `allow_email_alias` | boolean | Enables using Identity Provider email alias as SSH username. | +| ↳ `usernames` | array | Contains the Unix usernames that may be used when connecting over SSH. | +| `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings for infrastructure applications. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. For infrastructure applications, supported values are `piv_key` and `ssh_fido2_key`. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples: `5m` or `24h`. | +| `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `created_at` | string | created at | +| `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | The UUID of the policy | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access policy. | +| `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | +| `account_id` | string | Identifier. | +| `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | -### Cloudflare Create Zone +### Cloudflare Create Access Service Token -Adds a new zone (domain) to the Cloudflare account. +Creates a Cloudflare Access (Zero Trust) service token so a machine can authenticate to Access-protected applications. This is the only response that ever contains the client secret — Cloudflare will not return it again, so capture it in the same run. Requires an API token with Account Access: Service Tokens Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `name` | string | Yes | The domain name to add \(e.g., "example.com"\) | -| `accountId` | string | Yes | The Cloudflare account ID | -| `type` | string | No | Zone type: "full" \(Cloudflare manages DNS\), "partial" \(CNAME setup\), or "secondary" \(secondary DNS\). Cloudflare also defines "internal", which is not creatable through this tool | +| `client_secret_version` | number | No | A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately. | +| `enabled` | boolean | No | Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved and can be re-enabled. A service token reported as leaked is disabled automatically and cannot be re-enabled until its secret is rotated; attempting to do so returns a 409. Defaults to enabled when omitted on create. | +| `previous_client_secret_expires_at` | string | No | The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set. | +| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | +| `name` | string | Yes | Name of the service token | +| `duration` | string | No | How long the token stays valid before it expires, e.g. 8760h. Defaults to Cloudflare's standard lifetime | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Created zone ID | -| `name` | string | Domain name | -| `status` | string | Zone status \(initializing, pending, active, moved\) | -| `paused` | boolean | Whether the zone is paused | -| `type` | string | Zone type \(full, partial, secondary, or internal\) | -| `name_servers` | array | Assigned Cloudflare name servers | -| `original_name_servers` | array | Original name servers before moving to Cloudflare | -| `created_on` | string | ISO 8601 date when the zone was created | -| `modified_on` | string | ISO 8601 date when the zone was last modified | -| `activated_on` | string | ISO 8601 date when the zone was activated | -| `development_mode` | number | Seconds remaining in development mode \(0 = off\) | -| `plan` | object | Zone plan information | -| ↳ `id` | string | Plan identifier | -| ↳ `name` | string | Plan name | -| ↳ `price` | number | Plan price | -| ↳ `is_subscribed` | boolean | Whether the zone is subscribed to the plan | -| ↳ `frequency` | string | Plan billing frequency | -| ↳ `currency` | string | Plan currency | -| ↳ `legacy_id` | string | Legacy plan identifier | -| `account` | object | Account the zone belongs to | -| ↳ `id` | string | Account identifier | -| ↳ `name` | string | Account name | -| `owner` | object | Zone owner information | -| ↳ `id` | string | Owner identifier | -| ↳ `name` | string | Owner name | -| ↳ `type` | string | Owner type | -| `meta` | object | Zone metadata | -| ↳ `cdn_only` | boolean | Whether the zone is CDN only | -| ↳ `custom_certificate_quota` | number | Custom certificate quota | -| ↳ `dns_only` | boolean | Whether the zone is DNS only | -| ↳ `foundation_dns` | boolean | Whether foundation DNS is enabled | -| ↳ `page_rule_quota` | number | Page rule quota | -| ↳ `phishing_detected` | boolean | Whether phishing was detected | -| ↳ `step` | number | Current setup step | -| `vanity_name_servers` | array | Custom vanity name servers | -| `permissions` | array | User permissions for the zone | +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `client_secret` | string | The Client Secret for the service token. Access will check for this value in the `CF-Access-Client-Secret` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `id` | string | The ID of the service token. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | +| `expires_at` | string | Service token expires at when returned by Cloudflare; retained for existing workflows | +| `last_seen_at` | string | Service token last seen at when returned by Cloudflare; retained for existing workflows | -### Cloudflare Delete Zone +### Cloudflare Create DNS Record -Deletes a zone (domain) from the Cloudflare account. +Creates a new DNS record for a zone. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to delete | +| `settings` | json | No | JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname. | +| `private_routing` | boolean | No | Enables private network routing to the origin. | +| `data` | json | No | JSON object. Structured record data. The available fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint. | +| `include_shadow_metadata` | boolean | No | Whether to include shadow metadata in the `meta` field of each record in the response. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `zoneId` | string | Yes | The zone ID to create the DNS record in | +| `type` | string | Yes | DNS record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV"\) | +| `name` | string | Yes | DNS record name \(e.g., "example.com" or "subdomain.example.com"\) | +| `content` | string | No | DNS record content \(e.g., IP address for A records, target for CNAME\) | +| `ttl` | number | No | Time to live in seconds \(1 = automatic, default: 1\) | +| `proxied` | boolean | No | Whether to enable Cloudflare proxy \(default: false\) | +| `priority` | number | No | Record priority. Cloudflare accepts this top-level field for MX and URI records only; use the data object for structured records such as SRV \(priority, weight, port, target\) | +| `comment` | string | No | Comment for the DNS record | +| `tags` | string | No | Comma-separated tags for the DNS record | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Deleted zone ID | +| `comment` | string | Comments or notes about the DNS record. This field has no effect on DNS responses. | +| `name` | string | Complete DNS record name, including the zone name, in Punycode. | +| `proxied` | boolean | Whether the record is receiving the performance and security benefits of Cloudflare. | +| `settings` | json | Settings for the DNS record. | +| ↳ `ipv4_only` | boolean | When enabled, only A records will be generated, and AAAA records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `ipv6_only` | boolean | When enabled, only AAAA records will be generated, and A records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `flatten_cname` | boolean | If enabled, causes the CNAME record to be resolved externally and the resulting address records \(e.g., A and AAAA\) to be returned instead of the CNAME record itself. This setting is unavailable for proxied records, since they are always flattened. | +| `tags` | array | Custom tags for the DNS record. This field has no effect on DNS responses. | +| `ttl` | number | Time To Live \(TTL\) of the DNS record in seconds. Setting to 1 means 'automatic'. Value must be between 60 and 86400, with the minimum reduced to 30 for Enterprise zones. Values: 1. | +| `content` | string | Formatted URI content. See 'data' to set URI properties. | +| `private_routing` | boolean | Enables private network routing to the origin. | +| `type` | string | Record type. Values: A, AAAA, CNAME, MX, NS, OPENPGPKEY, PTR, TXT, CAA, CERT, DNSKEY, DS, HTTPS, LOC, NAPTR, SMIMEA, SRV, SSHFP, SVCB, TLSA, URI. | +| `priority` | number | Required for MX and URI records; ignored for other record types \(but may still be returned by the API\). Records with lower priorities are preferred. This field is to be deprecated in favor of the priority field within the data map. | +| `data` | json | Structured record data. The available fields depend on the DNS record type. | +| ↳ `flags` | json | Flags. | +| ↳ `tag` | string | Name of the property controlled by this record \(e.g.: issue, issuewild, iodef\). | +| ↳ `value` | string | Value. | +| ↳ `algorithm` | number | Algorithm. | +| ↳ `certificate` | string | Certificate. | +| ↳ `key_tag` | number | Key Tag. | +| ↳ `type` | number | Type. | +| ↳ `protocol` | number | Protocol. | +| ↳ `public_key` | string | Public Key. | +| ↳ `digest` | string | Digest. | +| ↳ `digest_type` | number | Digest Type. | +| ↳ `priority` | number | Priority. | +| ↳ `target` | string | The record content. | +| ↳ `altitude` | number | Altitude of location in meters. | +| ↳ `lat_degrees` | number | Degrees of latitude. | +| ↳ `lat_direction` | string | Latitude direction. Values: N, S. | +| ↳ `lat_minutes` | number | Minutes of latitude. | +| ↳ `lat_seconds` | number | Seconds of latitude. | +| ↳ `long_degrees` | number | Degrees of longitude. | +| ↳ `long_direction` | string | Longitude direction. Values: E, W. | +| ↳ `long_minutes` | number | Minutes of longitude. | +| ↳ `long_seconds` | number | Seconds of longitude. | +| ↳ `precision_horz` | number | Horizontal precision of location. | +| ↳ `precision_vert` | number | Vertical precision of location. | +| ↳ `size` | number | Size of location in meters. | +| ↳ `order` | number | Order. | +| ↳ `preference` | number | Preference. | +| ↳ `regex` | string | Regex. | +| ↳ `replacement` | string | Replacement. | +| ↳ `service` | string | Service. | +| ↳ `matching_type` | number | Matching Type. | +| ↳ `selector` | number | Selector. | +| ↳ `usage` | number | Usage. | +| ↳ `port` | number | The port of the service. | +| ↳ `weight` | number | The record weight. | +| ↳ `fingerprint` | string | Fingerprint. | +| `comment_modified_on` | string | When the record comment was last modified. Omitted if there is no comment. | +| `created_on` | string | When the record was created. | +| `id` | string | Identifier. | +| `meta` | json | Extra Cloudflare-specific metadata about the record. | +| ↳ `dead_glue` | boolean | Whether this glue record is not served because a shallower NS delegation takes precedence over the deeper delegation that needs it. | +| ↳ `is_glue` | boolean | Whether this A or AAAA record is glue for a subdomain NS delegation. See \[Glue records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records#glue-records). | +| ↳ `shadowed_by` | array | IDs of the NS records that shadow this record. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| ↳ `shadowed_records_count` | number | Number of records shadowed by this NS delegation. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `modified_on` | string | When the record was last modified. | +| `proxiable` | boolean | Whether the record can be proxied by Cloudflare or not. | +| `tags_modified_on` | string | When the record tags were last modified. Omitted if there are no tags. | +| `zone_id` | string | Legacy DNS response zone ID when returned by Cloudflare | +| `zone_name` | string | Legacy DNS response zone name when returned by Cloudflare | +| `locked` | boolean | Legacy DNS response lock flag when returned by Cloudflare | -### Cloudflare List DNS Records +### Cloudflare Create R2 Bucket -Lists DNS records for a specific zone. +Creates an R2 object storage bucket in an account. The location hint and jurisdiction are fixed at creation and cannot be changed later. Requires an API token with Account Workers R2 Storage Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to list DNS records for | -| `type` | string | No | Filter by record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT"\) | -| `name` | string | No | Filter by record name \(exact match\) | -| `content` | string | No | Filter by record content \(exact match\) | -| `page` | number | No | Page number for pagination \(default: 1\) | -| `per_page` | number | No | Number of records per page \(default: 100, max: 5000000\) | -| `direction` | string | No | Sort direction \(asc or desc\) | -| `match` | string | No | Match logic for filters: any or all \(default: all\) | -| `order` | string | No | Sort field \(type, name, content, ttl, proxied\) | -| `proxied` | boolean | No | Filter by proxy status | -| `search` | string | No | Free-text search across record name, content, and value | -| `tag` | string | No | Filter by an exact tag name | -| `tag_match` | string | No | Tag filter match logic: any or all. Only affects results when combined with multiple tag filter conditions; has no effect with the single exact-match Tag Filter above. | -| `commentFilter` | string | No | Filter records by comment content \(substring match\) | +| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | +| `bucketName` | string | Yes | Name for the new bucket | +| `locationHint` | string | No | Region hint for where the bucket should live: apac, eeur, enam, weur, wnam, or oc. Cannot be changed after creation | +| `storageClass` | string | No | Default storage class for objects: Standard or InfrequentAccess | +| `jurisdiction` | string | No | Data-residency jurisdiction to create the bucket in: default, eu, or fedramp. Cannot be changed after creation | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `records` | array | List of DNS records | -| ↳ `id` | string | Unique identifier for the DNS record | -| ↳ `zone_id` | string | The ID of the zone the record belongs to | -| ↳ `zone_name` | string | The name of the zone | -| ↳ `type` | string | Record type \(A, AAAA, CNAME, MX, TXT, etc.\) | -| ↳ `name` | string | Record name \(e.g., example.com\) | -| ↳ `content` | string | Record content \(e.g., IP address\) | -| ↳ `proxiable` | boolean | Whether the record can be proxied | -| ↳ `proxied` | boolean | Whether Cloudflare proxy is enabled | -| ↳ `ttl` | number | TTL in seconds \(1 = automatic\) | -| ↳ `locked` | boolean | Whether the record is locked | -| ↳ `priority` | number | Record priority, returned for MX and URI records | -| ↳ `comment` | string | Comment associated with the record | -| ↳ `tags` | array | Tags associated with the record | -| ↳ `comment_modified_on` | string | ISO 8601 timestamp when the comment was last modified | -| ↳ `tags_modified_on` | string | ISO 8601 timestamp when tags were last modified | -| ↳ `meta` | object | Record metadata | -| ↳ `source` | string | Source of the DNS record | -| ↳ `created_on` | string | ISO 8601 timestamp when the record was created | -| ↳ `modified_on` | string | ISO 8601 timestamp when the record was last modified | -| `total_count` | number | Total number of DNS records matching the query | +| `creation_date` | string | Creation timestamp. | +| `jurisdiction` | string | Jurisdiction where objects in this bucket are guaranteed to be stored. Values: default, eu, us, fedramp, fedramp-high. | +| `location` | string | Location of the bucket. Values: apac, eeur, enam, weur, wnam, oc. | +| `name` | string | Name of the bucket. | +| `storage_class` | string | Storage class for newly uploaded objects, unless specified otherwise. Values: Standard, InfrequentAccess. | -### Cloudflare Create DNS Record +### Cloudflare Create Rate Limiting Rule -Creates a new DNS record for a zone. +Creates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API (the legacy rate_limits endpoint is no longer available). Run "List Rate Limiting Rules" first to get the ruleset ID. Requires an API token with Zone WAF Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to create the DNS record in | -| `type` | string | Yes | DNS record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT", "NS", "SRV"\) | -| `name` | string | Yes | DNS record name \(e.g., "example.com" or "subdomain.example.com"\) | -| `content` | string | Yes | DNS record content \(e.g., IP address for A records, target for CNAME\) | -| `ttl` | number | No | Time to live in seconds \(1 = automatic, default: 1\) | -| `proxied` | boolean | No | Whether to enable Cloudflare proxy \(default: false\) | -| `priority` | number | No | Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority, weight, port, and target inside the record content instead | -| `comment` | string | No | Comment for the DNS record | -| `tags` | string | No | Comma-separated tags for the DNS record | +| `actionParameters` | json | No | JSON object. The parameters configuring the rule's action. Fields: response, algorithms, id, matched_data, overrides, cookie_fields, raw_response_fields, request_fields, response_fields, transformed_request_fields, from_list, from_value, headers, uri, host_header, origin, sni, increment, content_type, status_code, content, asset_name, immutable, max-age, must-revalidate, must-understand, no-cache, no-store, no-transform, private, proxy-revalidate, public, s-maxage, stale-if-error, stale-while-revalidate, additional_cacheable_ports, browser_ttl, cache, cache_key, cache_reserve, edge_ttl, origin_cache_control, origin_error_page_passthru, origin_range_requests, read_timeout, respect_strong_etags, serve_stale, shared_dictionary, strip_etags, strip_last_modified, strip_set_cookie, vary, operation, values, expression, automatic_https_rewrites, autominify, bic, content_converter, disable_apps, disable_pay_per_crawl, disable_rum, disable_zaraz, email_obfuscation, fonts, hotlink_protection, mirage, opportunistic_encryption, polish, redirects_for_ai_training, request_body_buffering, response_body_buffering, rocket_loader, security_level, server_side_excludes, ssl, sxg, webmcp_enabled, webmcp_packs, phase, phases, products, rules, ruleset, rulesets, link_maze. | +| `exposed_credential_check` | json | No | JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. | +| `id` | string | No | The unique ID of the rule. | +| `logging` | json | No | JSON object. An object configuring the rule's logging behavior. Fields: enabled. | +| `ref` | string | No | The reference of the rule \(the rule's ID by default\). | +| `position` | json | No | JSON object. An object configuring where the rule will be placed. Fields: before, after, index. | +| `score_per_period` | number | No | The score threshold per period for which the action will be executed the first time. | +| `score_response_header_name` | string | No | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID to add the rate limiting rule to | +| `rulesetId` | string | Yes | The http_ratelimit entry point ruleset ID, as returned by "List Rate Limiting Rules" | +| `expression` | string | Yes | Cloudflare filter expression selecting the requests the rule applies to, e.g. \(http.request.uri.path matches "^/api/"\) | +| `characteristics` | string | Yes | Comma-separated counting characteristics. cf.colo.id is mandatory. ip.src and cf.unique_visitor_id are mutually exclusive — include at most one. Example: cf.colo.id,ip.src | +| `period` | number | Yes | Counting window in seconds. Cloudflare accepts only 10, 60, 120, 300, 600, or 3600 | +| `requestsPerPeriod` | number | Yes | Number of requests allowed within the counting period before the action fires | +| `action` | string | No | Action applied once the limit is exceeded, e.g. block, managed_challenge, js_challenge, challenge, or log. Defaults to block | +| `mitigationTimeout` | number | No | Seconds the action stays applied after the limit is exceeded. Cloudflare accepts only 0, 10, 60, 120, 300, 600, 3600, or 86400 | +| `counting_expression` | string | No | Optional expression defining which requests are counted, when it differs from the matching expression | +| `requestsToOrigin` | boolean | No | When true, only requests that reach the origin are counted | +| `description` | string | No | Human-readable description of the rule | +| `enabled` | boolean | No | Whether the rule is enabled | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Unique identifier for the created DNS record | -| `zone_id` | string | The ID of the zone the record belongs to | -| `zone_name` | string | The name of the zone | -| `type` | string | DNS record type \(A, AAAA, CNAME, MX, TXT, etc.\) | -| `name` | string | DNS record hostname | -| `content` | string | DNS record value \(e.g., IP address, target hostname\) | -| `proxiable` | boolean | Whether the record can be proxied through Cloudflare | -| `proxied` | boolean | Whether Cloudflare proxy is enabled | -| `ttl` | number | Time to live in seconds \(1 = automatic\) | -| `locked` | boolean | Whether the record is locked | -| `priority` | number | Record priority, returned for MX and URI records | -| `comment` | string | Comment associated with the record | -| `tags` | array | Tags associated with the record | -| `comment_modified_on` | string | ISO 8601 timestamp when the comment was last modified | -| `tags_modified_on` | string | ISO 8601 timestamp when tags were last modified | -| `meta` | object | Record metadata | -| ↳ `source` | string | Source of the DNS record | -| `created_on` | string | ISO 8601 timestamp when the record was created | -| `modified_on` | string | ISO 8601 timestamp when the record was last modified | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | -### Cloudflare Update DNS Record +### Cloudflare Create Ruleset -Updates an existing DNS record for a zone. +Creates a zone ruleset for a phase, optionally seeded with its first rules. Use this when a phase has no entry point ruleset yet — reading the entry point returns 404 on a zone that has never had a rule in that phase, and rules can only be appended to a ruleset that already exists. Create the entry point with kind "zone" and the target phase (for example http_ratelimit for rate limiting rules or http_request_firewall_custom for WAF custom rules), then use the returned ruleset ID for later rule operations. Requires an API token with Zone WAF Edit (or another matching ruleset Edit permission). #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID containing the DNS record | -| `recordId` | string | Yes | The DNS record ID to update | -| `type` | string | No | DNS record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT"\) | -| `name` | string | No | DNS record name | -| `content` | string | No | DNS record content \(e.g., IP address\) | -| `ttl` | number | No | Time to live in seconds \(1 = automatic\) | -| `proxied` | boolean | No | Whether to enable Cloudflare proxy | -| `priority` | number | No | Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority, weight, port, and target inside the record content instead | -| `comment` | string | No | Comment for the DNS record | -| `tags` | string | No | Comma-separated tags for the DNS record | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID to create the ruleset in | +| `name` | string | Yes | Human-readable name for the ruleset | +| `phase` | string | Yes | The ruleset phase, e.g. http_ratelimit, http_request_firewall_custom, http_request_firewall_managed, http_request_transform, http_request_dynamic_redirect | +| `kind` | string | No | Ruleset kind: zone or custom. Use zone to create a phase entry point ruleset and custom for a ruleset an execute rule deploys. Defaults to zone. "root" is the account-level phase entry point and "managed" is Cloudflare-owned, so neither can be created on this zone-scoped endpoint | +| `description` | string | No | Description of the ruleset | +| `rules` | json | No | JSON array of rules to seed the ruleset with, in evaluation order. Each rule takes action, expression, and optionally description, enabled, action_parameters, and ratelimit | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Unique identifier for the updated DNS record | -| `zone_id` | string | The ID of the zone the record belongs to | -| `zone_name` | string | The name of the zone | -| `type` | string | DNS record type \(A, AAAA, CNAME, MX, TXT, etc.\) | -| `name` | string | DNS record hostname | -| `content` | string | DNS record value \(e.g., IP address, target hostname\) | -| `proxiable` | boolean | Whether the record can be proxied through Cloudflare | -| `proxied` | boolean | Whether Cloudflare proxy is enabled | -| `ttl` | number | Time to live in seconds \(1 = automatic\) | -| `locked` | boolean | Whether the record is locked | -| `priority` | number | Record priority, returned for MX and URI records | -| `comment` | string | Comment associated with the record | -| `tags` | array | Tags associated with the record | -| `comment_modified_on` | string | ISO 8601 timestamp when the comment was last modified | -| `tags_modified_on` | string | ISO 8601 timestamp when tags were last modified | -| `meta` | object | Record metadata | -| ↳ `source` | string | Source of the DNS record | -| `created_on` | string | ISO 8601 timestamp when the record was created | -| `modified_on` | string | ISO 8601 timestamp when the record was last modified | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | -### Cloudflare Delete DNS Record +### Cloudflare Create Ruleset Rule -Deletes a DNS record from a zone. +Adds a rule to a zone ruleset. Use "Get Phase Entry Point Ruleset" first to find the ruleset ID for the phase you want (for example http_request_firewall_custom for a WAF custom rule, or http_request_firewall_managed with action "execute" to deploy a managed ruleset). The rule is appended to the end of the ruleset unless a position is given. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID containing the DNS record | -| `recordId` | string | Yes | The DNS record ID to delete | +| `exposed_credential_check` | json | No | JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. | +| `id` | string | No | The unique ID of the rule. | +| `logging` | json | No | JSON object. An object configuring the rule's logging behavior. Fields: enabled. | +| `ratelimit` | json | No | JSON object. An object configuring the rule's rate limit behavior. Fields: characteristics, counting_expression, mitigation_timeout, period, requests_per_period, requests_to_origin, score_per_period, score_response_header_name. | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID that owns the ruleset | +| `rulesetId` | string | Yes | The ruleset ID to add the rule to | +| `action` | string | Yes | The action the rule performs. Valid values depend on the phase — e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute \(to deploy a managed ruleset\) | +| `expression` | string | Yes | Cloudflare filter expression selecting matching requests, e.g. \(ip.src.country in \{"GB" "FR"\}\). Use "true" to match every request | +| `description` | string | No | Human-readable description of the rule | +| `enabled` | boolean | No | Whether the rule is enabled | +| `ref` | string | No | Reference tag that stays stable across rule updates | +| `actionParameters` | string | No | JSON object of action-specific parameters. For an "execute" rule this carries the managed ruleset id and any overrides, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"action":"log"\}\} | +| `position` | string | No | JSON object placing the rule within the ruleset. Exactly one of \{"before":"<RULE_ID>"\}, \{"after":"<RULE_ID>"\}, or \{"index":<1-based position>\} | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Deleted record ID | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Create Tunnel + +Creates a remotely or locally managed Cloudflare Tunnel in an account. After creation, retrieve its token and run cloudflared to establish the connector connection. -### Cloudflare List Certificates +#### Input -Lists SSL/TLS certificate packs for a zone. +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `apiKey` | string | Yes | Cloudflare API token | +| `config_src` | string | No | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Allowed values: local, cloudflare. | +| `name` | string | Yes | A user-friendly name for a tunnel. | +| `tunnel_secret` | string | No | Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `account_tag` | string | Cloudflare account ID | +| `config_src` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare. | +| `connections` | array | The Cloudflare Tunnel connections between your origin and Cloudflare's edge. | +| ↳ `client_id` | string | UUID of the Cloudflare Tunnel connector. | +| ↳ `client_version` | string | The cloudflared version used to establish this connection. | +| ↳ `colo_name` | string | The Cloudflare data center used for this connection. | +| ↳ `id` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `is_pending_reconnect` | boolean | Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic. | +| ↳ `opened_at` | string | Timestamp of when the connection was established. | +| ↳ `origin_ip` | string | The public IP address of the host running cloudflared. | +| ↳ `uuid` | string | UUID of the Cloudflare Tunnel connection. | +| `conns_active_at` | string | Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive. | +| `conns_inactive_at` | string | Timestamp of when the tunnel became inactive \(no connections to Cloudflare's edge\). If `null`, the tunnel is active. | +| `created_at` | string | Timestamp of when the resource was created. | +| `deleted_at` | string | Timestamp of when the resource was deleted. If `null`, the resource has not been deleted. | +| `id` | string | UUID of the tunnel. | +| `metadata` | json | Metadata associated with the tunnel. | +| `name` | string | A user-friendly name for a tunnel. | +| `remote_config` | boolean | If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine. | +| `status` | string | The status of the tunnel. | +| `tun_type` | string | The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni. | + +### Cloudflare Create Worker Route + +Creates a route that maps a URL pattern to a Worker. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to list certificates for | -| `status` | string | No | Set to "all" to include every certificate pack regardless of status. Cloudflare documents no other value for this filter; omitting it returns only active packs | -| `page` | number | No | Page number of paginated results \(default: 1\) | -| `per_page` | number | No | Number of certificate packs per page \(default: 20, min: 5, max: 50\) | -| `deploy` | string | No | Filter by deployment environment: "staging" or "production" | -| `apiKey` | string | Yes | Cloudflare API Token | +| `zoneId` | string | Yes | Zone id | +| `apiKey` | string | Yes | Cloudflare API token | +| `pattern` | string | Yes | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| `script` | string | No | Name of the script to run if the route matches. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `certificates` | array | List of SSL/TLS certificate packs | -| ↳ `id` | string | Certificate pack ID | -| ↳ `type` | string | Certificate type \(e.g., "universal", "advanced"\) | -| ↳ `hosts` | array | Hostnames covered by this certificate pack | -| ↳ `primary_certificate` | string | ID of the primary certificate in the pack | -| ↳ `status` | string | Certificate pack status \(e.g., "active", "pending"\) | -| ↳ `certificates` | array | Individual certificates within the pack | -| ↳ `id` | string | Certificate ID | -| ↳ `hosts` | array | Hostnames covered by this certificate | -| ↳ `issuer` | string | Certificate issuer | -| ↳ `signature` | string | Signature algorithm \(e.g., "ECDSAWithSHA256"\) | -| ↳ `status` | string | Certificate status | -| ↳ `bundle_method` | string | Bundle method \(e.g., "ubiquitous"\) | -| ↳ `zone_id` | string | Zone ID the certificate belongs to | -| ↳ `uploaded_on` | string | Upload date \(ISO 8601\) | -| ↳ `modified_on` | string | Last modified date \(ISO 8601\) | -| ↳ `expires_on` | string | Expiration date \(ISO 8601\) | -| ↳ `priority` | number | Certificate priority order | -| ↳ `geo_restrictions` | object | Geographic restrictions for the certificate | -| ↳ `label` | string | Geographic restriction label | -| ↳ `cloudflare_branding` | boolean | Whether Cloudflare branding is enabled on the certificate | -| ↳ `validation_method` | string | Validation method \(e.g., "txt", "http", "cname"\) | -| ↳ `validity_days` | number | Validity period in days | -| ↳ `certificate_authority` | string | Certificate authority \(e.g., "lets_encrypt", "google"\) | -| ↳ `validation_errors` | array | Validation issues for the certificate pack | -| ↳ `message` | string | Validation error message | -| ↳ `validation_records` | array | Validation records for the certificate pack | -| ↳ `cname` | string | CNAME record name | -| ↳ `cname_target` | string | CNAME record target | -| ↳ `emails` | array | Email addresses for validation | -| ↳ `http_body` | string | HTTP validation body content | -| ↳ `http_url` | string | HTTP validation URL | -| ↳ `status` | string | Validation record status | -| ↳ `txt_name` | string | TXT record name | -| ↳ `txt_value` | string | TXT record value | -| ↳ `dcv_delegation_records` | array | Domain control validation delegation records | -| ↳ `cname` | string | CNAME record name | -| ↳ `cname_target` | string | CNAME record target | -| ↳ `emails` | array | Email addresses for validation | -| ↳ `http_body` | string | HTTP validation body content | -| ↳ `http_url` | string | HTTP validation URL | -| ↳ `status` | string | Delegation record status | -| ↳ `txt_name` | string | TXT record name | -| ↳ `txt_value` | string | TXT record value | -| `total_count` | number | Total number of certificate packs | +| `id` | string | Identifier. | +| `pattern` | string | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| `script` | string | Name of the script to run if the route matches. | -### Cloudflare Get Zone Settings +### Cloudflare Create Zone -Reads zone settings such as SSL mode, minimum TLS version, security level, and caching level. Cloudflare retired the endpoint that read every setting in one request, so each setting is read individually — name the ones you need to keep the read small. Defaults to ssl, always_use_https, min_tls_version, tls_1_3, security_level, cache_level, browser_cache_ttl, development_mode, rocket_loader, email_obfuscation, hotlink_protection, ip_geolocation, http2, http3, websockets. +Adds a new zone (domain) to the Cloudflare account. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to get settings for | -| `settingIds` | string | No | Comma-separated setting IDs to read, e.g. "ssl,min_tls_version,security_level". Leave blank to read the default set \(ssl, always_use_https, min_tls_version, tls_1_3, security_level, cache_level, browser_cache_ttl, development_mode, rocket_loader, email_obfuscation, hotlink_protection, ip_geolocation, http2, http3, websockets\). At most 40 settings per call. | +| `name` | string | Yes | The domain name to add \(e.g., "example.com"\) | +| `accountId` | string | Yes | The Cloudflare account ID | +| `type` | string | No | Zone type: "full" \(Cloudflare manages DNS\), "partial" \(CNAME setup\), "secondary" \(secondary DNS\), or "internal" \(internal DNS zone\) | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `settings` | array | The zone settings that were readable | -| ↳ `id` | string | Setting identifier \(e.g., ssl, cache_level, security_level, always_use_https\) | -| ↳ `value` | string | Setting value as a string. Simple values returned as-is \(e.g., "full", "on"\). Complex values are JSON-stringified \(e.g., \{"css":"on","html":"on","js":"on"\}\). | -| ↳ `editable` | boolean | Whether the setting can be modified for the current zone plan | -| ↳ `modified_on` | string | ISO 8601 timestamp when the setting was last modified | -| ↳ `time_remaining` | number | Development mode countdown, in seconds. Cloudflare documents this only on the zones_development_mode setting, where it is the interval from when development mode expires \(positive\) or last expired \(negative\) | -| `unreadable` | array | Requested settings Cloudflare refused, typically because the zone plan does not expose them or the setting ID does not exist | -| ↳ `id` | string | The requested setting identifier | -| ↳ `error` | string | Why Cloudflare would not return the setting | +| `account` | json | The account the zone belongs to. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the account. | +| `activated_on` | string | The last time proof of ownership was detected and the zone was made active. | +| `cname_suffix` | string | Allows the customer to use a custom apex. *Tenants Only Configuration*. | +| `created_on` | string | When the zone was created. | +| `development_mode` | number | The interval \(in seconds\) from when development mode expires \(positive integer\) or last expired \(negative integer\) for the domain. If development mode has never been enabled, this value is 0. | +| `id` | string | Identifier | +| `meta` | json | Metadata about the zone. | +| ↳ `cdn_only` | boolean | The zone is only configured for CDN. | +| ↳ `custom_certificate_quota` | number | Number of Custom Certificates the zone can have. | +| ↳ `dns_only` | boolean | The zone is only configured for DNS. | +| ↳ `foundation_dns` | boolean | The zone is setup with Foundation DNS. | +| ↳ `page_rule_quota` | number | Number of Page Rules a zone can have. | +| ↳ `phishing_detected` | boolean | The zone has been flagged for phishing. | +| ↳ `step` | number | step | +| `modified_on` | string | When the zone was last modified. | +| `name` | string | The domain name. Per \[RFC 1035\]\(https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the overall zone name can be up to 253 characters, with each segment \("label"\) not exceeding 63 characters. | +| `name_servers` | array | The name servers Cloudflare assigns to a zone. | +| `original_dnshost` | string | DNS host at the time of switching to Cloudflare. | +| `original_name_servers` | array | Original name servers before moving to Cloudflare. | +| `original_registrar` | string | Registrar for the domain at the time of switching to Cloudflare. | +| `owner` | json | The owner of the zone. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | Name of the owner. | +| ↳ `type` | string | The type of owner. | +| `paused` | boolean | Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits. | +| `permissions` | array | Legacy permissions based on legacy user membership information. | +| `plan` | json | A Zones subscription information. | +| ↳ `can_subscribe` | boolean | States if the subscription can be activated. | +| ↳ `currency` | string | The denomination of the customer. | +| ↳ `externally_managed` | boolean | If this Zone is managed by another company. | +| ↳ `frequency` | string | How often the customer is billed. | +| ↳ `id` | string | Identifier | +| ↳ `is_subscribed` | boolean | States if the subscription active. | +| ↳ `legacy_discount` | boolean | If the legacy discount applies to this Zone. | +| ↳ `legacy_id` | string | The legacy name of the plan. | +| ↳ `name` | string | Name of the owner. | +| ↳ `price` | number | How much the customer is paying. | +| `status` | string | The zone status on Cloudflare. Values: initializing, pending, active, moved. | +| `tenant` | json | The root organizational unit that this zone belongs to \(such as a tenant or organization\). | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the Tenant account. | +| `tenant_unit` | json | The immediate parent organizational unit that this zone belongs to \(such as under a tenant or sub-organization\). | +| ↳ `id` | string | Identifier | +| `type` | string | A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Values: full, partial, secondary, internal. | +| `vanity_name_servers` | array | An array of domains used for custom name servers. This is only available for Business and Enterprise plans. | +| `verification_key` | string | Verification key for partial zone setup. | -### Cloudflare Update Zone Setting +### Cloudflare Delete Access Application -Updates a specific zone setting such as SSL mode, security level, cache level, or other configuration. +Permanently deletes a Cloudflare Access (Zero Trust) application and every policy attached to it. The hostname it protected is immediately left without an Access identity check, so anyone who can reach it can reach the origin. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to update settings for | -| `settingId` | string | Yes | Setting to update \(e.g., "ssl", "security_level", "cache_level", "always_use_https", "browser_cache_ttl", "http3", "min_tls_version", "ciphers"\) | -| `value` | string | Yes | New value for the setting as a string, or a JSON string for complex values \(e.g., "full" for SSL, "medium" for security_level, "aggressive" for cache_level, \["ECDHE-RSA-AES128-GCM-SHA256"\] for ciphers\) | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID to delete permanently | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Setting identifier \(e.g., ssl, cache_level, security_level\) | -| `value` | string | Updated setting value as a string. Simple values returned as-is \(e.g., "full", "on"\). Complex values are JSON-stringified. | -| `editable` | boolean | Whether the setting can be modified for the current zone plan | -| `modified_on` | string | ISO 8601 timestamp when the setting was last modified | -| `time_remaining` | number | Development mode countdown, in seconds. Cloudflare documents this only on the zones_development_mode setting, where it is the interval from when development mode expires \(positive\) or last expired \(negative\) | +| `id` | string | Identifier of the deleted Access application | -### Cloudflare DNS Analytics +### Cloudflare Delete Access Group -Gets DNS analytics report for a zone including query counts and trends. +Deletes an Access group. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to get DNS analytics for | -| `since` | string | No | Start date for analytics \(ISO 8601, e.g., "2024-01-01T00:00:00Z"\) or relative \(e.g., "-6h"\) | -| `until` | string | No | End date for analytics \(ISO 8601, e.g., "2024-01-31T23:59:59Z"\) or relative \(e.g., "now"\) | -| `metrics` | string | No | Comma-separated metrics to retrieve \(e.g., "queryCount,uncachedCount,staleCount,responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th"\). Optional in the API | -| `dimensions` | string | No | Comma-separated dimensions to group by \(e.g., "queryName,queryType,responseCode,responseCached,coloName,origin,dayOfWeek,tcp,ipVersion,querySizeBucket,responseSizeBucket"\) | -| `filters` | string | No | Filters to apply to the data \(e.g., "queryType==A"\) | -| `sort` | string | No | Sort order for the result set. Fields must be included in metrics or dimensions \(e.g., "+queryCount" or "-responseTimeAvg"\) | -| `limit` | number | No | Maximum number of results to return | +| `accountId` | string | Yes | Account id | +| `groupId` | string | Yes | Group id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | string | UUID. | + +### Cloudflare Delete Access Policy + +Permanently deletes a Cloudflare Access (Zero Trust) policy from an application. This changes who can reach the application the moment it runs: removing an allow policy locks out everyone it covered, and removing a deny or require policy drops that restriction. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID that owns the policy | +| `policyId` | string | Yes | The Access policy ID to delete permanently | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `totals` | object | Aggregate DNS analytics totals for the entire queried period. Only the metrics that were requested are present. | -| ↳ `queryCount` | number | Total number of DNS queries. Absent when queryCount was not requested | -| ↳ `uncachedCount` | number | Number of uncached DNS queries. Absent when uncachedCount was not requested | -| ↳ `staleCount` | number | Number of stale DNS queries. Absent when staleCount was not requested | -| ↳ `responseTimeAvg` | number | Average response time in milliseconds | -| ↳ `responseTimeMedian` | number | Median response time in milliseconds | -| ↳ `responseTime90th` | number | 90th percentile response time in milliseconds | -| ↳ `responseTime99th` | number | 99th percentile response time in milliseconds | -| `min` | json | Per-metric minimums. Cloudflare documents this field as currently always an empty object, so treat a populated value as unexpected rather than relied upon. | -| `max` | json | Per-metric maximums. Cloudflare documents this field as currently always an empty object, so treat a populated value as unexpected rather than relied upon. | -| `data` | array | Raw analytics data rows returned by the Cloudflare DNS analytics report | -| ↳ `dimensions` | array | Dimension values for this data row, parallel to the requested dimensions list | -| ↳ `metrics` | array | Metric values for this data row, parallel to the requested metrics list | -| `data_lag` | number | Processing lag in seconds before analytics data becomes available | -| `rows` | number | Total number of rows in the result set | -| `query` | object | Echo of the query parameters sent to the API | -| ↳ `since` | string | Start date of the analytics query | -| ↳ `until` | string | End date of the analytics query | -| ↳ `metrics` | array | Metrics requested in the query | -| ↳ `dimensions` | array | Dimensions requested in the query | -| ↳ `filters` | string | Filters applied to the query | -| ↳ `sort` | array | Sort order applied to the query | -| ↳ `limit` | number | Maximum number of results requested | +| `id` | string | Identifier of the deleted Access policy | -### Cloudflare Purge Cache +### Cloudflare Delete DNS Record -Purges cached content for a zone. Can purge everything or specific files/tags/hosts/prefixes. +Deletes a DNS record from a zone. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID containing the DNS record | +| `recordId` | string | Yes | The DNS record ID to delete | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | string | Deleted record ID | + +### Cloudflare Delete R2 Bucket + +Permanently deletes an R2 object storage bucket. Cloudflare only deletes an empty bucket, and the deletion cannot be undone. Requires an API token with Account Workers R2 Storage Edit. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | +| `bucketName` | string | Yes | The name of the bucket to delete permanently | +| `jurisdiction` | string | No | Data-residency jurisdiction the bucket lives in: default, eu, or fedramp | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `name` | string | Name of the deleted bucket. Cloudflare returns an empty result body for this endpoint, so the name is echoed from the request | + +### Cloudflare Delete R2 Bucket Cors + +Delete the CORS policy for a bucket. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `bucketName` | string | Yes | Bucket name | +| `apiKey` | string | Yes | Cloudflare API token | +| `jurisdiction` | string | No | Jurisdiction where objects in this bucket are guaranteed to be stored. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether Cloudflare accepted the operation | + +### Cloudflare Delete Ruleset + +Deletes all versions of an existing zone ruleset. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | Zone id | +| `rulesetId` | string | Yes | Ruleset id | +| `apiKey` | string | Yes | Cloudflare API token | +| `dry_run` | boolean | No | Validates the request without persisting changes when set to `true`. Responses that normally return 200 return `result: null`; endpoints that normally return 204 continue to return 204. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether Cloudflare accepted the operation | + +### Cloudflare Delete Ruleset Rule + +Permanently deletes a rule from a zone ruleset. This takes effect immediately on live traffic and cannot be undone — deleting a WAF custom rule, a managed-ruleset deployment, or a rate limiting rule removes that protection from the zone. Also use this to delete rate limiting rules, which live in the http_ratelimit phase ruleset. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID that owns the ruleset | +| `rulesetId` | string | Yes | The ruleset ID containing the rule | +| `ruleId` | string | Yes | The rule ID to delete permanently | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Delete Tunnel + +Permanently deletes a Cloudflare Tunnel from an account. The tunnel must have no active connections. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `tunnelId` | string | Yes | Tunnel id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `account_tag` | string | Cloudflare account ID | +| `config_src` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare. | +| `connections` | array | The Cloudflare Tunnel connections between your origin and Cloudflare's edge. | +| ↳ `client_id` | string | UUID of the Cloudflare Tunnel connector. | +| ↳ `client_version` | string | The cloudflared version used to establish this connection. | +| ↳ `colo_name` | string | The Cloudflare data center used for this connection. | +| ↳ `id` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `is_pending_reconnect` | boolean | Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic. | +| ↳ `opened_at` | string | Timestamp of when the connection was established. | +| ↳ `origin_ip` | string | The public IP address of the host running cloudflared. | +| ↳ `uuid` | string | UUID of the Cloudflare Tunnel connection. | +| `conns_active_at` | string | Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive. | +| `conns_inactive_at` | string | Timestamp of when the tunnel became inactive \(no connections to Cloudflare's edge\). If `null`, the tunnel is active. | +| `created_at` | string | Timestamp of when the resource was created. | +| `deleted_at` | string | Timestamp of when the resource was deleted. If `null`, the resource has not been deleted. | +| `id` | string | UUID of the tunnel. | +| `metadata` | json | Metadata associated with the tunnel. | +| `name` | string | A user-friendly name for a tunnel. | +| `remote_config` | boolean | If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine. | +| `status` | string | The status of the tunnel. | +| `tun_type` | string | The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni. | + +### Cloudflare Delete Worker Route + +Deletes a Worker route. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | Zone id | +| `routeId` | string | Yes | Route id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | string | Identifier. | + +### Cloudflare Delete Worker Script + +Delete your worker. This call has no response body on a successful delete. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `scriptName` | string | Yes | Script name | +| `apiKey` | string | Yes | Cloudflare API token | +| `force` | boolean | No | If true, delete the Worker even when other Workers still reference it. Service bindings in those Workers may be left broken. Durable Object namespaces implemented by the deleted Worker are deleted even if other Workers reference them. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `success` | boolean | Whether Cloudflare accepted the operation | + +### Cloudflare Delete Zone + +Deletes a zone (domain) from the Cloudflare account. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID to delete | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | string | Deleted zone ID | + +### Cloudflare DNS Analytics + +Gets DNS analytics report for a zone including query counts and trends. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID to get DNS analytics for | +| `since` | string | No | Start date for analytics \(ISO 8601, e.g., "2024-01-01T00:00:00Z"\) or relative \(e.g., "-6h"\) | +| `until` | string | No | End date for analytics \(ISO 8601, e.g., "2024-01-31T23:59:59Z"\) or relative \(e.g., "now"\) | +| `metrics` | string | No | Comma-separated metrics to retrieve \(e.g., "queryCount,uncachedCount,staleCount,responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th"\). Optional in the API | +| `dimensions` | string | No | Comma-separated dimensions to group by \(e.g., "queryName,queryType,responseCode,responseCached,coloName,origin,dayOfWeek,tcp,ipVersion,querySizeBucket,responseSizeBucket"\) | +| `filters` | string | No | Filters to apply to the data \(e.g., "queryType==A"\) | +| `sort` | string | No | Sort order for the result set. Fields must be included in metrics or dimensions \(e.g., "+queryCount" or "-responseTimeAvg"\) | +| `limit` | number | No | Maximum number of results to return | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `totals` | object | Aggregate DNS analytics totals for the entire queried period. Only the metrics that were requested are present. | +| ↳ `queryCount` | number | Total number of DNS queries. Absent when queryCount was not requested | +| ↳ `uncachedCount` | number | Number of uncached DNS queries. Absent when uncachedCount was not requested | +| ↳ `staleCount` | number | Number of stale DNS queries. Absent when staleCount was not requested | +| ↳ `responseTimeAvg` | number | Average response time in milliseconds | +| ↳ `responseTimeMedian` | number | Median response time in milliseconds | +| ↳ `responseTime90th` | number | 90th percentile response time in milliseconds | +| ↳ `responseTime99th` | number | 99th percentile response time in milliseconds | +| `min` | json | Per-metric minimums. Cloudflare documents this field as currently always an empty object, so treat a populated value as unexpected rather than relied upon. | +| `max` | json | Per-metric maximums. Cloudflare documents this field as currently always an empty object, so treat a populated value as unexpected rather than relied upon. | +| `data` | array | Raw analytics data rows returned by the Cloudflare DNS analytics report | +| ↳ `dimensions` | array | Dimension values for this data row, parallel to the requested dimensions list | +| ↳ `metrics` | array | Metric values for this data row, parallel to the requested metrics list | +| `data_lag` | number | Processing lag in seconds before analytics data becomes available | +| `rows` | number | Total number of rows in the result set | +| `query` | object | Echo of the query parameters sent to the API | +| ↳ `since` | string | Start date of the analytics query | +| ↳ `until` | string | End date of the analytics query | +| ↳ `metrics` | array | Metrics requested in the query | +| ↳ `dimensions` | array | Dimensions requested in the query | +| ↳ `filters` | string | Filters applied to the query | +| ↳ `sort` | array | Sort order applied to the query | +| ↳ `limit` | number | Maximum number of results requested | + +### Cloudflare Get Access Application + +Reads a single Cloudflare Access (Zero Trust) application, including its attached policies. Requires an API token with Account Access: Apps and Policies Read. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID \(or audience tag\) to read | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `aud` | string | Audience tag. | +| `created_at` | string | created at | +| `id` | string | UUID. | +| `updated_at` | string | updated at | +| `allowed_idps` | array | The identity providers your users can select when connecting to this application. Defaults to all IdPs configured in your account. | +| `destinations` | array | List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| ↳ `overrides` | array | Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. Overrides are supported for public destinations and Worker destinations. | +| ↳ `behavior` | string | The behavior to apply to matching requests. Values: public. | +| ↳ `path_pattern` | string | The request path pattern to match. Wildcards \(`*`\) are supported, but each path segment may have at most one wildcard. Unlike the `uri` in public destinations, override path patterns do not implicitly cover subpaths; to do that, use a wildcard. | +| ↳ `type` | string | type Values: public, private, via_mcp_server_portal, worker, preview_worker, all_workers, all_preview_workers. | +| ↳ `uri` | string | The URI of the destination. Public destinations' URIs can include a domain and path with \[wildcards\]\(https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/). | +| ↳ `cidr` | string | The CIDR range of the destination. Single IPs will be computed as /32. | +| ↳ `hostname` | string | The hostname of the destination. Matches a valid SNI served by an HTTPS origin. | +| ↳ `l4_protocol` | string | The L4 protocol of the destination. When omitted, both UDP and TCP traffic will match. Values: tcp, udp. | +| ↳ `port_range` | string | The port range of the destination. Can be a single port or a range of ports. When omitted, all ports will match. | +| ↳ `vnet_id` | string | The VNET ID to match the destination. When omitted, all VNETs will match. | +| ↳ `mcp_server_id` | string | The MCP server id configured in ai-controls. | +| ↳ `worker_id` | string | The ID of the Cloudflare Worker whose preview deployments to protect with Access. | +| `domain` | string | The primary hostname and path secured by Access. This domain will be displayed if the app is visible in the App Launcher. | +| `name` | string | The name of the application. | +| `oauth_configuration` | json | **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. | +| ↳ `dynamic_client_registration` | json | Settings for OAuth dynamic client registration. | +| ↳ `allow_any_on_localhost` | boolean | Allows any client with redirect URIs on localhost. | +| ↳ `allow_any_on_loopback` | boolean | Allows any client with redirect URIs on 127.0.0.1. | +| ↳ `allowed_uris` | array | The URIs that are allowed as redirect URIs for dynamically registered clients. HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs must be explicitly configured and match exactly. | +| ↳ `enabled` | boolean | Whether dynamic client registration is enabled. | +| ↳ `enabled` | boolean | Whether the OAuth configuration is enabled for this application. When set to `false`, Access will not handle OAuth for this application. Defaults to `true` if omitted. Values: True. | +| ↳ `grant` | json | Settings for OAuth grant behavior. | +| ↳ `access_token_lifetime` | string | The lifetime of the access token. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| ↳ `session_duration` | string | The duration of the OAuth session. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| `self_hosted_domains` | array | List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| `type` | string | The application type. Values: end_user, self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, dash_sso, infrastructure, rdp, mcp, mcp_portal, proxy_endpoint. | +| `user_populations` | array | The single user population associated with this application. | +| `allow_authenticate_via_warp` | boolean | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| `allow_iframe` | boolean | Enables loading application content in an iFrame. | +| `app_launcher_visible` | boolean | Displays the application in the App Launcher. | +| `auto_redirect_to_identity` | boolean | When set to `true`, users skip the identity provider selection step during login. You must specify only one identity provider in allowed_idps. | +| `cors_headers` | json | cors headers | +| ↳ `allow_all_headers` | boolean | Allows all HTTP request headers. | +| ↳ `allow_all_methods` | boolean | Allows all HTTP request methods. | +| ↳ `allow_all_origins` | boolean | Allows all origins. | +| ↳ `allow_credentials` | boolean | When set to `true`, includes credentials \(cookies, authorization headers, or TLS client certificates\) with requests. | +| ↳ `allowed_headers` | array | Allowed HTTP request headers. | +| ↳ `allowed_methods` | array | Allowed HTTP request methods. | +| ↳ `allowed_origins` | array | Allowed origins. | +| ↳ `max_age` | number | The maximum number of seconds the results of a preflight request can be cached. | +| `custom_deny_message` | string | The custom error message shown to a user when they are denied access to the application. | +| `custom_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing identity-based rules. | +| `custom_non_identity_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| `custom_pages` | array | The custom pages that will be displayed when applicable for this application | +| `eager_redirect_cookie_setting` | boolean | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| `enable_binding_cookie` | boolean | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| `http_only_cookie_attribute` | boolean | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| `logo_url` | string | The image URL for the logo shown in the App Launcher dashboard. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| `options_preflight_bypass` | boolean | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| `path_cookie_attribute` | boolean | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| `read_service_tokens_from_header` | string | Allows matching Access Service Tokens passed HTTP in a single header with this name. | +| `same_site_cookie_attribute` | string | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| `scim_config` | json | Configuration for provisioning to this application via SCIM. This is currently in closed beta. | +| ↳ `authentication` | json | Multiple authentication schemes | +| ↳ `password` | string | Password used to authenticate with the remote SCIM service. | +| ↳ `scheme` | string | The authentication scheme to use when making SCIM requests to this application. Values: httpbasic, oauthbearertoken, oauth2, access_service_token. | +| ↳ `user` | string | User name used to authenticate with the remote SCIM service. | +| ↳ `token` | string | Token used to authenticate with the remote SCIM service. | +| ↳ `authorization_url` | string | URL used to generate the auth code used during token generation. | +| ↳ `client_id` | string | Client ID of the Access service token used to authenticate with the remote service. | +| ↳ `client_secret` | string | Client secret of the Access service token used to authenticate with the remote service. | +| ↳ `scopes` | array | The authorization scopes to request when generating the token used to authenticate with the remove SCIM service. | +| ↳ `token_url` | string | URL used to generate the token used to authenticate with the remote SCIM service. | +| ↳ `deactivate_on_delete` | boolean | If false, propagates DELETE requests to the target application for SCIM resources. If true, sets 'active' to false on the SCIM resource. Note: Some targets do not support DELETE operations. | +| ↳ `enabled` | boolean | Whether SCIM provisioning is turned on for this application. | +| ↳ `idp_uid` | string | The UID of the IdP to use as the source for SCIM resources to provision to this application. | +| ↳ `mappings` | array | A list of mappings to apply to SCIM resources before provisioning them in this application. These can transform or filter the resources to be provisioned. | +| ↳ `enabled` | boolean | Whether or not this mapping is enabled. | +| ↳ `filter` | string | A \[SCIM filter expression\]\(https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2) that matches resources that should be provisioned to this application. | +| ↳ `operations` | json | Whether or not this mapping applies to creates, updates, or deletes. | +| ↳ `create` | boolean | Whether or not this mapping applies to create \(POST\) operations. | +| ↳ `delete` | boolean | Whether or not this mapping applies to DELETE operations. | +| ↳ `update` | boolean | Whether or not this mapping applies to update \(PATCH/PUT\) operations. | +| ↳ `schema` | string | Which SCIM resource type this mapping applies to. | +| ↳ `strictness` | string | The level of adherence to outbound resource schemas when provisioning to this mapping. ‘Strict’ removes unknown values, while ‘passthrough’ passes unknown values to the target. Values: strict, passthrough. | +| ↳ `transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms the resource before provisioning it in the application. | +| ↳ `remote_uri` | string | The base URI for the application's SCIM-compatible API. | +| `service_auth_401_redirect` | boolean | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| `session_duration` | string | The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `skip_interstitial` | boolean | Enables automatic authentication through cloudflared. | +| `tags` | array | The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. | +| `use_clientless_isolation_app_launcher_url` | boolean | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| `policies` | array | policies | +| ↳ `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| ↳ `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| ↳ `connection_rules` | json | The rules that define how users may connect to targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| ↳ `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| ↳ `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| ↳ `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `created_at` | string | created at | +| ↳ `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | The UUID of the policy | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access policy. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| ↳ `account_id` | string | Identifier. | +| ↳ `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | +| `saas_app` | json | saas app | +| ↳ `auth_type` | string | Identifier of the authentication protocol used for the saas app. Required for OIDC. Values: saml, oidc. | +| ↳ `consumer_service_url` | string | The service provider's endpoint that is responsible for receiving and parsing a SAML assertion. | +| ↳ `created_at` | string | created at | +| ↳ `custom_attributes` | array | custom attributes | +| ↳ `friendly_name` | string | The SAML FriendlyName of the attribute. | +| ↳ `name` | string | The name of the attribute. | +| ↳ `name_format` | string | A globally unique name for an identity or service provider. Values: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified, urn:oasis:names:tc:SAML:2.0:attrname-format:basic, urn:oasis:names:tc:SAML:2.0:attrname-format:uri. | +| ↳ `required` | boolean | If the attribute is required when building a SAML assertion. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP attribute. | +| ↳ `name_by_idp` | array | A mapping from IdP ID to attribute name. | +| ↳ `idp_id` | string | The UID of the IdP. | +| ↳ `source_name` | string | The name of the IdP provided attribute. | +| ↳ `default_relay_state` | string | The URL that the user will be redirected to after a successful login for IDP initiated logins. | +| ↳ `idp_entity_id` | string | The unique identifier for your SaaS application. | +| ↳ `name_id_format` | string | The format of the name identifier sent to the SaaS application. Values: id, email. | +| ↳ `name_id_transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms an application's user identities into a NameID value for its SAML assertion. This expression should evaluate to a singular string. The output of this expression can override the `name_id_format` setting. | +| ↳ `public_key` | string | The Access public certificate that will be used to verify your identity. | +| ↳ `saml_attribute_transform_jsonata` | string | A \[JSONata\] \(https://jsonata.org/) expression that transforms an application's user identities into attribute assertions in the SAML response. | +| ↳ `sp_entity_id` | string | A globally unique name for an identity or service provider. | +| ↳ `sso_endpoint` | string | The endpoint where your SaaS application will send login requests. | +| ↳ `updated_at` | string | updated at | +| ↳ `access_token_lifetime` | string | The lifetime of the OIDC Access Token after creation. Valid units are m,h. Must be greater than or equal to 1m and less than or equal to 24h. | +| ↳ `allow_pkce_without_client_secret` | boolean | If client secret should be required on the token endpoint when authorization_code_with_pkce grant is used. | +| ↳ `app_launcher_url` | string | The URL where this applications tile redirects users | +| ↳ `client_id` | string | The application client id | +| ↳ `client_secret` | string | The application client secret, only returned on POST request. | +| ↳ `custom_claims` | array | custom claims | +| ↳ `name` | string | The name of the claim. | +| ↳ `required` | boolean | If the claim is required when building an OIDC token. | +| ↳ `scope` | string | The scope of the claim. Values: groups, profile, email, openid. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP claim. | +| ↳ `name_by_idp` | json | A mapping from IdP ID to claim name. | +| ↳ `grant_types` | array | The OIDC flows supported by this application | +| ↳ `group_filter_regex` | string | A regex to filter Cloudflare groups returned in ID token and userinfo endpoint | +| ↳ `hybrid_and_implicit_options` | json | hybrid and implicit options | +| ↳ `return_access_token_from_authorization_endpoint` | boolean | If an Access Token should be returned from the OIDC Authorization endpoint | +| ↳ `return_id_token_from_authorization_endpoint` | boolean | If an ID Token should be returned from the OIDC Authorization endpoint | +| ↳ `redirect_uris` | array | The permitted URL's for Cloudflare to return Authorization codes and Access/ID tokens | +| ↳ `refresh_token_options` | json | refresh token options | +| ↳ `lifetime` | string | How long a refresh token will be valid for after creation. Valid units are m,h,d. Must be longer than 1m. | +| ↳ `scopes` | array | Define the user information shared with access, "offline_access" scope will be automatically enabled if refresh tokens are enabled | +| `app_launcher_logo_url` | string | The image URL of the logo shown in the App Launcher header. | +| `bg_color` | string | The background color of the App Launcher page. | +| `footer_links` | array | The links in the App Launcher footer. | +| ↳ `name` | string | The hypertext in the footer link. | +| ↳ `url` | string | the hyperlink in the footer link. | +| `header_bg_color` | string | The background color of the App Launcher header. | +| `landing_page_design` | json | The design of the App Launcher landing page shown to users when they log in. | +| ↳ `button_color` | string | The background color of the log in button on the landing page. | +| ↳ `button_text_color` | string | The color of the text in the log in button on the landing page. | +| ↳ `image_url` | string | The URL of the image shown on the landing page. | +| ↳ `message` | string | The message shown on the landing page. | +| ↳ `title` | string | The title shown on the landing page. | +| `skip_app_launcher_login_page` | boolean | Determines when to skip the App Launcher landing page. | +| `target_criteria` | array | target criteria | +| ↳ `exclude` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `include` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `port` | number | The port that the targets use for the chosen communication protocol. A port cannot be assigned to multiple protocols. | +| ↳ `require` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `target_attributes` | json | Contains a map of target attribute keys to target attribute values. | +| ↳ `protocol` | string | The communication protocol your application secures. Values: RDP. | + +### Cloudflare Get Access Group + +Fetches a single Access group. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `groupId` | string | Yes | Group id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `created_at` | string | created at | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | UUID. | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `is_default` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access group. | +| `require` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | + +### Cloudflare Get Access Policy + +Fetches a single Access policy configured for an application. Returns both exclusively owned and reusable policies used by the application. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `appId` | string | Yes | App id | +| `policyId` | string | Yes | Policy id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| `connection_rules` | json | The rules that define how users may connect to the targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `ssh` | json | The SSH-specific rules that define how users may connect to the targets secured by your application. | +| ↳ `allow_email_alias` | boolean | Enables using Identity Provider email alias as SSH username. | +| ↳ `usernames` | array | Contains the Unix usernames that may be used when connecting over SSH. | +| `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings for infrastructure applications. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. For infrastructure applications, supported values are `piv_key` and `ssh_fido2_key`. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples: `5m` or `24h`. | +| `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `created_at` | string | created at | +| `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | The UUID of the policy | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access policy. | +| `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | +| `account_id` | string | Identifier. | +| `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | + +### Cloudflare Get Access Service Token + +Fetches a single service token. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `serviceTokenId` | string | Yes | Service token id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `expires_at` | string | expires at | +| `id` | string | UUID. | +| `last_seen_at` | string | last seen at | +| `leak_report_url` | string | Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked. | +| `leak_reported_at` | string | When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked. | +| `leak_reporter` | string | The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | + +### Cloudflare Get Dns Record + +Retrieves details for a specific DNS record in the zone. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | Zone id | +| `recordId` | string | Yes | Dns record id | +| `apiKey` | string | Yes | Cloudflare API token | +| `include_shadow_metadata` | boolean | No | Whether to include shadow metadata in the `meta` field of each record in the response. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `comment` | string | Comments or notes about the DNS record. This field has no effect on DNS responses. | +| `name` | string | Complete DNS record name, including the zone name, in Punycode. | +| `proxied` | boolean | Whether the record is receiving the performance and security benefits of Cloudflare. | +| `settings` | json | Settings for the DNS record. | +| ↳ `ipv4_only` | boolean | When enabled, only A records will be generated, and AAAA records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `ipv6_only` | boolean | When enabled, only AAAA records will be generated, and A records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `flatten_cname` | boolean | If enabled, causes the CNAME record to be resolved externally and the resulting address records \(e.g., A and AAAA\) to be returned instead of the CNAME record itself. This setting is unavailable for proxied records, since they are always flattened. | +| `tags` | array | Custom tags for the DNS record. This field has no effect on DNS responses. | +| `ttl` | number | Time To Live \(TTL\) of the DNS record in seconds. Setting to 1 means 'automatic'. Value must be between 60 and 86400, with the minimum reduced to 30 for Enterprise zones. Values: 1. | +| `content` | string | Formatted URI content. See 'data' to set URI properties. | +| `private_routing` | boolean | Enables private network routing to the origin. | +| `type` | string | Record type. Values: A, AAAA, CNAME, MX, NS, OPENPGPKEY, PTR, TXT, CAA, CERT, DNSKEY, DS, HTTPS, LOC, NAPTR, SMIMEA, SRV, SSHFP, SVCB, TLSA, URI. | +| `priority` | number | Required for MX and URI records; ignored for other record types \(but may still be returned by the API\). Records with lower priorities are preferred. This field is to be deprecated in favor of the priority field within the data map. | +| `data` | json | Structured record data. The available fields depend on the DNS record type. | +| ↳ `flags` | json | Flags. | +| ↳ `tag` | string | Name of the property controlled by this record \(e.g.: issue, issuewild, iodef\). | +| ↳ `value` | string | Value. | +| ↳ `algorithm` | number | Algorithm. | +| ↳ `certificate` | string | Certificate. | +| ↳ `key_tag` | number | Key Tag. | +| ↳ `type` | number | Type. | +| ↳ `protocol` | number | Protocol. | +| ↳ `public_key` | string | Public Key. | +| ↳ `digest` | string | Digest. | +| ↳ `digest_type` | number | Digest Type. | +| ↳ `priority` | number | Priority. | +| ↳ `target` | string | The record content. | +| ↳ `altitude` | number | Altitude of location in meters. | +| ↳ `lat_degrees` | number | Degrees of latitude. | +| ↳ `lat_direction` | string | Latitude direction. Values: N, S. | +| ↳ `lat_minutes` | number | Minutes of latitude. | +| ↳ `lat_seconds` | number | Seconds of latitude. | +| ↳ `long_degrees` | number | Degrees of longitude. | +| ↳ `long_direction` | string | Longitude direction. Values: E, W. | +| ↳ `long_minutes` | number | Minutes of longitude. | +| ↳ `long_seconds` | number | Seconds of longitude. | +| ↳ `precision_horz` | number | Horizontal precision of location. | +| ↳ `precision_vert` | number | Vertical precision of location. | +| ↳ `size` | number | Size of location in meters. | +| ↳ `order` | number | Order. | +| ↳ `preference` | number | Preference. | +| ↳ `regex` | string | Regex. | +| ↳ `replacement` | string | Replacement. | +| ↳ `service` | string | Service. | +| ↳ `matching_type` | number | Matching Type. | +| ↳ `selector` | number | Selector. | +| ↳ `usage` | number | Usage. | +| ↳ `port` | number | The port of the service. | +| ↳ `weight` | number | The record weight. | +| ↳ `fingerprint` | string | Fingerprint. | +| `comment_modified_on` | string | When the record comment was last modified. Omitted if there is no comment. | +| `created_on` | string | When the record was created. | +| `id` | string | Identifier. | +| `meta` | json | Extra Cloudflare-specific metadata about the record. | +| ↳ `dead_glue` | boolean | Whether this glue record is not served because a shallower NS delegation takes precedence over the deeper delegation that needs it. | +| ↳ `is_glue` | boolean | Whether this A or AAAA record is glue for a subdomain NS delegation. See \[Glue records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records#glue-records). | +| ↳ `shadowed_by` | array | IDs of the NS records that shadow this record. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| ↳ `shadowed_records_count` | number | Number of records shadowed by this NS delegation. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `modified_on` | string | When the record was last modified. | +| `proxiable` | boolean | Whether the record can be proxied by Cloudflare or not. | +| `tags_modified_on` | string | When the record tags were last modified. Omitted if there are no tags. | +| `zone_id` | string | Legacy DNS response zone ID when returned by Cloudflare | +| `zone_name` | string | Legacy DNS response zone name when returned by Cloudflare | +| `locked` | boolean | Legacy DNS response lock flag when returned by Cloudflare | + +### Cloudflare Get R2 Bucket + +Reads the metadata of a single R2 object storage bucket. Requires an API token with Account Workers R2 Storage Read. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | +| `bucketName` | string | Yes | The name of the bucket to read | +| `jurisdiction` | string | No | Data-residency jurisdiction the bucket lives in: default, eu, or fedramp | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `creation_date` | string | Creation timestamp. | +| `jurisdiction` | string | Jurisdiction where objects in this bucket are guaranteed to be stored. Values: default, eu, us, fedramp, fedramp-high. | +| `location` | string | Location of the bucket. Values: apac, eeur, enam, weur, wnam, oc. | +| `name` | string | Name of the bucket. | +| `storage_class` | string | Storage class for newly uploaded objects, unless specified otherwise. Values: Standard, InfrequentAccess. | + +### Cloudflare Get R2 Bucket Cors + +Get the CORS policy for a bucket. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `bucketName` | string | Yes | Bucket name | +| `apiKey` | string | Yes | Cloudflare API token | +| `jurisdiction` | string | No | Jurisdiction where objects in this bucket are guaranteed to be stored. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `rules` | array | rules | +| ↳ `allowed` | json | Object specifying allowed origins, methods and headers for this CORS rule. | +| ↳ `headers` | array | Specifies the value for the Access-Control-Allow-Headers header R2 sets when requesting objects in this bucket from a browser. Cross-origin requests that include custom headers \(e.g. x-user-id\) should specify these headers as AllowedHeaders. | +| ↳ `methods` | array | Specifies the value for the Access-Control-Allow-Methods header R2 sets when requesting objects in a bucket from a browser. | +| ↳ `origins` | array | Specifies the value for the Access-Control-Allow-Origin header R2 sets when requesting objects in a bucket from a browser. | +| ↳ `exposeHeaders` | array | Specifies the headers that can be exposed back, and accessed by, the JavaScript making the cross-origin request. If you need to access headers beyond the safelisted response headers, such as Content-Encoding or cf-cache-status, you must specify it here. | +| ↳ `id` | string | Identifier for this rule. | +| ↳ `maxAgeSeconds` | number | Specifies the amount of time \(in seconds\) browsers are allowed to cache CORS preflight responses. Browsers may limit this to 2 hours or less, even if the maximum value \(86400\) is specified. | + +### Cloudflare Get R2 Bucket Lifecycle + +Get object lifecycle rules for a bucket. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Account id | +| `bucketName` | string | Yes | Bucket name | +| `apiKey` | string | Yes | Cloudflare API token | +| `jurisdiction` | string | No | Jurisdiction where objects in this bucket are guaranteed to be stored. | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `rules` | array | rules | +| ↳ `abortMultipartUploadsTransition` | json | Transition to abort ongoing multipart uploads. | +| ↳ `condition` | json | Condition for lifecycle transitions to apply after an object reaches an age in seconds. | +| ↳ `maxAge` | number | maxAge | +| ↳ `type` | string | type Values: Age. | +| ↳ `conditions` | json | Conditions that apply to all transitions of this rule. | +| ↳ `prefix` | string | Transitions will only apply to objects/uploads in the bucket that start with the given prefix, an empty prefix can be provided to scope rule to all objects/uploads. | +| ↳ `deleteObjectsTransition` | json | Transition to delete objects. | +| ↳ `condition` | json | Condition for lifecycle transitions to apply on a specific date. | +| ↳ `maxAge` | number | maxAge | +| ↳ `type` | string | type Values: Age, Date. | +| ↳ `date` | string | date | +| ↳ `enabled` | boolean | Whether or not this rule is in effect. | +| ↳ `id` | string | Unique identifier for this rule. | +| ↳ `storageClassTransitions` | array | Transitions to change the storage class of objects. | +| ↳ `condition` | json | Condition for lifecycle transitions to apply on a specific date. | +| ↳ `maxAge` | number | maxAge | +| ↳ `type` | string | type Values: Age, Date. | +| ↳ `date` | string | date | +| ↳ `storageClass` | string | storageClass Values: InfrequentAccess. | + +### Cloudflare Get Ruleset + +Reads a single zone ruleset including every rule it contains, in evaluation order. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID that owns the ruleset | +| `rulesetId` | string | Yes | The ruleset ID to read | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Get Phase Entry Point Ruleset + +Reads the entry point ruleset for a phase on a zone, including all of its rules. This is how you find the ruleset ID you need before adding, updating, or deleting a rule — for example http_request_firewall_custom for WAF custom rules, http_request_firewall_managed for managed-ruleset deployments and overrides, or http_ratelimit for rate limiting rules. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID to read the phase entry point for | +| `phase` | string | Yes | The ruleset phase, e.g. http_request_firewall_custom, http_request_firewall_managed, http_ratelimit, http_request_transform, http_request_dynamic_redirect | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Get Tunnel + +Reads a single Cloudflare Tunnel (cloudflared), including its health status and active connector connections. Requires an API token with Account Cloudflare Tunnel Read. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | +| `tunnelId` | string | Yes | The tunnel ID to read | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `account_tag` | string | Cloudflare account ID | +| `config_src` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare. | +| `connections` | array | The Cloudflare Tunnel connections between your origin and Cloudflare's edge. | +| ↳ `client_id` | string | UUID of the Cloudflare Tunnel connector. | +| ↳ `client_version` | string | The cloudflared version used to establish this connection. | +| ↳ `colo_name` | string | The Cloudflare data center used for this connection. | +| ↳ `id` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `is_pending_reconnect` | boolean | Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic. | +| ↳ `opened_at` | string | Timestamp of when the connection was established. | +| ↳ `origin_ip` | string | The public IP address of the host running cloudflared. | +| ↳ `uuid` | string | UUID of the Cloudflare Tunnel connection. | +| `conns_active_at` | string | Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive. | +| `conns_inactive_at` | string | Timestamp of when the tunnel became inactive \(no connections to Cloudflare's edge\). If `null`, the tunnel is active. | +| `created_at` | string | Timestamp of when the resource was created. | +| `deleted_at` | string | Timestamp of when the resource was deleted. If `null`, the resource has not been deleted. | +| `id` | string | UUID of the tunnel. | +| `metadata` | json | Metadata associated with the tunnel. | +| `name` | string | A user-friendly name for a tunnel. | +| `remote_config` | boolean | If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine. | +| `status` | string | The status of the tunnel. | +| `tun_type` | string | The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni. | + +### Cloudflare Get Tunnel Configuration + +Reads the configuration of a remotely-managed Cloudflare Tunnel — its ingress rules, origin request settings, and WARP routing. Only tunnels whose configuration source is "cloudflare" have a remote configuration; locally-managed tunnels keep it in their own config file. Requires an API token with Account Cloudflare Tunnel Read. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | +| `tunnelId` | string | Yes | The tunnel ID to read the configuration for | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `account_id` | string | Identifier. | +| `config` | json | The tunnel configuration and ingress rules. | +| ↳ `ingress` | array | List of public hostname definitions. At least one ingress rule needs to be defined for the tunnel. | +| ↳ `hostname` | string | Public hostname for this service. | +| ↳ `originRequest` | json | Configuration parameters for the public hostname specific connection settings between cloudflared and origin server. | +| ↳ `access` | json | For all L7 requests to this hostname, cloudflared will validate each request's Cf-Access-Jwt-Assertion request header. | +| ↳ `audTag` | array | Access applications that are allowed to reach this hostname for this Tunnel. Audience tags can be identified in the dashboard or via the List Access policies API. | +| ↳ `required` | boolean | Deny traffic that has not fulfilled Access authorization. | +| ↳ `teamName` | string | teamName | +| ↳ `caPool` | string | Path to the certificate authority \(CA\) for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare. | +| ↳ `connectTimeout` | number | Timeout for establishing a new TCP connection to your origin server. This excludes the time taken to establish TLS, which is controlled by tlsTimeout. | +| ↳ `disableChunkedEncoding` | boolean | Disables chunked transfer encoding. Useful if you are running a WSGI server. | +| ↳ `http2Origin` | boolean | Attempt to connect to origin using HTTP2. Origin must be configured as https. | +| ↳ `httpHostHeader` | string | Sets the HTTP Host header on requests sent to the local service. | +| ↳ `keepAliveConnections` | number | Maximum number of idle keepalive connections between Tunnel and your origin. This does not restrict the total number of concurrent connections. | +| ↳ `keepAliveTimeout` | number | Timeout after which an idle keepalive connection can be discarded. | +| ↳ `matchSNItoHost` | boolean | Auto configure the Hostname on the origin server certificate. | +| ↳ `noHappyEyeballs` | boolean | Disable the “happy eyeballs” algorithm for IPv4/IPv6 fallback if your local network has misconfigured one of the protocols. | +| ↳ `noTLSVerify` | boolean | Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. | +| ↳ `originServerName` | string | Hostname that cloudflared should expect from your origin server certificate. | +| ↳ `proxyType` | string | cloudflared starts a proxy server to translate HTTP traffic into TCP when proxying, for example, SSH or RDP. This configures what type of proxy will be started. Valid options are: "" for the regular proxy and "socks" for a SOCKS5 proxy. | +| ↳ `tcpKeepAlive` | number | The timeout after which a TCP keepalive packet is sent on a connection between Tunnel and the origin server. | +| ↳ `tlsTimeout` | number | Timeout for completing a TLS handshake to your origin server, if you have chosen to connect Tunnel to an HTTPS server. | +| ↳ `path` | string | Requests with this path route to this public hostname. | +| ↳ `service` | string | Protocol and address of destination server. Supported protocols: http://, https://, unix://, tcp://, ssh://, rdp://, unix+tls://, smb://. Alternatively can return a HTTP status code http_status:\[code\] e.g. 'http_status:404'. | +| ↳ `originRequest` | json | Configuration parameters for the public hostname specific connection settings between cloudflared and origin server. | +| ↳ `access` | json | For all L7 requests to this hostname, cloudflared will validate each request's Cf-Access-Jwt-Assertion request header. | +| ↳ `audTag` | array | Access applications that are allowed to reach this hostname for this Tunnel. Audience tags can be identified in the dashboard or via the List Access policies API. | +| ↳ `required` | boolean | Deny traffic that has not fulfilled Access authorization. | +| ↳ `teamName` | string | teamName | +| ↳ `caPool` | string | Path to the certificate authority \(CA\) for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare. | +| ↳ `connectTimeout` | number | Timeout for establishing a new TCP connection to your origin server. This excludes the time taken to establish TLS, which is controlled by tlsTimeout. | +| ↳ `disableChunkedEncoding` | boolean | Disables chunked transfer encoding. Useful if you are running a WSGI server. | +| ↳ `http2Origin` | boolean | Attempt to connect to origin using HTTP2. Origin must be configured as https. | +| ↳ `httpHostHeader` | string | Sets the HTTP Host header on requests sent to the local service. | +| ↳ `keepAliveConnections` | number | Maximum number of idle keepalive connections between Tunnel and your origin. This does not restrict the total number of concurrent connections. | +| ↳ `keepAliveTimeout` | number | Timeout after which an idle keepalive connection can be discarded. | +| ↳ `matchSNItoHost` | boolean | Auto configure the Hostname on the origin server certificate. | +| ↳ `noHappyEyeballs` | boolean | Disable the “happy eyeballs” algorithm for IPv4/IPv6 fallback if your local network has misconfigured one of the protocols. | +| ↳ `noTLSVerify` | boolean | Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. | +| ↳ `originServerName` | string | Hostname that cloudflared should expect from your origin server certificate. | +| ↳ `proxyType` | string | cloudflared starts a proxy server to translate HTTP traffic into TCP when proxying, for example, SSH or RDP. This configures what type of proxy will be started. Valid options are: "" for the regular proxy and "socks" for a SOCKS5 proxy. | +| ↳ `tcpKeepAlive` | number | The timeout after which a TCP keepalive packet is sent on a connection between Tunnel and the origin server. | +| ↳ `tlsTimeout` | number | Timeout for completing a TLS handshake to your origin server, if you have chosen to connect Tunnel to an HTTPS server. | +| ↳ `warp-routing` | json | Enable private network access from WARP users to private network routes. This is enabled if the tunnel has an assigned route. | +| ↳ `enabled` | boolean | enabled | +| `created_at` | string | created at | +| `source` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel's configuration on the Zero Trust dashboard. Values: local, cloudflare. | +| `tunnel_id` | string | UUID of the tunnel. | +| `version` | number | The version of the Tunnel Configuration. | + +### Cloudflare Get Tunnel Token + +Gets the connector token used to run a remotely managed Cloudflare Tunnel with cloudflared. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | Cloudflare account ID | +| `tunnelId` | string | Yes | Cloudflare Tunnel ID | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `token` | string | Token for connecting cloudflared to the tunnel | + +### Cloudflare Get Worker Route + +Returns information about a Worker route, including URL pattern and Worker. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | Zone id | +| `routeId` | string | Yes | Route id | +| `apiKey` | string | Yes | Cloudflare API token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `id` | string | Identifier. | +| `pattern` | string | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| `script` | string | Name of the script to run if the route matches. | + +### Cloudflare Get Worker Script Settings + +Reads the deployment settings of a single Workers script — bindings, compatibility date and flags, limits, observability, placement, and tail consumers. The plain "get script" endpoint in the Cloudflare API returns raw JavaScript source rather than JSON, so this settings endpoint is the structured way to inspect one script. Requires an API token with Account Workers Scripts Read. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `accountId` | string | Yes | The Cloudflare account ID. Workers scripts are account-scoped | +| `scriptName` | string | Yes | The name of the Workers script to read settings for | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `annotations` | json | Annotations for the Worker version. Annotations are not inherited across settings updates; omitting this field means the new version will have no annotations. | +| ↳ `workers/message` | string | Human-readable message about the version. Truncated to 1000 bytes if longer. | +| ↳ `workers/tag` | string | User-provided identifier for the version. Maximum 100 bytes. | +| ↳ `workers/triggered_by` | string | Operation that triggered the creation of the version. This is read-only and set by the server. | +| `bindings` | array | List of bindings attached to a Worker. You can find more about bindings on our docs: https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/#bindings. | +| ↳ `name` | string | A JavaScript variable name for the binding. | +| ↳ `type` | string | The kind of resource that the binding provides. | +| ↳ `instance_name` | string | The user-chosen instance name. Must exist at deploy time. The worker can search, chat, update, and manage items/jobs on this instance. | +| ↳ `namespace` | string | The name of the dispatch namespace. | +| ↳ `dataset` | string | The name of the dataset to bind to. | +| ↳ `database_id` | string | Identifier of the D1 database to bind to. | +| ↳ `id` | string | Identifier of the Hyperdrive connection to bind to. | +| ↳ `part` | string | The name of the file containing the WebAssembly module content. Only accepted for `service worker syntax` Workers. | +| ↳ `outbound` | json | Outbound worker. | +| ↳ `params` | array | Pass information from the Dispatch Worker to the Outbound Worker through the parameters. | +| ↳ `name` | string | Name of the parameter. | +| ↳ `worker` | json | Outbound worker. | +| ↳ `entrypoint` | string | Entrypoint to invoke on the outbound worker. | +| ↳ `environment` | string | Environment of the outbound worker. | +| ↳ `service` | string | Name of the outbound worker. | +| ↳ `class_name` | string | Class name of the Workflow. Should only be provided if the Workflow belongs to this script. | +| ↳ `dispatch_namespace` | string | The dispatch namespace the Durable Object script belongs to. | +| ↳ `environment` | string | Optional environment if the Worker utilizes one. | +| ↳ `namespace_id` | string | Identifier of the rate limit namespace to bind to. | +| ↳ `script_name` | string | Script name that contains the Workflow. If not provided, defaults to this script name. | +| ↳ `old_name` | string | The old name of the inherited binding. If set, the binding will be renamed from `old_name` to `name` in the new version. If not set, the binding will keep the same name between versions. | +| ↳ `version_id` | string | Identifier for the version to inherit the binding from. | +| ↳ `json` | json | JSON data to use. | +| ↳ `certificate_id` | string | Identifier of the certificate to bind to. | +| ↳ `text` | string | The secret value to use. | +| ↳ `pipeline` | string | Name of the Pipeline to bind to. | +| ↳ `stream` | string | ID of a K2 stream owned by the account deploying the Worker. | +| ↳ `queue_name` | string | Name of the Queue to bind to. | +| ↳ `simple` | json | The rate limit configuration. | +| ↳ `limit` | number | The limit \(requests per period\). | +| ↳ `mitigation_timeout` | number | Duration in seconds to apply the mitigation action after the rate limit is exceeded. Valid values are 0 \(disabled\), 10, or multiples of 60 up to 86400. Must be greater than or equal to the period when non-zero. | +| ↳ `period` | number | The period in seconds. | +| ↳ `bucket_name` | string | R2 bucket to bind to. | +| ↳ `jurisdiction` | string | The \[jurisdiction\]\(https://developers.cloudflare.com/r2/reference/data-location/#jurisdictional-restrictions) of the R2 bucket. Values: eu, fedramp, fedramp-high, us. | +| ↳ `allowed_destination_addresses` | array | List of allowed destination addresses. | +| ↳ `allowed_sender_addresses` | array | List of allowed sender addresses. | +| ↳ `destination_address` | string | Destination address for the email. | +| ↳ `entrypoint` | string | Entrypoint to invoke on the target Worker. | +| ↳ `service` | string | Name of Worker to bind to. | +| ↳ `index_name` | string | Name of the Vectorize index to bind to. | +| ↳ `secret_name` | string | Name of the secret in the store. | +| ↳ `store_id` | string | ID of the store containing the secret. | +| ↳ `app_id` | string | ID of the Flagship app to bind to for feature flag evaluation. | +| ↳ `algorithm` | json | Algorithm-specific key parameters. \[Learn more\]\(https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#algorithm). | +| ↳ `format` | string | Data format of the key. \[Learn more\]\(https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#format). Values: raw, pkcs8, spki, jwk. | +| ↳ `key_base64` | string | Base64-encoded key data. Required if `format` is "raw", "pkcs8", or "spki". | +| ↳ `key_jwk` | json | Key data in \[JSON Web Key\]\(https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#json_web_key) format. Required if `format` is "jwk". | +| ↳ `usages` | array | Allowed operations with the key. \[Learn more\]\(https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#keyUsages). | +| ↳ `workflow_name` | string | Name of the Workflow to bind to. | +| ↳ `service_id` | string | Identifier of the VPC service to bind to. | +| ↳ `identity` | string | Enables Gateway identity for the binding. Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. Values: runtime-email-alpha. | +| ↳ `network_id` | string | Identifier of the network to bind to. Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id. | +| ↳ `tunnel_id` | string | UUID of the Cloudflare Tunnel to bind to. Mutually exclusive with network_id. | +| `cache_options` | json | Global CacheW configuration for the Worker. When caching is on, the platform provisions a `cloudflare.app` zone for the Worker. A `type: worker` entry in the `exports` map can override this value for a single entrypoint. | +| ↳ `cross_version_cache` | boolean | Whether cached responses are shared across Worker version uploads. This is independent of `enabled`. It can stay true while caching is off, so the preference survives turning caching off and back on. | +| ↳ `enabled` | boolean | Whether caching is enabled for this Worker. | +| `compatibility_date` | string | Date indicating targeted support in the Workers runtime. Backwards incompatible fixes to the runtime following this date will not affect this Worker. | +| `compatibility_flags` | array | Flags that enable or disable certain features in the Workers runtime. Used to enable upcoming features or opt in or out of specific changes not included in a `compatibility_date`. | +| `exports` | json | Declarative exports for the Worker, keyed by export name. Worker entrypoint entries \(`type: worker`\) carry cache configuration for that entrypoint. Durable Object entries \(`type: durable-object`\) are also configured here and drive namespace reconciliation. At most 100 entries; class names are at most 128 characters. | +| `exports_reconciliation` | json | Summary of what the declarative exports reconciliation did on this upload. | +| ↳ `created` | array | Class names for which a new namespace was provisioned. | +| ↳ `deleted` | array | Class names whose namespace was deleted by a `deleted` tombstone. | +| ↳ `info` | array | Non-blocking info entries \(stale tombstones, tombstone applied with class still in code\). See `exports_reconciliation_info`. | +| ↳ `class` | string | The class name the info entry is about. | +| ↳ `message` | string | Human-readable explanation. | +| ↳ `namespace_id` | string | The provisioned namespace the entry relates to, when applicable. | +| ↳ `referencing_scripts` | array | Other Workers in the account that still bind to the affected class. Advisory: while non-empty the tombstone is not yet safe to remove — redeploy these Workers with bindings re-pointed first. | +| ↳ `scenario` | string | Stable, machine-readable tag identifying which reconciliation scenario produced an error, warning, or info entry. | +| ↳ `removable_entries` | array | Source class names whose tombstone entry is now stale and safe to delete from `exports` \(no remaining referencing scripts\). | +| ↳ `renamed` | array | Applied `renamed` tombstones. | +| ↳ `from` | string | The original \(source\) class name. | +| ↳ `to` | string | The new class name \(`renamed_to`\). | +| ↳ `transfer_pending` | array | Phase-1 transfer hints recorded on the target side. | +| ↳ `class` | string | The target-side class name awaiting transfer. | +| ↳ `from` | string | The source script the namespace will be transferred from. | +| ↳ `transferred` | array | Committed `transferred` tombstones \(phase-2\). | +| ↳ `class` | string | The source class name that was transferred. | +| ↳ `phase` | string | The transfer phase. Currently always `committed`. Values: committed. | +| ↳ `to` | string | The destination script that now owns the namespace. | +| ↳ `updated` | array | Class names whose provisioned namespace was mutated in place. | +| ↳ `warnings` | array | Non-blocking warnings. See `exports_reconciliation_warning`. | +| ↳ `class` | string | The class name the warning is about. | +| ↳ `message` | string | Human-readable explanation of the warning. | +| ↳ `namespace_id` | string | The provisioned namespace the warning relates to, when applicable. | +| ↳ `scenario` | string | Stable, machine-readable tag identifying which reconciliation scenario produced an error, warning, or info entry. | +| `limits` | json | Limits to apply for this Worker. | +| ↳ `cpu_ms` | number | The amount of CPU time this Worker can use in milliseconds. | +| ↳ `subrequests` | number | The number of subrequests this Worker can make per request. | +| `logpush` | boolean | Whether Logpush is turned on for the Worker. | +| `migrations` | json | A single set of migrations to apply. | +| ↳ `new_tag` | string | Tag to set as the latest migration tag. | +| ↳ `old_tag` | string | Tag used to verify against the latest migration tag for this Worker. If they don't match, the upload is rejected. | +| ↳ `deleted_classes` | array | A list of classes to delete Durable Object namespaces from. | +| ↳ `new_classes` | array | A list of classes to create Durable Object namespaces from. | +| ↳ `new_sqlite_classes` | array | A list of classes to create Durable Object namespaces with SQLite from. | +| ↳ `renamed_classes` | array | A list of classes with Durable Object namespaces that were renamed. | +| ↳ `from` | string | from | +| ↳ `to` | string | to | +| ↳ `transferred_classes` | array | A list of transfers for Durable Object namespaces from a different Worker and class to a class defined in this Worker. | +| ↳ `from` | string | from | +| ↳ `from_script` | string | from script | +| ↳ `to` | string | to | +| ↳ `steps` | array | Migrations to apply in order. | +| ↳ `deleted_classes` | array | A list of classes to delete Durable Object namespaces from. | +| ↳ `new_classes` | array | A list of classes to create Durable Object namespaces from. | +| ↳ `new_sqlite_classes` | array | A list of classes to create Durable Object namespaces with SQLite from. | +| ↳ `renamed_classes` | array | A list of classes with Durable Object namespaces that were renamed. | +| ↳ `from` | string | from | +| ↳ `to` | string | to | +| ↳ `transferred_classes` | array | A list of transfers for Durable Object namespaces from a different Worker and class to a class defined in this Worker. | +| ↳ `from` | string | from | +| ↳ `from_script` | string | from script | +| ↳ `to` | string | to | +| `observability` | json | Observability settings for the Worker. | +| ↳ `enabled` | boolean | Whether observability is enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for incoming requests. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `issues` | json | Real-time Issues settings for the Worker. | +| ↳ `enabled` | boolean | Whether real-time Issues are enabled for the Worker. | +| ↳ `logs` | json | Log settings for the Worker. | +| ↳ `destinations` | array | A list of destinations where logs will be exported to. | +| ↳ `enabled` | boolean | Whether logs are enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for logs. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `invocation_logs` | boolean | Whether \[invocation logs\]\(https://developers.cloudflare.com/workers/observability/logs/workers-logs/#invocation-logs) are enabled for the Worker. | +| ↳ `persist` | boolean | Whether log persistence is enabled for the Worker. | +| ↳ `redact_query_string` | boolean | Whether query strings are removed from request URLs in logs and traces. | +| ↳ `traces` | json | Trace settings for the Worker. | +| ↳ `destinations` | array | A list of destinations where traces will be exported to. | +| ↳ `enabled` | boolean | Whether traces are enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for traces. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `persist` | boolean | Whether trace persistence is enabled for the Worker. | +| ↳ `propagation_policy` | string | Controls how inbound trace context \(traceparent/tracestate\) headers on incoming requests are handled. | +| `placement` | json | Configuration for \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host. | +| ↳ `mode` | string | Targeted placement mode. Values: smart, targeted. | +| ↳ `region` | string | Cloud region for targeted placement in format 'provider:region'. | +| ↳ `hostname` | string | HTTP hostname for targeted placement. | +| ↳ `host` | string | TCP host and port for targeted placement. | +| ↳ `target` | array | Array of placement targets \(currently limited to single target\). | +| ↳ `region` | string | Cloud region in format 'provider:region'. | +| ↳ `hostname` | string | HTTP hostname for targeted placement. | +| ↳ `host` | string | TCP host:port for targeted placement. | +| `tags` | array | Tags associated with the Worker. | +| `tail_consumers` | array | List of Workers that will consume logs from the attached Worker. | +| ↳ `environment` | string | Optional environment if the Worker utilizes one. | +| ↳ `namespace` | string | Optional dispatch namespace the script belongs to. | +| ↳ `service` | string | Name of Worker that is to be the consumer. | +| `usage_model` | string | Usage model for the Worker invocations. Values: standard, bundled, unbound. | + +### Cloudflare Get Zone + +Gets details for a specific zone (domain) by its ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `zoneId` | string | Yes | The zone ID to retrieve details for | +| `apiKey` | string | Yes | Cloudflare API Token | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `account` | json | The account the zone belongs to. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the account. | +| `activated_on` | string | The last time proof of ownership was detected and the zone was made active. | +| `cname_suffix` | string | Allows the customer to use a custom apex. *Tenants Only Configuration*. | +| `created_on` | string | When the zone was created. | +| `development_mode` | number | The interval \(in seconds\) from when development mode expires \(positive integer\) or last expired \(negative integer\) for the domain. If development mode has never been enabled, this value is 0. | +| `id` | string | Identifier | +| `meta` | json | Metadata about the zone. | +| ↳ `cdn_only` | boolean | The zone is only configured for CDN. | +| ↳ `custom_certificate_quota` | number | Number of Custom Certificates the zone can have. | +| ↳ `dns_only` | boolean | The zone is only configured for DNS. | +| ↳ `foundation_dns` | boolean | The zone is setup with Foundation DNS. | +| ↳ `page_rule_quota` | number | Number of Page Rules a zone can have. | +| ↳ `phishing_detected` | boolean | The zone has been flagged for phishing. | +| ↳ `step` | number | step | +| `modified_on` | string | When the zone was last modified. | +| `name` | string | The domain name. Per \[RFC 1035\]\(https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the overall zone name can be up to 253 characters, with each segment \("label"\) not exceeding 63 characters. | +| `name_servers` | array | The name servers Cloudflare assigns to a zone. | +| `original_dnshost` | string | DNS host at the time of switching to Cloudflare. | +| `original_name_servers` | array | Original name servers before moving to Cloudflare. | +| `original_registrar` | string | Registrar for the domain at the time of switching to Cloudflare. | +| `owner` | json | The owner of the zone. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | Name of the owner. | +| ↳ `type` | string | The type of owner. | +| `paused` | boolean | Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits. | +| `permissions` | array | Legacy permissions based on legacy user membership information. | +| `plan` | json | A Zones subscription information. | +| ↳ `can_subscribe` | boolean | States if the subscription can be activated. | +| ↳ `currency` | string | The denomination of the customer. | +| ↳ `externally_managed` | boolean | If this Zone is managed by another company. | +| ↳ `frequency` | string | How often the customer is billed. | +| ↳ `id` | string | Identifier | +| ↳ `is_subscribed` | boolean | States if the subscription active. | +| ↳ `legacy_discount` | boolean | If the legacy discount applies to this Zone. | +| ↳ `legacy_id` | string | The legacy name of the plan. | +| ↳ `name` | string | Name of the owner. | +| ↳ `price` | number | How much the customer is paying. | +| `status` | string | The zone status on Cloudflare. Values: initializing, pending, active, moved. | +| `tenant` | json | The root organizational unit that this zone belongs to \(such as a tenant or organization\). | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the Tenant account. | +| `tenant_unit` | json | The immediate parent organizational unit that this zone belongs to \(such as under a tenant or sub-organization\). | +| ↳ `id` | string | Identifier | +| `type` | string | A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Values: full, partial, secondary, internal. | +| `vanity_name_servers` | array | An array of domains used for custom name servers. This is only available for Business and Enterprise plans. | +| `verification_key` | string | Verification key for partial zone setup. | + +### Cloudflare Get Zone Settings + +Reads zone settings such as SSL mode, minimum TLS version, security level, and caching level. Cloudflare retired the endpoint that read every setting in one request, so each setting is read individually — name the ones you need to keep the read small. Defaults to ssl, always_use_https, min_tls_version, tls_1_3, security_level, cache_level, browser_cache_ttl, development_mode, rocket_loader, email_obfuscation, hotlink_protection, ip_geolocation, http2, http3, websockets. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to purge cache for | -| `purge_everything` | boolean | No | Set to true to purge all cached content. Mutually exclusive with files, tags, hosts, and prefixes | -| `files` | string | No | Comma-separated list of URLs to purge from cache | -| `tags` | string | No | Comma-separated list of cache tags to purge \(Enterprise only\) | -| `hosts` | string | No | Comma-separated list of hostnames to purge \(Enterprise only\) | -| `prefixes` | string | No | Comma-separated list of URL prefixes to purge \(Enterprise only\) | +| `zoneId` | string | Yes | The zone ID to get settings for | +| `settingIds` | string | No | Comma-separated setting IDs to read, e.g. "ssl,min_tls_version,security_level". Leave blank to read the default set \(ssl, always_use_https, min_tls_version, tls_1_3, security_level, cache_level, browser_cache_ttl, development_mode, rocket_loader, email_obfuscation, hotlink_protection, ip_geolocation, http2, http3, websockets\). At most 40 settings per call. | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Purge request identifier returned by Cloudflare | +| `settings` | array | The zone settings that were readable | +| ↳ `id` | string | Setting identifier \(e.g., ssl, cache_level, security_level, always_use_https\) | +| ↳ `value` | string | Setting value as a string. Simple values returned as-is \(e.g., "full", "on"\). SSL Recommender returns its enabled flag. Complex values are JSON-stringified \(e.g., \{"css":"on","html":"on","js":"on"\}\). | +| ↳ `editable` | boolean | Whether the setting can be modified for the current zone plan | +| ↳ `modified_on` | string | ISO 8601 timestamp when the setting was last modified | +| ↳ `time_remaining` | number | Development mode countdown, in seconds. Cloudflare documents this only on the zones_development_mode setting, where it is the interval from when development mode expires \(positive\) or last expired \(negative\) | +| `unreadable` | array | Requested settings Cloudflare refused, typically because the zone plan does not expose them or the setting ID does not exist | +| ↳ `id` | string | The requested setting identifier | +| ↳ `error` | string | Why Cloudflare would not return the setting | -### Cloudflare List Rulesets +### Cloudflare List Access Applications -Lists every ruleset defined on a zone across all phases (WAF custom rules, managed rules, rate limiting, transform rules, and more). The list response deliberately omits the rules inside each ruleset — use "Get Ruleset" to read them. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). +Lists the Cloudflare Access (Zero Trust) applications protecting an account. Requires an API token with Account Access: Apps and Policies Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to list rulesets for | -| `per_page` | number | No | Number of rulesets to return per page | -| `cursor` | string | No | Cursor for the next page, taken from the cursor output of a previous call. This endpoint paginates by cursor, not by page number | +| `target_attributes` | string | No | Target Criteria attributes in key=value format. | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `name` | string | No | Filter by application name | +| `domain` | string | No | Filter by the primary hostname the application secures | +| `aud` | string | No | Filter by application audience \(AUD\) tag | +| `search` | string | No | Free-text search across applications | +| `exact` | boolean | No | Whether the name and domain filters must match exactly | +| `page` | number | No | Page number for pagination | +| `per_page` | number | No | Number of applications per page | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `rulesets` | array | Rulesets defined on the zone | -| ↳ `id` | string | Ruleset identifier | -| ↳ `name` | string | Ruleset name | -| ↳ `description` | string | Ruleset description | -| ↳ `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| ↳ `phase` | string | Phase the ruleset runs in \(e.g., http_request_firewall_custom, http_request_firewall_managed, http_ratelimit\) | -| ↳ `version` | string | Ruleset version | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| `total_count` | number | Number of rulesets returned on this page | -| `cursor` | string | Cursor to pass to the next call to read the following page, when more remain | +| `applications` | array | Applications | +| ↳ `aud` | string | Audience tag. | +| ↳ `created_at` | string | created at | +| ↳ `id` | string | UUID. | +| ↳ `updated_at` | string | updated at | +| ↳ `allowed_idps` | array | The identity providers your users can select when connecting to this application. Defaults to all IdPs configured in your account. | +| ↳ `destinations` | array | List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| ↳ `overrides` | array | Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. Overrides are supported for public destinations and Worker destinations. | +| ↳ `behavior` | string | The behavior to apply to matching requests. Values: public. | +| ↳ `path_pattern` | string | The request path pattern to match. Wildcards \(`*`\) are supported, but each path segment may have at most one wildcard. Unlike the `uri` in public destinations, override path patterns do not implicitly cover subpaths; to do that, use a wildcard. | +| ↳ `type` | string | type Values: public, private, via_mcp_server_portal, worker, preview_worker, all_workers, all_preview_workers. | +| ↳ `uri` | string | The URI of the destination. Public destinations' URIs can include a domain and path with \[wildcards\]\(https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/). | +| ↳ `cidr` | string | The CIDR range of the destination. Single IPs will be computed as /32. | +| ↳ `hostname` | string | The hostname of the destination. Matches a valid SNI served by an HTTPS origin. | +| ↳ `l4_protocol` | string | The L4 protocol of the destination. When omitted, both UDP and TCP traffic will match. Values: tcp, udp. | +| ↳ `port_range` | string | The port range of the destination. Can be a single port or a range of ports. When omitted, all ports will match. | +| ↳ `vnet_id` | string | The VNET ID to match the destination. When omitted, all VNETs will match. | +| ↳ `mcp_server_id` | string | The MCP server id configured in ai-controls. | +| ↳ `worker_id` | string | The ID of the Cloudflare Worker whose preview deployments to protect with Access. | +| ↳ `domain` | string | The primary hostname and path secured by Access. This domain will be displayed if the app is visible in the App Launcher. | +| ↳ `name` | string | The name of the application. | +| ↳ `oauth_configuration` | json | **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. | +| ↳ `dynamic_client_registration` | json | Settings for OAuth dynamic client registration. | +| ↳ `allow_any_on_localhost` | boolean | Allows any client with redirect URIs on localhost. | +| ↳ `allow_any_on_loopback` | boolean | Allows any client with redirect URIs on 127.0.0.1. | +| ↳ `allowed_uris` | array | The URIs that are allowed as redirect URIs for dynamically registered clients. HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs must be explicitly configured and match exactly. | +| ↳ `enabled` | boolean | Whether dynamic client registration is enabled. | +| ↳ `enabled` | boolean | Whether the OAuth configuration is enabled for this application. When set to `false`, Access will not handle OAuth for this application. Defaults to `true` if omitted. Values: True. | +| ↳ `grant` | json | Settings for OAuth grant behavior. | +| ↳ `access_token_lifetime` | string | The lifetime of the access token. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| ↳ `session_duration` | string | The duration of the OAuth session. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| ↳ `self_hosted_domains` | array | List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| ↳ `type` | string | The application type. Values: end_user, self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, dash_sso, infrastructure, rdp, mcp, mcp_portal, proxy_endpoint. | +| ↳ `user_populations` | array | The single user population associated with this application. | +| ↳ `allow_authenticate_via_warp` | boolean | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| ↳ `allow_iframe` | boolean | Enables loading application content in an iFrame. | +| ↳ `app_launcher_visible` | boolean | Displays the application in the App Launcher. | +| ↳ `auto_redirect_to_identity` | boolean | When set to `true`, users skip the identity provider selection step during login. You must specify only one identity provider in allowed_idps. | +| ↳ `cors_headers` | json | cors headers | +| ↳ `allow_all_headers` | boolean | Allows all HTTP request headers. | +| ↳ `allow_all_methods` | boolean | Allows all HTTP request methods. | +| ↳ `allow_all_origins` | boolean | Allows all origins. | +| ↳ `allow_credentials` | boolean | When set to `true`, includes credentials \(cookies, authorization headers, or TLS client certificates\) with requests. | +| ↳ `allowed_headers` | array | Allowed HTTP request headers. | +| ↳ `allowed_methods` | array | Allowed HTTP request methods. | +| ↳ `allowed_origins` | array | Allowed origins. | +| ↳ `max_age` | number | The maximum number of seconds the results of a preflight request can be cached. | +| ↳ `custom_deny_message` | string | The custom error message shown to a user when they are denied access to the application. | +| ↳ `custom_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing identity-based rules. | +| ↳ `custom_non_identity_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| ↳ `custom_pages` | array | The custom pages that will be displayed when applicable for this application | +| ↳ `eager_redirect_cookie_setting` | boolean | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| ↳ `enable_binding_cookie` | boolean | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| ↳ `http_only_cookie_attribute` | boolean | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| ↳ `logo_url` | string | The image URL for the logo shown in the App Launcher dashboard. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| ↳ `options_preflight_bypass` | boolean | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| ↳ `path_cookie_attribute` | boolean | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| ↳ `read_service_tokens_from_header` | string | Allows matching Access Service Tokens passed HTTP in a single header with this name. | +| ↳ `same_site_cookie_attribute` | string | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| ↳ `scim_config` | json | Configuration for provisioning to this application via SCIM. This is currently in closed beta. | +| ↳ `authentication` | json | Multiple authentication schemes | +| ↳ `password` | string | Password used to authenticate with the remote SCIM service. | +| ↳ `scheme` | string | The authentication scheme to use when making SCIM requests to this application. Values: httpbasic, oauthbearertoken, oauth2, access_service_token. | +| ↳ `user` | string | User name used to authenticate with the remote SCIM service. | +| ↳ `token` | string | Token used to authenticate with the remote SCIM service. | +| ↳ `authorization_url` | string | URL used to generate the auth code used during token generation. | +| ↳ `client_id` | string | Client ID of the Access service token used to authenticate with the remote service. | +| ↳ `client_secret` | string | Client secret of the Access service token used to authenticate with the remote service. | +| ↳ `scopes` | array | The authorization scopes to request when generating the token used to authenticate with the remove SCIM service. | +| ↳ `token_url` | string | URL used to generate the token used to authenticate with the remote SCIM service. | +| ↳ `deactivate_on_delete` | boolean | If false, propagates DELETE requests to the target application for SCIM resources. If true, sets 'active' to false on the SCIM resource. Note: Some targets do not support DELETE operations. | +| ↳ `enabled` | boolean | Whether SCIM provisioning is turned on for this application. | +| ↳ `idp_uid` | string | The UID of the IdP to use as the source for SCIM resources to provision to this application. | +| ↳ `mappings` | array | A list of mappings to apply to SCIM resources before provisioning them in this application. These can transform or filter the resources to be provisioned. | +| ↳ `enabled` | boolean | Whether or not this mapping is enabled. | +| ↳ `filter` | string | A \[SCIM filter expression\]\(https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2) that matches resources that should be provisioned to this application. | +| ↳ `operations` | json | Whether or not this mapping applies to creates, updates, or deletes. | +| ↳ `create` | boolean | Whether or not this mapping applies to create \(POST\) operations. | +| ↳ `delete` | boolean | Whether or not this mapping applies to DELETE operations. | +| ↳ `update` | boolean | Whether or not this mapping applies to update \(PATCH/PUT\) operations. | +| ↳ `schema` | string | Which SCIM resource type this mapping applies to. | +| ↳ `strictness` | string | The level of adherence to outbound resource schemas when provisioning to this mapping. ‘Strict’ removes unknown values, while ‘passthrough’ passes unknown values to the target. Values: strict, passthrough. | +| ↳ `transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms the resource before provisioning it in the application. | +| ↳ `remote_uri` | string | The base URI for the application's SCIM-compatible API. | +| ↳ `service_auth_401_redirect` | boolean | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| ↳ `session_duration` | string | The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `skip_interstitial` | boolean | Enables automatic authentication through cloudflared. | +| ↳ `tags` | array | The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. | +| ↳ `use_clientless_isolation_app_launcher_url` | boolean | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| ↳ `policies` | array | policies | +| ↳ `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| ↳ `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| ↳ `connection_rules` | json | The rules that define how users may connect to targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| ↳ `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| ↳ `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| ↳ `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `created_at` | string | created at | +| ↳ `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | The UUID of the policy | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access policy. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| ↳ `account_id` | string | Identifier. | +| ↳ `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | +| ↳ `saas_app` | json | saas app | +| ↳ `auth_type` | string | Identifier of the authentication protocol used for the saas app. Required for OIDC. Values: saml, oidc. | +| ↳ `consumer_service_url` | string | The service provider's endpoint that is responsible for receiving and parsing a SAML assertion. | +| ↳ `created_at` | string | created at | +| ↳ `custom_attributes` | array | custom attributes | +| ↳ `friendly_name` | string | The SAML FriendlyName of the attribute. | +| ↳ `name` | string | The name of the attribute. | +| ↳ `name_format` | string | A globally unique name for an identity or service provider. Values: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified, urn:oasis:names:tc:SAML:2.0:attrname-format:basic, urn:oasis:names:tc:SAML:2.0:attrname-format:uri. | +| ↳ `required` | boolean | If the attribute is required when building a SAML assertion. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP attribute. | +| ↳ `name_by_idp` | array | A mapping from IdP ID to attribute name. | +| ↳ `idp_id` | string | The UID of the IdP. | +| ↳ `source_name` | string | The name of the IdP provided attribute. | +| ↳ `default_relay_state` | string | The URL that the user will be redirected to after a successful login for IDP initiated logins. | +| ↳ `idp_entity_id` | string | The unique identifier for your SaaS application. | +| ↳ `name_id_format` | string | The format of the name identifier sent to the SaaS application. Values: id, email. | +| ↳ `name_id_transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms an application's user identities into a NameID value for its SAML assertion. This expression should evaluate to a singular string. The output of this expression can override the `name_id_format` setting. | +| ↳ `public_key` | string | The Access public certificate that will be used to verify your identity. | +| ↳ `saml_attribute_transform_jsonata` | string | A \[JSONata\] \(https://jsonata.org/) expression that transforms an application's user identities into attribute assertions in the SAML response. | +| ↳ `sp_entity_id` | string | A globally unique name for an identity or service provider. | +| ↳ `sso_endpoint` | string | The endpoint where your SaaS application will send login requests. | +| ↳ `updated_at` | string | updated at | +| ↳ `access_token_lifetime` | string | The lifetime of the OIDC Access Token after creation. Valid units are m,h. Must be greater than or equal to 1m and less than or equal to 24h. | +| ↳ `allow_pkce_without_client_secret` | boolean | If client secret should be required on the token endpoint when authorization_code_with_pkce grant is used. | +| ↳ `app_launcher_url` | string | The URL where this applications tile redirects users | +| ↳ `client_id` | string | The application client id | +| ↳ `client_secret` | string | The application client secret, only returned on POST request. | +| ↳ `custom_claims` | array | custom claims | +| ↳ `name` | string | The name of the claim. | +| ↳ `required` | boolean | If the claim is required when building an OIDC token. | +| ↳ `scope` | string | The scope of the claim. Values: groups, profile, email, openid. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP claim. | +| ↳ `name_by_idp` | json | A mapping from IdP ID to claim name. | +| ↳ `grant_types` | array | The OIDC flows supported by this application | +| ↳ `group_filter_regex` | string | A regex to filter Cloudflare groups returned in ID token and userinfo endpoint | +| ↳ `hybrid_and_implicit_options` | json | hybrid and implicit options | +| ↳ `return_access_token_from_authorization_endpoint` | boolean | If an Access Token should be returned from the OIDC Authorization endpoint | +| ↳ `return_id_token_from_authorization_endpoint` | boolean | If an ID Token should be returned from the OIDC Authorization endpoint | +| ↳ `redirect_uris` | array | The permitted URL's for Cloudflare to return Authorization codes and Access/ID tokens | +| ↳ `refresh_token_options` | json | refresh token options | +| ↳ `lifetime` | string | How long a refresh token will be valid for after creation. Valid units are m,h,d. Must be longer than 1m. | +| ↳ `scopes` | array | Define the user information shared with access, "offline_access" scope will be automatically enabled if refresh tokens are enabled | +| ↳ `app_launcher_logo_url` | string | The image URL of the logo shown in the App Launcher header. | +| ↳ `bg_color` | string | The background color of the App Launcher page. | +| ↳ `footer_links` | array | The links in the App Launcher footer. | +| ↳ `name` | string | The hypertext in the footer link. | +| ↳ `url` | string | the hyperlink in the footer link. | +| ↳ `header_bg_color` | string | The background color of the App Launcher header. | +| ↳ `landing_page_design` | json | The design of the App Launcher landing page shown to users when they log in. | +| ↳ `button_color` | string | The background color of the log in button on the landing page. | +| ↳ `button_text_color` | string | The color of the text in the log in button on the landing page. | +| ↳ `image_url` | string | The URL of the image shown on the landing page. | +| ↳ `message` | string | The message shown on the landing page. | +| ↳ `title` | string | The title shown on the landing page. | +| ↳ `skip_app_launcher_login_page` | boolean | Determines when to skip the App Launcher landing page. | +| ↳ `target_criteria` | array | target criteria | +| ↳ `exclude` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `include` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `port` | number | The port that the targets use for the chosen communication protocol. A port cannot be assigned to multiple protocols. | +| ↳ `require` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `target_attributes` | json | Contains a map of target attribute keys to target attribute values. | +| ↳ `protocol` | string | The communication protocol your application secures. Values: RDP. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Get Ruleset +### Cloudflare List Access Groups -Reads a single zone ruleset including every rule it contains, in evaluation order. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). +Lists the reusable Cloudflare Access (Zero Trust) groups in an account. Groups bundle identity rules that policies can reference by ID. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID that owns the ruleset | -| `rulesetId` | string | Yes | The ruleset ID to read | +| `accountId` | string | Yes | The Cloudflare account ID. Access groups are account-scoped | +| `name` | string | No | Filter by group name | +| `search` | string | No | Free-text search across groups | +| `page` | number | No | Page number for pagination | +| `per_page` | number | No | Number of groups per page | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules contained in the ruleset, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs \(e.g., block, challenge, log, skip, execute\) | -| ↳ `action_parameters` | json | Action-specific parameters, including managed-ruleset overrides on execute rules | -| ↳ `expression` | string | Filter expression selecting matching requests. Empty on managed-ruleset rules | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag that survives rule updates | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration for rules in the http_ratelimit phase | +| `groups` | array | Groups | +| ↳ `created_at` | string | created at | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | UUID. | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `is_default` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access group. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Get Phase Entry Point Ruleset +### Cloudflare List Access Identity Providers -Reads the entry point ruleset for a phase on a zone, including all of its rules. This is how you find the ruleset ID you need before adding, updating, or deleting a rule — for example http_request_firewall_custom for WAF custom rules, http_request_firewall_managed for managed-ruleset deployments and overrides, or http_ratelimit for rate limiting rules. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). +Lists the identity providers configured for Cloudflare Access (Zero Trust) in an account, such as Okta, Entra ID, Google Workspace, or a one-time PIN. Use the returned IDs to restrict an application with allowed_idps. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to read the phase entry point for | -| `phase` | string | Yes | The ruleset phase, e.g. http_request_firewall_custom, http_request_firewall_managed, http_ratelimit, http_request_transform, http_request_dynamic_redirect | +| `scim_enabled` | string | No | Indicates to Access to only retrieve identity providers that have the System for Cross-Domain Identity Management \(SCIM\) enabled. | +| `page` | number | No | Page number of results. | +| `per_page` | number | No | Number of results per page. | +| `accountId` | string | Yes | The Cloudflare account ID. Identity providers are account-scoped | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Entry point ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules contained in the ruleset, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs \(e.g., block, challenge, log, skip, execute\) | -| ↳ `action_parameters` | json | Action-specific parameters, including managed-ruleset overrides on execute rules | -| ↳ `expression` | string | Filter expression selecting matching requests. Empty on managed-ruleset rules | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag that survives rule updates | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration for rules in the http_ratelimit phase | +| `identity_providers` | array | Identity providers | +| ↳ `config` | json | The configuration parameters for the identity provider. To view the required parameters for a specific provider, refer to our \[developer documentation\]\(https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/). | +| ↳ `client_id` | string | Your OAuth Client ID | +| ↳ `client_secret` | string | Your OAuth Client Secret | +| ↳ `claims` | array | Custom claims | +| ↳ `email_claim_name` | string | The claim name for email in the id_token response. | +| ↳ `conditional_access_enabled` | boolean | Should Cloudflare try to load authentication contexts from your account | +| ↳ `directory_id` | string | Your Azure directory uuid | +| ↳ `prompt` | string | Configures the prompt behavior for Google authentication. Values: login, select_account, none, consent. | +| ↳ `support_groups` | boolean | Should Cloudflare try to load groups from your account | +| ↳ `centrify_account` | string | Your centrify account url | +| ↳ `centrify_app_id` | string | Your centrify app id | +| ↳ `apps_domain` | string | Your companies TLD | +| ↳ `use_login_hint` | boolean | Whether to use a previously authenticated Access email as a Google login hint when exactly one email matches the Workspace domain. | +| ↳ `auth_url` | string | The authorization_endpoint URL of your IdP | +| ↳ `certs_url` | string | The jwks_uri endpoint of your IdP to allow the IdP keys to sign the tokens | +| ↳ `pkce_enabled` | boolean | Enable Proof Key for Code Exchange \(PKCE\) | +| ↳ `scopes` | array | OAuth scopes | +| ↳ `token_url` | string | The token_endpoint URL of your IdP | +| ↳ `issuer_url` | string | IdP Entity ID or Issuer URL | +| ↳ `authorization_server_id` | string | Your okta authorization server id | +| ↳ `okta_account` | string | Your okta account url | +| ↳ `onelogin_account` | string | Your OneLogin account url | +| ↳ `ping_env_id` | string | Your PingOne environment identifier | +| ↳ `attributes` | array | A list of SAML attribute names that will be added to your signed JWT token and can be used in SAML policy rules. | +| ↳ `email_attribute_name` | string | The attribute name for email in the SAML response. | +| ↳ `enable_encryption` | boolean | Enable SAML assertion encryption. | +| ↳ `force_authn` | boolean | Asks the IdP to reauthenticate the user for each SAML authentication request. | +| ↳ `header_attributes` | array | Add a list of attribute names that will be returned in the response header from the Access callback. | +| ↳ `attribute_name` | string | attribute name from the IDP | +| ↳ `header_name` | string | header that will be added on the request to the origin | +| ↳ `idp_public_certs` | array | X509 certificate to verify the signature in the SAML authentication response | +| ↳ `max_sso_url_length` | number | The maximum URL length the IdP accepts for the SSO redirect URL. When the constructed SSO URL would exceed this length, the RelayState is stored server-side and a short nonce is passed to the IdP instead. Set this if your IdP enforces a URL length limit. | +| ↳ `sign_request` | boolean | Sign the SAML authentication request with Access credentials. To verify the signature, use the public key from the Access certs endpoints. | +| ↳ `sso_target_url` | string | URL to send the SAML authentication requests to | +| ↳ `redirect_url` | string | redirect url | +| ↳ `restrict_to_account_members` | boolean | When enabled, only users who are members of your Cloudflare account can authenticate through this identity provider. When disabled, any user with a Cloudflare account can authenticate, subject to your Access policies. | +| ↳ `login_page_auto_prompt` | boolean | When enabled, the Access login page automatically prompts the user to authenticate with a passkey. | +| ↳ `id` | string | UUID. | +| ↳ `name` | string | The name of the identity provider, shown to users on the login page. | +| ↳ `read_only` | boolean | Indicates that the identity provider is immutable and cannot be updated or deleted via the API. | +| ↳ `saml_certificate_set` | json | A SAML encryption certificate set containing current and optionally previous certificates for encryption key rotation. | +| ↳ `created_at` | string | Timestamp when the certificate set was created | +| ↳ `current_certificate` | json | A single SAML encryption certificate with metadata | +| ↳ `is_current` | boolean | Indicates whether this is the currently active certificate | +| ↳ `not_after` | string | Certificate expiration date. Certificates are automatically rotated 30 days before expiration. | +| ↳ `public_certificate` | string | PEM-encoded X.509 certificate containing the public key. Configure this certificate in your external SAML Identity Provider to enable encryption. | +| ↳ `uid` | string | Unique identifier for the certificate | +| ↳ `previous_certificate` | json | The previous certificate, maintained during rotation to ensure continuity. Null if no rotation has occurred. Mirrors the structure of `saml_certificate`. | +| ↳ `uid` | string | Unique identifier for the certificate set | +| ↳ `updated_at` | string | Timestamp when the certificate set was last updated \(e.g., during rotation\) | +| ↳ `saml_certificate_set_id` | string | The UID of the SAML encryption certificate set assigned to this Identity Provider. Only present for SAML identity providers with encryption configured. Create a certificate set via POST to `/identity_providers/\{id\}/saml_certificate`. | +| ↳ `scim_config` | json | The configuration settings for enabling a System for Cross-Domain Identity Management \(SCIM\) with the identity provider. | +| ↳ `enabled` | boolean | A flag to enable or disable SCIM for the identity provider. | +| ↳ `identity_update_behavior` | string | Indicates how a SCIM event updates a user identity used for policy evaluation. | +| ↳ `scim_base_url` | string | The base URL of Cloudflare's SCIM V2.0 API endpoint. | +| ↳ `seat_deprovision` | boolean | A flag to remove a user's seat in Zero Trust when they have been deprovisioned in the Identity Provider. This cannot be enabled unless user_deprovision is also enabled. | +| ↳ `secret` | string | A read-only token generated when the SCIM integration is enabled for the first time. It is redacted on subsequent requests. If you lose this you will need to refresh it at /access/identity_providers/:idpID/refresh_scim_secret. | +| ↳ `user_deprovision` | boolean | A flag to enable revoking a user's session in Access and Gateway when they have been deprovisioned in the Identity Provider. | +| ↳ `type` | string | The type of identity provider. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Create Ruleset +### Cloudflare List Access Policies -Creates a zone ruleset for a phase, optionally seeded with its first rules. Use this when a phase has no entry point ruleset yet — reading the entry point returns 404 on a zone that has never had a rule in that phase, and rules can only be appended to a ruleset that already exists. Create the entry point with kind "zone" and the target phase (for example http_ratelimit for rate limiting rules or http_request_firewall_custom for WAF custom rules), then use the returned ruleset ID for later rule operations. Requires an API token with Zone WAF Edit (or another matching ruleset Edit permission). +Lists the Cloudflare Access (Zero Trust) policies attached to an application, in precedence order. Requires an API token with Account Access: Apps and Policies Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to create the ruleset in | -| `name` | string | Yes | Human-readable name for the ruleset | -| `phase` | string | Yes | The ruleset phase, e.g. http_ratelimit, http_request_firewall_custom, http_request_firewall_managed, http_request_transform, http_request_dynamic_redirect | -| `kind` | string | No | Ruleset kind: zone or custom. Use zone to create a phase entry point ruleset and custom for a ruleset an execute rule deploys. Defaults to zone. "root" is the account-level phase entry point and "managed" is Cloudflare-owned, so neither can be created on this zone-scoped endpoint | -| `description` | string | No | Description of the ruleset | -| `rules` | json | No | JSON array of rules to seed the ruleset with, in evaluation order. Each rule takes action, expression, and optionally description, enabled, action_parameters, and ratelimit | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID whose policies should be listed | +| `page` | number | No | Page number for pagination | +| `per_page` | number | No | Number of policies per page | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules contained in the ruleset, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs \(e.g., block, challenge, log, skip, execute\) | -| ↳ `action_parameters` | json | Action-specific parameters, including managed-ruleset overrides on execute rules | -| ↳ `expression` | string | Filter expression selecting matching requests. Empty on managed-ruleset rules | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag that survives rule updates | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration for rules in the http_ratelimit phase | +| `policies` | array | Policies | +| ↳ `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| ↳ `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| ↳ `connection_rules` | json | The rules that define how users may connect to the targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `ssh` | json | The SSH-specific rules that define how users may connect to the targets secured by your application. | +| ↳ `allow_email_alias` | boolean | Enables using Identity Provider email alias as SSH username. | +| ↳ `usernames` | array | Contains the Unix usernames that may be used when connecting over SSH. | +| ↳ `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings for infrastructure applications. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. For infrastructure applications, supported values are `piv_key` and `ssh_fido2_key`. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples: `5m` or `24h`. | +| ↳ `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| ↳ `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| ↳ `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `created_at` | string | created at | +| ↳ `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | The UUID of the policy | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access policy. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| ↳ `account_id` | string | Identifier. | +| ↳ `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Create Ruleset Rule +### Cloudflare List Access Service Tokens -Adds a rule to a zone ruleset. Use "Get Phase Entry Point Ruleset" first to find the ruleset ID for the phase you want (for example http_request_firewall_custom for a WAF custom rule, or http_request_firewall_managed with action "execute" to deploy a managed ruleset). The rule is appended to the end of the ruleset unless a position is given. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). +Lists the Cloudflare Access (Zero Trust) service tokens in an account, which let machines authenticate to Access-protected applications. Client secrets are never returned by this endpoint — only on creation. Requires an API token with Account Access: Service Tokens Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID that owns the ruleset | -| `rulesetId` | string | Yes | The ruleset ID to add the rule to | -| `action` | string | Yes | The action the rule performs. Valid values depend on the phase — e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute \(to deploy a managed ruleset\) | -| `expression` | string | Yes | Cloudflare filter expression selecting matching requests, e.g. \(ip.src.country in \{"GB" "FR"\}\). Use "true" to match every request | -| `description` | string | No | Human-readable description of the rule | -| `enabled` | boolean | No | Whether the rule is enabled | -| `ref` | string | No | Reference tag that stays stable across rule updates | -| `actionParameters` | string | No | JSON object of action-specific parameters. For an "execute" rule this carries the managed ruleset id and any overrides, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"action":"log"\}\} | -| `position` | string | No | JSON object placing the rule within the ruleset. Exactly one of \{"before":"<RULE_ID>"\}, \{"after":"<RULE_ID>"\}, or \{"index":<1-based position>\} | +| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | +| `name` | string | No | Filter by service token name | +| `search` | string | No | Free-text search across service tokens | +| `page` | number | No | Page number for pagination | +| `per_page` | number | No | Number of service tokens per page | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version after the change | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules in the ruleset after the change, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs | -| ↳ `action_parameters` | json | Action-specific parameters | -| ↳ `expression` | string | Filter expression | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration | +| `service_tokens` | array | Service tokens | +| ↳ `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| ↳ `created_at` | string | created at | +| ↳ `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| ↳ `enabled` | boolean | Whether the service token is enabled. | +| ↳ `expires_at` | string | expires at | +| ↳ `id` | string | UUID. | +| ↳ `last_seen_at` | string | last seen at | +| ↳ `leak_report_url` | string | Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked. | +| ↳ `leak_reported_at` | string | When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked. | +| ↳ `leak_reporter` | string | The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked. | +| ↳ `name` | string | The name of the service token. | +| ↳ `updated_at` | string | updated at | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Update Ruleset Rule +### Cloudflare List Certificates -Updates a rule in a zone ruleset. Cloudflare replaces the rule definition rather than merging it, so you must send every field you want the rule to keep — any field you omit is reset to its default. Read the current rule with "Get Ruleset" first. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). +Lists SSL/TLS certificate packs for a zone. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID that owns the ruleset | -| `rulesetId` | string | Yes | The ruleset ID containing the rule | -| `ruleId` | string | Yes | The rule ID to update | -| `action` | string | Yes | The action the rule performs, e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute. Required because this endpoint replaces the rule definition — omitting it resets the stored action | -| `expression` | string | Yes | Cloudflare filter expression selecting matching requests. Required because this endpoint replaces the rule definition — omitting it resets the stored expression | -| `description` | string | No | Human-readable description of the rule | -| `enabled` | boolean | No | Whether the rule is enabled | -| `ref` | string | No | Reference tag that stays stable across rule updates. Because the update replaces the rule, omitting it resets the tag to the rule ID and breaks anything matching on the old value | -| `actionParameters` | string | No | JSON object of action-specific parameters, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"rules":\[\{"id":"<RULE_ID>","action":"log","enabled":true,"score_threshold":40\}\]\}\}. Required on an execute rule and must be sent on every update: the endpoint replaces the rule, so omitting it resets action_parameters to \{\} — which unbinds the managed ruleset the rule deploys and every override under it | -| `ratelimit` | string | No | JSON rate limiting configuration to preserve on a rule in the http_ratelimit phase, e.g. \{"characteristics":\["cf.colo.id","ip.src"\],"period":60,"requests_per_period":100\}. Because the update replaces the rule, omitting this on a rate limiting rule stops it rate limiting | -| `logging` | string | No | JSON logging configuration to preserve, e.g. \{"enabled":true\}. Omitting it on a rule that had logging configured resets it to the default | +| `zoneId` | string | Yes | The zone ID to list certificates for | +| `status` | string | No | Set to "all" to include every certificate pack regardless of status. Cloudflare documents no other value for this filter; omitting it returns only active packs | +| `page` | number | No | Page number of paginated results \(default: 1\) | +| `per_page` | number | No | Number of certificate packs per page \(default: 20, min: 5, max: 50\) | +| `deploy` | string | No | Filter by deployment environment: "staging" or "production" | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version after the change | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules in the ruleset after the change, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs | -| ↳ `action_parameters` | json | Action-specific parameters | -| ↳ `expression` | string | Filter expression | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration | +| `certificates` | array | Certificates | +| ↳ `certificate_authority` | string | Certificate Authority selected for the order. For information on any certificate authority specific details or restrictions \[see this page for more details\]\(https://developers.cloudflare.com/ssl/reference/certificate-authorities). Values: google, lets_encrypt, ssl_com. | +| ↳ `certificates` | array | Array of certificates in this pack. | +| ↳ `bundle_method` | string | Certificate bundle method. | +| ↳ `expires_on` | string | When the certificate from the authority expires. | +| ↳ `geo_restrictions` | json | Specify the region where your private key can be held locally. | +| ↳ `label` | string | label Values: us, eu, highest_security. | +| ↳ `hosts` | array | Hostnames covered by this certificate. | +| ↳ `id` | string | Certificate identifier. | +| ↳ `issuer` | string | The certificate authority that issued the certificate. | +| ↳ `modified_on` | string | When the certificate was last modified. | +| ↳ `priority` | number | The order/priority in which the certificate will be used. | +| ↳ `signature` | string | The type of hash used for the certificate. | +| ↳ `status` | string | Certificate status. | +| ↳ `uploaded_on` | string | When the certificate was uploaded to Cloudflare. | +| ↳ `zone_id` | string | Identifier. | +| ↳ `cloudflare_branding` | boolean | Whether or not to add Cloudflare Branding for the order. This will add a subdomain of sni.cloudflaressl.com as the Common Name if set to true. | +| ↳ `dcv_delegation_records` | array | DCV Delegation records for domain validation. | +| ↳ `cname` | string | The CNAME record hostname for DCV delegation. | +| ↳ `cname_target` | string | The CNAME record target value for DCV delegation. | +| ↳ `emails` | array | The set of email addresses that the certificate authority \(CA\) will use to complete domain validation. | +| ↳ `http_body` | string | The content that the certificate authority \(CA\) will expect to find at the http_url during the domain validation. | +| ↳ `http_url` | string | The url that will be checked during domain validation. | +| ↳ `status` | string | Status of the validation record. | +| ↳ `txt_name` | string | The hostname that the certificate authority \(CA\) will check for a TXT record during domain validation . | +| ↳ `txt_value` | string | The TXT record that the certificate authority \(CA\) will check during domain validation. | +| ↳ `hosts` | array | Comma separated list of valid host names for the certificate packs. Must contain the zone apex, may not contain more than 50 hosts, and may not be empty. | +| ↳ `id` | string | The unique identifier for a certificate_pack. | +| ↳ `primary_certificate` | string | Identifier of the primary certificate in a pack. | +| ↳ `status` | string | Status of certificate pack. | +| ↳ `type` | string | Type of certificate pack. Values: mh_custom, managed_hostname, sni_custom, universal, advanced, total_tls, keyless, legacy_custom. | +| ↳ `validation_errors` | array | Domain validation errors that have been received by the certificate authority \(CA\). | +| ↳ `message` | string | A domain validation error. | +| ↳ `validation_method` | string | Validation Method selected for the order. Values: txt, http, email. | +| ↳ `validation_records` | array | Certificates' validation records. | +| ↳ `cname` | string | The CNAME record hostname for DCV delegation. | +| ↳ `cname_target` | string | The CNAME record target value for DCV delegation. | +| ↳ `emails` | array | The set of email addresses that the certificate authority \(CA\) will use to complete domain validation. | +| ↳ `http_body` | string | The content that the certificate authority \(CA\) will expect to find at the http_url during the domain validation. | +| ↳ `http_url` | string | The url that will be checked during domain validation. | +| ↳ `status` | string | Status of the validation record. | +| ↳ `txt_name` | string | The hostname that the certificate authority \(CA\) will check for a TXT record during domain validation . | +| ↳ `txt_value` | string | The TXT record that the certificate authority \(CA\) will check during domain validation. | +| ↳ `validity_days` | number | Validity Days selected for the order. Values: 14, 30, 90, 365. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Delete Ruleset Rule +### Cloudflare List DNS Records -Permanently deletes a rule from a zone ruleset. This takes effect immediately on live traffic and cannot be undone — deleting a WAF custom rule, a managed-ruleset deployment, or a rate limiting rule removes that protection from the zone. Also use this to delete rate limiting rules, which live in the http_ratelimit phase ruleset. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). +Lists DNS records for a specific zone. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID that owns the ruleset | -| `rulesetId` | string | Yes | The ruleset ID containing the rule | -| `ruleId` | string | Yes | The rule ID to delete permanently | +| `name_contains` | string | No | Substring of the DNS record name. Name filters are case-insensitive. | +| `name_startswith` | string | No | Prefix of the DNS record name. Name filters are case-insensitive. | +| `name_endswith` | string | No | Suffix of the DNS record name. Name filters are case-insensitive. | +| `content_contains` | string | No | Substring of the DNS record content. Content filters are case-insensitive. | +| `content_startswith` | string | No | Prefix of the DNS record content. Content filters are case-insensitive. | +| `content_endswith` | string | No | Suffix of the DNS record content. Content filters are case-insensitive. | +| `comment_present` | boolean | No | If this parameter is present, only records *with* a comment are returned. | +| `comment_absent` | boolean | No | If this parameter is present, only records *without* a comment are returned. | +| `comment_exact` | string | No | Exact value of the DNS record comment. Comment filters are case-insensitive. | +| `comment_startswith` | string | No | Prefix of the DNS record comment. Comment filters are case-insensitive. | +| `comment_endswith` | string | No | Suffix of the DNS record comment. Comment filters are case-insensitive. | +| `tag_present` | string | No | Name of a tag which must be present on the DNS record. Tag filters are case-insensitive. | +| `tag_absent` | string | No | Name of a tag which must *not* be present on the DNS record. Tag filters are case-insensitive. | +| `tag_contains` | string | No | A tag and value, of the form `<tag-name>:<tag-value>`. The API will only return DNS records that have a tag named `<tag-name>` whose value contains `<tag-value>`. Tag filters are case-insensitive. | +| `tag_startswith` | string | No | A tag and value, of the form `<tag-name>:<tag-value>`. The API will only return DNS records that have a tag named `<tag-name>` whose value starts with `<tag-value>`. Tag filters are case-insensitive. | +| `tag_endswith` | string | No | A tag and value, of the form `<tag-name>:<tag-value>`. The API will only return DNS records that have a tag named `<tag-name>` whose value ends with `<tag-value>`. Tag filters are case-insensitive. | +| `include_shadow_metadata` | boolean | No | Whether to include shadow metadata in the `meta` field of each record in the response. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `shadowed_by_name` | string | No | Filters the response to records at or below the specified NS delegation name. NS, DS, and NSEC records at the delegation name are excluded because they are not shadowed by that delegation. Those record types are included only when they exist below the delegation. The value must be a non-apex subdomain of the zone. Requires `include_shadow_metadata=true`. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `shadowing_name` | string | No | Returns NS records that shadow the given name, searching at the name itself and each of its ancestor names within the zone, excluding the zone apex. The value must be a subdomain of the zone; the zone apex is not accepted. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `zoneId` | string | Yes | The zone ID to list DNS records for | +| `type` | string | No | Filter by record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT"\) | +| `name` | string | No | Filter by record name \(exact match\) | +| `content` | string | No | Filter by record content \(exact match\) | +| `page` | number | No | Page number for pagination \(default: 1\) | +| `per_page` | number | No | Number of records per page \(default: 100, max: 5000000\) | +| `direction` | string | No | Sort direction \(asc or desc\) | +| `match` | string | No | Match logic for filters: any or all \(default: all\) | +| `order` | string | No | Sort field \(type, name, content, ttl, proxied\) | +| `proxied` | boolean | No | Filter by proxy status | +| `search` | string | No | Free-text search across record name, content, and value | +| `tag` | string | No | Filter by tag name, or an exact name:value pair \(e.g., team:DNS\) | +| `tag_match` | string | No | Tag filter match logic: any or all. Only affects results when combined with multiple tag filter conditions; has no effect with the single exact-match Tag Filter above. | +| `commentFilter` | string | No | Filter records by comment content \(substring match\) | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset identifier | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind \(managed, custom, root, or zone\) | -| `phase` | string | Phase the ruleset runs in | -| `version` | string | Ruleset version after the change | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rules remaining in the ruleset, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action the rule performs | -| ↳ `action_parameters` | json | Action-specific parameters | -| ↳ `expression` | string | Filter expression | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration | +| `records` | array | Records | +| ↳ `comment` | string | Comments or notes about the DNS record. This field has no effect on DNS responses. | +| ↳ `name` | string | Complete DNS record name, including the zone name, in Punycode. | +| ↳ `proxied` | boolean | Whether the record is receiving the performance and security benefits of Cloudflare. | +| ↳ `settings` | json | Settings for the DNS record. | +| ↳ `ipv4_only` | boolean | When enabled, only A records will be generated, and AAAA records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `ipv6_only` | boolean | When enabled, only AAAA records will be generated, and A records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `flatten_cname` | boolean | If enabled, causes the CNAME record to be resolved externally and the resulting address records \(e.g., A and AAAA\) to be returned instead of the CNAME record itself. This setting is unavailable for proxied records, since they are always flattened. | +| ↳ `tags` | array | Custom tags for the DNS record. This field has no effect on DNS responses. | +| ↳ `ttl` | number | Time To Live \(TTL\) of the DNS record in seconds. Setting to 1 means 'automatic'. Value must be between 60 and 86400, with the minimum reduced to 30 for Enterprise zones. Values: 1. | +| ↳ `content` | string | Formatted URI content. See 'data' to set URI properties. | +| ↳ `private_routing` | boolean | Enables private network routing to the origin. | +| ↳ `type` | string | Record type. Values: A, AAAA, CNAME, MX, NS, OPENPGPKEY, PTR, TXT, CAA, CERT, DNSKEY, DS, HTTPS, LOC, NAPTR, SMIMEA, SRV, SSHFP, SVCB, TLSA, URI. | +| ↳ `priority` | number | Required for MX and URI records; ignored for other record types \(but may still be returned by the API\). Records with lower priorities are preferred. This field is to be deprecated in favor of the priority field within the data map. | +| ↳ `data` | json | Structured record data. The available fields depend on the DNS record type. | +| ↳ `flags` | json | Flags. | +| ↳ `tag` | string | Name of the property controlled by this record \(e.g.: issue, issuewild, iodef\). | +| ↳ `value` | string | Value. | +| ↳ `algorithm` | number | Algorithm. | +| ↳ `certificate` | string | Certificate. | +| ↳ `key_tag` | number | Key Tag. | +| ↳ `type` | number | Type. | +| ↳ `protocol` | number | Protocol. | +| ↳ `public_key` | string | Public Key. | +| ↳ `digest` | string | Digest. | +| ↳ `digest_type` | number | Digest Type. | +| ↳ `priority` | number | Priority. | +| ↳ `target` | string | The record content. | +| ↳ `altitude` | number | Altitude of location in meters. | +| ↳ `lat_degrees` | number | Degrees of latitude. | +| ↳ `lat_direction` | string | Latitude direction. Values: N, S. | +| ↳ `lat_minutes` | number | Minutes of latitude. | +| ↳ `lat_seconds` | number | Seconds of latitude. | +| ↳ `long_degrees` | number | Degrees of longitude. | +| ↳ `long_direction` | string | Longitude direction. Values: E, W. | +| ↳ `long_minutes` | number | Minutes of longitude. | +| ↳ `long_seconds` | number | Seconds of longitude. | +| ↳ `precision_horz` | number | Horizontal precision of location. | +| ↳ `precision_vert` | number | Vertical precision of location. | +| ↳ `size` | number | Size of location in meters. | +| ↳ `order` | number | Order. | +| ↳ `preference` | number | Preference. | +| ↳ `regex` | string | Regex. | +| ↳ `replacement` | string | Replacement. | +| ↳ `service` | string | Service. | +| ↳ `matching_type` | number | Matching Type. | +| ↳ `selector` | number | Selector. | +| ↳ `usage` | number | Usage. | +| ↳ `port` | number | The port of the service. | +| ↳ `weight` | number | The record weight. | +| ↳ `fingerprint` | string | Fingerprint. | +| ↳ `comment_modified_on` | string | When the record comment was last modified. Omitted if there is no comment. | +| ↳ `created_on` | string | When the record was created. | +| ↳ `id` | string | Identifier. | +| ↳ `meta` | json | Extra Cloudflare-specific metadata about the record. | +| ↳ `dead_glue` | boolean | Whether this glue record is not served because a shallower NS delegation takes precedence over the deeper delegation that needs it. | +| ↳ `is_glue` | boolean | Whether this A or AAAA record is glue for a subdomain NS delegation. See \[Glue records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records#glue-records). | +| ↳ `shadowed_by` | array | IDs of the NS records that shadow this record. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| ↳ `shadowed_records_count` | number | Number of records shadowed by this NS delegation. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| ↳ `modified_on` | string | When the record was last modified. | +| ↳ `proxiable` | boolean | Whether the record can be proxied by Cloudflare or not. | +| ↳ `tags_modified_on` | string | When the record tags were last modified. Omitted if there are no tags. | +| ↳ `zone_id` | string | Legacy DNS response zone ID when returned by Cloudflare | +| ↳ `zone_name` | string | Legacy DNS response zone name when returned by Cloudflare | +| ↳ `locked` | boolean | Legacy DNS response lock flag when returned by Cloudflare | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | ### Cloudflare List Managed Ruleset Overrides @@ -838,874 +5914,2867 @@ Lists the WAF managed rulesets deployed on a zone together with the overrides ap | ↳ `overrides` | json | Overrides applied to the managed ruleset, at three levels. Cloudflare documents action, enabled, and sensitivity_level at the ruleset \(top\) level; category, action, enabled, and sensitivity_level per category; and id, action, enabled, score_threshold, and sensitivity_level per rule. Rule overrides beat category overrides, which beat the ruleset-level override. sensitivity_level applies only to the DDoS phases, so for a WAF managed ruleset the rule-level properties are action, enabled, and score_threshold | | `total_count` | number | Number of managed ruleset deployments found | -### Cloudflare List Rate Limiting Rules +### Cloudflare List R2 Buckets -Lists the rate limiting rules on a zone by reading the http_ratelimit phase entry point ruleset. This uses the current Rulesets-based rate limiting API; the legacy rate_limits endpoint is no longer available. The returned ruleset ID is what "Create Rate Limiting Rule", "Update Rate Limiting Rule", and "Delete Ruleset Rule" need. Requires an API token with Zone WAF Read. +Lists the R2 object storage buckets in an account. Requires an API token with Account Workers R2 Storage Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to list rate limiting rules for | +| `order` | string | No | Order buckets by name. Allowed values: name. | +| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | +| `name_contains` | string | No | Only return buckets whose name contains this substring | +| `start_after` | string | No | Bucket name to start listing after | +| `cursor` | string | No | Pagination cursor returned by a previous call | +| `direction` | string | No | Sort direction by bucket name: asc or desc | +| `per_page` | number | No | Number of buckets per page | +| `jurisdiction` | string | No | Data-residency jurisdiction to list within: default, eu, or fedramp | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset ID of the http_ratelimit entry point, needed to create or edit rules | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind | -| `phase` | string | Phase the ruleset runs in \(http_ratelimit\) | -| `version` | string | Ruleset version | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rate limiting rules, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action applied once the rate limit is exceeded | -| ↳ `action_parameters` | json | Action-specific parameters, such as a custom block response | -| ↳ `expression` | string | Filter expression selecting the requests the rule applies to | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration \(characteristics, period, requests_per_period, mitigation_timeout, counting_expression, requests_to_origin\) | +| `buckets` | array | Buckets | +| ↳ `creation_date` | string | Creation timestamp. | +| ↳ `jurisdiction` | string | Jurisdiction where objects in this bucket are guaranteed to be stored. Values: default, eu, us, fedramp, fedramp-high. | +| ↳ `location` | string | Location of the bucket. Values: apac, eeur, enam, weur, wnam, oc. | +| ↳ `name` | string | Name of the bucket. | +| ↳ `storage_class` | string | Storage class for newly uploaded objects, unless specified otherwise. Values: Standard, InfrequentAccess. | +| `total_count` | number | Total active buckets in the requested jurisdiction, independent of filtering or pagination. Eventually consistent for accounts with elevated bucket limits. Falls back to this page’s bucket count when the API omits the total. | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total active buckets in the requested jurisdiction, independent of filtering or pagination. Eventually consistent for accounts with elevated bucket limits. | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | +| `cursor` | string | Cursor for the next page | -### Cloudflare Create Rate Limiting Rule +### Cloudflare List Rate Limiting Rules -Creates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API (the legacy rate_limits endpoint is no longer available). Run "List Rate Limiting Rules" first to get the ruleset ID. Requires an API token with Zone WAF Edit. +Lists the rate limiting rules on a zone by reading the http_ratelimit phase entry point ruleset. This uses the current Rulesets-based rate limiting API; the legacy rate_limits endpoint is no longer available. The returned ruleset ID is what "Create Rate Limiting Rule", "Update Rate Limiting Rule", and "Delete Ruleset Rule" need. Requires an API token with Zone WAF Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to add the rate limiting rule to | -| `rulesetId` | string | Yes | The http_ratelimit entry point ruleset ID, as returned by "List Rate Limiting Rules" | -| `expression` | string | Yes | Cloudflare filter expression selecting the requests the rule applies to, e.g. \(http.request.uri.path matches "^/api/"\) | -| `characteristics` | string | Yes | Comma-separated counting characteristics. cf.colo.id is mandatory. ip.src and cf.unique_visitor_id are mutually exclusive — include at most one. Example: cf.colo.id,ip.src | -| `period` | number | Yes | Counting window in seconds. Cloudflare accepts only 10, 60, 120, 300, 600, or 3600 | -| `requestsPerPeriod` | number | Yes | Number of requests allowed within the counting period before the action fires | -| `action` | string | No | Action applied once the limit is exceeded, e.g. block, managed_challenge, js_challenge, challenge, or log. Defaults to block | -| `mitigationTimeout` | number | No | Seconds the action stays applied after the limit is exceeded. Cloudflare accepts only 0, 10, 60, 120, 300, 600, 3600, or 86400 | -| `counting_expression` | string | No | Optional expression defining which requests are counted, when it differs from the matching expression | -| `requestsToOrigin` | boolean | No | When true, only requests that reach the origin are counted | -| `description` | string | No | Human-readable description of the rule | -| `enabled` | boolean | No | Whether the rule is enabled | +| `zoneId` | string | Yes | The zone ID to list rate limiting rules for | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset ID of the http_ratelimit entry point | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind | -| `phase` | string | Phase the ruleset runs in \(http_ratelimit\) | -| `version` | string | Ruleset version after the change | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rate limiting rules after the change, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action applied once the limit is exceeded | -| ↳ `action_parameters` | json | Action-specific parameters | -| ↳ `expression` | string | Filter expression | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration applied to the rule | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | -### Cloudflare Update Rate Limiting Rule +### Cloudflare List Rulesets -Updates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API. Cloudflare replaces the rule definition rather than merging it, so send the complete rule — every field you omit is reset. Run "List Rate Limiting Rules" first to read the current definition and get the ruleset ID. Requires an API token with Zone WAF Edit. +Lists every ruleset defined on a zone across all phases (WAF custom rules, managed rules, rate limiting, transform rules, and more). The list response deliberately omits the rules inside each ruleset — use "Get Ruleset" to read them. Requires an API token with Zone WAF Read (or another matching ruleset Read permission). #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID that owns the rule | -| `rulesetId` | string | Yes | The http_ratelimit entry point ruleset ID, as returned by "List Rate Limiting Rules" | -| `ruleId` | string | Yes | The rate limiting rule ID to update | -| `expression` | string | Yes | Cloudflare filter expression selecting the requests the rule applies to | -| `characteristics` | string | Yes | Comma-separated counting characteristics. cf.colo.id is mandatory. ip.src and cf.unique_visitor_id are mutually exclusive — include at most one. | -| `period` | number | Yes | Counting window in seconds. Cloudflare accepts only 10, 60, 120, 300, 600, or 3600 | -| `requestsPerPeriod` | number | Yes | Number of requests allowed within the counting period before the action fires | -| `action` | string | Yes | Action applied once the limit is exceeded: block, managed_challenge, js_challenge, challenge, or log. Required because this endpoint replaces the rule rather than merging into it — a defaulted action would silently convert an existing log or challenge rule into a hard block | -| `mitigationTimeout` | number | No | Seconds the action stays applied. Cloudflare accepts only 0, 10, 60, 120, 300, 600, 3600, or 86400 | -| `counting_expression` | string | No | Optional expression defining which requests are counted | -| `requestsToOrigin` | boolean | No | When true, only requests that reach the origin are counted | -| `description` | string | No | Human-readable description of the rule | -| `enabled` | boolean | No | Whether the rule is enabled | -| `ref` | string | No | Reference tag that stays stable across rule updates. Because the update replaces the rule, omitting it resets the tag to the rule ID and breaks anything matching on the old value | -| `actionParameters` | string | No | JSON object of action-specific parameters for the mitigation action, e.g. \{"response":\{"status_code":429,"content":"\{\"error\":\"rate limited\"\}","content_type":"application/json"\}\} for a custom block response. Because the update replaces the rule, omitting it resets action_parameters to \{\} and the rule falls back to Cloudflare's default block page | -| `logging` | string | No | JSON logging configuration to preserve, e.g. \{"enabled":true\}. Omitting it on a rule that had logging configured resets it to the default | +| `zoneId` | string | Yes | The zone ID to list rulesets for | +| `per_page` | number | No | Number of rulesets to return per page | +| `cursor` | string | No | Cursor for the next page, taken from the cursor output of a previous call. This endpoint paginates by cursor, not by page number | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Ruleset ID of the http_ratelimit entry point | -| `name` | string | Ruleset name | -| `description` | string | Ruleset description | -| `kind` | string | Ruleset kind | -| `phase` | string | Phase the ruleset runs in \(http_ratelimit\) | -| `version` | string | Ruleset version after the change | -| `last_updated` | string | RFC 3339 timestamp of the last change | -| `rules` | array | Rate limiting rules after the change, in evaluation order | -| ↳ `id` | string | Rule identifier | -| ↳ `version` | string | Rule version | -| ↳ `action` | string | Action applied once the limit is exceeded | -| ↳ `action_parameters` | json | Action-specific parameters | -| ↳ `expression` | string | Filter expression | -| ↳ `description` | string | Rule description | -| ↳ `enabled` | boolean | Whether the rule is enabled | -| ↳ `ref` | string | Rule reference tag | -| ↳ `last_updated` | string | RFC 3339 timestamp of the last change | -| ↳ `categories` | array | Managed-rule categories | -| ↳ `logging` | json | Logging configuration | -| ↳ `ratelimit` | json | Rate limiting configuration applied to the rule | +| `rulesets` | array | Rulesets | +| ↳ `description` | string | An informative description of the ruleset. | +| ↳ `id` | string | The unique ID of the ruleset. | +| ↳ `last_updated` | string | The timestamp of when the ruleset was last modified. | +| ↳ `name` | string | The human-readable name of the ruleset. | +| ↳ `version` | string | The version of the ruleset. | +| ↳ `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| ↳ `phase` | string | The phase of the ruleset. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | +| `cursor` | string | Cursor for the next page | -### Cloudflare List Access Applications +### Cloudflare List Tunnels -Lists the Cloudflare Access (Zero Trust) applications protecting an account. Requires an API token with Account Access: Apps and Policies Read. +Lists the Cloudflare Tunnels (cloudflared) in an account, with their health status and active connections. Requires an API token with Account Cloudflare Tunnel Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `name` | string | No | Filter by application name | -| `domain` | string | No | Filter by the primary hostname the application secures | -| `aud` | string | No | Filter by application audience \(AUD\) tag | -| `search` | string | No | Free-text search across applications | -| `exact` | boolean | No | Whether the name and domain filters must match exactly | +| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | +| `name` | string | No | Filter by exact tunnel name | +| `status` | string | No | Filter by tunnel health: inactive, degraded, healthy, or down | +| `uuid` | string | No | Filter by tunnel UUID | +| `is_deleted` | boolean | No | Whether to return deleted tunnels instead of active ones | +| `include_prefix` | string | No | Only include tunnels whose name starts with this prefix | +| `exclude_prefix` | string | No | Exclude tunnels whose name starts with this prefix | +| `existed_at` | string | No | Return tunnels that existed at this RFC 3339 timestamp | +| `was_active_at` | string | No | Return tunnels that were active at this RFC 3339 timestamp | +| `was_inactive_at` | string | No | Return tunnels that were inactive at this RFC 3339 timestamp | | `page` | number | No | Page number for pagination | -| `per_page` | number | No | Number of applications per page | -| `apiKey` | string | Yes | Cloudflare API Token | - -#### Output - -| Parameter | Type | Description | -| --------- | ---- | ----------- | -| `applications` | array | Access applications in the account | -| ↳ `id` | string | Access application identifier | -| ↳ `name` | string | Application name | -| ↳ `domain` | string | Primary hostname and path secured by Access | -| ↳ `type` | string | Application type \(e.g., self_hosted, saas, ssh, app_launcher, bookmark\) | -| ↳ `aud` | string | Audience tag used to verify Access JWTs | -| ↳ `session_duration` | string | How long an Access session stays valid \(e.g., 24h\) | -| ↳ `allowed_idps` | array | Identity provider IDs users may authenticate with | -| ↳ `app_launcher_visible` | boolean | Whether the app appears in the App Launcher | -| ↳ `auto_redirect_to_identity` | boolean | Whether users skip the identity provider picker | -| ↳ `custom_deny_message` | string | Message shown when access is denied | -| ↳ `custom_deny_url` | string | URL users are redirected to when access is denied | -| ↳ `logo_url` | string | Logo image URL | -| ↳ `self_hosted_domains` | array | Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application | -| ↳ `destinations` | json | Public and private destinations secured by the application | -| ↳ `tags` | array | Tags categorizing the application | -| ↳ `policies` | json | Access policies attached to the application | -| `total_count` | number | Total number of Access applications | - -### Cloudflare Get Access Application - -Reads a single Cloudflare Access (Zero Trust) application, including its attached policies. Requires an API token with Account Access: Apps and Policies Read. - -#### Input - -| Parameter | Type | Required | Description | -| --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID \(or audience tag\) to read | +| `per_page` | number | No | Number of tunnels per page | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Access application identifier | -| `name` | string | Application name | -| `domain` | string | Primary hostname and path secured by Access | -| `type` | string | Application type \(e.g., self_hosted, saas, ssh, app_launcher, bookmark\) | -| `aud` | string | Audience tag used to verify Access JWTs | -| `session_duration` | string | How long an Access session stays valid \(e.g., 24h\) | -| `allowed_idps` | array | Identity provider IDs users may authenticate with | -| `app_launcher_visible` | boolean | Whether the app appears in the App Launcher | -| `auto_redirect_to_identity` | boolean | Whether users skip the identity provider picker | -| `custom_deny_message` | string | Message shown when access is denied | -| `custom_deny_url` | string | URL users are redirected to when access is denied | -| `logo_url` | string | Logo image URL | -| `self_hosted_domains` | array | Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application | -| `destinations` | json | Public and private destinations secured by the application | -| `tags` | array | Tags categorizing the application | -| `policies` | json | Access policies attached to the application | +| `tunnels` | array | Tunnels | +| ↳ `account_tag` | string | Cloudflare account ID | +| ↳ `config_src` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare. | +| ↳ `connections` | array | The Cloudflare Tunnel connections between your origin and Cloudflare's edge. | +| ↳ `client_id` | string | UUID of the Cloudflare Tunnel connector. | +| ↳ `client_version` | string | The cloudflared version used to establish this connection. | +| ↳ `colo_name` | string | The Cloudflare data center used for this connection. | +| ↳ `id` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `is_pending_reconnect` | boolean | Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic. | +| ↳ `opened_at` | string | Timestamp of when the connection was established. | +| ↳ `origin_ip` | string | The public IP address of the host running cloudflared. | +| ↳ `uuid` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `conns_active_at` | string | Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive. | +| ↳ `conns_inactive_at` | string | Timestamp of when the tunnel became inactive \(no connections to Cloudflare's edge\). If `null`, the tunnel is active. | +| ↳ `created_at` | string | Timestamp of when the resource was created. | +| ↳ `deleted_at` | string | Timestamp of when the resource was deleted. If `null`, the resource has not been deleted. | +| ↳ `id` | string | UUID of the tunnel. | +| ↳ `metadata` | json | Metadata associated with the tunnel. | +| ↳ `name` | string | A user-friendly name for a tunnel. | +| ↳ `remote_config` | boolean | If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine. | +| ↳ `status` | string | The status of the tunnel. | +| ↳ `tun_type` | string | The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Create Access Application +### Cloudflare List Worker Routes -Creates a Cloudflare Access (Zero Trust) application that puts an identity check in front of a hostname. Until at least one policy is attached the application denies everyone, so pair this with "Create Access Policy". Requires an API token with Account Access: Apps and Policies Edit. +Lists the Workers routes on a zone, showing which URL patterns are handled by which Worker script. Unlike the Workers script endpoints, routes are zone-scoped. Requires an API token with Zone Workers Routes Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `type` | string | Yes | Application type: self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be created through the API | -| `domain` | string | No | The primary hostname and path secured by Access, e.g. internal.example.com or example.com/admin. Required for the self_hosted, ssh, vnc, and rdp types; optional for bookmark and mcp_portal; read-only for app_launcher, warp, biso, and proxy_endpoint; and absent from the saas, infrastructure, and mcp variants | -| `name` | string | No | Friendly name shown in the dashboard and App Launcher | -| `sessionDuration` | string | No | How long an Access session stays valid, e.g. 24h or 30m | -| `allowedIdps` | string | No | Comma-separated identity provider IDs users may authenticate with. Leave empty to allow all configured providers | -| `appLauncherVisible` | boolean | No | Whether the application is shown in the App Launcher | -| `autoRedirectToIdentity` | boolean | No | Whether users skip the identity provider picker | -| `customDenyMessage` | string | No | Message shown to users who are denied access | -| `customDenyUrl` | string | No | URL denied users are redirected to | -| `logoUrl` | string | No | Logo image URL shown in the dashboard and App Launcher | -| `tags` | string | No | Comma-separated tag names categorizing the application | -| `policies` | string | No | JSON array of policies to attach. Entries may be reusable policy IDs or inline policy objects, e.g. \["<POLICY_ID>"\] | -| `saasApp` | string | No | JSON SaaS configuration, required for the saas type and rejected on every other type. SAML, e.g. \{ "auth_type": "saml", "consumer_service_url": "https://example.com/acs", "sp_entity_id": "https://example.com" \}; OIDC, e.g. \{ "auth_type": "oidc", "client_id": "...", "redirect_uris": \[ "https://example.com/callback" \] \} | -| `targetCriteria` | string | No | JSON array of infrastructure target criteria, required for the infrastructure and rdp types and rejected on every other type, e.g. \[\{"port":22,"protocol":"SSH","target_attributes":\{"hostname":\["production"\]\}\}\] | +| `zoneId` | string | Yes | The zone ID to list Workers routes for. Routes are zone-scoped, not account-scoped | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Created Access application identifier | -| `name` | string | Application name | -| `domain` | string | Primary hostname and path secured by Access | -| `type` | string | Application type | -| `aud` | string | Audience tag used to verify Access JWTs | -| `session_duration` | string | How long an Access session stays valid | -| `allowed_idps` | array | Identity provider IDs users may authenticate with | -| `app_launcher_visible` | boolean | Whether the app appears in the App Launcher | -| `auto_redirect_to_identity` | boolean | Whether users skip the identity provider picker | -| `custom_deny_message` | string | Message shown when access is denied | -| `custom_deny_url` | string | URL users are redirected to when access is denied | -| `logo_url` | string | Logo image URL | -| `self_hosted_domains` | array | Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application | -| `destinations` | json | Public and private destinations secured by the application | -| `tags` | array | Tags categorizing the application | -| `policies` | json | Access policies attached to the application | +| `routes` | array | Routes | +| ↳ `id` | string | Identifier. | +| ↳ `pattern` | string | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| ↳ `script` | string | Name of the script to run if the route matches. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Update Access Application +### Cloudflare List Worker Scripts -Updates a Cloudflare Access (Zero Trust) application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: send every field the application should keep, because an omitted field may revert to its default and widen or break access. Read the current configuration with "Get Access Application" first. Requires an API token with Account Access: Apps and Policies Edit. +Lists the Workers scripts deployed in an account. Requires an API token with Account Workers Scripts Read. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID to update | -| `type` | string | Yes | Application type: self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be written through the API | -| `domain` | string | No | The primary hostname and path secured by Access. Required for the self_hosted, ssh, vnc, and rdp types; optional for bookmark and mcp_portal; read-only for app_launcher, warp, biso, and proxy_endpoint; and absent from the saas, infrastructure, and mcp variants | -| `name` | string | No | Friendly name shown in the dashboard and App Launcher | -| `sessionDuration` | string | No | How long an Access session stays valid, e.g. 24h or 30m | -| `allowedIdps` | string | No | Comma-separated identity provider IDs users may authenticate with | -| `appLauncherVisible` | boolean | No | Whether the application is shown in the App Launcher | -| `autoRedirectToIdentity` | boolean | No | Whether users skip the identity provider picker | -| `customDenyMessage` | string | No | Message shown to users who are denied access | -| `customDenyUrl` | string | No | URL denied users are redirected to | -| `logoUrl` | string | No | Logo image URL shown in the dashboard and App Launcher | -| `tags` | string | No | Comma-separated tag names categorizing the application | -| `saasApp` | string | No | JSON SaaS configuration, required for the saas type and rejected on every other type. SAML, e.g. \{ "auth_type": "saml", "consumer_service_url": "https://example.com/acs", "sp_entity_id": "https://example.com" \}; OIDC, e.g. \{ "auth_type": "oidc", "client_id": "...", "redirect_uris": \[ "https://example.com/callback" \] \} | -| `targetCriteria` | string | No | JSON array of infrastructure target criteria, required for the infrastructure and rdp types and rejected on every other type, e.g. \[\{"port":22,"protocol":"SSH","target_attributes":\{"hostname":\["production"\]\}\}\] | -| `policies` | string | No | JSON array of policies to attach. Entries may be reusable policy IDs or inline policy objects | +| `accountId` | string | Yes | The Cloudflare account ID. Workers scripts are account-scoped | +| `tags` | string | No | Filter scripts by tag. Cloudflare expects a comma-separated list of tag:allowed pairs where allowed is yes or no, e.g. team:core:yes,deprecated:no | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Access application identifier | -| `name` | string | Application name | -| `domain` | string | Primary hostname and path secured by Access | -| `type` | string | Application type | -| `aud` | string | Audience tag used to verify Access JWTs | -| `session_duration` | string | How long an Access session stays valid | -| `allowed_idps` | array | Identity provider IDs users may authenticate with | -| `app_launcher_visible` | boolean | Whether the app appears in the App Launcher | -| `auto_redirect_to_identity` | boolean | Whether users skip the identity provider picker | -| `custom_deny_message` | string | Message shown when access is denied | -| `custom_deny_url` | string | URL users are redirected to when access is denied | -| `logo_url` | string | Logo image URL | -| `self_hosted_domains` | array | Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application | -| `destinations` | json | Public and private destinations secured by the application | -| `tags` | array | Tags categorizing the application | -| `policies` | json | Access policies attached to the application | +| `scripts` | array | Scripts | +| ↳ `cache_options` | json | Global CacheW configuration for the Worker. When caching is on, the platform provisions a `cloudflare.app` zone for the Worker. A `type: worker` entry in the `exports` map can override this value for a single entrypoint. | +| ↳ `cross_version_cache` | boolean | Whether cached responses are shared across Worker version uploads. This is independent of `enabled`. It can stay true while caching is off, so the preference survives turning caching off and back on. | +| ↳ `enabled` | boolean | Whether caching is enabled for this Worker. | +| ↳ `compatibility_date` | string | Date indicating targeted support in the Workers runtime. Backwards incompatible fixes to the runtime following this date will not affect this Worker. | +| ↳ `compatibility_flags` | array | Flags that enable or disable certain features in the Workers runtime. Used to enable upcoming features or opt in or out of specific changes not included in a `compatibility_date`. | +| ↳ `created_on` | string | When the script was created. | +| ↳ `etag` | string | Hashed script content, can be used in a If-None-Match header when updating. | +| ↳ `exports` | json | Declarative exports for the Worker, keyed by export name. Worker entrypoint entries \(`type: worker`\) carry cache configuration for that entrypoint. Durable Object entries \(`type: durable-object`\) are also configured here and drive namespace reconciliation. At most 100 entries; class names are at most 128 characters. | +| ↳ `handlers` | array | The names of handlers exported as part of the default export. | +| ↳ `has_assets` | boolean | Whether a Worker contains assets. | +| ↳ `has_modules` | boolean | Whether a Worker contains modules. | +| ↳ `id` | string | The name used to identify the script. | +| ↳ `last_deployed_from` | string | The client most recently used to deploy this Worker. | +| ↳ `logpush` | boolean | Whether Logpush is turned on for the Worker. | +| ↳ `migration_tag` | string | The tag of the Durable Object migration that was most recently applied for this Worker. | +| ↳ `modified_on` | string | When the script was last modified. | +| ↳ `named_handlers` | array | Named exports, such as Durable Object class implementations and named entrypoints. | +| ↳ `handlers` | array | The names of handlers exported as part of the named export. | +| ↳ `name` | string | The name of the export. | +| ↳ `observability` | json | Observability settings for the Worker. | +| ↳ `enabled` | boolean | Whether observability is enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for incoming requests. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `issues` | json | Real-time Issues settings for the Worker. | +| ↳ `enabled` | boolean | Whether real-time Issues are enabled for the Worker. | +| ↳ `logs` | json | Log settings for the Worker. | +| ↳ `destinations` | array | A list of destinations where logs will be exported to. | +| ↳ `enabled` | boolean | Whether logs are enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for logs. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `invocation_logs` | boolean | Whether \[invocation logs\]\(https://developers.cloudflare.com/workers/observability/logs/workers-logs/#invocation-logs) are enabled for the Worker. | +| ↳ `persist` | boolean | Whether log persistence is enabled for the Worker. | +| ↳ `redact_query_string` | boolean | Whether query strings are removed from request URLs in logs and traces. | +| ↳ `traces` | json | Trace settings for the Worker. | +| ↳ `destinations` | array | A list of destinations where traces will be exported to. | +| ↳ `enabled` | boolean | Whether traces are enabled for the Worker. | +| ↳ `head_sampling_rate` | number | The sampling rate for traces. From 0 to 1 \(1 = 100%, 0.1 = 10%\). Default is 1. | +| ↳ `persist` | boolean | Whether trace persistence is enabled for the Worker. | +| ↳ `propagation_policy` | string | Controls how inbound trace context \(traceparent/tracestate\) headers on incoming requests are handled. | +| ↳ `placement` | json | Configuration for \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host. | +| ↳ `mode` | string | Targeted placement mode. Values: smart, targeted. | +| ↳ `region` | string | Cloud region for targeted placement in format 'provider:region'. | +| ↳ `hostname` | string | HTTP hostname for targeted placement. | +| ↳ `host` | string | TCP host and port for targeted placement. | +| ↳ `target` | array | Array of placement targets \(currently limited to single target\). | +| ↳ `region` | string | Cloud region in format 'provider:region'. | +| ↳ `hostname` | string | HTTP hostname for targeted placement. | +| ↳ `host` | string | TCP host:port for targeted placement. | +| ↳ `last_analyzed_at` | string | The last time the script was analyzed for \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). | +| ↳ `status` | string | Status of \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). Values: SUCCESS, UNSUPPORTED_APPLICATION, INSUFFICIENT_INVOCATIONS. | +| ↳ `placement_mode` | string | Configuration for \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host. Values: smart, targeted. | +| ↳ `placement_status` | string | Status of \[Smart Placement\]\(https://developers.cloudflare.com/workers/configuration/smart-placement). Values: SUCCESS, UNSUPPORTED_APPLICATION, INSUFFICIENT_INVOCATIONS. | +| ↳ `tag` | string | The immutable ID of the script. | +| ↳ `tags` | array | Tags associated with the Worker. | +| ↳ `tail_consumers` | array | List of Workers that will consume logs from the attached Worker. | +| ↳ `environment` | string | Optional environment if the Worker utilizes one. | +| ↳ `namespace` | string | Optional dispatch namespace the script belongs to. | +| ↳ `service` | string | Name of Worker that is to be the consumer. | +| ↳ `usage_model` | string | Usage model for the Worker invocations. Values: standard, bundled, unbound. | +| ↳ `routes` | array | Routes associated with the Worker. | +| ↳ `id` | string | Identifier. | +| ↳ `pattern` | string | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| ↳ `script` | string | Name of the script to run if the route matches. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare Delete Access Application +### Cloudflare List Zones -Permanently deletes a Cloudflare Access (Zero Trust) application and every policy attached to it. The hostname it protected is immediately left without an Access identity check, so anyone who can reach it can reach the origin. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit. +Lists one page of zones (domains) in the Cloudflare account. #### Input | Parameter | Type | Required | Description | -| --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID to delete permanently | +| --------- | ---- | -------- | ----------- | +| `type` | string | No | Comma-separated zone types: full, partial, secondary, internal | +| `account_name` | string | No | Account name; prefix the value with an operator, e.g. contains:Test. Supported operators: * `equal` \(default\) * `not_equal` * `starts_with` * `ends_with` * `contains` * `starts_with_case_sensitive` * `ends_with_case_sensitive` * `contains_case_sensitive` | +| `name` | string | No | Filter zones by domain name \(e.g., "example.com"\) | +| `status` | string | No | Filter by zone status: "initializing", "pending", "active", or "moved" | +| `page` | number | No | Page number for pagination \(default: 1\) | +| `per_page` | number | No | Number of zones per page \(default: 20, max: 50\) | +| `accountId` | string | No | Filter zones by account ID | +| `order` | string | No | Sort field \(name, status, account.id, account.name, plan.id\) | +| `direction` | string | No | Sort direction \(asc, desc\) | +| `match` | string | No | Match logic for filters \(any, all\). Default: all | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Identifier of the deleted Access application | +| `zones` | array | Zones | +| ↳ `account` | json | The account the zone belongs to. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the account. | +| ↳ `activated_on` | string | The last time proof of ownership was detected and the zone was made active. | +| ↳ `cname_suffix` | string | Allows the customer to use a custom apex. *Tenants Only Configuration*. | +| ↳ `created_on` | string | When the zone was created. | +| ↳ `development_mode` | number | The interval \(in seconds\) from when development mode expires \(positive integer\) or last expired \(negative integer\) for the domain. If development mode has never been enabled, this value is 0. | +| ↳ `id` | string | Identifier | +| ↳ `meta` | json | Metadata about the zone. | +| ↳ `cdn_only` | boolean | The zone is only configured for CDN. | +| ↳ `custom_certificate_quota` | number | Number of Custom Certificates the zone can have. | +| ↳ `dns_only` | boolean | The zone is only configured for DNS. | +| ↳ `foundation_dns` | boolean | The zone is setup with Foundation DNS. | +| ↳ `page_rule_quota` | number | Number of Page Rules a zone can have. | +| ↳ `phishing_detected` | boolean | The zone has been flagged for phishing. | +| ↳ `step` | number | step | +| ↳ `modified_on` | string | When the zone was last modified. | +| ↳ `name` | string | The domain name. Per \[RFC 1035\]\(https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the overall zone name can be up to 253 characters, with each segment \("label"\) not exceeding 63 characters. | +| ↳ `name_servers` | array | The name servers Cloudflare assigns to a zone. | +| ↳ `original_dnshost` | string | DNS host at the time of switching to Cloudflare. | +| ↳ `original_name_servers` | array | Original name servers before moving to Cloudflare. | +| ↳ `original_registrar` | string | Registrar for the domain at the time of switching to Cloudflare. | +| ↳ `owner` | json | The owner of the zone. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | Name of the owner. | +| ↳ `type` | string | The type of owner. | +| ↳ `paused` | boolean | Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits. | +| ↳ `permissions` | array | Legacy permissions based on legacy user membership information. | +| ↳ `plan` | json | A Zones subscription information. | +| ↳ `can_subscribe` | boolean | States if the subscription can be activated. | +| ↳ `currency` | string | The denomination of the customer. | +| ↳ `externally_managed` | boolean | If this Zone is managed by another company. | +| ↳ `frequency` | string | How often the customer is billed. | +| ↳ `id` | string | Identifier | +| ↳ `is_subscribed` | boolean | States if the subscription active. | +| ↳ `legacy_discount` | boolean | If the legacy discount applies to this Zone. | +| ↳ `legacy_id` | string | The legacy name of the plan. | +| ↳ `name` | string | Name of the owner. | +| ↳ `price` | number | How much the customer is paying. | +| ↳ `status` | string | The zone status on Cloudflare. Values: initializing, pending, active, moved. | +| ↳ `tenant` | json | The root organizational unit that this zone belongs to \(such as a tenant or organization\). | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the Tenant account. | +| ↳ `tenant_unit` | json | The immediate parent organizational unit that this zone belongs to \(such as under a tenant or sub-organization\). | +| ↳ `id` | string | Identifier | +| ↳ `type` | string | A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Values: full, partial, secondary, internal. | +| ↳ `vanity_name_servers` | array | An array of domains used for custom name servers. This is only available for Business and Enterprise plans. | +| ↳ `verification_key` | string | Verification key for partial zone setup. | +| `total_count` | number | Total matching resources, or the number of resources returned on this page when the API omits a total | +| `result_info` | json | Pagination metadata returned by Cloudflare | +| ↳ `page` | number | Current page | +| ↳ `per_page` | number | Page size | +| ↳ `count` | number | Count on the current page | +| ↳ `total_count` | number | Total matching resources | +| ↳ `total_pages` | number | Total pages | +| ↳ `cursor` | string | Pagination cursor | +| ↳ `cursors` | json | Directional pagination cursors | +| ↳ `before` | string | | +| ↳ `after` | string | | -### Cloudflare List Access Policies +### Cloudflare Purge Cache -Lists the Cloudflare Access (Zero Trust) policies attached to an application, in precedence order. Requires an API token with Account Access: Apps and Policies Read. +Purges cached content for a zone. Can purge everything or specific files/tags/hosts/prefixes. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID whose policies should be listed | -| `page` | number | No | Page number for pagination | -| `per_page` | number | No | Number of policies per page | +| `zoneId` | string | Yes | The zone ID to purge cache for | +| `purge_everything` | boolean | No | Set to true to purge all cached content. Mutually exclusive with files, tags, hosts, and prefixes | +| `files` | string | No | Comma-separated URLs or a JSON array of URL strings and \{url, headers\} objects. Use headers for custom cache keys, for example \[\{"url":"https://example.com/a","headers":\{"CF-IPCountry":"US"\}\}] | +| `tags` | string | No | Comma-separated list of cache tags to purge | +| `hosts` | string | No | Comma-separated list of hostnames to purge | +| `prefixes` | string | No | Comma-separated list of URL prefixes to purge | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `policies` | array | Access policies attached to the application | -| ↳ `id` | string | Policy identifier | -| ↳ `name` | string | Policy name | -| ↳ `decision` | string | Decision the policy applies: allow, deny, non_identity, or bypass | -| ↳ `precedence` | number | Evaluation order of the policy within the application | -| ↳ `include` | json | Rules evaluated with OR logic — matching any one selects the policy | -| ↳ `exclude` | json | Rules evaluated with NOT logic — matching any one rejects the request | -| ↳ `require` | json | Rules evaluated with AND logic — all must match | -| ↳ `session_duration` | string | How long a session granted by this policy stays valid | -| ↳ `approval_required` | boolean | Whether an approver must grant each access request | -| ↳ `isolation_required` | boolean | Whether the session must run in a remote browser | -| ↳ `purpose_justification_required` | boolean | Whether users must state a reason for access | -| ↳ `purpose_justification_prompt` | string | Prompt shown when a justification is required | -| ↳ `created_at` | string | Creation timestamp | -| ↳ `updated_at` | string | Last update timestamp | -| `total_count` | number | Total number of policies | +| `id` | string | Purge request identifier returned by Cloudflare | -### Cloudflare Create Access Policy +### Cloudflare Refresh Access Service Token -Creates a Cloudflare Access (Zero Trust) policy on an application, deciding who may reach it. A policy takes effect on live traffic as soon as it is created — an allow policy with a broad include rule grants access immediately. Requires an API token with Account Access: Apps and Policies Edit. +Refreshes the expiration of a service token. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID to attach the policy to | -| `name` | string | Yes | Name of the policy | -| `decision` | string | Yes | What the policy does when it matches: allow, deny, non_identity \(service tokens and other non-identity rules\), or bypass \(skip Access entirely\) | -| `include` | string | Yes | JSON array of Access rules evaluated with OR logic — matching any one selects the policy. Example: \[\{"email":\{"email":"user@example.com"\}\}\] or \[\{"email_domain":\{"domain":"example.com"\}\}\] | -| `exclude` | string | No | JSON array of Access rules evaluated with NOT logic — matching any one rejects the request | -| `require` | string | No | JSON array of Access rules evaluated with AND logic — all of them must match | -| `precedence` | number | No | Evaluation order of the policy within the application | -| `sessionDuration` | string | No | How long a session granted by this policy stays valid, e.g. 24h. Leave it unset on a policy attached to an infrastructure-typed application — Cloudflare rejects those with error 12130 | -| `approvalRequired` | boolean | No | Whether an approver must grant each access request | -| `isolationRequired` | boolean | No | Whether the session must run in a remote isolated browser | -| `purposeJustificationRequired` | boolean | No | Whether users must state a reason for access | -| `purposeJustificationPrompt` | string | No | Prompt shown when a justification is required | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `serviceTokenId` | string | Yes | Service token id | +| `apiKey` | string | Yes | Cloudflare API token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Created policy identifier | -| `name` | string | Policy name | -| `decision` | string | Decision the policy applies: allow, deny, non_identity, or bypass | -| `precedence` | number | Evaluation order of the policy within the application | -| `include` | json | Rules evaluated with OR logic | -| `exclude` | json | Rules evaluated with NOT logic | -| `require` | json | Rules evaluated with AND logic | -| `session_duration` | string | How long a session granted by this policy stays valid | -| `approval_required` | boolean | Whether an approver must grant each access request | -| `isolation_required` | boolean | Whether the session must run in a remote browser | -| `purpose_justification_required` | boolean | Whether users must state a reason for access | -| `purpose_justification_prompt` | string | Prompt shown when a justification is required | -| `created_at` | string | Creation timestamp | -| `updated_at` | string | Last update timestamp | +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `expires_at` | string | expires at | +| `id` | string | UUID. | +| `last_seen_at` | string | last seen at | +| `leak_report_url` | string | Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked. | +| `leak_reported_at` | string | When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked. | +| `leak_reporter` | string | The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | -### Cloudflare Update Access Policy +### Cloudflare Revoke Access Service Token -Updates a Cloudflare Access (Zero Trust) policy on an application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: send every rule the policy should keep, because an omitted exclude or require rule may be dropped and widen who gets in. The change applies to live traffic immediately. Read the current policy with "List Access Policies" first. Requires an API token with Account Access: Apps and Policies Edit. +Permanently deletes a Cloudflare Access (Zero Trust) service token, revoking it. Every machine or integration still presenting that client ID and secret is locked out of the Access-protected applications immediately, and the secret cannot be recovered. This cannot be undone. Requires an API token with Account Access: Service Tokens Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID that owns the policy | -| `policyId` | string | Yes | The Access policy ID to update | -| `name` | string | Yes | Name of the policy | -| `decision` | string | Yes | What the policy does when it matches: allow, deny, non_identity, or bypass \(skip Access entirely\) | -| `include` | string | Yes | JSON array of Access rules evaluated with OR logic. Example: \[\{"email_domain":\{"domain":"example.com"\}\}\] | -| `exclude` | string | No | JSON array of Access rules evaluated with NOT logic | -| `require` | string | No | JSON array of Access rules evaluated with AND logic | -| `precedence` | number | No | Evaluation order of the policy within the application | -| `sessionDuration` | string | No | How long a session granted by this policy stays valid, e.g. 24h. Leave it unset on a policy attached to an infrastructure-typed application — Cloudflare rejects those with error 12130 | -| `approvalRequired` | boolean | No | Whether an approver must grant each access request | -| `isolationRequired` | boolean | No | Whether the session must run in a remote isolated browser | -| `purposeJustificationRequired` | boolean | No | Whether users must state a reason for access | -| `purposeJustificationPrompt` | string | No | Prompt shown when a justification is required | +| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | +| `serviceTokenId` | string | Yes | The service token ID to revoke permanently | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Policy identifier | -| `name` | string | Policy name | -| `decision` | string | Decision the policy applies: allow, deny, non_identity, or bypass | -| `precedence` | number | Evaluation order of the policy within the application | -| `include` | json | Rules evaluated with OR logic | -| `exclude` | json | Rules evaluated with NOT logic | -| `require` | json | Rules evaluated with AND logic | -| `session_duration` | string | How long a session granted by this policy stays valid | -| `approval_required` | boolean | Whether an approver must grant each access request | -| `isolation_required` | boolean | Whether the session must run in a remote browser | -| `purpose_justification_required` | boolean | Whether users must state a reason for access | -| `purpose_justification_prompt` | string | Prompt shown when a justification is required | -| `created_at` | string | Creation timestamp | -| `updated_at` | string | Last update timestamp | - -### Cloudflare Delete Access Policy - -Permanently deletes a Cloudflare Access (Zero Trust) policy from an application. This changes who can reach the application the moment it runs: removing an allow policy locks out everyone it covered, and removing a deny or require policy drops that restriction. This cannot be undone. Requires an API token with Account Access: Apps and Policies Edit. +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `expires_at` | string | expires at | +| `id` | string | UUID. | +| `last_seen_at` | string | last seen at | +| `leak_report_url` | string | Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked. | +| `leak_reported_at` | string | When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked. | +| `leak_reporter` | string | The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | + +### Cloudflare Rotate Access Service Token + +Generates a new Client Secret. The previous secret expires immediately unless previous_client_secret_expires_at schedules a later expiration. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | -| `appId` | string | Yes | The Access application ID that owns the policy | -| `policyId` | string | Yes | The Access policy ID to delete permanently | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `serviceTokenId` | string | Yes | Service token id | +| `apiKey` | string | Yes | Cloudflare API token | +| `previous_client_secret_expires_at` | string | No | The expiration of the previous `client_secret`. If not provided, it defaults to the current timestamp in order to immediately expire the previous secret. If the service token was reported as leaked, this must not be in the future; the leaked secret is discarded immediately. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Identifier of the deleted Access policy | +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `client_secret` | string | The Client Secret for the service token. Access will check for this value in the `CF-Access-Client-Secret` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `id` | string | The ID of the service token. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | +| `expires_at` | string | Service token expires at when returned by Cloudflare; retained for existing workflows | +| `last_seen_at` | string | Service token last seen at when returned by Cloudflare; retained for existing workflows | -### Cloudflare List Access Groups +### Cloudflare Update Access Application -Lists the reusable Cloudflare Access (Zero Trust) groups in an account. Groups bundle identity rules that policies can reference by ID. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read. +Updates a Cloudflare Access (Zero Trust) application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: send every field the application should keep, because an omitted field may revert to its default and widen or break access. Read the current configuration with "Get Access Application" first. Requires an API token with Account Access: Apps and Policies Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Access groups are account-scoped | -| `name` | string | No | Filter by group name | -| `search` | string | No | Free-text search across groups | -| `page` | number | No | Page number for pagination | -| `per_page` | number | No | Number of groups per page | +| `destinations` | json | No | JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id. | +| `oauth_configuration` | json | No | JSON object. Required for end_user applications. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support \[RFC 8707\]\(https://datatracker.ietf.org/doc/html/rfc8707) \(Resource Indicators for OAuth 2.0\). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant. | +| `self_hosted_domains` | json | No | JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| `user_populations` | json | No | JSON array. Required for end_user applications. The single user population associated with this application. | +| `allow_authenticate_via_warp` | boolean | No | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| `allow_iframe` | boolean | No | Enables loading application content in an iFrame. | +| `cors_headers` | json | No | JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age. | +| `custom_non_identity_deny_url` | string | No | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| `custom_pages` | json | No | JSON array. The custom pages that will be displayed when applicable for this application | +| `eager_redirect_cookie_setting` | boolean | No | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| `enable_binding_cookie` | boolean | No | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| `http_only_cookie_attribute` | boolean | No | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| `mfa_config` | json | No | JSON object. Configures multi-factor authentication \(MFA\) settings. Fields: allowed_authenticators, mfa_disabled, session_duration. | +| `options_preflight_bypass` | boolean | No | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| `path_cookie_attribute` | boolean | No | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| `read_service_tokens_from_header` | string | No | Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the \(CF-Access-Client-Id, CF-Access-Client-Secret\) pair of headers. The header value will be interpreted as a json object similar to: \{ "cf-access-client-id": "<CLIENT_ID>", "cf-access-client-secret": "<CLIENT_SECRET>" \} | +| `same_site_cookie_attribute` | string | No | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| `scim_config` | json | No | JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri. | +| `service_auth_401_redirect` | boolean | No | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| `skip_interstitial` | boolean | No | Enables automatic authentication through cloudflared. | +| `use_clientless_isolation_app_launcher_url` | boolean | No | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| `app_launcher_logo_url` | string | No | The image URL of the logo shown in the App Launcher header. | +| `bg_color` | string | No | The background color of the App Launcher page. | +| `footer_links` | json | No | JSON array. The links in the App Launcher footer. Fields: name, url. | +| `header_bg_color` | string | No | The background color of the App Launcher header. | +| `landing_page_design` | json | No | JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title. | +| `skip_app_launcher_login_page` | boolean | No | Determines when to skip the App Launcher landing page. | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID to update | +| `type` | string | Yes | Application type: self_hosted, end_user, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be written through the API | +| `domain` | string | No | The primary hostname and path secured by Access. Required for the self_hosted, ssh, vnc, and rdp types; optional for bookmark and mcp_portal; read-only for app_launcher, warp, biso, and proxy_endpoint; and absent from the saas, infrastructure, and mcp variants | +| `name` | string | No | Friendly name shown in the dashboard and App Launcher | +| `sessionDuration` | string | No | How long an Access session stays valid, e.g. 24h or 30m | +| `allowedIdps` | string | No | Comma-separated identity provider IDs users may authenticate with | +| `appLauncherVisible` | boolean | No | Whether the application is shown in the App Launcher | +| `autoRedirectToIdentity` | boolean | No | Whether users skip the identity provider picker | +| `customDenyMessage` | string | No | Message shown to users who are denied access | +| `customDenyUrl` | string | No | URL denied users are redirected to | +| `logoUrl` | string | No | Logo image URL shown in the dashboard and App Launcher | +| `tags` | string | No | Comma-separated tag names categorizing the application | +| `saasApp` | string | No | JSON SaaS configuration, required for the saas type and rejected on every other type. SAML, e.g. \{ "auth_type": "saml", "consumer_service_url": "https://example.com/acs", "sp_entity_id": "https://example.com" \}; OIDC, e.g. \{ "auth_type": "oidc", "client_id": "...", "redirect_uris": \[ "https://example.com/callback" \] \} | +| `targetCriteria` | string | No | JSON array of infrastructure target criteria, required for the infrastructure and rdp types and rejected on every other type, e.g. \[\{"port":22,"protocol":"SSH","target_attributes":\{"hostname":\["production"\]\}\}\] | +| `policies` | string | No | JSON array of policies to attach. Entries may be reusable policy IDs or inline policy objects | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `groups` | array | Access groups in the account | -| ↳ `id` | string | Access group identifier | -| ↳ `name` | string | Group name | -| ↳ `is_default` | json | Rules that place this group in every Access application by default. Cloudflare returns an array of rule objects here, not a boolean | -| ↳ `include` | json | Rules evaluated with OR logic | -| ↳ `exclude` | json | Rules evaluated with NOT logic | -| ↳ `require` | json | Rules evaluated with AND logic | -| ↳ `created_at` | string | Creation timestamp | -| ↳ `updated_at` | string | Last update timestamp | -| `total_count` | number | Total number of Access groups | - -### Cloudflare List Access Identity Providers - -Lists the identity providers configured for Cloudflare Access (Zero Trust) in an account, such as Okta, Entra ID, Google Workspace, or a one-time PIN. Use the returned IDs to restrict an application with allowed_idps. Requires an API token with Account Access: Organizations, Identity Providers, and Groups Read. +| `aud` | string | Audience tag. | +| `created_at` | string | created at | +| `id` | string | UUID. | +| `updated_at` | string | updated at | +| `allowed_idps` | array | The identity providers your users can select when connecting to this application. Defaults to all IdPs configured in your account. | +| `destinations` | array | List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| ↳ `overrides` | array | Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. Overrides are supported for public destinations and Worker destinations. | +| ↳ `behavior` | string | The behavior to apply to matching requests. Values: public. | +| ↳ `path_pattern` | string | The request path pattern to match. Wildcards \(`*`\) are supported, but each path segment may have at most one wildcard. Unlike the `uri` in public destinations, override path patterns do not implicitly cover subpaths; to do that, use a wildcard. | +| ↳ `type` | string | type Values: public, private, via_mcp_server_portal, worker, preview_worker, all_workers, all_preview_workers. | +| ↳ `uri` | string | The URI of the destination. Public destinations' URIs can include a domain and path with \[wildcards\]\(https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/). | +| ↳ `cidr` | string | The CIDR range of the destination. Single IPs will be computed as /32. | +| ↳ `hostname` | string | The hostname of the destination. Matches a valid SNI served by an HTTPS origin. | +| ↳ `l4_protocol` | string | The L4 protocol of the destination. When omitted, both UDP and TCP traffic will match. Values: tcp, udp. | +| ↳ `port_range` | string | The port range of the destination. Can be a single port or a range of ports. When omitted, all ports will match. | +| ↳ `vnet_id` | string | The VNET ID to match the destination. When omitted, all VNETs will match. | +| ↳ `mcp_server_id` | string | The MCP server id configured in ai-controls. | +| ↳ `worker_id` | string | The ID of the Cloudflare Worker whose preview deployments to protect with Access. | +| `domain` | string | The primary hostname and path secured by Access. This domain will be displayed if the app is visible in the App Launcher. | +| `name` | string | The name of the application. | +| `oauth_configuration` | json | **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. | +| ↳ `dynamic_client_registration` | json | Settings for OAuth dynamic client registration. | +| ↳ `allow_any_on_localhost` | boolean | Allows any client with redirect URIs on localhost. | +| ↳ `allow_any_on_loopback` | boolean | Allows any client with redirect URIs on 127.0.0.1. | +| ↳ `allowed_uris` | array | The URIs that are allowed as redirect URIs for dynamically registered clients. HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs must be explicitly configured and match exactly. | +| ↳ `enabled` | boolean | Whether dynamic client registration is enabled. | +| ↳ `enabled` | boolean | Whether the OAuth configuration is enabled for this application. When set to `false`, Access will not handle OAuth for this application. Defaults to `true` if omitted. Values: True. | +| ↳ `grant` | json | Settings for OAuth grant behavior. | +| ↳ `access_token_lifetime` | string | The lifetime of the access token. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| ↳ `session_duration` | string | The duration of the OAuth session. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us \(or µs\), ms, s, m, h. | +| `self_hosted_domains` | array | List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. | +| `type` | string | The application type. Values: end_user, self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, dash_sso, infrastructure, rdp, mcp, mcp_portal, proxy_endpoint. | +| `user_populations` | array | The single user population associated with this application. | +| `allow_authenticate_via_warp` | boolean | When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication. | +| `allow_iframe` | boolean | Enables loading application content in an iFrame. | +| `app_launcher_visible` | boolean | Displays the application in the App Launcher. | +| `auto_redirect_to_identity` | boolean | When set to `true`, users skip the identity provider selection step during login. You must specify only one identity provider in allowed_idps. | +| `cors_headers` | json | cors headers | +| ↳ `allow_all_headers` | boolean | Allows all HTTP request headers. | +| ↳ `allow_all_methods` | boolean | Allows all HTTP request methods. | +| ↳ `allow_all_origins` | boolean | Allows all origins. | +| ↳ `allow_credentials` | boolean | When set to `true`, includes credentials \(cookies, authorization headers, or TLS client certificates\) with requests. | +| ↳ `allowed_headers` | array | Allowed HTTP request headers. | +| ↳ `allowed_methods` | array | Allowed HTTP request methods. | +| ↳ `allowed_origins` | array | Allowed origins. | +| ↳ `max_age` | number | The maximum number of seconds the results of a preflight request can be cached. | +| `custom_deny_message` | string | The custom error message shown to a user when they are denied access to the application. | +| `custom_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing identity-based rules. | +| `custom_non_identity_deny_url` | string | The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. | +| `custom_pages` | array | The custom pages that will be displayed when applicable for this application | +| `eager_redirect_cookie_setting` | boolean | Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior. | +| `enable_binding_cookie` | boolean | Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks. | +| `http_only_cookie_attribute` | boolean | Enables the HttpOnly cookie attribute, which increases security against XSS attacks. | +| `logo_url` | string | The image URL for the logo shown in the App Launcher dashboard. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| `options_preflight_bypass` | boolean | Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set. | +| `path_cookie_attribute` | boolean | Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default | +| `read_service_tokens_from_header` | string | Allows matching Access Service Tokens passed HTTP in a single header with this name. | +| `same_site_cookie_attribute` | string | Sets the SameSite cookie setting, which provides increased security against CSRF attacks. | +| `scim_config` | json | Configuration for provisioning to this application via SCIM. This is currently in closed beta. | +| ↳ `authentication` | json | Multiple authentication schemes | +| ↳ `password` | string | Password used to authenticate with the remote SCIM service. | +| ↳ `scheme` | string | The authentication scheme to use when making SCIM requests to this application. Values: httpbasic, oauthbearertoken, oauth2, access_service_token. | +| ↳ `user` | string | User name used to authenticate with the remote SCIM service. | +| ↳ `token` | string | Token used to authenticate with the remote SCIM service. | +| ↳ `authorization_url` | string | URL used to generate the auth code used during token generation. | +| ↳ `client_id` | string | Client ID of the Access service token used to authenticate with the remote service. | +| ↳ `client_secret` | string | Client secret of the Access service token used to authenticate with the remote service. | +| ↳ `scopes` | array | The authorization scopes to request when generating the token used to authenticate with the remove SCIM service. | +| ↳ `token_url` | string | URL used to generate the token used to authenticate with the remote SCIM service. | +| ↳ `deactivate_on_delete` | boolean | If false, propagates DELETE requests to the target application for SCIM resources. If true, sets 'active' to false on the SCIM resource. Note: Some targets do not support DELETE operations. | +| ↳ `enabled` | boolean | Whether SCIM provisioning is turned on for this application. | +| ↳ `idp_uid` | string | The UID of the IdP to use as the source for SCIM resources to provision to this application. | +| ↳ `mappings` | array | A list of mappings to apply to SCIM resources before provisioning them in this application. These can transform or filter the resources to be provisioned. | +| ↳ `enabled` | boolean | Whether or not this mapping is enabled. | +| ↳ `filter` | string | A \[SCIM filter expression\]\(https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2) that matches resources that should be provisioned to this application. | +| ↳ `operations` | json | Whether or not this mapping applies to creates, updates, or deletes. | +| ↳ `create` | boolean | Whether or not this mapping applies to create \(POST\) operations. | +| ↳ `delete` | boolean | Whether or not this mapping applies to DELETE operations. | +| ↳ `update` | boolean | Whether or not this mapping applies to update \(PATCH/PUT\) operations. | +| ↳ `schema` | string | Which SCIM resource type this mapping applies to. | +| ↳ `strictness` | string | The level of adherence to outbound resource schemas when provisioning to this mapping. ‘Strict’ removes unknown values, while ‘passthrough’ passes unknown values to the target. Values: strict, passthrough. | +| ↳ `transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms the resource before provisioning it in the application. | +| ↳ `remote_uri` | string | The base URI for the application's SCIM-compatible API. | +| `service_auth_401_redirect` | boolean | Returns a 401 status code when the request is blocked by a Service Auth policy. | +| `session_duration` | string | The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `skip_interstitial` | boolean | Enables automatic authentication through cloudflared. | +| `tags` | array | The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard. | +| `use_clientless_isolation_app_launcher_url` | boolean | Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application. | +| `policies` | array | policies | +| ↳ `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| ↳ `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| ↳ `connection_rules` | json | The rules that define how users may connect to targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| ↳ `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples:`5m` or `24h`. | +| ↳ `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| ↳ `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| ↳ `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| ↳ `created_at` | string | created at | +| ↳ `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| ↳ `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `id` | string | The UUID of the policy | +| ↳ `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `name` | string | The name of the Access policy. | +| ↳ `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| ↳ `updated_at` | string | updated at | +| ↳ `account_id` | string | Identifier. | +| ↳ `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | +| `saas_app` | json | saas app | +| ↳ `auth_type` | string | Identifier of the authentication protocol used for the saas app. Required for OIDC. Values: saml, oidc. | +| ↳ `consumer_service_url` | string | The service provider's endpoint that is responsible for receiving and parsing a SAML assertion. | +| ↳ `created_at` | string | created at | +| ↳ `custom_attributes` | array | custom attributes | +| ↳ `friendly_name` | string | The SAML FriendlyName of the attribute. | +| ↳ `name` | string | The name of the attribute. | +| ↳ `name_format` | string | A globally unique name for an identity or service provider. Values: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified, urn:oasis:names:tc:SAML:2.0:attrname-format:basic, urn:oasis:names:tc:SAML:2.0:attrname-format:uri. | +| ↳ `required` | boolean | If the attribute is required when building a SAML assertion. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP attribute. | +| ↳ `name_by_idp` | array | A mapping from IdP ID to attribute name. | +| ↳ `idp_id` | string | The UID of the IdP. | +| ↳ `source_name` | string | The name of the IdP provided attribute. | +| ↳ `default_relay_state` | string | The URL that the user will be redirected to after a successful login for IDP initiated logins. | +| ↳ `idp_entity_id` | string | The unique identifier for your SaaS application. | +| ↳ `name_id_format` | string | The format of the name identifier sent to the SaaS application. Values: id, email. | +| ↳ `name_id_transform_jsonata` | string | A \[JSONata\]\(https://jsonata.org/) expression that transforms an application's user identities into a NameID value for its SAML assertion. This expression should evaluate to a singular string. The output of this expression can override the `name_id_format` setting. | +| ↳ `public_key` | string | The Access public certificate that will be used to verify your identity. | +| ↳ `saml_attribute_transform_jsonata` | string | A \[JSONata\] \(https://jsonata.org/) expression that transforms an application's user identities into attribute assertions in the SAML response. | +| ↳ `sp_entity_id` | string | A globally unique name for an identity or service provider. | +| ↳ `sso_endpoint` | string | The endpoint where your SaaS application will send login requests. | +| ↳ `updated_at` | string | updated at | +| ↳ `access_token_lifetime` | string | The lifetime of the OIDC Access Token after creation. Valid units are m,h. Must be greater than or equal to 1m and less than or equal to 24h. | +| ↳ `allow_pkce_without_client_secret` | boolean | If client secret should be required on the token endpoint when authorization_code_with_pkce grant is used. | +| ↳ `app_launcher_url` | string | The URL where this applications tile redirects users | +| ↳ `client_id` | string | The application client id | +| ↳ `client_secret` | string | The application client secret, only returned on POST request. | +| ↳ `custom_claims` | array | custom claims | +| ↳ `name` | string | The name of the claim. | +| ↳ `required` | boolean | If the claim is required when building an OIDC token. | +| ↳ `scope` | string | The scope of the claim. Values: groups, profile, email, openid. | +| ↳ `source` | json | source | +| ↳ `name` | string | The name of the IdP claim. | +| ↳ `name_by_idp` | json | A mapping from IdP ID to claim name. | +| ↳ `grant_types` | array | The OIDC flows supported by this application | +| ↳ `group_filter_regex` | string | A regex to filter Cloudflare groups returned in ID token and userinfo endpoint | +| ↳ `hybrid_and_implicit_options` | json | hybrid and implicit options | +| ↳ `return_access_token_from_authorization_endpoint` | boolean | If an Access Token should be returned from the OIDC Authorization endpoint | +| ↳ `return_id_token_from_authorization_endpoint` | boolean | If an ID Token should be returned from the OIDC Authorization endpoint | +| ↳ `redirect_uris` | array | The permitted URL's for Cloudflare to return Authorization codes and Access/ID tokens | +| ↳ `refresh_token_options` | json | refresh token options | +| ↳ `lifetime` | string | How long a refresh token will be valid for after creation. Valid units are m,h,d. Must be longer than 1m. | +| ↳ `scopes` | array | Define the user information shared with access, "offline_access" scope will be automatically enabled if refresh tokens are enabled | +| `app_launcher_logo_url` | string | The image URL of the logo shown in the App Launcher header. | +| `bg_color` | string | The background color of the App Launcher page. | +| `footer_links` | array | The links in the App Launcher footer. | +| ↳ `name` | string | The hypertext in the footer link. | +| ↳ `url` | string | the hyperlink in the footer link. | +| `header_bg_color` | string | The background color of the App Launcher header. | +| `landing_page_design` | json | The design of the App Launcher landing page shown to users when they log in. | +| ↳ `button_color` | string | The background color of the log in button on the landing page. | +| ↳ `button_text_color` | string | The color of the text in the log in button on the landing page. | +| ↳ `image_url` | string | The URL of the image shown on the landing page. | +| ↳ `message` | string | The message shown on the landing page. | +| ↳ `title` | string | The title shown on the landing page. | +| `skip_app_launcher_login_page` | boolean | Determines when to skip the App Launcher landing page. | +| `target_criteria` | array | target criteria | +| ↳ `exclude` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `include` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `port` | number | The port that the targets use for the chosen communication protocol. A port cannot be assigned to multiple protocols. | +| ↳ `require` | json | Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty. | +| ↳ `tags` | json | Map of target tag keys to values. Values within a key are OR'd. | +| ↳ `target_attributes` | json | Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key. | +| ↳ `hostname` | array | hostname | +| ↳ `target_attributes` | json | Contains a map of target attribute keys to target attribute values. | +| ↳ `protocol` | string | The communication protocol your application secures. Values: RDP. | + +### Cloudflare Update Access Group + +Updates a configured Access group. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Identity providers are account-scoped | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `groupId` | string | Yes | Group id | +| `apiKey` | string | Yes | Cloudflare API token | +| `exclude` | json | No | JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | +| `include` | json | Yes | JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | +| `is_default` | boolean | No | Whether this is the default group | +| `name` | string | Yes | The name of the Access group. | +| `require` | json | No | JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `identity_providers` | array | Identity providers configured for Access | -| ↳ `id` | string | Identity provider identifier | -| ↳ `name` | string | Display name shown to users on the login page | -| ↳ `type` | string | Provider type, e.g. azureAD, okta, google, saml, oidc, or onetimepin | -| ↳ `read_only` | boolean | Whether the provider is immutable through the API | -| ↳ `config` | json | Provider-specific configuration parameters | -| ↳ `scim_config` | json | SCIM user and group provisioning configuration | -| `total_count` | number | Total number of identity providers | +| `created_at` | string | created at | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | UUID. | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `is_default` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access group. | +| `require` | array | Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | -### Cloudflare List Access Service Tokens +### Cloudflare Update Access Policy -Lists the Cloudflare Access (Zero Trust) service tokens in an account, which let machines authenticate to Access-protected applications. Client secrets are never returned by this endpoint — only on creation. Requires an API token with Account Access: Service Tokens Read. +Updates a Cloudflare Access (Zero Trust) policy on an application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: resend all settings to retain, including exclude, require, approval_groups, connection_rules, and mfa_config; omitted rules or security settings may be dropped and widen access. The change applies to live traffic immediately. Read the current policy with "List Access Policies" first. Requires an API token with Account Access: Apps and Policies Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | -| `name` | string | No | Filter by service token name | -| `search` | string | No | Free-text search across service tokens | -| `page` | number | No | Page number for pagination | -| `per_page` | number | No | Number of service tokens per page | +| `approval_groups` | json | No | JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid. | +| `connection_rules` | json | No | JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh. | +| `mfa_config` | json | No | JSON object. Configures multi-factor authentication \(MFA\) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration. | +| `accountId` | string | Yes | The Cloudflare account ID. Access applications are account-scoped | +| `appId` | string | Yes | The Access application ID that owns the policy | +| `policyId` | string | Yes | The Access policy ID to update | +| `name` | string | Yes | Name of the policy | +| `decision` | string | Yes | What the policy does when it matches: allow, deny, non_identity, or bypass \(skip Access entirely\) | +| `include` | string | Yes | JSON array of Access rules evaluated with OR logic. Example: \[\{"email_domain":\{"domain":"example.com"\}\}\] | +| `exclude` | string | No | JSON array of Access rules evaluated with NOT logic | +| `require` | string | No | JSON array of Access rules evaluated with AND logic | +| `precedence` | number | No | Evaluation order of the policy within the application | +| `sessionDuration` | string | No | How long a session granted by this policy stays valid, e.g. 24h. Leave it unset on a policy attached to an infrastructure-typed application — Cloudflare rejects those with error 12130 | +| `approvalRequired` | boolean | No | Whether an approver must grant each access request | +| `isolationRequired` | boolean | No | Whether the session must run in a remote isolated browser | +| `purposeJustificationRequired` | boolean | No | Whether users must state a reason for access | +| `purposeJustificationPrompt` | string | No | Prompt shown when a justification is required | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `service_tokens` | array | Access service tokens in the account | -| ↳ `id` | string | Service token identifier | -| ↳ `name` | string | Service token name | -| ↳ `client_id` | string | Client ID sent in the CF-Access-Client-Id header | -| ↳ `duration` | string | How long the token stays valid before it expires | -| ↳ `enabled` | boolean | Whether the token is active | -| ↳ `expires_at` | string | Expiry timestamp | -| ↳ `last_seen_at` | string | When the token was last used | -| ↳ `created_at` | string | Creation timestamp | -| ↳ `updated_at` | string | Last update timestamp | -| `total_count` | number | Total number of service tokens | - -### Cloudflare Create Access Service Token - -Creates a Cloudflare Access (Zero Trust) service token so a machine can authenticate to Access-protected applications. This is the only response that ever contains the client secret — Cloudflare will not return it again, so capture it in the same run. Requires an API token with Account Access: Service Tokens Edit. +| `approval_groups` | array | Administrators who can approve a temporary authentication request. | +| ↳ `approvals_needed` | number | The number of approvals needed to obtain access. | +| ↳ `email_addresses` | array | A list of emails that can approve the access request. | +| ↳ `email_list_uuid` | string | The UUID of an re-usable email list. | +| `approval_required` | boolean | Requires the user to request access from an administrator at the start of each session. | +| `connection_rules` | json | The rules that define how users may connect to the targets secured by your application. | +| ↳ `rdp` | json | The RDP-specific rules that define clipboard behavior for RDP connections. | +| ↳ `allowed_clipboard_local_to_remote_formats` | array | Clipboard formats allowed when copying from local machine to remote RDP session. | +| ↳ `allowed_clipboard_remote_to_local_formats` | array | Clipboard formats allowed when copying from remote RDP session to local machine. | +| ↳ `ssh` | json | The SSH-specific rules that define how users may connect to the targets secured by your application. | +| ↳ `allow_email_alias` | boolean | Enables using Identity Provider email alias as SSH username. | +| ↳ `usernames` | array | Contains the Unix usernames that may be used when connecting over SSH. | +| `isolation_required` | boolean | Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature. | +| `mfa_config` | json | Configures multi-factor authentication \(MFA\) settings for infrastructure applications. | +| ↳ `allowed_authenticators` | array | Lists the MFA methods that users can authenticate with. For infrastructure applications, supported values are `piv_key` and `ssh_fido2_key`. | +| ↳ `mfa_disabled` | boolean | Indicates whether to disable MFA for this resource. This option is available at the application and policy level. | +| ↳ `session_duration` | string | Defines the duration of an MFA session. Must be in minutes \(m\) or hours \(h\). Minimum: 0m. Maximum: 720h \(30 days\). Examples: `5m` or `24h`. | +| `purpose_justification_prompt` | string | A custom message that will appear on the purpose justification screen. | +| `purpose_justification_required` | boolean | Require users to enter a justification when they log in to the application. | +| `session_duration` | string | The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us \(or µs\), ms, s, m, h. | +| `created_at` | string | created at | +| `decision` | string | The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass. | +| `exclude` | array | Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `id` | string | The UUID of the policy | +| `include` | array | Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `name` | string | The name of the Access policy. | +| `require` | array | Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules. | +| ↳ `group` | json | group | +| ↳ `id` | string | The ID of a previously created Access group. | +| ↳ `any_valid_service_token` | json | An empty object which matches on all service tokens. | +| ↳ `auth_context` | json | auth context | +| ↳ `ac_id` | string | The ACID of an Authentication context. | +| ↳ `id` | string | The ID of an Authentication context. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `auth_method` | json | auth method | +| ↳ `auth_method` | string | The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2. | +| ↳ `azureAD` | json | azureAD | +| ↳ `id` | string | The ID of an Azure group. | +| ↳ `identity_provider_id` | string | The ID of your Azure identity provider. | +| ↳ `certificate` | json | certificate | +| ↳ `common_name` | json | common name | +| ↳ `common_name` | string | The common name to match. | +| ↳ `geo` | json | geo | +| ↳ `country_code` | string | The country code that should be matched. | +| ↳ `device_posture` | json | device posture | +| ↳ `account_id` | string | Identifier. | +| ↳ `integration_uid` | string | The ID of a device posture integration. | +| ↳ `email_domain` | json | email domain | +| ↳ `domain` | string | The email domain to match. | +| ↳ `email_list` | json | email list | +| ↳ `id` | string | The ID of a previously created email list. | +| ↳ `email` | json | email | +| ↳ `email` | string | The email of the user. | +| ↳ `everyone` | json | An empty object which matches on all users. | +| ↳ `external_evaluation` | json | external evaluation | +| ↳ `evaluate_url` | string | The API endpoint containing your business logic. | +| ↳ `keys_url` | string | The API endpoint containing the key that Access uses to verify that the response came from your API. | +| ↳ `github-organization` | json | github-organization | +| ↳ `identity_provider_id` | string | The ID of your Github identity provider. | +| ↳ `name` | string | The name of the organization. | +| ↳ `team` | string | The name of the team | +| ↳ `gsuite` | json | gsuite | +| ↳ `email` | string | The email of the Google Workspace group. | +| ↳ `identity_provider_id` | string | The ID of your Google Workspace identity provider. | +| ↳ `login_method` | json | login method | +| ↳ `id` | string | The ID of an identity provider. | +| ↳ `ip_list` | json | ip list | +| ↳ `id` | string | The ID of a previously created IP list. | +| ↳ `ip` | json | ip | +| ↳ `ip` | string | An IPv4 or IPv6 CIDR block. | +| ↳ `okta` | json | okta | +| ↳ `identity_provider_id` | string | The ID of your Okta identity provider. | +| ↳ `name` | string | The name of the Okta group. | +| ↳ `saml` | json | saml | +| ↳ `attribute_name` | string | The name of the SAML attribute. | +| ↳ `attribute_value` | string | The SAML attribute value to look for. | +| ↳ `identity_provider_id` | string | The ID of your SAML identity provider. | +| ↳ `oidc` | json | oidc | +| ↳ `claim_name` | string | The name of the OIDC claim. | +| ↳ `claim_value` | string | The OIDC claim value to look for. | +| ↳ `identity_provider_id` | string | The ID of your OIDC identity provider. | +| ↳ `service_token` | json | service token | +| ↳ `token_id` | string | The ID of a Service Token. | +| ↳ `linked_app_token` | json | linked app token | +| ↳ `app_uid` | string | The ID of an Access OIDC SaaS application | +| ↳ `user_risk_score` | json | user risk score | +| ↳ `user_risk_score` | array | A list of risk score levels to match. Values can be low, medium, high, or unscored. | +| ↳ `cloudflare_account_member` | json | cloudflare account member | +| ↳ `account_id` | string | Identifier. | +| `updated_at` | string | updated at | +| `account_id` | string | Identifier. | +| `precedence` | number | The order of execution for this policy. Must be unique for each policy within an app. | + +### Cloudflare Update Access Service Token + +Updates a configured service token. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | -| `name` | string | Yes | Name of the service token | -| `duration` | string | No | How long the token stays valid before it expires, e.g. 8760h. Defaults to Cloudflare's standard lifetime | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `serviceTokenId` | string | Yes | Service token id | +| `apiKey` | string | Yes | Cloudflare API token | +| `client_secret_version` | number | No | A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately. | +| `duration` | string | No | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | No | Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved and can be re-enabled. A service token reported as leaked is disabled automatically and cannot be re-enabled until its secret is rotated; attempting to do so returns a 409. Defaults to enabled when omitted on create. | +| `name` | string | No | The name of the service token. | +| `previous_client_secret_expires_at` | string | No | The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Created service token identifier | -| `name` | string | Service token name | -| `client_id` | string | Client ID sent in the CF-Access-Client-Id header | -| `client_secret` | string | Client secret sent in the CF-Access-Client-Secret header. Returned only once, at creation | -| `duration` | string | How long the token stays valid before it expires | -| `enabled` | boolean | Whether the token is active | -| `expires_at` | string | Expiry timestamp | -| `last_seen_at` | string | When the token was last used | -| `created_at` | string | Creation timestamp | -| `updated_at` | string | Last update timestamp | +| `client_id` | string | The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header. | +| `created_at` | string | created at | +| `duration` | string | The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us \(or µs\), ms, s, m, h. The default is 1 year in hours \(8760h\). | +| `enabled` | boolean | Whether the service token is enabled. | +| `expires_at` | string | expires at | +| `id` | string | UUID. | +| `last_seen_at` | string | last seen at | +| `leak_report_url` | string | Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked. | +| `leak_reported_at` | string | When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked. | +| `leak_reporter` | string | The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked. | +| `name` | string | The name of the service token. | +| `updated_at` | string | updated at | -### Cloudflare Revoke Access Service Token +### Cloudflare Update DNS Record -Permanently deletes a Cloudflare Access (Zero Trust) service token, revoking it. Every machine or integration still presenting that client ID and secret is locked out of the Access-protected applications immediately, and the secret cannot be recovered. This cannot be undone. Requires an API token with Account Access: Service Tokens Edit. +Updates an existing DNS record for a zone. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Service tokens are account-scoped | -| `serviceTokenId` | string | Yes | The service token ID to revoke permanently | +| `clearComment` | boolean | No | Clear the stored DNS record comment | +| `settings` | json | No | JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname. | +| `private_routing` | boolean | No | Enables private network routing to the origin. | +| `data` | json | No | JSON object. Structured record data. The available fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint. | +| `include_shadow_metadata` | boolean | No | Whether to include shadow metadata in the `meta` field of each record in the response. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `zoneId` | string | Yes | The zone ID containing the DNS record | +| `recordId` | string | Yes | The DNS record ID to update | +| `type` | string | No | DNS record type \(e.g., "A", "AAAA", "CNAME", "MX", "TXT"\) | +| `name` | string | No | DNS record name | +| `content` | string | No | DNS record content \(e.g., IP address\) | +| `ttl` | number | No | Time to live in seconds \(1 = automatic\) | +| `proxied` | boolean | No | Whether to enable Cloudflare proxy | +| `priority` | number | No | Record priority. Cloudflare accepts this top-level field for MX and URI records only; use the data object for structured records such as SRV \(priority, weight, port, target\) | +| `comment` | string | No | Comment for the DNS record | +| `tags` | string | No | Comma-separated tags for the DNS record | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Identifier of the revoked service token | -| `name` | string | Service token name | -| `client_id` | string | Client ID that is no longer accepted | -| `duration` | string | Configured token lifetime | -| `enabled` | boolean | Whether the token was active | -| `expires_at` | string | Expiry timestamp | -| `last_seen_at` | string | When the token was last used | -| `created_at` | string | Creation timestamp | -| `updated_at` | string | Last update timestamp | - -### Cloudflare List R2 Buckets - -Lists the R2 object storage buckets in an account. Requires an API token with Account Workers R2 Storage Read. +| `comment` | string | Comments or notes about the DNS record. This field has no effect on DNS responses. | +| `name` | string | Complete DNS record name, including the zone name, in Punycode. | +| `proxied` | boolean | Whether the record is receiving the performance and security benefits of Cloudflare. | +| `settings` | json | Settings for the DNS record. | +| ↳ `ipv4_only` | boolean | When enabled, only A records will be generated, and AAAA records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `ipv6_only` | boolean | When enabled, only AAAA records will be generated, and A records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6. | +| ↳ `flatten_cname` | boolean | If enabled, causes the CNAME record to be resolved externally and the resulting address records \(e.g., A and AAAA\) to be returned instead of the CNAME record itself. This setting is unavailable for proxied records, since they are always flattened. | +| `tags` | array | Custom tags for the DNS record. This field has no effect on DNS responses. | +| `ttl` | number | Time To Live \(TTL\) of the DNS record in seconds. Setting to 1 means 'automatic'. Value must be between 60 and 86400, with the minimum reduced to 30 for Enterprise zones. Values: 1. | +| `content` | string | Formatted URI content. See 'data' to set URI properties. | +| `private_routing` | boolean | Enables private network routing to the origin. | +| `type` | string | Record type. Values: A, AAAA, CNAME, MX, NS, OPENPGPKEY, PTR, TXT, CAA, CERT, DNSKEY, DS, HTTPS, LOC, NAPTR, SMIMEA, SRV, SSHFP, SVCB, TLSA, URI. | +| `priority` | number | Required for MX and URI records; ignored for other record types \(but may still be returned by the API\). Records with lower priorities are preferred. This field is to be deprecated in favor of the priority field within the data map. | +| `data` | json | Structured record data. The available fields depend on the DNS record type. | +| ↳ `flags` | json | Flags. | +| ↳ `tag` | string | Name of the property controlled by this record \(e.g.: issue, issuewild, iodef\). | +| ↳ `value` | string | Value. | +| ↳ `algorithm` | number | Algorithm. | +| ↳ `certificate` | string | Certificate. | +| ↳ `key_tag` | number | Key Tag. | +| ↳ `type` | number | Type. | +| ↳ `protocol` | number | Protocol. | +| ↳ `public_key` | string | Public Key. | +| ↳ `digest` | string | Digest. | +| ↳ `digest_type` | number | Digest Type. | +| ↳ `priority` | number | Priority. | +| ↳ `target` | string | The record content. | +| ↳ `altitude` | number | Altitude of location in meters. | +| ↳ `lat_degrees` | number | Degrees of latitude. | +| ↳ `lat_direction` | string | Latitude direction. Values: N, S. | +| ↳ `lat_minutes` | number | Minutes of latitude. | +| ↳ `lat_seconds` | number | Seconds of latitude. | +| ↳ `long_degrees` | number | Degrees of longitude. | +| ↳ `long_direction` | string | Longitude direction. Values: E, W. | +| ↳ `long_minutes` | number | Minutes of longitude. | +| ↳ `long_seconds` | number | Seconds of longitude. | +| ↳ `precision_horz` | number | Horizontal precision of location. | +| ↳ `precision_vert` | number | Vertical precision of location. | +| ↳ `size` | number | Size of location in meters. | +| ↳ `order` | number | Order. | +| ↳ `preference` | number | Preference. | +| ↳ `regex` | string | Regex. | +| ↳ `replacement` | string | Replacement. | +| ↳ `service` | string | Service. | +| ↳ `matching_type` | number | Matching Type. | +| ↳ `selector` | number | Selector. | +| ↳ `usage` | number | Usage. | +| ↳ `port` | number | The port of the service. | +| ↳ `weight` | number | The record weight. | +| ↳ `fingerprint` | string | Fingerprint. | +| `comment_modified_on` | string | When the record comment was last modified. Omitted if there is no comment. | +| `created_on` | string | When the record was created. | +| `id` | string | Identifier. | +| `meta` | json | Extra Cloudflare-specific metadata about the record. | +| ↳ `dead_glue` | boolean | Whether this glue record is not served because a shallower NS delegation takes precedence over the deeper delegation that needs it. | +| ↳ `is_glue` | boolean | Whether this A or AAAA record is glue for a subdomain NS delegation. See \[Glue records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records#glue-records). | +| ↳ `shadowed_by` | array | IDs of the NS records that shadow this record. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| ↳ `shadowed_records_count` | number | Number of records shadowed by this NS delegation. See \[Shadowed records\]\(https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). | +| `modified_on` | string | When the record was last modified. | +| `proxiable` | boolean | Whether the record can be proxied by Cloudflare or not. | +| `tags_modified_on` | string | When the record tags were last modified. Omitted if there are no tags. | +| `zone_id` | string | Legacy DNS response zone ID when returned by Cloudflare | +| `zone_name` | string | Legacy DNS response zone name when returned by Cloudflare | +| `locked` | boolean | Legacy DNS response lock flag when returned by Cloudflare | + +### Cloudflare Update R2 Bucket Cors + +Replaces the Cross-Origin Resource Sharing (CORS) rules for an R2 bucket. Rules specify which origins, methods, and headers are allowed for browser requests to objects in the bucket. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | -| `name_contains` | string | No | Only return buckets whose name contains this substring | -| `start_after` | string | No | Bucket name to start listing after | -| `cursor` | string | No | Pagination cursor returned by a previous call | -| `direction` | string | No | Sort direction by bucket name: asc or desc | -| `per_page` | number | No | Number of buckets per page | -| `jurisdiction` | string | No | Data-residency jurisdiction to list within: default, eu, or fedramp | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `bucketName` | string | Yes | Bucket name | +| `apiKey` | string | Yes | Cloudflare API token | +| `rules` | json | No | JSON array. rules Fields: allowed, exposeHeaders, id, maxAgeSeconds. | +| `jurisdiction` | string | No | Jurisdiction where objects in this bucket are guaranteed to be stored. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `buckets` | array | R2 buckets in the account | -| ↳ `name` | string | Bucket name | -| ↳ `creation_date` | string | Creation timestamp | -| ↳ `location` | string | Location hint the bucket was created with \(apac, eeur, enam, weur, wnam, or oc\) | -| ↳ `storage_class` | string | Default storage class \(Standard or InfrequentAccess\) | -| ↳ `jurisdiction` | string | Data-residency jurisdiction \(default, eu, or fedramp\) | -| `cursor` | string | Pagination cursor to pass to the next call | +| `success` | boolean | Whether Cloudflare accepted the operation | -### Cloudflare Get R2 Bucket +### Cloudflare Update R2 Bucket Lifecycle -Reads the metadata of a single R2 object storage bucket. Requires an API token with Account Workers R2 Storage Read. +Replaces the object lifecycle rules for an R2 bucket. Rules match object-key prefixes and can expire objects, abort incomplete multipart uploads, or transition objects to Infrequent Access storage. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | -| `bucketName` | string | Yes | The name of the bucket to read | -| `jurisdiction` | string | No | Data-residency jurisdiction the bucket lives in: default, eu, or fedramp | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `bucketName` | string | Yes | Bucket name | +| `apiKey` | string | Yes | Cloudflare API token | +| `rules` | json | No | JSON array. rules Fields: abortMultipartUploadsTransition, conditions, deleteObjectsTransition, enabled, id, storageClassTransitions. | +| `jurisdiction` | string | No | Jurisdiction where objects in this bucket are guaranteed to be stored. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `name` | string | Bucket name | -| `creation_date` | string | Creation timestamp | -| `location` | string | Location hint the bucket was created with \(apac, eeur, enam, weur, wnam, or oc\) | -| `storage_class` | string | Default storage class \(Standard or InfrequentAccess\) | -| `jurisdiction` | string | Data-residency jurisdiction \(default, eu, or fedramp\) | +| `success` | boolean | Whether Cloudflare accepted the operation | -### Cloudflare Create R2 Bucket +### Cloudflare Update Rate Limiting Rule -Creates an R2 object storage bucket in an account. The location hint and jurisdiction are fixed at creation and cannot be changed later. Requires an API token with Account Workers R2 Storage Edit. +Updates a rate limiting rule in the http_ratelimit phase entry point ruleset of a zone, using the current Rulesets-based rate limiting API. Cloudflare replaces the rule definition rather than merging it, so send the complete rule — every field you omit is reset. Run "List Rate Limiting Rules" first to read the current definition and get the ruleset ID. Requires an API token with Zone WAF Edit. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | -| `bucketName` | string | Yes | Name for the new bucket | -| `locationHint` | string | No | Region hint for where the bucket should live: apac, eeur, enam, weur, wnam, or oc. Cannot be changed after creation | -| `storageClass` | string | No | Default storage class for objects: Standard or InfrequentAccess | -| `jurisdiction` | string | No | Data-residency jurisdiction to create the bucket in: default, eu, or fedramp. Cannot be changed after creation | +| `exposed_credential_check` | json | No | JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. | +| `position` | json | No | JSON object. An object configuring where the rule will be placed. Fields: before, after, index. | +| `score_per_period` | number | No | The score threshold per period for which the action will be executed the first time. | +| `score_response_header_name` | string | No | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID that owns the rule | +| `rulesetId` | string | Yes | The http_ratelimit entry point ruleset ID, as returned by "List Rate Limiting Rules" | +| `ruleId` | string | Yes | The rate limiting rule ID to update | +| `expression` | string | Yes | Cloudflare filter expression selecting the requests the rule applies to | +| `characteristics` | string | Yes | Comma-separated counting characteristics. cf.colo.id is mandatory. ip.src and cf.unique_visitor_id are mutually exclusive — include at most one. | +| `period` | number | Yes | Counting window in seconds. Cloudflare accepts only 10, 60, 120, 300, 600, or 3600 | +| `requestsPerPeriod` | number | Yes | Number of requests allowed within the counting period before the action fires | +| `action` | string | Yes | Action applied once the limit is exceeded: block, managed_challenge, js_challenge, challenge, or log. Required because this endpoint replaces the rule rather than merging into it — a defaulted action would silently convert an existing log or challenge rule into a hard block | +| `mitigationTimeout` | number | No | Seconds the action stays applied. Cloudflare accepts only 0, 10, 60, 120, 300, 600, 3600, or 86400 | +| `counting_expression` | string | No | Optional expression defining which requests are counted | +| `requestsToOrigin` | boolean | No | When true, only requests that reach the origin are counted | +| `description` | string | No | Human-readable description of the rule | +| `enabled` | boolean | No | Whether the rule is enabled | +| `ref` | string | No | Reference tag that stays stable across rule updates. Because the update replaces the rule, omitting it resets the tag to the rule ID and breaks anything matching on the old value | +| `actionParameters` | string | No | JSON object of action-specific parameters for the mitigation action, e.g. \{"response":\{"status_code":429,"content":"\{\"error\":\"rate limited\"\}","content_type":"application/json"\}\} for a custom block response. Because the update replaces the rule, omitting it resets action_parameters to \{\} and the rule falls back to Cloudflare's default block page | +| `logging` | string | No | JSON logging configuration to preserve, e.g. \{"enabled":true\}. Omitting it on a rule that had logging configured resets it to the default | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `name` | string | Created bucket name | -| `creation_date` | string | Creation timestamp | -| `location` | string | Location the bucket was created in | -| `storage_class` | string | Default storage class \(Standard or InfrequentAccess\) | -| `jurisdiction` | string | Data-residency jurisdiction \(default, eu, or fedramp\) | - -### Cloudflare Delete R2 Bucket - -Permanently deletes an R2 object storage bucket. Cloudflare only deletes an empty bucket, and the deletion cannot be undone. Requires an API token with Account Workers R2 Storage Edit. +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Update Ruleset + +Updates the description and rules of a zone ruleset, creating a new version. Read the current rules with "Get Ruleset" before replacing the list. The rules array replaces the complete list: include every existing rule you want to keep; omitted rules are removed. Use "Create Ruleset Rule" to add a single rule without replacing the list. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. R2 buckets are account-scoped | -| `bucketName` | string | Yes | The name of the bucket to delete permanently | -| `jurisdiction` | string | No | Data-residency jurisdiction the bucket lives in: default, eu, or fedramp | -| `apiKey` | string | Yes | Cloudflare API Token | +| `zoneId` | string | Yes | Zone id | +| `rulesetId` | string | Yes | Ruleset id | +| `apiKey` | string | Yes | Cloudflare API token | +| `description` | string | No | An informative description of the ruleset. | +| `rules` | json | No | JSON array replacing the complete rule list. Read "Get Ruleset" first and include every rule to retain; omitted rules are removed, and \[\] removes all rules. Fields: action, action_parameters, categories, description, enabled, exposed_credential_check, expression, id, last_updated, logging, ratelimit, ref, version. | +| `dry_run` | boolean | No | Validates the request without persisting changes when set to `true`. Responses that normally return 200 return `result: null`; endpoints that normally return 204 continue to return 204. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `name` | string | Name of the deleted bucket. Cloudflare returns an empty result body for this endpoint, so the name is echoed from the request | +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | -### Cloudflare List Worker Scripts +### Cloudflare Update Ruleset Rule -Lists the Workers scripts deployed in an account. Requires an API token with Account Workers Scripts Read. +Updates a rule in a zone ruleset. Cloudflare replaces the rule definition rather than merging it, so you must send every field you want the rule to keep — any field you omit is reset to its default. Read the current rule with "Get Ruleset" first. Requires an API token with Zone WAF Edit (or another matching ruleset Write permission). #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Workers scripts are account-scoped | -| `tags` | string | No | Filter scripts by tag. Cloudflare expects a comma-separated list of tag:allowed pairs where allowed is yes or no, e.g. team:core:yes,deprecated:no | +| `exposed_credential_check` | json | No | JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. | +| `position` | json | No | JSON object. An object configuring where the rule will be placed. Fields: before, after, index. | +| `dry_run` | boolean | No | dry run | +| `zoneId` | string | Yes | The zone ID that owns the ruleset | +| `rulesetId` | string | Yes | The ruleset ID containing the rule | +| `ruleId` | string | Yes | The rule ID to update | +| `action` | string | Yes | The action the rule performs, e.g. block, challenge, js_challenge, managed_challenge, log, skip, or execute. Required because this endpoint replaces the rule definition — omitting it resets the stored action | +| `expression` | string | Yes | Cloudflare filter expression selecting matching requests. Required because this endpoint replaces the rule definition — omitting it resets the stored expression | +| `description` | string | No | Human-readable description of the rule | +| `enabled` | boolean | No | Whether the rule is enabled | +| `ref` | string | No | Reference tag that stays stable across rule updates. Because the update replaces the rule, omitting it resets the tag to the rule ID and breaks anything matching on the old value | +| `actionParameters` | string | No | JSON object of action-specific parameters, e.g. \{"id":"<MANAGED_RULESET_ID>","overrides":\{"rules":\[\{"id":"<RULE_ID>","action":"log","enabled":true,"score_threshold":40\}\]\}\}. Required on an execute rule and must be sent on every update: the endpoint replaces the rule, so omitting it resets action_parameters to \{\} — which unbinds the managed ruleset the rule deploys and every override under it | +| `ratelimit` | string | No | JSON rate limiting configuration to preserve on a rule in the http_ratelimit phase, e.g. \{"characteristics":\["cf.colo.id","ip.src"\],"period":60,"requests_per_period":100\}. Because the update replaces the rule, omitting this on a rate limiting rule stops it rate limiting | +| `logging` | string | No | JSON logging configuration to preserve, e.g. \{"enabled":true\}. Omitting it on a rule that had logging configured resets it to the default | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `scripts` | array | Workers scripts in the account | -| ↳ `id` | string | Script name | -| ↳ `tag` | string | Immutable script identifier, distinct from the script name | -| ↳ `etag` | string | Hash of the script content | -| ↳ `created_on` | string | Creation timestamp | -| ↳ `modified_on` | string | Last deployment timestamp | -| ↳ `usage_model` | string | Billing usage model \(standard, bundled, or unbound\) | -| ↳ `placement_mode` | string | Smart placement mode \(smart or targeted\) | -| ↳ `logpush` | boolean | Whether Workers Logpush is enabled | -| ↳ `has_assets` | boolean | Whether the script ships static assets | -| ↳ `has_modules` | boolean | Whether the script uses ES modules | -| ↳ `compatibility_date` | string | Workers runtime compatibility date | -| ↳ `compatibility_flags` | array | Workers runtime compatibility flags | -| ↳ `routes` | json | Routes the script is bound to | -| ↳ `tail_consumers` | json | Workers that consume this script's tail events | -| `total_count` | number | Number of scripts returned | - -### Cloudflare Get Worker Script Settings - -Reads the deployment settings of a single Workers script — bindings, compatibility date and flags, limits, observability, placement, and tail consumers. The plain "get script" endpoint in the Cloudflare API returns raw JavaScript source rather than JSON, so this settings endpoint is the structured way to inspect one script. Requires an API token with Account Workers Scripts Read. +| `description` | string | An informative description of the ruleset. | +| `id` | string | The unique ID of the ruleset. | +| `last_updated` | string | The timestamp of when the ruleset was last modified. | +| `name` | string | The human-readable name of the ruleset. | +| `version` | string | The version of the ruleset. | +| `kind` | string | The kind of the ruleset. Values: managed, custom, root, zone. | +| `phase` | string | The phase of the ruleset. | +| `rules` | array | The list of rules in the ruleset. | +| ↳ `action` | string | The action to perform when the rule matches. | +| ↳ `action_parameters` | json | The parameters configuring the rule's action. | +| ↳ `response` | json | The response to show when the block is applied. | +| ↳ `content` | string | The content to return. | +| ↳ `content_type` | string | The type of the content to return. | +| ↳ `status_code` | number | The status code to return. | +| ↳ `algorithms` | array | Custom order for compression algorithms. | +| ↳ `name` | string | Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd. | +| ↳ `id` | string | The ID of the ruleset to execute. | +| ↳ `matched_data` | json | The configuration to use for matched data logging. | +| ↳ `public_key` | string | The public key to encrypt matched data logs with. | +| ↳ `overrides` | json | A set of overrides to apply to the target ruleset. | +| ↳ `action` | string | An action to override all rules with. This option has lower precedence than rule and category overrides. | +| ↳ `categories` | array | A list of category-level overrides. This option has the second-highest precedence after rule-level overrides. | +| ↳ `action` | string | The action to override rules in the category with. | +| ↳ `category` | string | The name of the category to override. | +| ↳ `enabled` | boolean | Whether to enable execution of rules in the category. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `enabled` | boolean | Whether to enable execution of all rules. This option has lower precedence than rule and category overrides. | +| ↳ `rules` | array | A list of rule-level overrides. This option has the highest precedence. | +| ↳ `action` | string | The action to override the rule with. | +| ↳ `enabled` | boolean | Whether to enable execution of the rule. | +| ↳ `id` | string | The ID of the rule to override. | +| ↳ `score_threshold` | number | The score threshold to use for the rule. | +| ↳ `sensitivity_level` | string | The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `sensitivity_level` | string | A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff. | +| ↳ `cookie_fields` | array | The cookie fields to log. | +| ↳ `name` | string | The name of the cookie. | +| ↳ `raw_response_fields` | array | The raw response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `request_fields` | array | The raw request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `response_fields` | array | The transformed response fields to log. | +| ↳ `name` | string | The name of the response header. | +| ↳ `preserve_duplicates` | boolean | Whether to log duplicate values of the same header. | +| ↳ `transformed_request_fields` | array | The transformed request fields to log. | +| ↳ `name` | string | The name of the header. | +| ↳ `from_list` | json | A redirect based on a bulk list lookup. | +| ↳ `key` | string | An expression that evaluates to the list lookup key. | +| ↳ `name` | string | The name of the list to match against. | +| ↳ `from_value` | json | A redirect based on the request properties. | +| ↳ `preserve_query_string` | boolean | Whether to keep the query string of the original request. | +| ↳ `status_code` | number | The status code to use for the redirect. Values: 301, 302, 303, 307, 308. | +| ↳ `target_url` | json | A URL to redirect the request to. | +| ↳ `expression` | string | An expression that evaluates to a URL to redirect the request to. | +| ↳ `value` | string | A URL to redirect the request to. | +| ↳ `headers` | json | A map of headers to rewrite. | +| ↳ `uri` | json | A URI query rewrite. | +| ↳ `path` | json | A URI path rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI path to. | +| ↳ `value` | string | A value to rewrite the URI path to. | +| ↳ `query` | json | A URI query rewrite. | +| ↳ `expression` | string | An expression that evaluates to a value to rewrite the URI query to. | +| ↳ `value` | string | A value to rewrite the URI query to. | +| ↳ `origin` | boolean | Whether to propagate the rewritten URI to origin. | +| ↳ `host_header` | string | A value to rewrite the HTTP host header to. | +| ↳ `origin` | json | An origin to route to. | +| ↳ `host` | string | A resolved host to route to. | +| ↳ `port` | number | A destination port to route to. | +| ↳ `sni` | json | A Server Name Indication \(SNI\) override. | +| ↳ `value` | string | A value to override the SNI to. | +| ↳ `increment` | number | A delta to change the score by, which can be either positive or negative. | +| ↳ `content_type` | string | The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml. | +| ↳ `status_code` | number | The status code to use for the error. | +| ↳ `content` | string | The response content. | +| ↳ `asset_name` | string | The name of a custom asset to serve as the error response. | +| ↳ `immutable` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `max-age` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `must-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `must-understand` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-cache` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `no-store` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `no-transform` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `private` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `qualifiers` | array | Optional list of header names to qualify the directive \(e.g., for "private" or "no-cache" directives\). | +| ↳ `proxy-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `public` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `s-maxage` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-if-error` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `stale-while-revalidate` | json | Remove the directive. | +| ↳ `cloudflare_only` | boolean | Whether the directive should only be applied to the Cloudflare CDN cache. | +| ↳ `operation` | string | The operation to perform on the cache-control directive. Values: set, remove. | +| ↳ `value` | number | The duration value in seconds for the directive. | +| ↳ `additional_cacheable_ports` | array | A list of additional ports that caching should be enabled on. | +| ↳ `browser_ttl` | json | How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content. | +| ↳ `default` | number | The browser TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass. | +| ↳ `cache` | boolean | Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations. | +| ↳ `cache_key` | json | Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache. | +| ↳ `cache_by_device_type` | boolean | Whether to separate cached content based on the visitor's device type. | +| ↳ `cache_deception_armor` | boolean | Whether to protect from web cache deception attacks, while allowing static assets to be cached. | +| ↳ `custom_key` | json | Which components of the request are included or excluded from the cache key. | +| ↳ `cookie` | json | Which cookies to include in the cache key. | +| ↳ `check_presence` | array | A list of cookies to check for the presence of. The presence of these cookies is included in the cache key. | +| ↳ `include` | array | A list of cookies to include in the cache key. | +| ↳ `header` | json | Which headers to include in the cache key. | +| ↳ `check_presence` | array | A list of headers to check for the presence of. The presence of these headers is included in the cache key. | +| ↳ `contains` | json | A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key. | +| ↳ `exclude_origin` | boolean | Whether to exclude the origin header in the cache key. | +| ↳ `include` | array | A list of headers to include in the cache key. | +| ↳ `host` | json | How to use the host in the cache key. | +| ↳ `resolved` | boolean | Whether to use the resolved host in the cache key. | +| ↳ `query_string` | json | Which query string parameters to include in or exclude from the cache key. | +| ↳ `exclude` | json | Which query string parameters to exclude from the cache key. | +| ↳ `all` | boolean | Whether to exclude all query string parameters from the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to exclude from the cache key. | +| ↳ `include` | json | Which query string parameters to include in the cache key. | +| ↳ `all` | boolean | Whether to include all query string parameters in the cache key. Values: True. | +| ↳ `list` | array | A list of query string parameters to include in the cache key. | +| ↳ `user` | json | How to use characteristics of the request user agent in the cache key. | +| ↳ `device_type` | boolean | Whether to use the user agent's device type in the cache key. | +| ↳ `geo` | boolean | Whether to use the user agents's country in the cache key. | +| ↳ `lang` | boolean | Whether to use the user agent's language in the cache key. | +| ↳ `ignore_query_strings_order` | boolean | Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in. | +| ↳ `cache_reserve` | json | Settings to determine whether the request's response from origin is eligible for Cache Reserve \(requires a Cache Reserve add-on plan\). | +| ↳ `eligible` | boolean | Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve. | +| ↳ `minimum_file_size` | number | The minimum file size eligible for storage in Cache Reserve. | +| ↳ `edge_ttl` | json | How long the Cloudflare edge network should cache the response. | +| ↳ `default` | number | The edge TTL \(in seconds\) if you choose the "override_origin" mode. | +| ↳ `mode` | string | The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin. | +| ↳ `status_code_ttl` | array | A list of TTLs to apply to specific status codes or status code ranges. | +| ↳ `status_code` | number | A single status code to apply the TTL to. | +| ↳ `status_code_range` | json | A range of status codes to apply the TTL to. | +| ↳ `from` | number | The lower bound of the range. | +| ↳ `to` | number | The upper bound of the range. | +| ↳ `value` | number | The time to cache the response for \(in seconds\). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store". | +| ↳ `origin_cache_control` | boolean | Whether Cloudflare will aim to strictly adhere to RFC 7234. | +| ↳ `origin_error_page_passthru` | boolean | Whether to generate Cloudflare error pages for issues from the origin server. | +| ↳ `origin_range_requests` | json | Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request. | +| ↳ `mode` | string | Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default. | +| ↳ `read_timeout` | number | A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value. | +| ↳ `respect_strong_etags` | boolean | Whether Cloudflare should respect strong ETag \(entity tag\) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers. | +| ↳ `serve_stale` | json | When to serve stale content from cache. | +| ↳ `disable_stale_while_updating` | boolean | Whether Cloudflare should disable serving stale content while getting the latest content from the origin. | +| ↳ `shared_dictionary` | json | Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses. | +| ↳ `match_pattern` | string | URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary. | +| ↳ `strip_etags` | boolean | Whether to strip ETag headers from the origin response before caching. | +| ↳ `strip_last_modified` | boolean | Whether to strip Last-Modified headers from the origin response before caching. | +| ↳ `strip_set_cookie` | boolean | Whether to strip Set-Cookie headers from the origin response before caching. | +| ↳ `vary` | json | Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override. | +| ↳ `default` | json | Controls how response Vary headers without a per-header override contribute to the cache key. | +| ↳ `action` | string | How the header value is treated when building the cache key. Values: bypass, passthrough, normalize. | +| ↳ `headers` | json | A mapping of lowercase request header names to their vary configuration. | +| ↳ `operation` | string | The operation to perform on the cache tags. Values: add, remove, set. | +| ↳ `values` | array | A list of cache tag values. | +| ↳ `expression` | string | An expression that evaluates to an array of cache tag values. | +| ↳ `automatic_https_rewrites` | boolean | Whether to enable Automatic HTTPS Rewrites. | +| ↳ `autominify` | json | Which file extensions to minify automatically. | +| ↳ `css` | boolean | Whether to minify CSS files. | +| ↳ `html` | boolean | Whether to minify HTML files. | +| ↳ `js` | boolean | Whether to minify JavaScript files. | +| ↳ `bic` | boolean | Whether to enable Browser Integrity Check \(BIC\). | +| ↳ `content_converter` | boolean | Whether to enable content conversion \(e.g., HTML to Markdown\). | +| ↳ `disable_apps` | boolean | Whether to disable Cloudflare Apps. Values: True. | +| ↳ `disable_pay_per_crawl` | boolean | Whether to disable Pay Per Crawl. Values: True. | +| ↳ `disable_rum` | boolean | Whether to disable Real User Monitoring \(RUM\). Values: True. | +| ↳ `disable_zaraz` | boolean | Whether to disable Zaraz. Values: True. | +| ↳ `email_obfuscation` | boolean | Whether to enable Email Obfuscation. | +| ↳ `fonts` | boolean | Whether to enable Cloudflare Fonts. | +| ↳ `hotlink_protection` | boolean | Whether to enable Hotlink Protection. | +| ↳ `mirage` | boolean | Whether to enable Mirage. | +| ↳ `opportunistic_encryption` | boolean | Whether to enable Opportunistic Encryption. | +| ↳ `polish` | string | The Polish level to configure. Values: off, lossless, lossy, webp. | +| ↳ `redirects_for_ai_training` | boolean | Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response. | +| ↳ `request_body_buffering` | string | The request body buffering mode. Values: none, standard, full. | +| ↳ `response_body_buffering` | string | The response body buffering mode. Values: none, standard. | +| ↳ `rocket_loader` | boolean | Whether to enable Rocket Loader. | +| ↳ `security_level` | string | The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack. | +| ↳ `server_side_excludes` | boolean | Whether to enable Server-Side Excludes. | +| ↳ `ssl` | string | The SSL level to configure. Values: off, flexible, full, strict, origin_pull. | +| ↳ `sxg` | boolean | Whether to enable Signed Exchanges \(SXG\). | +| ↳ `webmcp_enabled` | boolean | Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents. | +| ↳ `webmcp_packs` | array | Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself. | +| ↳ `phase` | string | A phase to skip the execution of. This option is only compatible with the products option. Values: current. | +| ↳ `phases` | array | A list of phases to skip the execution of. This option is incompatible with the rulesets option. | +| ↳ `products` | array | A list of legacy security products to skip the execution of. | +| ↳ `rules` | json | A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option. | +| ↳ `ruleset` | string | A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current. | +| ↳ `rulesets` | array | A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options. | +| ↳ `link_maze` | json | Enables the link maze transformation on the response. | +| ↳ `categories` | array | The categories of the rule. | +| ↳ `description` | string | An informative description of the rule. | +| ↳ `enabled` | boolean | Whether the rule should be executed. | +| ↳ `exposed_credential_check` | json | Configuration for exposed credential checking. | +| ↳ `password_expression` | string | An expression that selects the password used in the credentials check. | +| ↳ `username_expression` | string | An expression that selects the user ID used in the credentials check. | +| ↳ `expression` | string | The expression defining which traffic will match the rule. | +| ↳ `id` | string | The unique ID of the rule. | +| ↳ `last_updated` | string | The timestamp of when the rule was last modified. | +| ↳ `logging` | json | An object configuring the rule's logging behavior. | +| ↳ `enabled` | boolean | Whether to generate a log when the rule matches. | +| ↳ `ratelimit` | json | An object configuring the rule's rate limit behavior. | +| ↳ `characteristics` | array | Characteristics of the request on which the rate limit counter will be incremented. | +| ↳ `counting_expression` | string | An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression. | +| ↳ `mitigation_timeout` | number | Period of time in seconds after which the action will be disabled following its first execution. | +| ↳ `period` | number | Period in seconds over which the counter is being incremented. | +| ↳ `requests_per_period` | number | The threshold of requests per period after which the action will be executed for the first time. | +| ↳ `requests_to_origin` | boolean | Whether counting is only performed when an origin is reached. | +| ↳ `score_per_period` | number | The score threshold per period for which the action will be executed the first time. | +| ↳ `score_response_header_name` | string | A response header name provided by the origin, which contains the score to increment rate limit counter with. | +| ↳ `ref` | string | The reference of the rule \(the rule's ID by default\). | +| ↳ `version` | string | The version of the rule. | + +### Cloudflare Update Tunnel + +Updates the name or secret of an existing Cloudflare Tunnel. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Workers scripts are account-scoped | -| `scriptName` | string | Yes | The name of the Workers script to read settings for | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `tunnelId` | string | Yes | Tunnel id | +| `apiKey` | string | Yes | Cloudflare API token | +| `name` | string | No | A user-friendly name for a tunnel. | +| `tunnel_secret` | string | No | Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `bindings` | json | Resource bindings available to the script \(KV, R2, D1, secrets, and more\) | -| `compatibility_date` | string | Workers runtime compatibility date | -| `compatibility_flags` | array | Workers runtime compatibility flags | -| `limits` | json | CPU and other execution limits | -| `logpush` | boolean | Whether Workers Logpush is enabled | -| `migrations` | json | Durable Object migrations | -| `observability` | json | Observability and log-sampling configuration | -| `placement` | json | Smart placement configuration | -| `tags` | array | Tags attached to the script | -| `tail_consumers` | json | Workers that consume this script's tail events | -| `usage_model` | string | Billing usage model | - -### Cloudflare List Worker Routes - -Lists the Workers routes on a zone, showing which URL patterns are handled by which Worker script. Unlike the Workers script endpoints, routes are zone-scoped. Requires an API token with Zone Workers Routes Read. +| `account_tag` | string | Cloudflare account ID | +| `config_src` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare. | +| `connections` | array | The Cloudflare Tunnel connections between your origin and Cloudflare's edge. | +| ↳ `client_id` | string | UUID of the Cloudflare Tunnel connector. | +| ↳ `client_version` | string | The cloudflared version used to establish this connection. | +| ↳ `colo_name` | string | The Cloudflare data center used for this connection. | +| ↳ `id` | string | UUID of the Cloudflare Tunnel connection. | +| ↳ `is_pending_reconnect` | boolean | Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic. | +| ↳ `opened_at` | string | Timestamp of when the connection was established. | +| ↳ `origin_ip` | string | The public IP address of the host running cloudflared. | +| ↳ `uuid` | string | UUID of the Cloudflare Tunnel connection. | +| `conns_active_at` | string | Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive. | +| `conns_inactive_at` | string | Timestamp of when the tunnel became inactive \(no connections to Cloudflare's edge\). If `null`, the tunnel is active. | +| `created_at` | string | Timestamp of when the resource was created. | +| `deleted_at` | string | Timestamp of when the resource was deleted. If `null`, the resource has not been deleted. | +| `id` | string | UUID of the tunnel. | +| `metadata` | json | Metadata associated with the tunnel. | +| `name` | string | A user-friendly name for a tunnel. | +| `remote_config` | boolean | If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine. | +| `status` | string | The status of the tunnel. | +| `tun_type` | string | The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni. | + +### Cloudflare Update Tunnel Configuration + +Replaces the configuration for a remotely managed Cloudflare Tunnel, including its ingress rules and origin request settings. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `zoneId` | string | Yes | The zone ID to list Workers routes for. Routes are zone-scoped, not account-scoped | -| `apiKey` | string | Yes | Cloudflare API Token | +| `accountId` | string | Yes | Account id | +| `tunnelId` | string | Yes | Tunnel id | +| `apiKey` | string | Yes | Cloudflare API token | +| `config` | json | No | JSON object. The tunnel configuration and ingress rules. Fields: ingress, originRequest, warp-routing. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `routes` | array | Workers routes on the zone | -| ↳ `id` | string | Route identifier | -| ↳ `pattern` | string | URL pattern the route matches, e.g. example.com/* | -| ↳ `script` | string | Name of the Workers script handling the route | -| `total_count` | number | Number of routes returned | - -### Cloudflare List Tunnels - -Lists the Cloudflare Tunnels (cloudflared) in an account, with their health status and active connections. Requires an API token with Account Cloudflare Tunnel Read. +| `account_id` | string | Identifier. | +| `config` | json | The tunnel configuration and ingress rules. | +| ↳ `ingress` | array | List of public hostname definitions. At least one ingress rule needs to be defined for the tunnel. | +| ↳ `hostname` | string | Public hostname for this service. | +| ↳ `originRequest` | json | Configuration parameters for the public hostname specific connection settings between cloudflared and origin server. | +| ↳ `access` | json | For all L7 requests to this hostname, cloudflared will validate each request's Cf-Access-Jwt-Assertion request header. | +| ↳ `audTag` | array | Access applications that are allowed to reach this hostname for this Tunnel. Audience tags can be identified in the dashboard or via the List Access policies API. | +| ↳ `required` | boolean | Deny traffic that has not fulfilled Access authorization. | +| ↳ `teamName` | string | teamName | +| ↳ `caPool` | string | Path to the certificate authority \(CA\) for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare. | +| ↳ `connectTimeout` | number | Timeout for establishing a new TCP connection to your origin server. This excludes the time taken to establish TLS, which is controlled by tlsTimeout. | +| ↳ `disableChunkedEncoding` | boolean | Disables chunked transfer encoding. Useful if you are running a WSGI server. | +| ↳ `http2Origin` | boolean | Attempt to connect to origin using HTTP2. Origin must be configured as https. | +| ↳ `httpHostHeader` | string | Sets the HTTP Host header on requests sent to the local service. | +| ↳ `keepAliveConnections` | number | Maximum number of idle keepalive connections between Tunnel and your origin. This does not restrict the total number of concurrent connections. | +| ↳ `keepAliveTimeout` | number | Timeout after which an idle keepalive connection can be discarded. | +| ↳ `matchSNItoHost` | boolean | Auto configure the Hostname on the origin server certificate. | +| ↳ `noHappyEyeballs` | boolean | Disable the “happy eyeballs” algorithm for IPv4/IPv6 fallback if your local network has misconfigured one of the protocols. | +| ↳ `noTLSVerify` | boolean | Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. | +| ↳ `originServerName` | string | Hostname that cloudflared should expect from your origin server certificate. | +| ↳ `proxyType` | string | cloudflared starts a proxy server to translate HTTP traffic into TCP when proxying, for example, SSH or RDP. This configures what type of proxy will be started. Valid options are: "" for the regular proxy and "socks" for a SOCKS5 proxy. | +| ↳ `tcpKeepAlive` | number | The timeout after which a TCP keepalive packet is sent on a connection between Tunnel and the origin server. | +| ↳ `tlsTimeout` | number | Timeout for completing a TLS handshake to your origin server, if you have chosen to connect Tunnel to an HTTPS server. | +| ↳ `path` | string | Requests with this path route to this public hostname. | +| ↳ `service` | string | Protocol and address of destination server. Supported protocols: http://, https://, unix://, tcp://, ssh://, rdp://, unix+tls://, smb://. Alternatively can return a HTTP status code http_status:\[code\] e.g. 'http_status:404'. | +| ↳ `originRequest` | json | Configuration parameters for the public hostname specific connection settings between cloudflared and origin server. | +| ↳ `access` | json | For all L7 requests to this hostname, cloudflared will validate each request's Cf-Access-Jwt-Assertion request header. | +| ↳ `audTag` | array | Access applications that are allowed to reach this hostname for this Tunnel. Audience tags can be identified in the dashboard or via the List Access policies API. | +| ↳ `required` | boolean | Deny traffic that has not fulfilled Access authorization. | +| ↳ `teamName` | string | teamName | +| ↳ `caPool` | string | Path to the certificate authority \(CA\) for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare. | +| ↳ `connectTimeout` | number | Timeout for establishing a new TCP connection to your origin server. This excludes the time taken to establish TLS, which is controlled by tlsTimeout. | +| ↳ `disableChunkedEncoding` | boolean | Disables chunked transfer encoding. Useful if you are running a WSGI server. | +| ↳ `http2Origin` | boolean | Attempt to connect to origin using HTTP2. Origin must be configured as https. | +| ↳ `httpHostHeader` | string | Sets the HTTP Host header on requests sent to the local service. | +| ↳ `keepAliveConnections` | number | Maximum number of idle keepalive connections between Tunnel and your origin. This does not restrict the total number of concurrent connections. | +| ↳ `keepAliveTimeout` | number | Timeout after which an idle keepalive connection can be discarded. | +| ↳ `matchSNItoHost` | boolean | Auto configure the Hostname on the origin server certificate. | +| ↳ `noHappyEyeballs` | boolean | Disable the “happy eyeballs” algorithm for IPv4/IPv6 fallback if your local network has misconfigured one of the protocols. | +| ↳ `noTLSVerify` | boolean | Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted. | +| ↳ `originServerName` | string | Hostname that cloudflared should expect from your origin server certificate. | +| ↳ `proxyType` | string | cloudflared starts a proxy server to translate HTTP traffic into TCP when proxying, for example, SSH or RDP. This configures what type of proxy will be started. Valid options are: "" for the regular proxy and "socks" for a SOCKS5 proxy. | +| ↳ `tcpKeepAlive` | number | The timeout after which a TCP keepalive packet is sent on a connection between Tunnel and the origin server. | +| ↳ `tlsTimeout` | number | Timeout for completing a TLS handshake to your origin server, if you have chosen to connect Tunnel to an HTTPS server. | +| ↳ `warp-routing` | json | Enable private network access from WARP users to private network routes. This is enabled if the tunnel has an assigned route. | +| ↳ `enabled` | boolean | enabled | +| `created_at` | string | created at | +| `source` | string | Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel's configuration on the Zero Trust dashboard. Values: local, cloudflare. | +| `tunnel_id` | string | UUID of the tunnel. | +| `version` | number | The version of the Tunnel Configuration. | + +### Cloudflare Update Worker Route + +Replaces the URL pattern or Worker associated with a Worker route. Replaces the configuration; resend all values to retain. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | -| `name` | string | No | Filter by exact tunnel name | -| `status` | string | No | Filter by tunnel health: inactive, degraded, healthy, or down | -| `uuid` | string | No | Filter by tunnel UUID | -| `is_deleted` | boolean | No | Whether to return deleted tunnels instead of active ones | -| `include_prefix` | string | No | Only include tunnels whose name starts with this prefix | -| `exclude_prefix` | string | No | Exclude tunnels whose name starts with this prefix | -| `existed_at` | string | No | Return tunnels that existed at this RFC 3339 timestamp | -| `was_active_at` | string | No | Return tunnels that were active at this RFC 3339 timestamp | -| `was_inactive_at` | string | No | Return tunnels that were inactive at this RFC 3339 timestamp | -| `page` | number | No | Page number for pagination | -| `per_page` | number | No | Number of tunnels per page | -| `apiKey` | string | Yes | Cloudflare API Token | +| `zoneId` | string | Yes | Zone id | +| `routeId` | string | Yes | Route id | +| `apiKey` | string | Yes | Cloudflare API token | +| `pattern` | string | Yes | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| `script` | string | No | Name of the script to run if the route matches. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `tunnels` | array | Cloudflare Tunnels in the account | -| ↳ `id` | string | Tunnel identifier | -| ↳ `name` | string | Tunnel name | -| ↳ `account_tag` | string | Account the tunnel belongs to | -| ↳ `config_src` | string | Where the tunnel configuration lives: local or cloudflare | -| ↳ `status` | string | Tunnel health: inactive, degraded, healthy, or down | -| ↳ `tun_type` | string | Tunnel type, e.g. cfd_tunnel, warp_connector, or warp | -| ↳ `remote_config` | boolean | Whether the tunnel is remotely managed | -| ↳ `metadata` | json | Metadata associated with the tunnel | -| ↳ `created_at` | string | Creation timestamp | -| ↳ `deleted_at` | string | Deletion timestamp | -| ↳ `conns_active_at` | string | When the tunnel last had active connections | -| ↳ `conns_inactive_at` | string | When the tunnel last lost all connections | -| ↳ `connections` | json | Active connector connections for the tunnel | -| `total_count` | number | Total number of tunnels | +| `id` | string | Identifier. | +| `pattern` | string | Pattern to match incoming requests against. \[Learn more\]\(https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). | +| `script` | string | Name of the script to run if the route matches. | -### Cloudflare Get Tunnel +### Cloudflare Update Zone -Reads a single Cloudflare Tunnel (cloudflared), including its health status and active connector connections. Requires an API token with Account Cloudflare Tunnel Read. +Edits a zone. Only one zone property can be changed at a time. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | -| `tunnelId` | string | Yes | The tunnel ID to read | -| `apiKey` | string | Yes | Cloudflare API Token | +| `zoneId` | string | Yes | Zone id | +| `apiKey` | string | Yes | Cloudflare API token | +| `paused` | boolean | No | Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits. | +| `plan` | json | No | JSON object. \(Deprecated\) Please use the `/zones/\{zone_id\}/subscription` API to update a zone's plan. Changing this value will create/cancel associated subscriptions. To view available plans for this zone, see Zone Plans. Fields: id. | +| `type` | string | No | A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. This parameter is only available to Enterprise customers or if it has been explicitly enabled on a zone. Allowed values: full, partial, secondary, internal. | +| `vanity_name_servers` | json | No | JSON array. An array of domains used for custom name servers. This is only available for Business and Enterprise plans. | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `id` | string | Tunnel identifier | -| `name` | string | Tunnel name | -| `account_tag` | string | Account the tunnel belongs to | -| `config_src` | string | Where the tunnel configuration lives: local or cloudflare | -| `status` | string | Tunnel health: inactive, degraded, healthy, or down | -| `tun_type` | string | Tunnel type, e.g. cfd_tunnel, warp_connector, or warp | -| `remote_config` | boolean | Whether the tunnel is remotely managed | -| `metadata` | json | Metadata associated with the tunnel | -| `created_at` | string | Creation timestamp | -| `deleted_at` | string | Deletion timestamp | -| `conns_active_at` | string | When the tunnel last had active connections | -| `conns_inactive_at` | string | When the tunnel last lost all connections | -| `connections` | json | Active connector connections for the tunnel | +| `account` | json | The account the zone belongs to. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the account. | +| `activated_on` | string | The last time proof of ownership was detected and the zone was made active. | +| `cname_suffix` | string | Allows the customer to use a custom apex. *Tenants Only Configuration*. | +| `created_on` | string | When the zone was created. | +| `development_mode` | number | The interval \(in seconds\) from when development mode expires \(positive integer\) or last expired \(negative integer\) for the domain. If development mode has never been enabled, this value is 0. | +| `id` | string | Identifier | +| `meta` | json | Metadata about the zone. | +| ↳ `cdn_only` | boolean | The zone is only configured for CDN. | +| ↳ `custom_certificate_quota` | number | Number of Custom Certificates the zone can have. | +| ↳ `dns_only` | boolean | The zone is only configured for DNS. | +| ↳ `foundation_dns` | boolean | The zone is setup with Foundation DNS. | +| ↳ `page_rule_quota` | number | Number of Page Rules a zone can have. | +| ↳ `phishing_detected` | boolean | The zone has been flagged for phishing. | +| ↳ `step` | number | step | +| `modified_on` | string | When the zone was last modified. | +| `name` | string | The domain name. Per \[RFC 1035\]\(https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the overall zone name can be up to 253 characters, with each segment \("label"\) not exceeding 63 characters. | +| `name_servers` | array | The name servers Cloudflare assigns to a zone. | +| `original_dnshost` | string | DNS host at the time of switching to Cloudflare. | +| `original_name_servers` | array | Original name servers before moving to Cloudflare. | +| `original_registrar` | string | Registrar for the domain at the time of switching to Cloudflare. | +| `owner` | json | The owner of the zone. | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | Name of the owner. | +| ↳ `type` | string | The type of owner. | +| `paused` | boolean | Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits. | +| `permissions` | array | Legacy permissions based on legacy user membership information. | +| `plan` | json | A Zones subscription information. | +| ↳ `can_subscribe` | boolean | States if the subscription can be activated. | +| ↳ `currency` | string | The denomination of the customer. | +| ↳ `externally_managed` | boolean | If this Zone is managed by another company. | +| ↳ `frequency` | string | How often the customer is billed. | +| ↳ `id` | string | Identifier | +| ↳ `is_subscribed` | boolean | States if the subscription active. | +| ↳ `legacy_discount` | boolean | If the legacy discount applies to this Zone. | +| ↳ `legacy_id` | string | The legacy name of the plan. | +| ↳ `name` | string | Name of the owner. | +| ↳ `price` | number | How much the customer is paying. | +| `status` | string | The zone status on Cloudflare. Values: initializing, pending, active, moved. | +| `tenant` | json | The root organizational unit that this zone belongs to \(such as a tenant or organization\). | +| ↳ `id` | string | Identifier | +| ↳ `name` | string | The name of the Tenant account. | +| `tenant_unit` | json | The immediate parent organizational unit that this zone belongs to \(such as under a tenant or sub-organization\). | +| ↳ `id` | string | Identifier | +| `type` | string | A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Values: full, partial, secondary, internal. | +| `vanity_name_servers` | array | An array of domains used for custom name servers. This is only available for Business and Enterprise plans. | +| `verification_key` | string | Verification key for partial zone setup. | -### Cloudflare Get Tunnel Configuration +### Cloudflare Update Zone Setting -Reads the configuration of a remotely-managed Cloudflare Tunnel — its ingress rules, origin request settings, and WARP routing. Only tunnels whose configuration source is "cloudflare" have a remote configuration; locally-managed tunnels keep it in their own config file. Requires an API token with Account Cloudflare Tunnel Read. +Updates a specific zone setting such as SSL mode, security level, cache level, or other configuration. #### Input | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | -| `accountId` | string | Yes | The Cloudflare account ID. Tunnels are account-scoped | -| `tunnelId` | string | Yes | The tunnel ID to read the configuration for | +| `enabled` | boolean | No | Enrollment value for ssl_recommender; this setting uses enabled instead of value | +| `zoneId` | string | Yes | The zone ID to update settings for | +| `settingId` | string | Yes | Setting to update \(e.g., "ssl", "security_level", "cache_level", "always_use_https", "browser_cache_ttl", "http3", "min_tls_version", "ciphers"\) | +| `value` | string | No | Required except for ssl_recommender. New value as a string, or a JSON string for complex values \(e.g., "full" for SSL, "medium" for security_level, "aggressive" for cache_level, \["ECDHE-RSA-AES128-GCM-SHA256"\] for ciphers\) | | `apiKey` | string | Yes | Cloudflare API Token | #### Output | Parameter | Type | Description | | --------- | ---- | ----------- | -| `tunnel_id` | string | Tunnel the configuration belongs to | -| `account_id` | string | Account the tunnel belongs to | -| `version` | number | Configuration version, incremented on every change | -| `source` | string | Where the configuration is managed: local or cloudflare | -| `created_at` | string | Creation timestamp | -| `config` | json | Tunnel configuration with ingress rules, originRequest defaults, and warp-routing settings | +| `id` | string | Setting identifier \(e.g., ssl, cache_level, security_level\) | +| `value` | string | Updated setting value as a string. Simple values returned as-is \(e.g., "full", "on"\). SSL Recommender returns its enabled flag. Complex values are JSON-stringified. | +| `editable` | boolean | Whether the setting can be modified for the current zone plan | +| `modified_on` | string | ISO 8601 timestamp when the setting was last modified | +| `time_remaining` | number | Development mode countdown, in seconds. Cloudflare documents this only on the zones_development_mode setting, where it is the interval from when development mode expires \(positive\) or last expired \(negative\) | diff --git a/apps/sim/blocks/blocks/cloudflare.ts b/apps/sim/blocks/blocks/cloudflare.ts index ea82789ea40..473dc71240f 100644 --- a/apps/sim/blocks/blocks/cloudflare.ts +++ b/apps/sim/blocks/blocks/cloudflare.ts @@ -1,62 +1,237 @@ import { CloudflareIcon } from '@/components/icons' import { AuthMode, type BlockConfig, type BlockMeta, IntegrationType } from '@/blocks/types' -/** - * Per-operation aliases from a tool param name to the subBlock id that supplies - * it, keyed by operation. - * - * Block state is keyed by subBlock id, so two controls sharing an id share one - * stored value and the last definition in file order wins the seeded default. - * That is fine — and deliberate — when both controls mean the same thing (a zone - * id, a page number, a record name). It is not fine when they differ: a control - * in `mode: 'advanced'` is serialized whenever its stored value is non-empty, - * *before* its own `condition` is evaluated (`shouldSerializeSubBlock` in - * `serializer/index.ts`), so a hidden filter from one operation would otherwise - * arrive as a written value on another — a `list_dns_records` "Content Filter" - * silently overwriting a record's content on `update_dns_record`, or a - * `list_zones` status reaching `list_tunnels`, whose status enum is disjoint. - * - * Every such control therefore carries its own id and is republished here under - * the tool's param name, before any coercion in the mapper reads it. - * - * Which side of a collision gets the new id is not a free choice. Block state - * is never migrated, and `extractBlockParams` (`serializer/index.ts`) drops a - * stored value whose id matches no subBlock config — a deleted input — so the - * renamed side silently loses whatever shipped workflows stored. The read - * filters therefore keep their original ids, where losing a value means - * returning the whole zone under `success: true`, and the write controls take - * the new ones, where losing a value means a PATCH simply omits the field. - */ +/** Advanced inputs serialize before conditions; separate aliases prevent hidden values crossing operations. */ const SUBBLOCK_ALIASES: Record> = { create_zone: { type: 'zoneType' }, - create_dns_record: { type: 'recordType', proxied: 'recordProxied', tags: 'recordTags' }, + create_dns_record: { + type: 'recordType', + proxied: 'recordProxied', + tags: 'recordTags', + settings: 'dnsRecordSettings', + private_routing: 'dnsRecordPrivateRouting', + data: 'dnsRecordData', + include_shadow_metadata: 'dnsRecordIncludeShadowMetadata', + }, update_dns_record: { type: 'updateRecordType', name: 'updateRecordName', content: 'updateRecordContent', proxied: 'updateRecordProxied', tags: 'updateRecordTags', + clearComment: 'dnsRecordClearcomment', + settings: 'dnsRecordSettings', + private_routing: 'dnsRecordPrivateRouting', + data: 'dnsRecordData', + include_shadow_metadata: 'dnsRecordIncludeShadowMetadata', + }, + list_dns_records: { + order: 'dnsOrder', + name_contains: 'listDnsRecordsNameContains', + name_startswith: 'listDnsRecordsNameStartswith', + name_endswith: 'listDnsRecordsNameEndswith', + content_contains: 'listDnsRecordsContentContains', + content_startswith: 'listDnsRecordsContentStartswith', + content_endswith: 'listDnsRecordsContentEndswith', + comment_present: 'listDnsRecordsCommentPresent', + comment_absent: 'listDnsRecordsCommentAbsent', + comment_exact: 'listDnsRecordsCommentExact', + comment_startswith: 'listDnsRecordsCommentStartswith', + comment_endswith: 'listDnsRecordsCommentEndswith', + tag_present: 'listDnsRecordsTagPresent', + tag_absent: 'listDnsRecordsTagAbsent', + tag_contains: 'listDnsRecordsTagContains', + tag_startswith: 'listDnsRecordsTagStartswith', + tag_endswith: 'listDnsRecordsTagEndswith', + include_shadow_metadata: 'listDnsRecordsIncludeShadowMetadata', + shadowed_by_name: 'listDnsRecordsShadowedByName', + shadowing_name: 'listDnsRecordsShadowingName', }, - list_dns_records: { order: 'dnsOrder' }, list_certificates: { status: 'certificateStatus' }, - create_ruleset: { name: 'rulesetName' }, - update_ruleset_rule: { enabled: 'updateRuleEnabled' }, - create_rate_limit_rule: { action: 'rateLimitAction' }, + create_ruleset: { name: 'rulesetName', dry_run: 'rulesetDryRun' }, + update_ruleset_rule: { + enabled: 'updateRuleEnabled', + exposed_credential_check: 'rulesetRuleExposedCredentialCheck', + position: 'rulesetRulePosition', + dry_run: 'rulesetRuleDryRun', + }, + create_rate_limit_rule: { + action: 'rateLimitAction', + actionParameters: 'rateLimitRuleActionparameters', + exposed_credential_check: 'rateLimitRuleExposedCredentialCheck', + id: 'rateLimitRuleId', + logging: 'rateLimitRuleLogging', + ref: 'rateLimitRuleRef', + position: 'rateLimitRulePosition', + score_per_period: 'rateLimitRuleScorePerPeriod', + score_response_header_name: 'rateLimitRuleScoreResponseHeaderName', + dry_run: 'rateLimitRuleDryRun', + }, update_rate_limit_rule: { action: 'updateRateLimitAction', enabled: 'updateRuleEnabled', actionParameters: 'rateLimitActionParameters', + exposed_credential_check: 'rateLimitRuleExposedCredentialCheck', + position: 'rateLimitRulePosition', + score_per_period: 'rateLimitRuleScorePerPeriod', + score_response_header_name: 'rateLimitRuleScoreResponseHeaderName', + dry_run: 'rateLimitRuleDryRun', + }, + create_access_application: { + type: 'appType', + tags: 'accessAppTags', + destinations: 'accessApplicationDestinations', + oauth_configuration: 'accessApplicationOauthConfiguration', + self_hosted_domains: 'accessApplicationSelfHostedDomains', + user_populations: 'accessApplicationUserPopulations', + allow_authenticate_via_warp: 'accessApplicationAllowAuthenticateViaWarp', + allow_iframe: 'accessApplicationAllowIframe', + cors_headers: 'accessApplicationCorsHeaders', + custom_non_identity_deny_url: 'accessApplicationCustomNonIdentityDenyUrl', + custom_pages: 'accessApplicationCustomPages', + eager_redirect_cookie_setting: 'accessApplicationEagerRedirectCookieSetting', + enable_binding_cookie: 'accessApplicationEnableBindingCookie', + http_only_cookie_attribute: 'accessApplicationHttpOnlyCookieAttribute', + mfa_config: 'accessApplicationMfaConfig', + options_preflight_bypass: 'accessApplicationOptionsPreflightBypass', + path_cookie_attribute: 'accessApplicationPathCookieAttribute', + read_service_tokens_from_header: 'accessApplicationReadServiceTokensFromHeader', + same_site_cookie_attribute: 'accessApplicationSameSiteCookieAttribute', + scim_config: 'accessApplicationScimConfig', + service_auth_401_redirect: 'accessApplicationServiceAuth401Redirect', + skip_interstitial: 'accessApplicationSkipInterstitial', + use_clientless_isolation_app_launcher_url: + 'accessApplicationUseClientlessIsolationAppLauncherUrl', + app_launcher_logo_url: 'accessApplicationAppLauncherLogoUrl', + bg_color: 'accessApplicationBgColor', + footer_links: 'accessApplicationFooterLinks', + header_bg_color: 'accessApplicationHeaderBgColor', + landing_page_design: 'accessApplicationLandingPageDesign', + skip_app_launcher_login_page: 'accessApplicationSkipAppLauncherLoginPage', + }, + update_access_application: { + type: 'updateAppType', + tags: 'accessAppTags', + destinations: 'accessApplicationDestinations', + oauth_configuration: 'accessApplicationOauthConfiguration', + self_hosted_domains: 'accessApplicationSelfHostedDomains', + user_populations: 'accessApplicationUserPopulations', + allow_authenticate_via_warp: 'accessApplicationAllowAuthenticateViaWarp', + allow_iframe: 'accessApplicationAllowIframe', + cors_headers: 'accessApplicationCorsHeaders', + custom_non_identity_deny_url: 'accessApplicationCustomNonIdentityDenyUrl', + custom_pages: 'accessApplicationCustomPages', + eager_redirect_cookie_setting: 'accessApplicationEagerRedirectCookieSetting', + enable_binding_cookie: 'accessApplicationEnableBindingCookie', + http_only_cookie_attribute: 'accessApplicationHttpOnlyCookieAttribute', + mfa_config: 'accessApplicationMfaConfig', + options_preflight_bypass: 'accessApplicationOptionsPreflightBypass', + path_cookie_attribute: 'accessApplicationPathCookieAttribute', + read_service_tokens_from_header: 'accessApplicationReadServiceTokensFromHeader', + same_site_cookie_attribute: 'accessApplicationSameSiteCookieAttribute', + scim_config: 'accessApplicationScimConfig', + service_auth_401_redirect: 'accessApplicationServiceAuth401Redirect', + skip_interstitial: 'accessApplicationSkipInterstitial', + use_clientless_isolation_app_launcher_url: + 'accessApplicationUseClientlessIsolationAppLauncherUrl', + app_launcher_logo_url: 'accessApplicationAppLauncherLogoUrl', + bg_color: 'accessApplicationBgColor', + footer_links: 'accessApplicationFooterLinks', + header_bg_color: 'accessApplicationHeaderBgColor', + landing_page_design: 'accessApplicationLandingPageDesign', + skip_app_launcher_login_page: 'accessApplicationSkipAppLauncherLoginPage', + }, + update_access_policy: { + decision: 'updatePolicyDecision', + approval_groups: 'accessPolicyApprovalGroups', + connection_rules: 'accessPolicyConnectionRules', + mfa_config: 'accessPolicyMfaConfig', + }, + list_access_applications: { + name: 'listNameFilter', + domain: 'accessAppDomainFilter', + target_attributes: 'listAccessApplicationsTargetAttributes', }, - create_access_application: { type: 'appType', tags: 'accessAppTags' }, - update_access_application: { type: 'updateAppType', tags: 'accessAppTags' }, - update_access_policy: { decision: 'updatePolicyDecision' }, - list_access_applications: { name: 'listNameFilter', domain: 'accessAppDomainFilter' }, list_access_groups: { name: 'listNameFilter' }, list_access_service_tokens: { name: 'listNameFilter' }, list_worker_scripts: { tags: 'workerTagFilter' }, list_tunnels: { status: 'tunnelStatus', name: 'listNameFilter' }, - list_r2_buckets: { cursor: 'r2Cursor' }, + list_r2_buckets: { cursor: 'r2Cursor', order: 'listR2BucketsOrder' }, list_rulesets: { cursor: 'rulesetCursor' }, + create_access_group: { + exclude: 'accessGroupExclude', + include: 'accessGroupInclude', + is_default: 'accessGroupIsDefault', + name: 'accessGroupName', + require: 'accessGroupRequire', + }, + create_access_policy: { + approval_groups: 'accessPolicyApprovalGroups', + connection_rules: 'accessPolicyConnectionRules', + mfa_config: 'accessPolicyMfaConfig', + }, + create_access_service_token: { + client_secret_version: 'accessServiceTokenClientSecretVersion', + enabled: 'accessServiceTokenEnabled', + previous_client_secret_expires_at: 'accessServiceTokenPreviousClientSecretExpiresAt', + }, + create_ruleset_rule: { + exposed_credential_check: 'rulesetRuleExposedCredentialCheck', + id: 'rulesetRuleId', + logging: 'rulesetRuleLogging', + ratelimit: 'rulesetRuleRatelimit', + dry_run: 'rulesetRuleDryRun', + }, + create_tunnel: { + config_src: 'tunnelConfigSrc', + name: 'tunnelName', + tunnel_secret: 'tunnelTunnelSecret', + }, + create_worker_route: { pattern: 'workerRoutePattern', script: 'workerRouteScript' }, + delete_ruleset_rule: { dry_run: 'deleteRulesetRuleDryRun' }, + delete_ruleset: { dry_run: 'deleteRulesetDryRun' }, + delete_worker_script: { force: 'deleteWorkerScriptForce' }, + get_dns_record: { include_shadow_metadata: 'getDnsRecordIncludeShadowMetadata' }, + list_access_identity_providers: { + scim_enabled: 'listAccessIdentityProvidersScimEnabled', + page: 'listAccessIdentityProvidersPage', + per_page: 'listAccessIdentityProvidersPerPage', + }, + list_zones: { type: 'listZonesType', account_name: 'listZonesAccountName' }, + rotate_access_service_token: { + previous_client_secret_expires_at: 'rotateAccessServiceTokenPreviousClientSecretExpiresAt', + }, + update_access_group: { + exclude: 'accessGroupExclude', + include: 'accessGroupInclude', + is_default: 'accessGroupIsDefault', + name: 'accessGroupName', + require: 'accessGroupRequire', + }, + update_access_service_token: { + client_secret_version: 'accessServiceTokenClientSecretVersion', + duration: 'accessServiceTokenDuration', + enabled: 'accessServiceTokenEnabled', + name: 'accessServiceTokenName', + previous_client_secret_expires_at: 'accessServiceTokenPreviousClientSecretExpiresAt', + }, + update_r2_bucket_cors: { rules: 'r2BucketCorsRules' }, + update_r2_bucket_lifecycle: { rules: 'r2BucketLifecycleRules' }, + update_ruleset: { + description: 'rulesetDescription', + rules: 'rulesetRules', + dry_run: 'rulesetDryRun', + }, + update_tunnel_configuration: { config: 'tunnelConfigurationConfig' }, + update_tunnel: { name: 'tunnelName', tunnel_secret: 'tunnelTunnelSecret' }, + update_worker_route: { pattern: 'workerRoutePattern', script: 'workerRouteScript' }, + update_zone_setting: { enabled: 'zoneSettingEnabled' }, + update_zone: { + paused: 'zonePaused', + plan: 'zonePlan', + type: 'updateZoneType', + vanity_name_servers: 'zoneVanityNameServers', + }, } /** @@ -80,7 +255,7 @@ export const CloudflareBlock: BlockConfig = { description: 'Manage DNS, WAF, Zero Trust access, and edge infrastructure', authMode: AuthMode.ApiKey, longDescription: - 'Manage zones (domains), DNS records, SSL/TLS certificates, zone settings, DNS analytics, and cache purging. Configure WAF rulesets, managed rule overrides, and rate limiting rules through the current Rulesets engine. Administer Cloudflare Access (Zero Trust) applications, policies, groups, identity providers, and service tokens, and inspect R2 buckets, Workers scripts and routes, and Cloudflare Tunnels.', + 'Manage Cloudflare DNS, zones, SSL, cache, and analytics. Configure WAF rulesets and rate limiting; administer Access applications, policies, groups, and service tokens; manage Worker routes and tunnels; and configure R2 buckets, CORS, and lifecycle rules.', docsLink: 'https://docs.sim.ai/integrations/cloudflare', category: 'tools', integrationType: IntegrationType.DevOps, @@ -133,11 +308,7 @@ export const CloudflareBlock: BlockConfig = { { text: 'to', field: 'value' }, { text: 'on zone', field: 'zoneId' }, ], - dns_analytics: [ - { text: 'Report DNS analytics for zone', field: 'zoneId', core: true }, - { text: ', from', field: 'since', core: true }, - { text: 'to', field: 'until', core: true }, - ], + dns_analytics: [{ text: 'Report DNS analytics for zone', field: 'zoneId', core: true }], purge_cache: [ { text: 'Purge cache for zone', field: 'zoneId', core: true }, { text: ', limited to', field: ['files', 'prefixes', 'hosts', 'tags'] }, @@ -191,8 +362,8 @@ export const CloudflareBlock: BlockConfig = { ], get_access_application: [{ text: 'Read Access application', field: 'appId', core: true }], create_access_application: [ - { text: 'Protect', field: 'domain', core: true }, - { text: 'with an Access application named', field: 'name' }, + 'Create an Access application', + { text: 'named', field: 'name' }, ], update_access_application: [ { text: 'Update Access application', field: 'appId', core: true }, @@ -259,6 +430,34 @@ export const CloudflareBlock: BlockConfig = { get_tunnel_configuration: [ { text: 'Read the configuration of tunnel', field: 'tunnelId', core: true }, ], + create_access_group: ['Create Access Group'], + create_tunnel: ['Create Tunnel'], + create_worker_route: ['Create Worker Route'], + delete_access_group: ['Delete Access Group'], + delete_r2_bucket_cors: ['Delete R2 Bucket CORS'], + delete_ruleset: ['Delete Ruleset'], + delete_tunnel: ['Delete Tunnel'], + delete_worker_route: ['Delete Worker Route'], + delete_worker_script: ['Delete Worker Script'], + get_access_group: ['Get Access Group'], + get_access_policy: ['Get Access Policy'], + get_access_service_token: ['Get Access Service Token'], + get_dns_record: ['Get DNS Record'], + get_r2_bucket_cors: ['Get R2 Bucket CORS'], + get_r2_bucket_lifecycle: ['Get R2 Bucket Lifecycle'], + get_tunnel_token: ['Get Tunnel Token'], + get_worker_route: ['Get Worker Route'], + refresh_access_service_token: ['Refresh Access Service Token'], + rotate_access_service_token: ['Rotate Access Service Token'], + update_access_group: ['Update Access Group'], + update_access_service_token: ['Update Access Service Token'], + update_r2_bucket_cors: ['Update R2 Bucket CORS'], + update_r2_bucket_lifecycle: ['Update R2 Bucket Lifecycle'], + update_ruleset: ['Update Ruleset'], + update_tunnel_configuration: ['Update Tunnel Configuration'], + update_tunnel: ['Update Tunnel'], + update_worker_route: ['Update Worker Route'], + update_zone: ['Update Zone'], }, }, }, @@ -276,9 +475,11 @@ export const CloudflareBlock: BlockConfig = { { label: 'Create DNS Record', id: 'create_dns_record' }, { label: 'Update DNS Record', id: 'update_dns_record' }, { label: 'Delete DNS Record', id: 'delete_dns_record' }, + { label: 'Get DNS Record', id: 'get_dns_record' }, { label: 'List Certificates', id: 'list_certificates' }, { label: 'Get Zone Settings', id: 'get_zone_settings' }, { label: 'Update Zone Setting', id: 'update_zone_setting' }, + { label: 'Update Zone', id: 'update_zone' }, { label: 'DNS Analytics', id: 'dns_analytics' }, { label: 'Purge Cache', id: 'purge_cache' }, { label: 'List Rulesets', id: 'list_rulesets' }, @@ -289,6 +490,8 @@ export const CloudflareBlock: BlockConfig = { { label: 'Update Ruleset Rule', id: 'update_ruleset_rule' }, { label: 'Delete Ruleset Rule', id: 'delete_ruleset_rule' }, { label: 'List Managed Ruleset Overrides', id: 'list_managed_ruleset_overrides' }, + { label: 'Delete Ruleset', id: 'delete_ruleset' }, + { label: 'Update Ruleset', id: 'update_ruleset' }, { label: 'List Rate Limiting Rules', id: 'list_rate_limit_rules' }, { label: 'Create Rate Limiting Rule', id: 'create_rate_limit_rule' }, { label: 'Update Rate Limiting Rule', id: 'update_rate_limit_rule' }, @@ -301,33 +504,82 @@ export const CloudflareBlock: BlockConfig = { { label: 'Create Access Policy', id: 'create_access_policy' }, { label: 'Update Access Policy', id: 'update_access_policy' }, { label: 'Delete Access Policy', id: 'delete_access_policy' }, + { label: 'Get Access Policy', id: 'get_access_policy' }, { label: 'List Access Groups', id: 'list_access_groups' }, + { label: 'Create Access Group', id: 'create_access_group' }, + { label: 'Delete Access Group', id: 'delete_access_group' }, + { label: 'Get Access Group', id: 'get_access_group' }, + { label: 'Update Access Group', id: 'update_access_group' }, { label: 'List Access Identity Providers', id: 'list_access_identity_providers' }, { label: 'List Access Service Tokens', id: 'list_access_service_tokens' }, { label: 'Create Access Service Token', id: 'create_access_service_token' }, { label: 'Revoke Access Service Token', id: 'revoke_access_service_token' }, + { label: 'Get Access Service Token', id: 'get_access_service_token' }, + { label: 'Refresh Access Service Token', id: 'refresh_access_service_token' }, + { label: 'Rotate Access Service Token', id: 'rotate_access_service_token' }, + { label: 'Update Access Service Token', id: 'update_access_service_token' }, { label: 'List R2 Buckets', id: 'list_r2_buckets' }, { label: 'Get R2 Bucket', id: 'get_r2_bucket' }, { label: 'Create R2 Bucket', id: 'create_r2_bucket' }, { label: 'Delete R2 Bucket', id: 'delete_r2_bucket' }, { label: 'List Worker Scripts', id: 'list_worker_scripts' }, { label: 'Get Worker Script Settings', id: 'get_worker_script_settings' }, + { label: 'Delete Worker Script', id: 'delete_worker_script' }, { label: 'List Worker Routes', id: 'list_worker_routes' }, + { label: 'Create Worker Route', id: 'create_worker_route' }, + { label: 'Delete Worker Route', id: 'delete_worker_route' }, + { label: 'Get Worker Route', id: 'get_worker_route' }, + { label: 'Update Worker Route', id: 'update_worker_route' }, { label: 'List Tunnels', id: 'list_tunnels' }, { label: 'Get Tunnel', id: 'get_tunnel' }, { label: 'Get Tunnel Configuration', id: 'get_tunnel_configuration' }, + { label: 'Update Tunnel Configuration', id: 'update_tunnel_configuration' }, + { label: 'Create Tunnel', id: 'create_tunnel' }, + { label: 'Delete Tunnel', id: 'delete_tunnel' }, + { label: 'Delete R2 Bucket CORS', id: 'delete_r2_bucket_cors' }, + { label: 'Get R2 Bucket CORS', id: 'get_r2_bucket_cors' }, + { label: 'Update R2 Bucket CORS', id: 'update_r2_bucket_cors' }, + { label: 'Get R2 Bucket Lifecycle', id: 'get_r2_bucket_lifecycle' }, + { label: 'Update R2 Bucket Lifecycle', id: 'update_r2_bucket_lifecycle' }, + { label: 'Get Tunnel Token', id: 'get_tunnel_token' }, + { label: 'Update Tunnel', id: 'update_tunnel' }, ], value: () => 'list_zones', }, - - // List Zones inputs { id: 'name', - title: 'Domain Name', + title: 'Name', type: 'short-input', - placeholder: 'Filter by domain (e.g., example.com)', - condition: { field: 'operation', value: 'list_zones' }, - mode: 'advanced', + placeholder: 'Enter name', + condition: { + field: 'operation', + value: [ + 'list_zones', + 'create_zone', + 'list_dns_records', + 'create_dns_record', + 'create_access_application', + 'update_access_application', + 'create_access_policy', + 'update_access_policy', + 'create_access_service_token', + ], + }, + required: { + field: 'operation', + value: [ + 'create_zone', + 'create_dns_record', + 'create_access_policy', + 'update_access_policy', + 'create_access_service_token', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare name value. Return ONLY the value.', + placeholder: 'Describe the name', + }, }, { id: 'status', @@ -349,24 +601,162 @@ export const CloudflareBlock: BlockConfig = { title: 'Page', type: 'short-input', placeholder: 'Page number (default: 1)', - condition: { field: 'operation', value: 'list_zones' }, + condition: { + field: 'operation', + value: [ + 'list_zones', + 'list_dns_records', + 'list_certificates', + 'list_access_applications', + 'list_access_policies', + 'list_access_groups', + 'list_access_service_tokens', + 'list_tunnels', + ], + }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare page value. Return ONLY the value.', + placeholder: 'Describe the page', + }, }, { id: 'per_page', title: 'Per Page', type: 'short-input', placeholder: 'Results per page (default: 20, max: 50)', - condition: { field: 'operation', value: 'list_zones' }, + condition: { + field: 'operation', + value: [ + 'list_zones', + 'list_dns_records', + 'list_certificates', + 'list_access_applications', + 'list_access_policies', + 'list_access_groups', + 'list_access_service_tokens', + 'list_r2_buckets', + 'list_rulesets', + 'list_tunnels', + ], + }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare per page value. Return ONLY the value.', + placeholder: 'Describe the per page', + }, }, { id: 'accountId', title: 'Account ID', type: 'short-input', - placeholder: 'Filter by account ID', - condition: { field: 'operation', value: 'list_zones' }, - mode: 'advanced', + placeholder: 'Enter account id', + condition: { + field: 'operation', + value: [ + 'list_zones', + 'create_zone', + 'list_access_applications', + 'get_access_application', + 'create_access_application', + 'update_access_application', + 'delete_access_application', + 'list_access_policies', + 'create_access_policy', + 'update_access_policy', + 'delete_access_policy', + 'list_access_groups', + 'list_access_identity_providers', + 'list_access_service_tokens', + 'create_access_service_token', + 'revoke_access_service_token', + 'list_r2_buckets', + 'get_r2_bucket', + 'create_r2_bucket', + 'delete_r2_bucket', + 'list_worker_scripts', + 'get_worker_script_settings', + 'list_tunnels', + 'get_tunnel', + 'get_tunnel_configuration', + 'create_access_group', + 'create_tunnel', + 'delete_access_group', + 'delete_r2_bucket_cors', + 'delete_tunnel', + 'delete_worker_script', + 'get_access_group', + 'get_access_policy', + 'get_access_service_token', + 'get_r2_bucket_cors', + 'get_r2_bucket_lifecycle', + 'get_tunnel_token', + 'refresh_access_service_token', + 'rotate_access_service_token', + 'update_access_group', + 'update_access_service_token', + 'update_r2_bucket_cors', + 'update_r2_bucket_lifecycle', + 'update_tunnel_configuration', + 'update_tunnel', + ], + }, + required: { + field: 'operation', + value: [ + 'create_zone', + 'list_access_applications', + 'get_access_application', + 'create_access_application', + 'update_access_application', + 'delete_access_application', + 'list_access_policies', + 'create_access_policy', + 'update_access_policy', + 'delete_access_policy', + 'list_access_groups', + 'list_access_identity_providers', + 'list_access_service_tokens', + 'create_access_service_token', + 'revoke_access_service_token', + 'list_r2_buckets', + 'get_r2_bucket', + 'create_r2_bucket', + 'delete_r2_bucket', + 'list_worker_scripts', + 'get_worker_script_settings', + 'list_tunnels', + 'get_tunnel', + 'get_tunnel_configuration', + 'create_access_group', + 'create_tunnel', + 'delete_access_group', + 'delete_r2_bucket_cors', + 'delete_tunnel', + 'delete_worker_script', + 'get_access_group', + 'get_access_policy', + 'get_access_service_token', + 'get_r2_bucket_cors', + 'get_r2_bucket_lifecycle', + 'get_tunnel_token', + 'refresh_access_service_token', + 'rotate_access_service_token', + 'update_access_group', + 'update_access_service_token', + 'update_r2_bucket_cors', + 'update_r2_bucket_lifecycle', + 'update_tunnel_configuration', + 'update_tunnel', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare account id value. Return ONLY the value.', + placeholder: 'Describe the account id', + }, }, { id: 'order', @@ -394,7 +784,10 @@ export const CloudflareBlock: BlockConfig = { { label: 'Descending', id: 'desc' }, ], value: () => '', - condition: { field: 'operation', value: 'list_zones' }, + condition: { + field: 'operation', + value: ['list_zones', 'list_dns_records', 'list_r2_buckets'], + }, mode: 'advanced', }, { @@ -407,27 +800,9 @@ export const CloudflareBlock: BlockConfig = { { label: 'All', id: 'all' }, ], value: () => '', - condition: { field: 'operation', value: 'list_zones' }, + condition: { field: 'operation', value: ['list_zones', 'list_dns_records'] }, mode: 'advanced', }, - - // Create Zone inputs - { - id: 'name', - title: 'Domain Name', - type: 'short-input', - required: true, - placeholder: 'e.g., example.com', - condition: { field: 'operation', value: 'create_zone' }, - }, - { - id: 'accountId', - title: 'Account ID', - type: 'short-input', - required: true, - placeholder: 'Enter Cloudflare account ID', - condition: { field: 'operation', value: 'create_zone' }, - }, { id: 'zoneType', title: 'Zone Type', @@ -436,99 +811,119 @@ export const CloudflareBlock: BlockConfig = { { label: 'Full (Cloudflare DNS)', id: 'full' }, { label: 'Partial (CNAME Setup)', id: 'partial' }, { label: 'Secondary (Secondary DNS)', id: 'secondary' }, + { label: 'Internal DNS', id: 'internal' }, ], value: () => 'full', condition: { field: 'operation', value: 'create_zone' }, mode: 'advanced', }, - // Get Zone inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'get_zone' }, - }, - - // Delete Zone inputs { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID to delete', - condition: { field: 'operation', value: 'delete_zone' }, + id: 'updateZoneType', + title: 'Zone Type', + type: 'dropdown', + options: [ + { label: 'Unchanged', id: '' }, + { label: 'Full (Cloudflare DNS)', id: 'full' }, + { label: 'Partial (CNAME Setup)', id: 'partial' }, + { label: 'Secondary (Secondary DNS)', id: 'secondary' }, + { label: 'Internal DNS', id: 'internal' }, + ], + value: () => '', + condition: { field: 'operation', value: 'update_zone' }, + mode: 'advanced', }, - - // List DNS Records inputs { id: 'zoneId', title: 'Zone ID', type: 'short-input', required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'list_dns_records' }, + placeholder: 'Enter zone id', + condition: { + field: 'operation', + value: [ + 'get_zone', + 'delete_zone', + 'list_dns_records', + 'create_dns_record', + 'update_dns_record', + 'delete_dns_record', + 'list_certificates', + 'get_zone_settings', + 'update_zone_setting', + 'dns_analytics', + 'purge_cache', + 'list_rulesets', + 'get_ruleset', + 'get_ruleset_entrypoint', + 'create_ruleset', + 'create_ruleset_rule', + 'update_ruleset_rule', + 'delete_ruleset_rule', + 'list_managed_ruleset_overrides', + 'list_rate_limit_rules', + 'create_rate_limit_rule', + 'update_rate_limit_rule', + 'list_worker_routes', + 'create_worker_route', + 'delete_ruleset', + 'delete_worker_route', + 'get_dns_record', + 'get_worker_route', + 'update_ruleset', + 'update_worker_route', + 'update_zone', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare zone id value. Return ONLY the value.', + placeholder: 'Describe the zone id', + }, }, { id: 'type', title: 'Record Type', type: 'dropdown', options: [ - { label: 'All', id: '' }, + { label: 'Any / unchanged', id: '' }, { label: 'A', id: 'A' }, { label: 'AAAA', id: 'AAAA' }, + { label: 'CAA', id: 'CAA' }, + { label: 'CERT', id: 'CERT' }, { label: 'CNAME', id: 'CNAME' }, + { label: 'DNSKEY', id: 'DNSKEY' }, + { label: 'DS', id: 'DS' }, + { label: 'HTTPS', id: 'HTTPS' }, + { label: 'LOC', id: 'LOC' }, { label: 'MX', id: 'MX' }, - { label: 'TXT', id: 'TXT' }, + { label: 'NAPTR', id: 'NAPTR' }, { label: 'NS', id: 'NS' }, + { label: 'OPENPGPKEY', id: 'OPENPGPKEY' }, + { label: 'PTR', id: 'PTR' }, + { label: 'SMIMEA', id: 'SMIMEA' }, { label: 'SRV', id: 'SRV' }, + { label: 'SSHFP', id: 'SSHFP' }, + { label: 'SVCB', id: 'SVCB' }, + { label: 'TLSA', id: 'TLSA' }, + { label: 'TXT', id: 'TXT' }, + { label: 'URI', id: 'URI' }, ], value: () => '', condition: { field: 'operation', value: 'list_dns_records' }, mode: 'advanced', }, - { - id: 'name', - title: 'Name Filter', - type: 'short-input', - placeholder: 'Filter by record name (exact match)', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', - }, { id: 'content', - title: 'Content Filter', + title: 'Content', type: 'short-input', - placeholder: 'Filter by record content (exact match)', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', - }, - { - id: 'direction', - title: 'Sort Direction', - type: 'dropdown', - options: [ - { label: 'Default', id: '' }, - { label: 'Ascending', id: 'asc' }, - { label: 'Descending', id: 'desc' }, - ], - value: () => '', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', - }, - { - id: 'match', - title: 'Match Logic', - type: 'dropdown', - options: [ - { label: 'All (default)', id: '' }, - { label: 'Any', id: 'any' }, - { label: 'All', id: 'all' }, - ], - value: () => '', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', + placeholder: 'Record value, or provide structured record data', + condition: { field: 'operation', value: ['list_dns_records', 'create_dns_record'] }, + required: false, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare content value. Return ONLY the value.', + placeholder: 'Describe the content', + }, }, { id: 'dnsOrder', @@ -564,8 +959,21 @@ export const CloudflareBlock: BlockConfig = { title: 'Search', type: 'short-input', placeholder: 'Free-text search across record properties', - condition: { field: 'operation', value: 'list_dns_records' }, + condition: { + field: 'operation', + value: [ + 'list_dns_records', + 'list_access_applications', + 'list_access_groups', + 'list_access_service_tokens', + ], + }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare search value. Return ONLY the value.', + placeholder: 'Describe the search', + }, }, { id: 'tag', @@ -574,6 +982,11 @@ export const CloudflareBlock: BlockConfig = { placeholder: 'Exact tag name to filter by', condition: { field: 'operation', value: 'list_dns_records' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tag filter value. Return ONLY the value.', + placeholder: 'Describe the tag filter', + }, }, { id: 'tag_match', @@ -595,32 +1008,11 @@ export const CloudflareBlock: BlockConfig = { placeholder: 'Filter by comment content (substring match)', condition: { field: 'operation', value: 'list_dns_records' }, mode: 'advanced', - }, - { - id: 'page', - title: 'Page', - type: 'short-input', - placeholder: 'Page number (default: 1)', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', - }, - { - id: 'per_page', - title: 'Per Page', - type: 'short-input', - placeholder: 'Results per page (default: 100, max: 5000000)', - condition: { field: 'operation', value: 'list_dns_records' }, - mode: 'advanced', - }, - - // Create DNS Record inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'create_dns_record' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare comment filter value. Return ONLY the value.', + placeholder: 'Describe the comment filter', + }, }, { id: 'recordType', @@ -629,38 +1021,41 @@ export const CloudflareBlock: BlockConfig = { options: [ { label: 'A', id: 'A' }, { label: 'AAAA', id: 'AAAA' }, + { label: 'CAA', id: 'CAA' }, + { label: 'CERT', id: 'CERT' }, { label: 'CNAME', id: 'CNAME' }, + { label: 'DNSKEY', id: 'DNSKEY' }, + { label: 'DS', id: 'DS' }, + { label: 'HTTPS', id: 'HTTPS' }, + { label: 'LOC', id: 'LOC' }, { label: 'MX', id: 'MX' }, - { label: 'TXT', id: 'TXT' }, + { label: 'NAPTR', id: 'NAPTR' }, { label: 'NS', id: 'NS' }, + { label: 'OPENPGPKEY', id: 'OPENPGPKEY' }, + { label: 'PTR', id: 'PTR' }, + { label: 'SMIMEA', id: 'SMIMEA' }, { label: 'SRV', id: 'SRV' }, + { label: 'SSHFP', id: 'SSHFP' }, + { label: 'SVCB', id: 'SVCB' }, + { label: 'TLSA', id: 'TLSA' }, + { label: 'TXT', id: 'TXT' }, + { label: 'URI', id: 'URI' }, ], value: () => 'A', condition: { field: 'operation', value: 'create_dns_record' }, }, - { - id: 'name', - title: 'Record Name', - type: 'short-input', - required: true, - placeholder: 'e.g., example.com or sub.example.com', - condition: { field: 'operation', value: 'create_dns_record' }, - }, - { - id: 'content', - title: 'Record Content', - type: 'short-input', - required: true, - placeholder: 'e.g., 192.0.2.1 or target.example.com', - condition: { field: 'operation', value: 'create_dns_record' }, - }, { id: 'ttl', title: 'TTL (seconds)', type: 'short-input', placeholder: '1 (automatic)', - condition: { field: 'operation', value: 'create_dns_record' }, + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare ttl (seconds) value. Return ONLY the value.', + placeholder: 'Describe the ttl (seconds)', + }, }, { id: 'recordProxied', @@ -679,16 +1074,26 @@ export const CloudflareBlock: BlockConfig = { title: 'Priority', type: 'short-input', placeholder: 'MX/URI priority (e.g., 10)', - condition: { field: 'operation', value: 'create_dns_record' }, + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare priority value. Return ONLY the value.', + placeholder: 'Describe the priority', + }, }, { id: 'comment', title: 'Comment', type: 'short-input', placeholder: 'Optional comment', - condition: { field: 'operation', value: 'create_dns_record' }, + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare comment value. Return ONLY the value.', + placeholder: 'Describe the comment', + }, }, { id: 'recordTags', @@ -697,55 +1102,72 @@ export const CloudflareBlock: BlockConfig = { placeholder: 'Comma-separated tags (e.g., production,web)', condition: { field: 'operation', value: 'create_dns_record' }, mode: 'advanced', - }, - - // Update DNS Record inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'update_dns_record' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tags value. Return ONLY the value.', + placeholder: 'Describe the tags', + }, }, { id: 'recordId', title: 'Record ID', type: 'short-input', required: true, - placeholder: 'Enter DNS record ID', - condition: { field: 'operation', value: 'update_dns_record' }, + placeholder: 'Enter record id', + condition: { + field: 'operation', + value: ['update_dns_record', 'delete_dns_record', 'get_dns_record'], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare record id value. Return ONLY the value.', + placeholder: 'Describe the record id', + }, }, { id: 'updateRecordType', title: 'Record Type', type: 'dropdown', options: [ - { label: 'No Change', id: '' }, + { label: 'Any / unchanged', id: '' }, { label: 'A', id: 'A' }, { label: 'AAAA', id: 'AAAA' }, + { label: 'CAA', id: 'CAA' }, + { label: 'CERT', id: 'CERT' }, { label: 'CNAME', id: 'CNAME' }, + { label: 'DNSKEY', id: 'DNSKEY' }, + { label: 'DS', id: 'DS' }, + { label: 'HTTPS', id: 'HTTPS' }, + { label: 'LOC', id: 'LOC' }, { label: 'MX', id: 'MX' }, - { label: 'TXT', id: 'TXT' }, + { label: 'NAPTR', id: 'NAPTR' }, { label: 'NS', id: 'NS' }, + { label: 'OPENPGPKEY', id: 'OPENPGPKEY' }, + { label: 'PTR', id: 'PTR' }, + { label: 'SMIMEA', id: 'SMIMEA' }, { label: 'SRV', id: 'SRV' }, + { label: 'SSHFP', id: 'SSHFP' }, + { label: 'SVCB', id: 'SVCB' }, + { label: 'TLSA', id: 'TLSA' }, + { label: 'TXT', id: 'TXT' }, + { label: 'URI', id: 'URI' }, ], value: () => '', condition: { field: 'operation', value: 'update_dns_record' }, mode: 'advanced', }, { - /** - * Renaming a live DNS record is a write, and this control is advanced, so - * sharing the bare `name` id let a name typed under any other operation - * reach the PATCH and rename the record. - */ id: 'updateRecordName', title: 'Record Name', type: 'short-input', placeholder: 'e.g., example.com or sub.example.com', condition: { field: 'operation', value: 'update_dns_record' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare record name value. Return ONLY the value.', + placeholder: 'Describe the record name', + }, }, { id: 'updateRecordContent', @@ -754,14 +1176,11 @@ export const CloudflareBlock: BlockConfig = { placeholder: 'e.g., 192.0.2.1', condition: { field: 'operation', value: 'update_dns_record' }, mode: 'advanced', - }, - { - id: 'ttl', - title: 'TTL (seconds)', - type: 'short-input', - placeholder: '1 (automatic)', - condition: { field: 'operation', value: 'update_dns_record' }, - mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare new content value. Return ONLY the value.', + placeholder: 'Describe the new content', + }, }, { id: 'updateRecordProxied', @@ -776,22 +1195,6 @@ export const CloudflareBlock: BlockConfig = { condition: { field: 'operation', value: 'update_dns_record' }, mode: 'advanced', }, - { - id: 'priority', - title: 'Priority', - type: 'short-input', - placeholder: 'MX/URI priority (e.g., 10)', - condition: { field: 'operation', value: 'update_dns_record' }, - mode: 'advanced', - }, - { - id: 'comment', - title: 'Comment', - type: 'short-input', - placeholder: 'Optional comment', - condition: { field: 'operation', value: 'update_dns_record' }, - mode: 'advanced', - }, { id: 'updateRecordTags', title: 'Tags', @@ -799,34 +1202,11 @@ export const CloudflareBlock: BlockConfig = { placeholder: 'Comma-separated tags (e.g., production,web)', condition: { field: 'operation', value: 'update_dns_record' }, mode: 'advanced', - }, - - // Delete DNS Record inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'delete_dns_record' }, - }, - { - id: 'recordId', - title: 'Record ID', - type: 'short-input', - required: true, - placeholder: 'Enter DNS record ID to delete', - condition: { field: 'operation', value: 'delete_dns_record' }, - }, - - // List Certificates inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'list_certificates' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tags value. Return ONLY the value.', + placeholder: 'Describe the tags', + }, }, { id: 'certificateStatus', @@ -840,22 +1220,6 @@ export const CloudflareBlock: BlockConfig = { condition: { field: 'operation', value: 'list_certificates' }, mode: 'advanced', }, - { - id: 'page', - title: 'Page', - type: 'short-input', - placeholder: 'Page number (default: 1)', - condition: { field: 'operation', value: 'list_certificates' }, - mode: 'advanced', - }, - { - id: 'per_page', - title: 'Per Page', - type: 'short-input', - placeholder: 'Results per page (default: 20, min: 5, max: 50)', - condition: { field: 'operation', value: 'list_certificates' }, - mode: 'advanced', - }, { id: 'deploy', title: 'Environment', @@ -869,38 +1233,18 @@ export const CloudflareBlock: BlockConfig = { condition: { field: 'operation', value: 'list_certificates' }, mode: 'advanced', }, - - // Get Zone Settings inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'get_zone_settings' }, - }, { - /** - * Cloudflare retired the endpoint that read every setting in one request, - * so this operation reads one setting per request. Naming the settings - * keeps the fan-out to what the workflow actually reads. - */ id: 'settingIds', title: 'Settings', type: 'short-input', placeholder: 'Comma-separated setting IDs (blank reads the default set)', condition: { field: 'operation', value: 'get_zone_settings' }, mode: 'advanced', - }, - - // Update Zone Setting inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'update_zone_setting' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare settings value. Return ONLY the value.', + placeholder: 'Describe the settings', + }, }, { id: 'settingId', @@ -929,47 +1273,16 @@ export const CloudflareBlock: BlockConfig = { id: 'value', title: 'Value', type: 'short-input', - required: true, + required: { field: 'settingId', value: 'ssl_recommender', not: true }, placeholder: 'e.g., full, strict, on, off, medium', condition: { field: 'operation', value: 'update_zone_setting' }, wandConfig: { enabled: true, - prompt: `Generate the correct value for a Cloudflare zone setting based on the user's description. - -Common settings and their valid values: -- ssl: "off", "flexible", "full", "strict" -- always_use_https: "on", "off" -- security_level: "off", "essentially_off", "low", "medium", "high", "under_attack" -- cache_level: "aggressive", "basic", "simplified" -- browser_cache_ttl: number in seconds (e.g., 14400 for 4 hours, 86400 for 1 day) -- rocket_loader: "on", "off" -- email_obfuscation: "on", "off" -- hotlink_protection: "on", "off" -- ip_geolocation: "on", "off" -- http2: "on", "off" -- http3: "on", "off" -- websockets: "on", "off" -- tls_1_3: "on", "off", "zrt" -- min_tls_version: "1.0", "1.1", "1.2", "1.3" - -For simple string/boolean settings, return the plain value (e.g., "full", "on"). -For numeric settings like browser_cache_ttl, return the number (e.g., 14400). - -Return ONLY the value - no explanations, no extra text.`, - placeholder: - 'Describe the setting value (e.g., "enable strict SSL", "cache everything")...', + prompt: + 'Generate the correct value for a Cloudflare zone setting based on the user\'s description.\n\nCommon settings and their valid values:\n- ssl: "off", "flexible", "full", "strict"\n- always_use_https: "on", "off"\n- security_level: "off", "essentially_off", "low", "medium", "high", "under_attack"\n- cache_level: "aggressive", "basic", "simplified"\n- browser_cache_ttl: number in seconds (e.g., 14400 for 4 hours, 86400 for 1 day)\n- rocket_loader: "on", "off"\n- email_obfuscation: "on", "off"\n- hotlink_protection: "on", "off"\n- ip_geolocation: "on", "off"\n- http2: "on", "off"\n- http3: "on", "off"\n- websockets: "on", "off"\n- tls_1_3: "on", "off", "zrt"\n- min_tls_version: "1.0", "1.1", "1.2", "1.3"\n\nFor simple string/boolean settings, return the plain value (e.g., "full", "on").\nFor numeric settings like browser_cache_ttl, return the number (e.g., 14400).\n\nReturn ONLY the value - no explanations, no extra text.', + placeholder: 'Describe the value', }, }, - - // DNS Analytics inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'dns_analytics' }, - }, { id: 'since', title: 'Start Date', @@ -978,21 +1291,12 @@ Return ONLY the value - no explanations, no extra text.`, condition: { field: 'operation', value: 'dns_analytics' }, wandConfig: { enabled: true, - prompt: `Generate a timestamp or relative time expression for the Cloudflare DNS Analytics API based on the user's description. -Cloudflare accepts either ISO 8601 timestamps (e.g., 2024-01-01T00:00:00Z) or relative expressions (e.g., -6h, -7d, -30d). -Examples: -- "last 6 hours" -> -6h -- "last 24 hours" -> -24h -- "last 7 days" -> -7d -- "last 30 days" -> -30d -- "since January 1st 2024" -> 2024-01-01T00:00:00Z -- "beginning of this month" -> First day of current month at 00:00:00Z -- "1 hour ago" -> -1h - -Return ONLY the timestamp or relative expression - no explanations, no quotes, no extra text.`, - placeholder: 'Describe the start time (e.g., "last 7 days", "since January 1st")...', + prompt: + 'Generate a timestamp or relative time expression for the Cloudflare DNS Analytics API based on the user\'s description.\nCloudflare accepts either ISO 8601 timestamps (e.g., 2024-01-01T00:00:00Z) or relative expressions (e.g., -6h, -7d, -30d).\nExamples:\n- "last 6 hours" -> -6h\n- "last 24 hours" -> -24h\n- "last 7 days" -> -7d\n- "last 30 days" -> -30d\n- "since January 1st 2024" -> 2024-01-01T00:00:00Z\n- "beginning of this month" -> First day of current month at 00:00:00Z\n- "1 hour ago" -> -1h\n\nReturn ONLY the timestamp or relative expression - no explanations, no quotes, no extra text.', + placeholder: 'Describe the start date', generationType: 'timestamp', }, + mode: 'advanced', }, { id: 'until', @@ -1002,18 +1306,12 @@ Return ONLY the timestamp or relative expression - no explanations, no quotes, n condition: { field: 'operation', value: 'dns_analytics' }, wandConfig: { enabled: true, - prompt: `Generate a timestamp or relative time expression for the Cloudflare DNS Analytics API based on the user's description. -Cloudflare accepts either ISO 8601 timestamps (e.g., 2024-01-31T23:59:59Z) or relative expressions (e.g., now). -Examples: -- "now" -> now -- "today" -> Today's date at 23:59:59Z -- "end of yesterday" -> Yesterday's date at 23:59:59Z -- "end of last month" -> Last day of previous month at 23:59:59Z - -Return ONLY the timestamp or relative expression - no explanations, no quotes, no extra text.`, - placeholder: 'Describe the end time (e.g., "now", "end of yesterday")...', + prompt: + 'Generate a timestamp or relative time expression for the Cloudflare DNS Analytics API based on the user\'s description.\nCloudflare accepts either ISO 8601 timestamps (e.g., 2024-01-31T23:59:59Z) or relative expressions (e.g., now).\nExamples:\n- "now" -> now\n- "today" -> Today\'s date at 23:59:59Z\n- "end of yesterday" -> Yesterday\'s date at 23:59:59Z\n- "end of last month" -> Last day of previous month at 23:59:59Z\n\nReturn ONLY the timestamp or relative expression - no explanations, no quotes, no extra text.', + placeholder: 'Describe the end date', generationType: 'timestamp', }, + mode: 'advanced', }, { id: 'metrics', @@ -1023,25 +1321,9 @@ Return ONLY the timestamp or relative expression - no explanations, no quotes, n condition: { field: 'operation', value: 'dns_analytics' }, wandConfig: { enabled: true, - prompt: `Generate a comma-separated list of Cloudflare DNS Analytics metrics based on the user's description. - -Available metrics: -- queryCount: Total number of DNS queries -- uncachedCount: Number of DNS queries not served from cache -- staleCount: Number of stale DNS responses served -- responseTimeAvg: Average response time in milliseconds -- responseTimeMedian: Median response time in milliseconds -- responseTime90th: 90th percentile response time -- responseTime99th: 99th percentile response time - -Examples: -- "query counts" -> queryCount -- "all query metrics" -> queryCount,uncachedCount,staleCount -- "response times" -> responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th -- "everything" -> queryCount,uncachedCount,staleCount,responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th - -Return ONLY the comma-separated metric names - no explanations, no quotes, no extra text.`, - placeholder: 'Describe what to measure (e.g., "query counts and response times")...', + prompt: + 'Generate a comma-separated list of Cloudflare DNS Analytics metrics based on the user\'s description.\n\nAvailable metrics:\n- queryCount: Total number of DNS queries\n- uncachedCount: Number of DNS queries not served from cache\n- staleCount: Number of stale DNS responses served\n- responseTimeAvg: Average response time in milliseconds\n- responseTimeMedian: Median response time in milliseconds\n- responseTime90th: 90th percentile response time\n- responseTime99th: 99th percentile response time\n\nExamples:\n- "query counts" -> queryCount\n- "all query metrics" -> queryCount,uncachedCount,staleCount\n- "response times" -> responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th\n- "everything" -> queryCount,uncachedCount,staleCount,responseTimeAvg,responseTimeMedian,responseTime90th,responseTime99th\n\nReturn ONLY the comma-separated metric names - no explanations, no quotes, no extra text.', + placeholder: 'Describe the metrics', }, }, { @@ -1053,27 +1335,9 @@ Return ONLY the comma-separated metric names - no explanations, no quotes, no ex mode: 'advanced', wandConfig: { enabled: true, - prompt: `Generate a comma-separated list of Cloudflare DNS Analytics dimensions based on the user's description. - -Available dimensions: -- queryName: DNS record name being queried -- queryType: DNS query type (A, AAAA, CNAME, MX, etc.) -- responseCode: DNS response code (NOERROR, NXDOMAIN, SERVFAIL, etc.) -- responseCached: Whether the response was cached -- coloName: Cloudflare data center handling the query -- origin: Origin server -- dayOfWeek: Day of the week -- tcp: Whether the query used TCP -- ipVersion: IP version (4 or 6) - -Examples: -- "by record type" -> queryType -- "by record name and type" -> queryName,queryType -- "by data center" -> coloName -- "by response code and cache status" -> responseCode,responseCached - -Return ONLY the comma-separated dimension names - no explanations, no quotes, no extra text.`, - placeholder: 'Describe how to group results (e.g., "by record type and name")...', + prompt: + 'Generate a comma-separated list of Cloudflare DNS Analytics dimensions based on the user\'s description.\n\nAvailable dimensions:\n- queryName: DNS record name being queried\n- queryType: DNS query type (A, AAAA, CNAME, MX, etc.)\n- responseCode: DNS response code (NOERROR, NXDOMAIN, SERVFAIL, etc.)\n- responseCached: Whether the response was cached\n- coloName: Cloudflare data center handling the query\n- origin: Origin server\n- dayOfWeek: Day of the week\n- tcp: Whether the query used TCP\n- ipVersion: IP version (4 or 6)\n\nExamples:\n- "by record type" -> queryType\n- "by record name and type" -> queryName,queryType\n- "by data center" -> coloName\n- "by response code and cache status" -> responseCode,responseCached\n\nReturn ONLY the comma-separated dimension names - no explanations, no quotes, no extra text.', + placeholder: 'Describe the dimensions', }, }, { @@ -1085,29 +1349,9 @@ Return ONLY the comma-separated dimension names - no explanations, no quotes, no mode: 'advanced', wandConfig: { enabled: true, - prompt: `Generate a Cloudflare DNS Analytics filter expression based on the user's description. - -Filter syntax: field==value or field!=value -Multiple filters can be combined with semicolons: field1==value1;field2==value2 - -Available filter fields: -- queryType: DNS record type (A, AAAA, CNAME, MX, TXT, NS, SRV, etc.) -- queryName: DNS record name -- responseCode: DNS response code (NOERROR, NXDOMAIN, SERVFAIL, REFUSED) -- responseCached: Whether cached (0 or 1) -- coloName: Data center name -- origin: Origin server - -Examples: -- "only A records" -> queryType==A -- "only CNAME records" -> queryType==CNAME -- "failed queries" -> responseCode==SERVFAIL -- "non-existent domains" -> responseCode==NXDOMAIN -- "A records that weren't cached" -> queryType==A;responseCached==0 -- "queries for example.com" -> queryName==example.com - -Return ONLY the filter expression - no explanations, no quotes, no extra text.`, - placeholder: 'Describe what to filter (e.g., "only A records", "failed queries")...', + prompt: + 'Generate a Cloudflare DNS Analytics filter expression based on the user\'s description.\n\nFilter syntax: field==value or field!=value\nMultiple filters can be combined with semicolons: field1==value1;field2==value2\n\nAvailable filter fields:\n- queryType: DNS record type (A, AAAA, CNAME, MX, TXT, NS, SRV, etc.)\n- queryName: DNS record name\n- responseCode: DNS response code (NOERROR, NXDOMAIN, SERVFAIL, REFUSED)\n- responseCached: Whether cached (0 or 1)\n- coloName: Data center name\n- origin: Origin server\n\nExamples:\n- "only A records" -> queryType==A\n- "only CNAME records" -> queryType==CNAME\n- "failed queries" -> responseCode==SERVFAIL\n- "non-existent domains" -> responseCode==NXDOMAIN\n- "A records that weren\'t cached" -> queryType==A;responseCached==0\n- "queries for example.com" -> queryName==example.com\n\nReturn ONLY the filter expression - no explanations, no quotes, no extra text.', + placeholder: 'Describe the filters', }, }, { @@ -1117,6 +1361,11 @@ Return ONLY the filter expression - no explanations, no quotes, no extra text.`, placeholder: 'e.g., +queryCount or -responseTimeAvg', condition: { field: 'operation', value: 'dns_analytics' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare sort value. Return ONLY the value.', + placeholder: 'Describe the sort', + }, }, { id: 'limit', @@ -1125,16 +1374,11 @@ Return ONLY the filter expression - no explanations, no quotes, no extra text.`, placeholder: 'Max results (e.g., 100)', condition: { field: 'operation', value: 'dns_analytics' }, mode: 'advanced', - }, - - // Purge Cache inputs - { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { field: 'operation', value: 'purge_cache' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare limit value. Return ONLY the value.', + placeholder: 'Describe the limit', + }, }, { id: 'purge_everything', @@ -1160,149 +1404,97 @@ Return ONLY the filter expression - no explanations, no quotes, no extra text.`, }, wandConfig: { enabled: true, - prompt: `Generate a comma-separated list of URLs to purge from Cloudflare's cache based on the user's description. - -Each URL should be a full URL including the protocol (https://). -Examples: -- "the homepage and about page of example.com" -> https://example.com/, https://example.com/about -- "all CSS and JS files" -> https://example.com/style.css, https://example.com/app.js -- "the API endpoint" -> https://example.com/api/v1/data - -Return ONLY the comma-separated URLs - no explanations, no extra text.`, - placeholder: 'Describe what to purge (e.g., "homepage and CSS files")...', + prompt: + 'Generate a comma-separated list of URLs to purge from Cloudflare\'s cache based on the user\'s description.\n\nEach URL should be a full URL including the protocol (https://).\nExamples:\n- "the homepage and about page of example.com" -> https://example.com/, https://example.com/about\n- "all CSS and JS files" -> https://example.com/style.css, https://example.com/app.js\n- "the API endpoint" -> https://example.com/api/v1/data\n\nReturn ONLY the comma-separated URLs - no explanations, no extra text.', + placeholder: 'Describe the files to purge', }, }, { id: 'tags', title: 'Cache Tags', type: 'short-input', - placeholder: 'Comma-separated cache tags (Enterprise only)', + placeholder: 'Comma-separated cache tags', condition: { field: 'operation', value: 'purge_cache', and: { field: 'purge_everything', value: 'true', not: true }, }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare cache tags value. Return ONLY the value.', + placeholder: 'Describe the cache tags', + }, }, { id: 'hosts', title: 'Hostnames', type: 'short-input', - placeholder: 'Comma-separated hostnames (Enterprise only)', + placeholder: 'Comma-separated hostnames', condition: { field: 'operation', value: 'purge_cache', and: { field: 'purge_everything', value: 'true', not: true }, }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare hostnames value. Return ONLY the value.', + placeholder: 'Describe the hostnames', + }, }, { id: 'prefixes', title: 'URL Prefixes', type: 'short-input', - placeholder: 'Comma-separated URL prefixes (Enterprise only)', + placeholder: 'Comma-separated URL prefixes', condition: { field: 'operation', value: 'purge_cache', and: { field: 'purge_everything', value: 'true', not: true }, }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare url prefixes value. Return ONLY the value.', + placeholder: 'Describe the url prefixes', + }, }, - - // Zone ID for zone-scoped WAF, rate limiting, and Workers routes operations { - id: 'zoneId', - title: 'Zone ID', - type: 'short-input', - required: true, - placeholder: 'Enter zone ID', - condition: { - field: 'operation', - value: [ - 'list_rulesets', - 'get_ruleset', - 'get_ruleset_entrypoint', - 'create_ruleset', - 'create_ruleset_rule', - 'update_ruleset_rule', - 'delete_ruleset_rule', - 'list_managed_ruleset_overrides', - 'list_rate_limit_rules', - 'create_rate_limit_rule', - 'update_rate_limit_rule', - 'list_worker_routes', - ], - }, - }, - - // Account ID for account-scoped Access, R2, Workers scripts, and Tunnels operations - { - id: 'accountId', - title: 'Account ID', - type: 'short-input', - required: true, - placeholder: 'Enter Cloudflare account ID', - condition: { - field: 'operation', - value: [ - 'list_access_applications', - 'get_access_application', - 'create_access_application', - 'update_access_application', - 'delete_access_application', - 'list_access_policies', - 'create_access_policy', - 'update_access_policy', - 'delete_access_policy', - 'list_access_groups', - 'list_access_identity_providers', - 'list_access_service_tokens', - 'create_access_service_token', - 'revoke_access_service_token', - 'list_r2_buckets', - 'get_r2_bucket', - 'create_r2_bucket', - 'delete_r2_bucket', - 'list_worker_scripts', - 'get_worker_script_settings', - 'list_tunnels', - 'get_tunnel', - 'get_tunnel_configuration', - ], - }, - }, - - // Ruleset inputs - { - id: 'phase', - title: 'Phase', - type: 'dropdown', - options: [ - { label: 'WAF Custom Rules', id: 'http_request_firewall_custom' }, - { label: 'WAF Managed Rules', id: 'http_request_firewall_managed' }, - { label: 'Rate Limiting', id: 'http_ratelimit' }, - { label: 'Request Transform', id: 'http_request_transform' }, - { label: 'Late Request Transform', id: 'http_request_late_transform' }, - { label: 'Dynamic Redirects', id: 'http_request_dynamic_redirect' }, - { label: 'Request Cache Settings', id: 'http_request_cache_settings' }, - { label: 'Config Settings', id: 'http_config_settings' }, - { label: 'Origin', id: 'http_request_origin' }, - { label: 'Response Headers Transform', id: 'http_response_headers_transform' }, - { label: 'Response Compression', id: 'http_response_compression' }, - { label: 'Custom Errors', id: 'http_custom_errors' }, - { label: 'Super Bot Fight Mode', id: 'http_request_sbfm' }, - ], - value: () => 'http_request_firewall_custom', - required: true, - condition: { field: 'operation', value: ['get_ruleset_entrypoint', 'create_ruleset'] }, - }, - { - id: 'rulesetName', - title: 'Ruleset Name', + id: 'phase', + title: 'Phase', + type: 'dropdown', + options: [ + { label: 'WAF Custom Rules', id: 'http_request_firewall_custom' }, + { label: 'WAF Managed Rules', id: 'http_request_firewall_managed' }, + { label: 'Rate Limiting', id: 'http_ratelimit' }, + { label: 'Request Transform', id: 'http_request_transform' }, + { label: 'Late Request Transform', id: 'http_request_late_transform' }, + { label: 'Dynamic Redirects', id: 'http_request_dynamic_redirect' }, + { label: 'Request Cache Settings', id: 'http_request_cache_settings' }, + { label: 'Config Settings', id: 'http_config_settings' }, + { label: 'Origin', id: 'http_request_origin' }, + { label: 'Response Headers Transform', id: 'http_response_headers_transform' }, + { label: 'Response Compression', id: 'http_response_compression' }, + { label: 'Custom Errors', id: 'http_custom_errors' }, + { label: 'Super Bot Fight Mode', id: 'http_request_sbfm' }, + ], + value: () => 'http_request_firewall_custom', + required: true, + condition: { field: 'operation', value: ['get_ruleset_entrypoint', 'create_ruleset'] }, + }, + { + id: 'rulesetName', + title: 'Ruleset Name', type: 'short-input', required: true, placeholder: 'e.g. Zone rate limiting ruleset', condition: { field: 'operation', value: 'create_ruleset' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare ruleset name value. Return ONLY the value.', + placeholder: 'Describe the ruleset name', + }, }, { id: 'kind', @@ -1326,22 +1518,9 @@ Return ONLY the comma-separated URLs - no explanations, no extra text.`, wandConfig: { enabled: true, maintainHistory: true, - prompt: `Generate a Cloudflare ruleset rules array from the user's description. - -Each rule is an object with: -- "action": the action to take, e.g. "block", "challenge", "managed_challenge", "js_challenge", "log", "skip", "execute" -- "expression": a Cloudflare filter expression selecting matching requests -- "description": optional human-readable description -- "enabled": optional boolean, defaults to true - -A rate limiting rule (http_ratelimit phase) also takes "ratelimit" with "characteristics", "period", and "requests_per_period". - -Examples: -- "block traffic from Russia" -> [{"action":"block","expression":"(ip.geoip.country eq \\"RU\\")","description":"Block RU"}] -- "rate limit the login endpoint to 10 requests a minute per IP" -> [{"action":"block","expression":"(http.request.uri.path eq \\"/login\\")","description":"Login rate limit","ratelimit":{"characteristics":["ip.src","cf.colo.id"],"period":60,"requests_per_period":10}}] - -Return ONLY the JSON array - no explanations, no markdown fences.`, - placeholder: 'Describe the rules to seed this ruleset with...', + prompt: + 'Generate a Cloudflare ruleset rules array from the user\'s description.\n\nEach rule is an object with:\n- "action": the action to take, e.g. "block", "challenge", "managed_challenge", "js_challenge", "log", "skip", "execute"\n- "expression": a Cloudflare filter expression selecting matching requests\n- "description": optional human-readable description\n- "enabled": optional boolean, defaults to true\n\nA rate limiting rule (http_ratelimit phase) also takes "ratelimit" with "characteristics", "period", and "requests_per_period".\n\nExamples:\n- "block traffic from Russia" -> [{"action":"block","expression":"(ip.geoip.country eq \\"RU\\")","description":"Block RU"}]\n- "rate limit the login endpoint to 10 requests a minute per IP" -> [{"action":"block","expression":"(http.request.uri.path eq \\"/login\\")","description":"Login rate limit","ratelimit":{"characteristics":["ip.src","cf.colo.id"],"period":60,"requests_per_period":10}}]\n\nReturn ONLY the JSON array - no explanations, no markdown fences.', + placeholder: 'Describe the initial rules', generationType: 'json-array', }, }, @@ -1350,21 +1529,24 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, title: 'Ruleset ID', type: 'short-input', required: true, - placeholder: 'From "List Rulesets" or "Get Phase Entry Point Ruleset"', + placeholder: 'Enter ruleset id', condition: { field: 'operation', - value: ['get_ruleset', 'create_ruleset_rule', 'update_ruleset_rule', 'delete_ruleset_rule'], + value: [ + 'get_ruleset', + 'create_ruleset_rule', + 'update_ruleset_rule', + 'delete_ruleset_rule', + 'create_rate_limit_rule', + 'update_rate_limit_rule', + 'delete_ruleset', + 'update_ruleset', + ], }, - }, - { - id: 'rulesetId', - title: 'Rate Limiting Ruleset ID', - type: 'short-input', - required: true, - placeholder: 'From "List Rate Limiting Rules"', - condition: { - field: 'operation', - value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare ruleset id value. Return ONLY the value.', + placeholder: 'Describe the ruleset id', }, }, { @@ -1377,19 +1559,23 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, field: 'operation', value: ['update_ruleset_rule', 'delete_ruleset_rule', 'update_rate_limit_rule'], }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare rule id value. Return ONLY the value.', + placeholder: 'Describe the rule id', + }, }, { id: 'action', title: 'Action', type: 'short-input', - required: { - field: 'operation', - value: ['create_ruleset_rule', 'update_ruleset_rule'], - }, + required: { field: 'operation', value: ['create_ruleset_rule', 'update_ruleset_rule'] }, placeholder: 'block, challenge, managed_challenge, js_challenge, log, skip, execute', - condition: { - field: 'operation', - value: ['create_ruleset_rule', 'update_ruleset_rule'], + condition: { field: 'operation', value: ['create_ruleset_rule', 'update_ruleset_rule'] }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare action value. Return ONLY the value.', + placeholder: 'Describe the action', }, }, { @@ -1407,12 +1593,6 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, condition: { field: 'operation', value: 'create_rate_limit_rule' }, }, { - /** - * The update endpoint replaces the rule, so a seeded action would rewrite - * whatever the rule currently does the moment anything else is edited. - * This control carries no default: the user has to state the action the - * replaced rule should end up with. - */ id: 'updateRateLimitAction', title: 'Action', type: 'dropdown', @@ -1451,27 +1631,9 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, }, wandConfig: { enabled: true, - prompt: `Generate a Cloudflare Ruleset Engine filter expression from the user's description. - -Syntax uses fields, operators, and logical connectors: -- ip.src, ip.src.country, ip.src.asnum -- http.host, http.request.uri.path, http.request.uri.query, http.request.method -- http.user_agent, http.referer -- cf.threat_score, cf.bot_management.score, cf.client.bot -- ssl - -Operators: eq, ne, lt, gt, contains, matches (regex), in { } -Connectors: and, or, not, with parentheses - -Examples: -- "block traffic from the UK and France" -> (ip.src.country in {"GB" "FR"}) -- "everything under /api" -> (http.request.uri.path matches "^/api/") -- "the login page from non-verified bots" -> (http.request.uri.path eq "/login" and cf.client.bot) -- "all requests" -> true - -Return ONLY the expression - no explanations, no quotes around the whole expression, no extra text.`, - placeholder: - 'Describe the traffic to match (e.g., "requests to /api from outside the US")...', + prompt: + 'Generate a Cloudflare Ruleset Engine filter expression from the user\'s description.\n\nSyntax uses fields, operators, and logical connectors:\n- ip.src, ip.src.country, ip.src.asnum\n- http.host, http.request.uri.path, http.request.uri.query, http.request.method\n- http.user_agent, http.referer\n- cf.threat_score, cf.bot_management.score, cf.client.bot\n- ssl\n\nOperators: eq, ne, lt, gt, contains, matches (regex), in { }\nConnectors: and, or, not, with parentheses\n\nExamples:\n- "block traffic from the UK and France" -> (ip.src.country in {"GB" "FR"})\n- "everything under /api" -> (http.request.uri.path matches "^/api/")\n- "the login page from non-verified bots" -> (http.request.uri.path eq "/login" and cf.client.bot)\n- "all requests" -> true\n\nReturn ONLY the expression - no explanations, no quotes around the whole expression, no extra text.', + placeholder: 'Describe the expression', }, }, { @@ -1489,6 +1651,11 @@ Return ONLY the expression - no explanations, no quotes around the whole express 'update_rate_limit_rule', ], }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare description value. Return ONLY the value.', + placeholder: 'Describe the description', + }, }, { id: 'enabled', @@ -1500,34 +1667,20 @@ Return ONLY the expression - no explanations, no quotes around the whole express { label: 'No', id: 'false' }, ], value: () => '', - condition: { - field: 'operation', - value: ['create_ruleset_rule', 'create_rate_limit_rule'], - }, + condition: { field: 'operation', value: ['create_ruleset_rule', 'create_rate_limit_rule'] }, mode: 'advanced', }, { - /** - * The update endpoints replace the rule, so `enabled` is a live on/off - * switch for WAF and rate limiting there rather than a starting state. - * Sharing the create control's id let a `false` chosen while drafting a - * new rule reach a later update and disable an enforcing rule — from a - * field the operation does not render in basic mode, since an advanced - * control serializes on stored value alone, before its `condition` runs. - */ id: 'updateRuleEnabled', title: 'Enabled', type: 'dropdown', options: [ - { label: 'Leave unchanged (Cloudflare re-enables the rule)', id: '' }, + { label: 'Default (enabled)', id: '' }, { label: 'Yes', id: 'true' }, { label: 'No', id: 'false' }, ], value: () => '', - condition: { - field: 'operation', - value: ['update_ruleset_rule', 'update_rate_limit_rule'], - }, + condition: { field: 'operation', value: ['update_ruleset_rule', 'update_rate_limit_rule'] }, mode: 'advanced', }, { @@ -1540,6 +1693,11 @@ Return ONLY the expression - no explanations, no quotes around the whole express value: ['create_ruleset_rule', 'update_ruleset_rule', 'update_rate_limit_rule'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare reference tag value. Return ONLY the value.', + placeholder: 'Describe the reference tag', + }, }, { id: 'ratelimit', @@ -1549,55 +1707,37 @@ Return ONLY the expression - no explanations, no quotes around the whole express '{"characteristics":["cf.colo.id","ip.src"],"period":60,"requests_per_period":100}', condition: { field: 'operation', value: 'update_ruleset_rule' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare rate limiting configuration value. Return ONLY the value.', + placeholder: 'Describe the rate limiting configuration', + }, }, { id: 'logging', title: 'Logging Configuration', type: 'long-input', placeholder: '{"enabled":true}', - condition: { - field: 'operation', - value: ['update_ruleset_rule', 'update_rate_limit_rule'], - }, + condition: { field: 'operation', value: ['update_ruleset_rule', 'update_rate_limit_rule'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare logging configuration value. Return ONLY the value.', + placeholder: 'Describe the logging configuration', + }, }, { id: 'actionParameters', title: 'Action Parameters', type: 'long-input', - /** - * An `execute` rule carries the managed ruleset it deploys here, and the - * update endpoint replaces the rule — so leaving this blank resets - * action_parameters to {} and unbinds that ruleset. - */ required: { field: 'action', value: 'execute' }, placeholder: '{"id":"","overrides":{"action":"log"}}', - condition: { - field: 'operation', - value: ['create_ruleset_rule', 'update_ruleset_rule'], - }, + condition: { field: 'operation', value: ['create_ruleset_rule', 'update_ruleset_rule'] }, wandConfig: { enabled: true, - prompt: `Generate the JSON action_parameters object for a Cloudflare ruleset rule from the user's description. - -For an "execute" rule that deploys a WAF managed ruleset: -{"id":""} - -To override the whole managed ruleset: -{"id":"","overrides":{"action":"log"}} - -To override specific categories: -{"id":"","overrides":{"categories":[{"category":"wordpress","action":"block","enabled":true}]}} - -To override specific rules: -{"id":"","overrides":{"rules":[{"id":"","action":"log","enabled":true}]}} - -"action" and "enabled" are overridable at every level. Individual managed rulesets may accept more: an OWASP Core Ruleset rule override also takes "score_threshold", e.g. -{"id":"","overrides":{"rules":[{"id":"","score_threshold":60,"action":"managed_challenge"}]}} - -Return ONLY the JSON object - no explanations, no markdown fences.`, - placeholder: - 'Describe the action parameters (e.g., "deploy the Cloudflare Managed Ruleset in log mode")...', + prompt: + 'Generate the JSON action_parameters object for a Cloudflare ruleset rule from the user\'s description.\n\nFor an "execute" rule that deploys a WAF managed ruleset:\n{"id":""}\n\nTo override the whole managed ruleset:\n{"id":"","overrides":{"action":"log"}}\n\nTo override specific categories:\n{"id":"","overrides":{"categories":[{"category":"wordpress","action":"block","enabled":true}]}}\n\nTo override specific rules:\n{"id":"","overrides":{"rules":[{"id":"","action":"log","enabled":true}]}}\n\n"action" and "enabled" are overridable at every level. Individual managed rulesets may accept more: an OWASP Core Ruleset rule override also takes "score_threshold", e.g.\n{"id":"","overrides":{"rules":[{"id":"","score_threshold":60,"action":"managed_challenge"}]}}\n\nReturn ONLY the JSON object - no explanations, no markdown fences.', + placeholder: 'Describe the action parameters', generationType: 'json-object', }, }, @@ -1608,17 +1748,17 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, placeholder: '{"index":1} or {"before":""} or {"after":""}', condition: { field: 'operation', value: 'create_ruleset_rule' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare position value. Return ONLY the value.', + placeholder: 'Describe the position', + }, }, - - // Rate limiting inputs { id: 'characteristics', title: 'Characteristics', type: 'short-input', - required: { - field: 'operation', - value: ['create_rate_limit_rule', 'update_rate_limit_rule'], - }, + required: { field: 'operation', value: ['create_rate_limit_rule', 'update_rate_limit_rule'] }, placeholder: 'cf.colo.id,ip.src', condition: { field: 'operation', @@ -1626,33 +1766,9 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, }, wandConfig: { enabled: true, - prompt: `Generate a comma-separated list of Cloudflare rate limiting counting characteristics from the user's description. - -cf.colo.id is mandatory in every list. ip.src and cf.unique_visitor_id are mutually exclusive - include at most one, and neither is required. Do not add an IP or visitor characteristic the user did not ask for; a rule keyed on host, path, country, header, cookie or JA3/JA4 alone is valid. - -Available characteristics: -- cf.colo.id (mandatory) -- ip.src -- cf.unique_visitor_id -- http.host -- http.request.uri.path -- ip.src.asnum -- ip.src.country -- http.request.headers[""] -- http.request.cookies[""] -- http.request.uri.args[""] -- cf.bot_management.ja3_hash -- cf.bot_management.ja4 - -Examples: -- "per IP address" -> cf.colo.id,ip.src -- "per visitor" -> cf.colo.id,cf.unique_visitor_id -- "per API key header" -> cf.colo.id,http.request.headers["x-api-key"] -- "per country" -> cf.colo.id,ip.src.country - -Return ONLY the comma-separated list - no explanations, no extra text.`, - placeholder: - 'Describe how to group counters (e.g., "per IP address", "per API key header")...', + prompt: + 'Generate a comma-separated list of Cloudflare rate limiting counting characteristics from the user\'s description.\n\ncf.colo.id is mandatory in every list. ip.src and cf.unique_visitor_id are mutually exclusive - include at most one, and neither is required. Do not add an IP or visitor characteristic the user did not ask for; a rule keyed on host, path, country, header, cookie or JA3/JA4 alone is valid.\n\nAvailable characteristics:\n- cf.colo.id (mandatory)\n- ip.src\n- cf.unique_visitor_id\n- http.host\n- http.request.uri.path\n- ip.src.asnum\n- ip.src.country\n- http.request.headers[""]\n- http.request.cookies[""]\n- http.request.uri.args[""]\n- cf.bot_management.ja3_hash\n- cf.bot_management.ja4\n\nExamples:\n- "per IP address" -> cf.colo.id,ip.src\n- "per visitor" -> cf.colo.id,cf.unique_visitor_id\n- "per API key header" -> cf.colo.id,http.request.headers["x-api-key"]\n- "per country" -> cf.colo.id,ip.src.country\n\nReturn ONLY the comma-separated list - no explanations, no extra text.', + placeholder: 'Describe the characteristics', }, }, { @@ -1668,10 +1784,7 @@ Return ONLY the comma-separated list - no explanations, no extra text.`, { label: '1 hour', id: '3600' }, ], value: () => '60', - required: { - field: 'operation', - value: ['create_rate_limit_rule', 'update_rate_limit_rule'], - }, + required: { field: 'operation', value: ['create_rate_limit_rule', 'update_rate_limit_rule'] }, condition: { field: 'operation', value: ['create_rate_limit_rule', 'update_rate_limit_rule'], @@ -1681,15 +1794,17 @@ Return ONLY the comma-separated list - no explanations, no extra text.`, id: 'requestsPerPeriod', title: 'Requests Per Period', type: 'short-input', - required: { - field: 'operation', - value: ['create_rate_limit_rule', 'update_rate_limit_rule'], - }, + required: { field: 'operation', value: ['create_rate_limit_rule', 'update_rate_limit_rule'] }, placeholder: 'e.g., 100', condition: { field: 'operation', value: ['create_rate_limit_rule', 'update_rate_limit_rule'], }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare requests per period value. Return ONLY the value.', + placeholder: 'Describe the requests per period', + }, }, { id: 'mitigationTimeout', @@ -1723,6 +1838,11 @@ Return ONLY the comma-separated list - no explanations, no extra text.`, value: ['create_rate_limit_rule', 'update_rate_limit_rule'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare counting expression value. Return ONLY the value.', + placeholder: 'Describe the counting expression', + }, }, { id: 'requestsToOrigin', @@ -1741,13 +1861,6 @@ Return ONLY the comma-separated list - no explanations, no extra text.`, mode: 'advanced', }, { - /** - * A rate limiting rule carries its custom mitigation response here, and - * the update endpoint replaces the rule — so leaving this blank resets - * action_parameters to {} and the rule falls back to Cloudflare's default - * block page. It gets its own id because the WAF control of the same name - * holds a managed-ruleset payload, which is not what this rule takes. - */ id: 'rateLimitActionParameters', title: 'Action Parameters', type: 'long-input', @@ -1756,25 +1869,13 @@ Return ONLY the comma-separated list - no explanations, no extra text.`, condition: { field: 'operation', value: 'update_rate_limit_rule' }, wandConfig: { enabled: true, - prompt: `Generate the JSON action_parameters object for a Cloudflare rate limiting rule from the user's description. - -Only a "block" action takes action_parameters, and only to define a custom response: -{"response":{"status_code":429,"content":"You have been rate limited.","content_type":"text/plain"}} - -status_code must be in the 400-499 range. content_type is one of "text/plain", "text/html", or "application/json". For a JSON body, "content" is the JSON payload as a string: -{"response":{"status_code":429,"content":"{\\"error\\":\\"rate limited\\"}","content_type":"application/json"}} - -Challenge and log actions take no action_parameters - return {} for those. - -Return ONLY the JSON object - no explanations, no markdown fences.`, - placeholder: - 'Describe the mitigation response (e.g., "return a 429 with a JSON error body")...', + prompt: + 'Generate the JSON action_parameters object for a Cloudflare rate limiting rule from the user\'s description.\n\nOnly a "block" action takes action_parameters, and only to define a custom response:\n{"response":{"status_code":429,"content":"You have been rate limited.","content_type":"text/plain"}}\n\nstatus_code must be in the 400-499 range. content_type is one of "text/plain", "text/html", or "application/json". For a JSON body, "content" is the JSON payload as a string:\n{"response":{"status_code":429,"content":"{\\"error\\":\\"rate limited\\"}","content_type":"application/json"}}\n\nChallenge and log actions take no action_parameters - return {} for those.\n\nReturn ONLY the JSON object - no explanations, no markdown fences.', + placeholder: 'Describe the action parameters', generationType: 'json-object', }, mode: 'advanced', }, - - // Access application inputs { id: 'appId', title: 'Application ID', @@ -1791,14 +1892,21 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, 'create_access_policy', 'update_access_policy', 'delete_access_policy', + 'get_access_policy', ], }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare application id value. Return ONLY the value.', + placeholder: 'Describe the application id', + }, }, { id: 'appType', title: 'Application Type', type: 'dropdown', options: [ + { label: 'End User', id: 'end_user' }, { label: 'Self-Hosted', id: 'self_hosted' }, { label: 'SaaS', id: 'saas' }, { label: 'SSH', id: 'ssh' }, @@ -1818,15 +1926,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, condition: { field: 'operation', value: 'create_access_application' }, }, { - /** - * Updating an Access application replaces it, so a seeded type would - * rewrite what a live application IS as soon as anything else is edited. - * No default: the caller states the type the replaced application keeps. - */ id: 'updateAppType', title: 'Application Type', type: 'dropdown', options: [ + { label: 'End User', id: 'end_user' }, { label: 'Self-Hosted', id: 'self_hosted' }, { label: 'SaaS', id: 'saas' }, { label: 'SSH', id: 'ssh' }, @@ -1857,9 +1961,13 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, field: 'operation', value: ['create_access_application', 'update_access_application'], }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare domain value. Return ONLY the value.', + placeholder: 'Describe the domain', + }, }, { - /** `saas_app` is required on the saas request variant and rejected elsewhere. */ id: 'saasApp', title: 'SaaS Application', type: 'long-input', @@ -1877,9 +1985,13 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: 'saas', and: { field: 'operation', value: 'create_access_application' }, }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare saas application value. Return ONLY the value.', + placeholder: 'Describe the saas application', + }, }, { - /** `target_criteria` is required on the infrastructure and rdp variants. */ id: 'targetCriteria', title: 'Target Criteria', type: 'long-input', @@ -1897,6 +2009,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['infrastructure', 'rdp'], and: { field: 'operation', value: 'create_access_application' }, }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare target criteria value. Return ONLY the value.', + placeholder: 'Describe the target criteria', + }, }, { id: 'accessAppDomainFilter', @@ -1905,15 +2022,10 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, placeholder: 'Filter by the hostname the application secures', condition: { field: 'operation', value: 'list_access_applications' }, mode: 'advanced', - }, - { - id: 'name', - title: 'Application Name', - type: 'short-input', - placeholder: 'Friendly name shown in the dashboard', - condition: { - field: 'operation', - value: ['create_access_application', 'update_access_application'], + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare domain filter value. Return ONLY the value.', + placeholder: 'Describe the domain filter', }, }, { @@ -1931,6 +2043,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, ], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare name filter value. Return ONLY the value.', + placeholder: 'Describe the name filter', + }, }, { id: 'aud', @@ -1939,17 +2056,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, placeholder: 'Filter by application AUD tag', condition: { field: 'operation', value: 'list_access_applications' }, mode: 'advanced', - }, - { - id: 'search', - title: 'Search', - type: 'short-input', - placeholder: 'Free-text search', - condition: { - field: 'operation', - value: ['list_access_applications', 'list_access_groups', 'list_access_service_tokens'], + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare audience tag value. Return ONLY the value.', + placeholder: 'Describe the audience tag', }, - mode: 'advanced', }, { id: 'exact', @@ -1979,6 +2090,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, ], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare session duration value. Return ONLY the value.', + placeholder: 'Describe the session duration', + }, }, { id: 'allowedIdps', @@ -1990,6 +2106,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare allowed identity providers value. Return ONLY the value.', + placeholder: 'Describe the allowed identity providers', + }, }, { id: 'appLauncherVisible', @@ -2033,6 +2154,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare custom deny message value. Return ONLY the value.', + placeholder: 'Describe the custom deny message', + }, }, { id: 'customDenyUrl', @@ -2044,6 +2170,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare custom deny url value. Return ONLY the value.', + placeholder: 'Describe the custom deny url', + }, }, { id: 'logoUrl', @@ -2055,6 +2186,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare logo url value. Return ONLY the value.', + placeholder: 'Describe the logo url', + }, }, { id: 'accessAppTags', @@ -2066,6 +2202,11 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tags value. Return ONLY the value.', + placeholder: 'Describe the tags', + }, }, { id: 'policies', @@ -2077,9 +2218,12 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, value: ['create_access_application', 'update_access_application'], }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare policies value. Return ONLY the value.', + placeholder: 'Describe the policies', + }, }, - - // Access policy inputs { id: 'policyId', title: 'Policy ID', @@ -2088,18 +2232,12 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, placeholder: 'Enter Access policy ID', condition: { field: 'operation', - value: ['update_access_policy', 'delete_access_policy'], + value: ['update_access_policy', 'delete_access_policy', 'get_access_policy'], }, - }, - { - id: 'name', - title: 'Policy Name', - type: 'short-input', - required: true, - placeholder: 'e.g., Allow engineering team', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare policy id value. Return ONLY the value.', + placeholder: 'Describe the policy id', }, }, { @@ -2117,11 +2255,6 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, condition: { field: 'operation', value: 'create_access_policy' }, }, { - /** - * Updating a policy replaces it, so a seeded allow would silently widen a - * live deny, bypass, or non_identity policy the moment its rules are - * edited. No default: the caller states the decision. - */ id: 'updatePolicyDecision', title: 'Decision', type: 'dropdown', @@ -2140,38 +2273,12 @@ Return ONLY the JSON object - no explanations, no markdown fences.`, type: 'long-input', required: true, placeholder: '[{"email_domain":{"domain":"example.com"}}]', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, wandConfig: { enabled: true, - prompt: `Generate a JSON array of Cloudflare Access rules from the user's description. These are evaluated with OR logic. - -Rule shapes: -- {"email":{"email":"user@example.com"}} -- {"email_domain":{"domain":"example.com"}} -- {"email_list":{"id":""}} -- {"everyone":{}} -- {"ip":{"ip":"192.0.2.1/32"}} -- {"ip_list":{"id":""}} -- {"group":{"id":""}} -- {"service_token":{"token_id":""}} -- {"any_valid_service_token":{}} -- {"certificate":{}} -- {"geo":{"country_code":"US"}} -- {"azureAD":{"id":"","connection_id":""}} -- {"okta":{"name":"","connection_id":""}} -- {"gsuite":{"email":"","connection_id":""}} - -Examples: -- "anyone at example.com" -> [{"email_domain":{"domain":"example.com"}}] -- "a specific person" -> [{"email":{"email":"user@example.com"}}] -- "any service token" -> [{"any_valid_service_token":{}}] -- "everyone" -> [{"everyone":{}}] - -Return ONLY the JSON array - no explanations, no markdown fences.`, - placeholder: 'Describe who should match (e.g., "anyone with an @example.com email")...', + prompt: + 'Generate a JSON array of Cloudflare Access rules from the user\'s description. These are evaluated with OR logic.\n\nRule shapes:\n- {"email":{"email":"user@example.com"}}\n- {"email_domain":{"domain":"example.com"}}\n- {"email_list":{"id":""}}\n- {"everyone":{}}\n- {"ip":{"ip":"192.0.2.1/32"}}\n- {"ip_list":{"id":""}}\n- {"group":{"id":""}}\n- {"service_token":{"token_id":""}}\n- {"any_valid_service_token":{}}\n- {"certificate":{}}\n- {"geo":{"country_code":"US"}}\n- {"azureAD":{"id":"","connection_id":""}}\n- {"okta":{"name":"","connection_id":""}}\n- {"gsuite":{"email":"","connection_id":""}}\n\nExamples:\n- "anyone at example.com" -> [{"email_domain":{"domain":"example.com"}}]\n- "a specific person" -> [{"email":{"email":"user@example.com"}}]\n- "any service token" -> [{"any_valid_service_token":{}}]\n- "everyone" -> [{"everyone":{}}]\n\nReturn ONLY the JSON array - no explanations, no markdown fences.', + placeholder: 'Describe the include rules', generationType: 'json-array', }, }, @@ -2180,33 +2287,39 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, title: 'Exclude Rules', type: 'long-input', placeholder: 'JSON array of Access rules evaluated with NOT logic', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare exclude rules value. Return ONLY the value.', + placeholder: 'Describe the exclude rules', + }, }, { id: 'require', title: 'Require Rules', type: 'long-input', placeholder: 'JSON array of Access rules evaluated with AND logic', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare require rules value. Return ONLY the value.', + placeholder: 'Describe the require rules', + }, }, { id: 'precedence', title: 'Precedence', type: 'short-input', placeholder: 'Evaluation order within the application', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare precedence value. Return ONLY the value.', + placeholder: 'Describe the precedence', + }, }, { id: 'approvalRequired', @@ -2218,10 +2331,7 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, { label: 'No', id: 'false' }, ], value: () => '', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', }, { @@ -2234,10 +2344,7 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, { label: 'No', id: 'false' }, ], value: () => '', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', }, { @@ -2250,10 +2357,7 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, { label: 'No', id: 'false' }, ], value: () => '', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', }, { @@ -2261,21 +2365,13 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, title: 'Purpose Justification Prompt', type: 'short-input', placeholder: 'Why do you need access?', - condition: { - field: 'operation', - value: ['create_access_policy', 'update_access_policy'], - }, + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, mode: 'advanced', - }, - - // Access service token inputs - { - id: 'name', - title: 'Service Token Name', - type: 'short-input', - required: true, - placeholder: 'e.g., ci-pipeline', - condition: { field: 'operation', value: 'create_access_service_token' }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare purpose justification prompt value. Return ONLY the value.', + placeholder: 'Describe the purpose justification prompt', + }, }, { id: 'duration', @@ -2284,6 +2380,11 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'e.g., 8760h', condition: { field: 'operation', value: 'create_access_service_token' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare duration value. Return ONLY the value.', + placeholder: 'Describe the duration', + }, }, { id: 'serviceTokenId', @@ -2291,10 +2392,22 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, type: 'short-input', required: true, placeholder: 'Enter the service token ID to revoke', - condition: { field: 'operation', value: 'revoke_access_service_token' }, + condition: { + field: 'operation', + value: [ + 'revoke_access_service_token', + 'get_access_service_token', + 'refresh_access_service_token', + 'rotate_access_service_token', + 'update_access_service_token', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare service token id value. Return ONLY the value.', + placeholder: 'Describe the service token id', + }, }, - - // R2 inputs { id: 'bucketName', title: 'Bucket Name', @@ -2303,7 +2416,21 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Enter R2 bucket name', condition: { field: 'operation', - value: ['get_r2_bucket', 'create_r2_bucket', 'delete_r2_bucket'], + value: [ + 'get_r2_bucket', + 'create_r2_bucket', + 'delete_r2_bucket', + 'delete_r2_bucket_cors', + 'get_r2_bucket_cors', + 'get_r2_bucket_lifecycle', + 'update_r2_bucket_cors', + 'update_r2_bucket_lifecycle', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare bucket name value. Return ONLY the value.', + placeholder: 'Describe the bucket name', }, }, { @@ -2348,7 +2475,17 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, value: () => '', condition: { field: 'operation', - value: ['list_r2_buckets', 'get_r2_bucket', 'create_r2_bucket', 'delete_r2_bucket'], + value: [ + 'list_r2_buckets', + 'get_r2_bucket', + 'create_r2_bucket', + 'delete_r2_bucket', + 'delete_r2_bucket_cors', + 'get_r2_bucket_cors', + 'get_r2_bucket_lifecycle', + 'update_r2_bucket_cors', + 'update_r2_bucket_lifecycle', + ], }, mode: 'advanced', }, @@ -2359,6 +2496,11 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Filter buckets by name substring', condition: { field: 'operation', value: 'list_r2_buckets' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare name contains value. Return ONLY the value.', + placeholder: 'Describe the name contains', + }, }, { id: 'start_after', @@ -2367,19 +2509,24 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Bucket name to start listing after', condition: { field: 'operation', value: 'list_r2_buckets' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare start after value. Return ONLY the value.', + placeholder: 'Describe the start after', + }, }, { - /** - * R2 returns its cursor at `result_info.cursor` and the Rulesets API at - * `result_info.cursors.after`. The two are not interchangeable, so a - * cursor carried across from the other list 400s. - */ id: 'r2Cursor', title: 'Cursor', type: 'short-input', placeholder: 'Pagination cursor from a previous call', condition: { field: 'operation', value: 'list_r2_buckets' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare cursor value. Return ONLY the value.', + placeholder: 'Describe the cursor', + }, }, { id: 'rulesetCursor', @@ -2388,29 +2535,27 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Pagination cursor from a previous call', condition: { field: 'operation', value: 'list_rulesets' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare cursor value. Return ONLY the value.', + placeholder: 'Describe the cursor', + }, }, - { - id: 'direction', - title: 'Sort Direction', - type: 'dropdown', - options: [ - { label: 'Default', id: '' }, - { label: 'Ascending', id: 'asc' }, - { label: 'Descending', id: 'desc' }, - ], - value: () => '', - condition: { field: 'operation', value: 'list_r2_buckets' }, - mode: 'advanced', - }, - - // Workers inputs { id: 'scriptName', title: 'Script Name', type: 'short-input', required: true, placeholder: 'Enter Worker script name', - condition: { field: 'operation', value: 'get_worker_script_settings' }, + condition: { + field: 'operation', + value: ['get_worker_script_settings', 'delete_worker_script'], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare script name value. Return ONLY the value.', + placeholder: 'Describe the script name', + }, }, { id: 'workerTagFilter', @@ -2419,16 +2564,34 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Filter scripts by tag', condition: { field: 'operation', value: 'list_worker_scripts' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tag filter value. Return ONLY the value.', + placeholder: 'Describe the tag filter', + }, }, - - // Tunnel inputs { id: 'tunnelId', title: 'Tunnel ID', type: 'short-input', required: true, placeholder: 'Enter tunnel ID', - condition: { field: 'operation', value: ['get_tunnel', 'get_tunnel_configuration'] }, + condition: { + field: 'operation', + value: [ + 'get_tunnel', + 'get_tunnel_configuration', + 'delete_tunnel', + 'get_tunnel_token', + 'update_tunnel_configuration', + 'update_tunnel', + ], + }, + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tunnel id value. Return ONLY the value.', + placeholder: 'Describe the tunnel id', + }, }, { id: 'tunnelStatus', @@ -2452,6 +2615,11 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Filter by tunnel UUID', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare tunnel uuid value. Return ONLY the value.', + placeholder: 'Describe the tunnel uuid', + }, }, { id: 'is_deleted', @@ -2473,6 +2641,11 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Only tunnels whose name starts with this prefix', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare include name prefix value. Return ONLY the value.', + placeholder: 'Describe the include name prefix', + }, }, { id: 'exclude_prefix', @@ -2481,6 +2654,11 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'Skip tunnels whose name starts with this prefix', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare exclude name prefix value. Return ONLY the value.', + placeholder: 'Describe the exclude name prefix', + }, }, { id: 'existed_at', @@ -2489,6 +2667,12 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'RFC 3339 timestamp', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare existed at value. Return ONLY the value.', + placeholder: 'Describe the existed at', + generationType: 'timestamp', + }, }, { id: 'was_active_at', @@ -2497,6 +2681,12 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'RFC 3339 timestamp', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare was active at value. Return ONLY the value.', + placeholder: 'Describe the was active at', + generationType: 'timestamp', + }, }, { id: 'was_inactive_at', @@ -2505,171 +2695,1859 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, placeholder: 'RFC 3339 timestamp', condition: { field: 'operation', value: 'list_tunnels' }, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: 'Generate a Cloudflare was inactive at value. Return ONLY the value.', + placeholder: 'Describe the was inactive at', + generationType: 'timestamp', + }, }, - - // Shared pagination for the new list operations { - id: 'page', - title: 'Page', + id: 'apiKey', + title: 'API Token', type: 'short-input', - placeholder: 'Page number (default: 1)', + required: true, + placeholder: 'Enter your Cloudflare API token', + password: true, + }, + { + id: 'accessApplicationDestinations', + title: 'Destinations', + type: 'long-input', + placeholder: 'Enter destinations as JSON', condition: { field: 'operation', - value: [ - 'list_access_applications', - 'list_access_policies', - 'list_access_groups', - 'list_access_service_tokens', - 'list_tunnels', - ], + value: ['create_access_application', 'update_access_application'], }, + required: false, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare destinations value. JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id. Return ONLY the value.', + placeholder: 'Describe the destinations', + }, }, { - id: 'per_page', - title: 'Per Page', - type: 'short-input', - placeholder: 'Results per page', + id: 'accessApplicationOauthConfiguration', + title: 'OAuth Configuration', + type: 'long-input', + placeholder: 'Enter oauth configuration as JSON', condition: { field: 'operation', - value: [ - 'list_access_applications', - 'list_access_policies', - 'list_access_groups', - 'list_access_service_tokens', - 'list_r2_buckets', - 'list_rulesets', - 'list_tunnels', - ], + value: ['create_access_application', 'update_access_application'], + }, + required: (params) => ({ + field: params?.operation === 'update_access_application' ? 'updateAppType' : 'appType', + value: 'end_user', + }), + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare oauth configuration value. JSON object. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant. Return ONLY the value.', + placeholder: 'Describe the oauth configuration', }, + }, + { + id: 'accessApplicationSelfHostedDomains', + title: 'Self Hosted Domains', + type: 'long-input', + placeholder: 'Enter self hosted domains as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare self hosted domains value. JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored. Return ONLY the value.', + placeholder: 'Describe the self hosted domains', + }, }, - - // API Key (common) { - id: 'apiKey', - title: 'API Token', + id: 'accessApplicationUserPopulations', + title: 'User Populations', + type: 'long-input', + placeholder: 'Enter user populations as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: (params) => ({ + field: params?.operation === 'update_access_application' ? 'updateAppType' : 'appType', + value: 'end_user', + }), + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare user populations value. JSON array. The single user population associated with this application. Return ONLY the value.', + placeholder: 'Describe the user populations', + }, + }, + { + id: 'accessApplicationAllowAuthenticateViaWarp', + title: 'Allow Authenticate Via Warp', + type: 'dropdown', + placeholder: 'Enter allow authenticate via warp', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationAllowIframe', + title: 'Allow Iframe', + type: 'dropdown', + placeholder: 'Enter allow iframe', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationCorsHeaders', + title: 'CORS Headers', + type: 'long-input', + placeholder: 'Enter cors headers as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare cors headers value. JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age. Return ONLY the value.', + placeholder: 'Describe the cors headers', + }, + }, + { + id: 'accessApplicationCustomNonIdentityDenyUrl', + title: 'Custom Non Identity Deny URL', type: 'short-input', - required: true, - placeholder: 'Enter your Cloudflare API token', - password: true, + placeholder: 'Enter custom non identity deny url', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare custom non identity deny url value. The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules. Return ONLY the value.', + placeholder: 'Describe the custom non identity deny url', + }, }, - ], - tools: { - access: [ - 'cloudflare_list_zones', - 'cloudflare_get_zone', - 'cloudflare_create_zone', - 'cloudflare_delete_zone', - 'cloudflare_list_dns_records', - 'cloudflare_create_dns_record', - 'cloudflare_update_dns_record', - 'cloudflare_delete_dns_record', - 'cloudflare_list_certificates', - 'cloudflare_get_zone_settings', - 'cloudflare_update_zone_setting', - 'cloudflare_dns_analytics', - 'cloudflare_purge_cache', - 'cloudflare_list_rulesets', - 'cloudflare_get_ruleset', - 'cloudflare_get_ruleset_entrypoint', - 'cloudflare_create_ruleset', - 'cloudflare_create_ruleset_rule', - 'cloudflare_update_ruleset_rule', - 'cloudflare_delete_ruleset_rule', - 'cloudflare_list_managed_ruleset_overrides', - 'cloudflare_list_rate_limit_rules', - 'cloudflare_create_rate_limit_rule', - 'cloudflare_update_rate_limit_rule', - 'cloudflare_list_access_applications', - 'cloudflare_get_access_application', + { + id: 'accessApplicationCustomPages', + title: 'Custom Pages', + type: 'long-input', + placeholder: 'Enter custom pages as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare custom pages value. JSON array. The custom pages that will be displayed when applicable for this application Return ONLY the value.', + placeholder: 'Describe the custom pages', + }, + }, + { + id: 'accessApplicationEagerRedirectCookieSetting', + title: 'Eager Redirect Cookie Setting', + type: 'dropdown', + placeholder: 'Enter eager redirect cookie setting', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationEnableBindingCookie', + title: 'Enable Binding Cookie', + type: 'dropdown', + placeholder: 'Enter enable binding cookie', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationHttpOnlyCookieAttribute', + title: 'Http Only Cookie Attribute', + type: 'dropdown', + placeholder: 'Enter http only cookie attribute', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationMfaConfig', + title: 'MFA Config', + type: 'long-input', + placeholder: 'Enter mfa config as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare mfa config value. JSON object. Configures multi-factor authentication (MFA) settings. Fields: allowed_authenticators, mfa_disabled, session_duration. Return ONLY the value.', + placeholder: 'Describe the mfa config', + }, + }, + { + id: 'accessApplicationOptionsPreflightBypass', + title: 'Options Preflight Bypass', + type: 'dropdown', + placeholder: 'Enter options preflight bypass', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationPathCookieAttribute', + title: 'Path Cookie Attribute', + type: 'dropdown', + placeholder: 'Enter path cookie attribute', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationReadServiceTokensFromHeader', + title: 'Read Service Tokens From Header', + type: 'short-input', + placeholder: 'Enter read service tokens from header', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare read service tokens from header value. Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the (CF-Access-Client-Id, CF-Access-Client-Secret) pair of headers. The header value will be interpreted as a json object similar to: { "cf-access-client-id": "", "cf-access-client-secret": "" } Return ONLY the value.', + placeholder: 'Describe the read service tokens from header', + }, + }, + { + id: 'accessApplicationSameSiteCookieAttribute', + title: 'Same Site Cookie Attribute', + type: 'short-input', + placeholder: 'Enter same site cookie attribute', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare same site cookie attribute value. Sets the SameSite cookie setting, which provides increased security against CSRF attacks. Return ONLY the value.', + placeholder: 'Describe the same site cookie attribute', + }, + }, + { + id: 'accessApplicationScimConfig', + title: 'SCIM Config', + type: 'long-input', + placeholder: 'Enter scim config as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare scim config value. JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri. Return ONLY the value.', + placeholder: 'Describe the scim config', + }, + }, + { + id: 'accessApplicationServiceAuth401Redirect', + title: 'Service Auth 401 Redirect', + type: 'dropdown', + placeholder: 'Enter service auth 401 redirect', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationSkipInterstitial', + title: 'Skip Interstitial', + type: 'dropdown', + placeholder: 'Enter skip interstitial', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationUseClientlessIsolationAppLauncherUrl', + title: 'Use Clientless Isolation App Launcher URL', + type: 'dropdown', + placeholder: 'Enter use clientless isolation app launcher url', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessApplicationAppLauncherLogoUrl', + title: 'App Launcher Logo URL', + type: 'short-input', + placeholder: 'Enter app launcher logo url', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare app launcher logo url value. The image URL of the logo shown in the App Launcher header. Return ONLY the value.', + placeholder: 'Describe the app launcher logo url', + }, + }, + { + id: 'accessApplicationBgColor', + title: 'Bg Color', + type: 'short-input', + placeholder: 'Enter bg color', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare bg color value. The background color of the App Launcher page. Return ONLY the value.', + placeholder: 'Describe the bg color', + }, + }, + { + id: 'accessApplicationFooterLinks', + title: 'Footer Links', + type: 'long-input', + placeholder: 'Enter footer links as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare footer links value. JSON array. The links in the App Launcher footer. Fields: name, url. Return ONLY the value.', + placeholder: 'Describe the footer links', + }, + }, + { + id: 'accessApplicationHeaderBgColor', + title: 'Header Bg Color', + type: 'short-input', + placeholder: 'Enter header bg color', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare header bg color value. The background color of the App Launcher header. Return ONLY the value.', + placeholder: 'Describe the header bg color', + }, + }, + { + id: 'accessApplicationLandingPageDesign', + title: 'Landing Page Design', + type: 'long-input', + placeholder: 'Enter landing page design as JSON', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare landing page design value. JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title. Return ONLY the value.', + placeholder: 'Describe the landing page design', + }, + }, + { + id: 'accessApplicationSkipAppLauncherLoginPage', + title: 'Skip App Launcher Login Page', + type: 'dropdown', + placeholder: 'Enter skip app launcher login page', + condition: { + field: 'operation', + value: ['create_access_application', 'update_access_application'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessGroupExclude', + title: 'Exclude', + type: 'long-input', + placeholder: 'Enter exclude as JSON', + condition: { field: 'operation', value: ['create_access_group', 'update_access_group'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare exclude value. JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. Return ONLY the value.', + placeholder: 'Describe the exclude', + }, + }, + { + id: 'accessGroupInclude', + title: 'Include', + type: 'long-input', + placeholder: 'Enter include as JSON', + condition: { field: 'operation', value: ['create_access_group', 'update_access_group'] }, + required: true, + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare include value. JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. Return ONLY the value.', + placeholder: 'Describe the include', + }, + }, + { + id: 'accessGroupIsDefault', + title: 'Is Default', + type: 'dropdown', + placeholder: 'Enter is default', + condition: { field: 'operation', value: ['create_access_group', 'update_access_group'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessGroupName', + title: 'Name', + type: 'short-input', + placeholder: 'Enter name', + condition: { field: 'operation', value: ['create_access_group', 'update_access_group'] }, + required: true, + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name value. The name of the Access group. Return ONLY the value.', + placeholder: 'Describe the name', + }, + }, + { + id: 'accessGroupRequire', + title: 'Require', + type: 'long-input', + placeholder: 'Enter require as JSON', + condition: { field: 'operation', value: ['create_access_group', 'update_access_group'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare require value. JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member. Return ONLY the value.', + placeholder: 'Describe the require', + }, + }, + { + id: 'accessPolicyApprovalGroups', + title: 'Approval Groups', + type: 'long-input', + placeholder: 'Enter approval groups as JSON', + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare approval groups value. JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid. Return ONLY the value.', + placeholder: 'Describe the approval groups', + }, + }, + { + id: 'accessPolicyConnectionRules', + title: 'Connection Rules', + type: 'long-input', + placeholder: 'Enter connection rules as JSON', + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare connection rules value. JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh. Return ONLY the value.', + placeholder: 'Describe the connection rules', + }, + }, + { + id: 'accessPolicyMfaConfig', + title: 'MFA Config', + type: 'long-input', + placeholder: 'Enter mfa config as JSON', + condition: { field: 'operation', value: ['create_access_policy', 'update_access_policy'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare mfa config value. JSON object. Configures multi-factor authentication (MFA) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration. Return ONLY the value.', + placeholder: 'Describe the mfa config', + }, + }, + { + id: 'accessServiceTokenClientSecretVersion', + title: 'Client Secret Version', + type: 'short-input', + placeholder: 'Enter client secret version', + condition: { + field: 'operation', + value: ['create_access_service_token', 'update_access_service_token'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare client secret version value. A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately. Return ONLY the value.', + placeholder: 'Describe the client secret version', + }, + }, + { + id: 'accessServiceTokenEnabled', + title: 'Enabled', + type: 'dropdown', + placeholder: 'Enter enabled', + condition: { + field: 'operation', + value: ['create_access_service_token', 'update_access_service_token'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'accessServiceTokenPreviousClientSecretExpiresAt', + title: 'Previous Client Secret Expires At', + type: 'short-input', + placeholder: 'Enter previous client secret expires at', + condition: { + field: 'operation', + value: ['create_access_service_token', 'update_access_service_token'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare previous client secret expires at value. The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set. Return ONLY the value.', + placeholder: 'Describe the previous client secret expires at', + generationType: 'timestamp', + }, + }, + { + id: 'dnsRecordSettings', + title: 'Settings', + type: 'long-input', + placeholder: 'Enter settings as JSON', + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare settings value. JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname. Return ONLY the value.', + placeholder: 'Describe the settings', + }, + }, + { + id: 'dnsRecordPrivateRouting', + title: 'Private Routing', + type: 'dropdown', + placeholder: 'Enter private routing', + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'dnsRecordData', + title: 'Data', + type: 'long-input', + placeholder: 'Enter data as JSON', + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare data value. JSON object. Structured record data; fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint. Return ONLY the value.', + placeholder: 'Describe the data', + }, + }, + { + id: 'dnsRecordIncludeShadowMetadata', + title: 'Include Shadow Metadata', + type: 'dropdown', + placeholder: 'Enter include shadow metadata', + condition: { field: 'operation', value: ['create_dns_record', 'update_dns_record'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'rateLimitRuleActionparameters', + title: 'Action Parameters', + type: 'long-input', + placeholder: 'Enter action parameters as JSON', + condition: { field: 'operation', value: ['create_rate_limit_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare action parameters value. JSON object. The parameters configuring the rule's action. Fields: response, algorithms, id, matched_data, overrides, cookie_fields, raw_response_fields, request_fields, response_fields, transformed_request_fields, from_list, from_value, headers, uri, host_header, origin, sni, increment, content_type, status_code, content, asset_name, immutable, max-age, must-revalidate, must-understand, no-cache, no-store, no-transform, private, proxy-revalidate, public, s-maxage, stale-if-error, stale-while-revalidate, additional_cacheable_ports, browser_ttl, cache, cache_key, cache_reserve, edge_ttl, origin_cache_control, origin_error_page_passthru, origin_range_requests, read_timeout, respect_strong_etags, serve_stale, shared_dictionary, strip_etags, strip_last_modified, strip_set_cookie, vary, operation, values, expression, automatic_https_rewrites, autominify, bic, content_converter, disable_apps, disable_pay_per_crawl, disable_rum, disable_zaraz, email_obfuscation, fonts, hotlink_protection, mirage, opportunistic_encryption, polish, redirects_for_ai_training, request_body_buffering, response_body_buffering, rocket_loader, security_level, server_side_excludes, ssl, sxg, webmcp_enabled, webmcp_packs, phase, phases, products, rules, ruleset, rulesets, link_maze. Return ONLY the value.", + placeholder: 'Describe the action parameters', + }, + }, + { + id: 'rateLimitRuleExposedCredentialCheck', + title: 'Exposed Credential Check', + type: 'long-input', + placeholder: 'Enter exposed credential check as JSON', + condition: { + field: 'operation', + value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare exposed credential check value. JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. Return ONLY the value.', + placeholder: 'Describe the exposed credential check', + }, + }, + { + id: 'rateLimitRuleId', + title: 'ID', + type: 'short-input', + placeholder: 'Enter id', + condition: { field: 'operation', value: ['create_rate_limit_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare id value. The unique ID of the rule. Return ONLY the value.', + placeholder: 'Describe the id', + }, + }, + { + id: 'rateLimitRuleLogging', + title: 'Logging', + type: 'long-input', + placeholder: 'Enter logging as JSON', + condition: { field: 'operation', value: ['create_rate_limit_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare logging value. JSON object. An object configuring the rule's logging behavior. Fields: enabled. Return ONLY the value.", + placeholder: 'Describe the logging', + }, + }, + { + id: 'rateLimitRuleRef', + title: 'Ref', + type: 'short-input', + placeholder: 'Enter ref', + condition: { field: 'operation', value: ['create_rate_limit_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare ref value. The reference of the rule (the rule's ID by default). Return ONLY the value.", + placeholder: 'Describe the ref', + }, + }, + { + id: 'rateLimitRulePosition', + title: 'Position', + type: 'long-input', + placeholder: 'Enter position as JSON', + condition: { + field: 'operation', + value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare position value. JSON object. An object configuring where the rule will be placed. Fields: before, after, index. Return ONLY the value.', + placeholder: 'Describe the position', + }, + }, + { + id: 'rateLimitRuleScorePerPeriod', + title: 'Score Per Period', + type: 'short-input', + placeholder: 'Enter score per period', + condition: { + field: 'operation', + value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare score per period value. The score threshold per period for which the action will be executed the first time. Return ONLY the value.', + placeholder: 'Describe the score per period', + }, + }, + { + id: 'rateLimitRuleScoreResponseHeaderName', + title: 'Score Response Header Name', + type: 'short-input', + placeholder: 'Enter score response header name', + condition: { + field: 'operation', + value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare score response header name value. A response header name provided by the origin, which contains the score to increment rate limit counter with. Return ONLY the value.', + placeholder: 'Describe the score response header name', + }, + }, + { + id: 'rateLimitRuleDryRun', + title: 'Dry Run', + type: 'dropdown', + placeholder: 'Enter dry run', + condition: { + field: 'operation', + value: ['create_rate_limit_rule', 'update_rate_limit_rule'], + }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'rulesetRuleExposedCredentialCheck', + title: 'Exposed Credential Check', + type: 'long-input', + placeholder: 'Enter exposed credential check as JSON', + condition: { field: 'operation', value: ['create_ruleset_rule', 'update_ruleset_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare exposed credential check value. JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression. Return ONLY the value.', + placeholder: 'Describe the exposed credential check', + }, + }, + { + id: 'rulesetRuleId', + title: 'ID', + type: 'short-input', + placeholder: 'Enter id', + condition: { field: 'operation', value: ['create_ruleset_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare id value. The unique ID of the rule. Return ONLY the value.', + placeholder: 'Describe the id', + }, + }, + { + id: 'rulesetRuleLogging', + title: 'Logging', + type: 'long-input', + placeholder: 'Enter logging as JSON', + condition: { field: 'operation', value: ['create_ruleset_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare logging value. JSON object. An object configuring the rule's logging behavior. Fields: enabled. Return ONLY the value.", + placeholder: 'Describe the logging', + }, + }, + { + id: 'rulesetRuleRatelimit', + title: 'Ratelimit', + type: 'long-input', + placeholder: 'Enter ratelimit as JSON', + condition: { field: 'operation', value: ['create_ruleset_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare ratelimit value. JSON object. An object configuring the rule's rate limit behavior. Fields: characteristics, counting_expression, mitigation_timeout, period, requests_per_period, requests_to_origin, score_per_period, score_response_header_name. Return ONLY the value.", + placeholder: 'Describe the ratelimit', + }, + }, + { + id: 'rulesetRuleDryRun', + title: 'Dry Run', + type: 'dropdown', + placeholder: 'Enter dry run', + condition: { field: 'operation', value: ['create_ruleset_rule', 'update_ruleset_rule'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'rulesetDryRun', + title: 'Dry Run', + type: 'dropdown', + placeholder: 'Enter dry run', + condition: { field: 'operation', value: ['create_ruleset', 'update_ruleset'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'tunnelConfigSrc', + title: 'Config Src', + type: 'dropdown', + condition: { field: 'operation', value: ['create_tunnel'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'local', id: 'local' }, + { label: 'cloudflare', id: 'cloudflare' }, + ], + value: () => '', + }, + { + id: 'tunnelName', + title: 'Name', + type: 'short-input', + placeholder: 'Enter name', + condition: { field: 'operation', value: ['create_tunnel', 'update_tunnel'] }, + required: true, + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name value. A user-friendly name for a tunnel. Return ONLY the value.', + placeholder: 'Describe the name', + }, + }, + { + id: 'tunnelTunnelSecret', + title: 'Tunnel Secret', + type: 'short-input', + placeholder: 'Enter tunnel secret', + condition: { field: 'operation', value: ['create_tunnel', 'update_tunnel'] }, + required: false, + mode: 'advanced', + password: true, + }, + { + id: 'workerRoutePattern', + title: 'Pattern', + type: 'short-input', + placeholder: 'Enter pattern', + condition: { field: 'operation', value: ['create_worker_route', 'update_worker_route'] }, + required: true, + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare pattern value. Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior). Return ONLY the value.', + placeholder: 'Describe the pattern', + }, + }, + { + id: 'workerRouteScript', + title: 'Script', + type: 'short-input', + placeholder: 'Enter script', + condition: { field: 'operation', value: ['create_worker_route', 'update_worker_route'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare script value. Name of the script to run if the route matches. Return ONLY the value.', + placeholder: 'Describe the script', + }, + }, + { + id: 'groupId', + title: 'Group ID', + type: 'short-input', + placeholder: 'Enter group id', + condition: { + field: 'operation', + value: ['delete_access_group', 'get_access_group', 'update_access_group'], + }, + required: true, + wandConfig: { + enabled: true, + prompt: 'Generate the Cloudflare group id value. Group id Return ONLY the value.', + placeholder: 'Describe the group id', + }, + }, + { + id: 'deleteRulesetRuleDryRun', + title: 'Dry Run', + type: 'dropdown', + placeholder: 'Enter dry run', + condition: { field: 'operation', value: ['delete_ruleset_rule'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'deleteRulesetDryRun', + title: 'Dry Run', + type: 'dropdown', + placeholder: 'Enter dry run', + condition: { field: 'operation', value: ['delete_ruleset'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'routeId', + title: 'Route ID', + type: 'short-input', + placeholder: 'Enter route id', + condition: { + field: 'operation', + value: ['delete_worker_route', 'get_worker_route', 'update_worker_route'], + }, + required: true, + wandConfig: { + enabled: true, + prompt: 'Generate the Cloudflare route id value. Route id Return ONLY the value.', + placeholder: 'Describe the route id', + }, + }, + { + id: 'deleteWorkerScriptForce', + title: 'Force', + type: 'dropdown', + placeholder: 'Enter force', + condition: { field: 'operation', value: ['delete_worker_script'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'getDnsRecordIncludeShadowMetadata', + title: 'Include Shadow Metadata', + type: 'dropdown', + placeholder: 'Enter include shadow metadata', + condition: { field: 'operation', value: ['get_dns_record'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'listAccessApplicationsTargetAttributes', + title: 'Target Attributes', + type: 'short-input', + placeholder: 'Enter target attributes', + condition: { field: 'operation', value: ['list_access_applications'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare target attributes value. Target Criteria attributes in key=value format. Return ONLY the value.', + placeholder: 'Describe the target attributes', + }, + }, + { + id: 'listAccessIdentityProvidersScimEnabled', + title: 'SCIM Enabled', + type: 'short-input', + placeholder: 'Enter scim enabled', + condition: { field: 'operation', value: ['list_access_identity_providers'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare scim enabled value. Indicates to Access to only retrieve identity providers that have the System for Cross-Domain Identity Management (SCIM) enabled. Return ONLY the value.', + placeholder: 'Describe the scim enabled', + }, + }, + { + id: 'listAccessIdentityProvidersPage', + title: 'Page', + type: 'short-input', + placeholder: 'Enter page', + condition: { field: 'operation', value: ['list_access_identity_providers'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare page value. Page number of results. Return ONLY the value.', + placeholder: 'Describe the page', + }, + }, + { + id: 'listAccessIdentityProvidersPerPage', + title: 'Per Page', + type: 'short-input', + placeholder: 'Enter per page', + condition: { field: 'operation', value: ['list_access_identity_providers'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare per page value. Number of results per page. Return ONLY the value.', + placeholder: 'Describe the per page', + }, + }, + { + id: 'listDnsRecordsNameContains', + title: 'Name Contains', + type: 'short-input', + placeholder: 'Enter name contains', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name contains value. Substring of the DNS record name. Name filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the name contains', + }, + }, + { + id: 'listDnsRecordsNameStartswith', + title: 'Name Startswith', + type: 'short-input', + placeholder: 'Enter name startswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name startswith value. Prefix of the DNS record name. Name filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the name startswith', + }, + }, + { + id: 'listDnsRecordsNameEndswith', + title: 'Name Endswith', + type: 'short-input', + placeholder: 'Enter name endswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name endswith value. Suffix of the DNS record name. Name filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the name endswith', + }, + }, + { + id: 'listDnsRecordsContentContains', + title: 'Content Contains', + type: 'short-input', + placeholder: 'Enter content contains', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare content contains value. Substring of the DNS record content. Content filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the content contains', + }, + }, + { + id: 'listDnsRecordsContentStartswith', + title: 'Content Startswith', + type: 'short-input', + placeholder: 'Enter content startswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare content startswith value. Prefix of the DNS record content. Content filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the content startswith', + }, + }, + { + id: 'listDnsRecordsContentEndswith', + title: 'Content Endswith', + type: 'short-input', + placeholder: 'Enter content endswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare content endswith value. Suffix of the DNS record content. Content filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the content endswith', + }, + }, + { + id: 'listDnsRecordsCommentPresent', + title: 'Comment Present', + type: 'dropdown', + placeholder: 'Enter comment present', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'listDnsRecordsCommentAbsent', + title: 'Comment Absent', + type: 'dropdown', + placeholder: 'Enter comment absent', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'listDnsRecordsCommentExact', + title: 'Comment Exact', + type: 'short-input', + placeholder: 'Enter comment exact', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare comment exact value. Exact value of the DNS record comment. Comment filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the comment exact', + }, + }, + { + id: 'listDnsRecordsCommentStartswith', + title: 'Comment Startswith', + type: 'short-input', + placeholder: 'Enter comment startswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare comment startswith value. Prefix of the DNS record comment. Comment filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the comment startswith', + }, + }, + { + id: 'listDnsRecordsCommentEndswith', + title: 'Comment Endswith', + type: 'short-input', + placeholder: 'Enter comment endswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare comment endswith value. Suffix of the DNS record comment. Comment filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the comment endswith', + }, + }, + { + id: 'listDnsRecordsTagPresent', + title: 'Tag Present', + type: 'short-input', + placeholder: 'Enter tag present', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare tag present value. Name of a tag which must be present on the DNS record. Tag filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the tag present', + }, + }, + { + id: 'listDnsRecordsTagAbsent', + title: 'Tag Absent', + type: 'short-input', + placeholder: 'Enter tag absent', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare tag absent value. Name of a tag which must *not* be present on the DNS record. Tag filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the tag absent', + }, + }, + { + id: 'listDnsRecordsTagContains', + title: 'Tag Contains', + type: 'short-input', + placeholder: 'Enter tag contains', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare tag contains value. A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value contains ``. Tag filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the tag contains', + }, + }, + { + id: 'listDnsRecordsTagStartswith', + title: 'Tag Startswith', + type: 'short-input', + placeholder: 'Enter tag startswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare tag startswith value. A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value starts with ``. Tag filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the tag startswith', + }, + }, + { + id: 'listDnsRecordsTagEndswith', + title: 'Tag Endswith', + type: 'short-input', + placeholder: 'Enter tag endswith', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare tag endswith value. A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value ends with ``. Tag filters are case-insensitive. Return ONLY the value.', + placeholder: 'Describe the tag endswith', + }, + }, + { + id: 'listDnsRecordsIncludeShadowMetadata', + title: 'Include Shadow Metadata', + type: 'dropdown', + placeholder: 'Enter include shadow metadata', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'listDnsRecordsShadowedByName', + title: 'Shadowed By Name', + type: 'short-input', + placeholder: 'Enter shadowed by name', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare shadowed by name value. Filters the response to records at or below the specified NS delegation name. NS, DS, and NSEC records at the delegation name are excluded because they are not shadowed by that delegation. Those record types are included only when they exist below the delegation. The value must be a non-apex subdomain of the zone. Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). Return ONLY the value.', + placeholder: 'Describe the shadowed by name', + }, + }, + { + id: 'listDnsRecordsShadowingName', + title: 'Shadowing Name', + type: 'short-input', + placeholder: 'Enter shadowing name', + condition: { field: 'operation', value: ['list_dns_records'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare shadowing name value. Returns NS records that shadow the given name, searching at the name itself and each of its ancestor names within the zone, excluding the zone apex. The value must be a subdomain of the zone; the zone apex is not accepted. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records). Return ONLY the value.', + placeholder: 'Describe the shadowing name', + }, + }, + { + id: 'listR2BucketsOrder', + title: 'Order', + type: 'dropdown', + condition: { field: 'operation', value: ['list_r2_buckets'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'name', id: 'name' }, + ], + value: () => '', + }, + { + id: 'listZonesType', + title: 'Type', + type: 'short-input', + placeholder: 'Enter type', + condition: { field: 'operation', value: ['list_zones'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare type value. Comma-separated zone types: full, partial, secondary, internal Return ONLY the value.', + placeholder: 'Describe the type', + }, + }, + { + id: 'listZonesAccountName', + title: 'Account Name', + type: 'short-input', + placeholder: 'Enter account name', + condition: { field: 'operation', value: ['list_zones'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare account name value. An account Name. Optional filter operators can be provided to extend refine the search: * `equal` (default) * `not_equal` * `starts_with` * `ends_with` * `contains` * `starts_with_case_sensitive` * `ends_with_case_sensitive` * `contains_case_sensitive` Return ONLY the value.', + placeholder: 'Describe the account name', + }, + }, + { + id: 'rotateAccessServiceTokenPreviousClientSecretExpiresAt', + title: 'Previous Client Secret Expires At', + type: 'short-input', + placeholder: 'Enter previous client secret expires at', + condition: { field: 'operation', value: ['rotate_access_service_token'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare previous client secret expires at value. The expiration of the previous `client_secret`. If not provided, it defaults to the current timestamp in order to immediately expire the previous secret. If the service token was reported as leaked, this must not be in the future; the leaked secret is discarded immediately. Return ONLY the value.', + placeholder: 'Describe the previous client secret expires at', + generationType: 'timestamp', + }, + }, + { + id: 'accessServiceTokenDuration', + title: 'Duration', + type: 'short-input', + placeholder: 'Enter duration', + condition: { field: 'operation', value: ['update_access_service_token'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare duration value. The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us (or µs), ms, s, m, h. The default is 1 year in hours (8760h). Return ONLY the value.', + placeholder: 'Describe the duration', + }, + }, + { + id: 'accessServiceTokenName', + title: 'Name', + type: 'short-input', + placeholder: 'Enter name', + condition: { field: 'operation', value: ['update_access_service_token'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare name value. The name of the service token. Return ONLY the value.', + placeholder: 'Describe the name', + }, + }, + { + id: 'dnsRecordClearcomment', + title: 'Clear Comment', + type: 'dropdown', + placeholder: 'Enter clear comment', + condition: { field: 'operation', value: ['update_dns_record'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'r2BucketCorsRules', + title: 'Rules', + type: 'long-input', + placeholder: 'Enter rules as JSON', + condition: { field: 'operation', value: ['update_r2_bucket_cors'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare rules value. JSON array. rules Fields: allowed, exposeHeaders, id, maxAgeSeconds. Return ONLY the value.', + placeholder: 'Describe the rules', + }, + }, + { + id: 'r2BucketLifecycleRules', + title: 'Rules', + type: 'long-input', + placeholder: 'Enter rules as JSON', + condition: { field: 'operation', value: ['update_r2_bucket_lifecycle'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare rules value. JSON array. rules Fields: abortMultipartUploadsTransition, conditions, deleteObjectsTransition, enabled, id, storageClassTransitions. Return ONLY the value.', + placeholder: 'Describe the rules', + }, + }, + { + id: 'rulesetRulePosition', + title: 'Position', + type: 'long-input', + placeholder: 'Enter position as JSON', + condition: { field: 'operation', value: ['update_ruleset_rule'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare position value. JSON object. An object configuring where the rule will be placed. Fields: before, after, index. Return ONLY the value.', + placeholder: 'Describe the position', + }, + }, + { + id: 'rulesetDescription', + title: 'Description', + type: 'short-input', + placeholder: 'Enter description', + condition: { field: 'operation', value: ['update_ruleset'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare description value. An informative description of the ruleset. Return ONLY the value.', + placeholder: 'Describe the description', + }, + }, + + { + id: 'rulesetRules', + title: 'Rules', + type: 'long-input', + placeholder: 'Enter rules as JSON', + description: + 'Read Get Ruleset first and include every rule to retain. This array replaces the complete rule list; [] removes all rules.', + condition: { field: 'operation', value: ['update_ruleset'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare rules value. JSON array replacing the complete rule list. Preserve every existing rule the user wants to keep from their Get Ruleset output. Omitted rules are removed, and [] removes all rules. Fields: action, action_parameters, categories, description, enabled, exposed_credential_check, expression, id, last_updated, logging, ratelimit, ref, version. Return ONLY the value.', + placeholder: 'Describe the rules', + }, + }, + { + id: 'tunnelConfigurationConfig', + title: 'Config', + type: 'long-input', + placeholder: 'Enter config as JSON', + condition: { field: 'operation', value: ['update_tunnel_configuration'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare config value. JSON object. The tunnel configuration and ingress rules. Fields: ingress, originRequest, warp-routing. Return ONLY the value.', + placeholder: 'Describe the config', + }, + }, + { + id: 'zoneSettingEnabled', + title: 'Enabled', + type: 'dropdown', + placeholder: 'Enter enabled', + condition: { + field: 'operation', + value: ['update_zone_setting'], + and: { field: 'settingId', value: 'ssl_recommender' }, + }, + required: true, + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'zonePaused', + title: 'Paused', + type: 'dropdown', + placeholder: 'Enter paused', + condition: { field: 'operation', value: ['update_zone'] }, + required: false, + mode: 'advanced', + options: [ + { label: 'Default', id: '' }, + { label: 'Yes', id: 'true' }, + { label: 'No', id: 'false' }, + ], + value: () => '', + }, + { + id: 'zonePlan', + title: 'Plan', + type: 'long-input', + placeholder: 'Enter plan as JSON', + condition: { field: 'operation', value: ['update_zone'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + "Generate the Cloudflare plan value. JSON object. (Deprecated) Please use the `/zones/{zone_id}/subscription` API to update a zone's plan. Changing this value will create/cancel associated subscriptions. To view available plans for this zone, see Zone Plans. Fields: id. Return ONLY the value.", + placeholder: 'Describe the plan', + }, + }, + { + id: 'zoneVanityNameServers', + title: 'Vanity Name Servers', + type: 'long-input', + placeholder: 'Enter vanity name servers as JSON', + condition: { field: 'operation', value: ['update_zone'] }, + required: false, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate the Cloudflare vanity name servers value. JSON array. An array of domains used for custom name servers. This is only available for Business and Enterprise plans. Return ONLY the value.', + placeholder: 'Describe the vanity name servers', + }, + }, + ], + tools: { + access: [ 'cloudflare_create_access_application', - 'cloudflare_update_access_application', + 'cloudflare_create_access_group', + 'cloudflare_create_access_policy', + 'cloudflare_create_access_service_token', + 'cloudflare_create_dns_record', + 'cloudflare_create_r2_bucket', + 'cloudflare_create_rate_limit_rule', + 'cloudflare_create_ruleset', + 'cloudflare_create_ruleset_rule', + 'cloudflare_create_tunnel', + 'cloudflare_create_worker_route', + 'cloudflare_create_zone', 'cloudflare_delete_access_application', - 'cloudflare_list_access_policies', - 'cloudflare_create_access_policy', - 'cloudflare_update_access_policy', + 'cloudflare_delete_access_group', 'cloudflare_delete_access_policy', + 'cloudflare_delete_dns_record', + 'cloudflare_delete_r2_bucket', + 'cloudflare_delete_r2_bucket_cors', + 'cloudflare_delete_ruleset', + 'cloudflare_delete_ruleset_rule', + 'cloudflare_delete_tunnel', + 'cloudflare_delete_worker_route', + 'cloudflare_delete_worker_script', + 'cloudflare_delete_zone', + 'cloudflare_dns_analytics', + 'cloudflare_get_access_application', + 'cloudflare_get_access_group', + 'cloudflare_get_access_policy', + 'cloudflare_get_access_service_token', + 'cloudflare_get_dns_record', + 'cloudflare_get_r2_bucket', + 'cloudflare_get_r2_bucket_cors', + 'cloudflare_get_r2_bucket_lifecycle', + 'cloudflare_get_ruleset', + 'cloudflare_get_ruleset_entrypoint', + 'cloudflare_get_tunnel', + 'cloudflare_get_tunnel_configuration', + 'cloudflare_get_tunnel_token', + 'cloudflare_get_worker_route', + 'cloudflare_get_worker_script_settings', + 'cloudflare_get_zone', + 'cloudflare_get_zone_settings', + 'cloudflare_list_access_applications', 'cloudflare_list_access_groups', 'cloudflare_list_access_identity_providers', + 'cloudflare_list_access_policies', 'cloudflare_list_access_service_tokens', - 'cloudflare_create_access_service_token', - 'cloudflare_revoke_access_service_token', + 'cloudflare_list_certificates', + 'cloudflare_list_dns_records', + 'cloudflare_list_managed_ruleset_overrides', 'cloudflare_list_r2_buckets', - 'cloudflare_get_r2_bucket', - 'cloudflare_create_r2_bucket', - 'cloudflare_delete_r2_bucket', - 'cloudflare_list_worker_scripts', - 'cloudflare_get_worker_script_settings', - 'cloudflare_list_worker_routes', + 'cloudflare_list_rate_limit_rules', + 'cloudflare_list_rulesets', 'cloudflare_list_tunnels', - 'cloudflare_get_tunnel', - 'cloudflare_get_tunnel_configuration', + 'cloudflare_list_worker_routes', + 'cloudflare_list_worker_scripts', + 'cloudflare_list_zones', + 'cloudflare_purge_cache', + 'cloudflare_refresh_access_service_token', + 'cloudflare_revoke_access_service_token', + 'cloudflare_rotate_access_service_token', + 'cloudflare_update_access_application', + 'cloudflare_update_access_group', + 'cloudflare_update_access_policy', + 'cloudflare_update_access_service_token', + 'cloudflare_update_dns_record', + 'cloudflare_update_r2_bucket_cors', + 'cloudflare_update_r2_bucket_lifecycle', + 'cloudflare_update_rate_limit_rule', + 'cloudflare_update_ruleset', + 'cloudflare_update_ruleset_rule', + 'cloudflare_update_tunnel', + 'cloudflare_update_tunnel_configuration', + 'cloudflare_update_worker_route', + 'cloudflare_update_zone', + 'cloudflare_update_zone_setting', ], config: { tool: (params) => `cloudflare_${params.operation}`, params: (params) => { - const result: Record = { ...params } + const result = { ...params } const operation = typeof result.operation === 'string' ? result.operation : '' - - for (const [toolParam, aliasId] of Object.entries(SUBBLOCK_ALIASES[operation] ?? {})) { + for (const [toolParam, aliasId] of Object.entries(SUBBLOCK_ALIASES[operation] ?? {})) result[toolParam] = result[aliasId] + for (const aliasId of ALIASED_SUBBLOCK_IDS) result[aliasId] = void 0 + if (result.proxied === 'true') result.proxied = !0 + else if (result.proxied === 'false') result.proxied = !1 + else if (result.proxied === '') result.proxied = void 0 + if (result.purge_everything === 'true') result.purge_everything = !0 + else if (result.purge_everything === 'false') result.purge_everything = !1 + if (operation === 'purge_cache' && result.purge_everything === !0) { + result.files = void 0 + result.tags = void 0 + result.hosts = void 0 + result.prefixes = void 0 } - /** - * The executor merges this mapper's output over the raw inputs - * (`finalInputs = { ...inputs, ...transformedParams }` in - * `executor/handlers/generic/handler.ts`), so a key this mapper - * merely omits survives as its raw subBlock string. Every alias id must - * therefore be assigned `undefined` rather than destructured away. - */ - for (const aliasId of ALIASED_SUBBLOCK_IDS) { - result[aliasId] = undefined - } - - if (result.proxied === 'true') result.proxied = true - else if (result.proxied === 'false') result.proxied = false - else if (result.proxied === '') result.proxied = undefined - - if (result.purge_everything === 'true') result.purge_everything = true - else if (result.purge_everything === 'false') result.purge_everything = false - - /** - * `tags`, `hosts`, and `prefixes` are advanced controls, and an advanced - * control serializes on stored value alone — the serializer returns - * `isNonEmptyValue(...)` before it ever evaluates the - * `and: { field: 'purge_everything', not: true }` guard - * (`serializer/index.ts`). So a target typed while purging specific - * content survives the switch to "Purge Everything", and the tool then - * refuses the whole purge over a field the editor no longer renders. - * This mapper is the only layer that can override a stale raw input. - */ - if (operation === 'purge_cache' && result.purge_everything === true) { - result.files = undefined - result.tags = undefined - result.hosts = undefined - result.prefixes = undefined - } - - if (result.type === '') result.type = undefined - if (result.status === '') result.status = undefined - if (result.order === '') result.order = undefined - if (result.direction === '') result.direction = undefined - if (result.match === '') result.match = undefined - if (result.tag_match === '') result.tag_match = undefined - if (result.deploy === '') result.deploy = undefined - + if (result.type === '') result.type = void 0 + if (result.status === '') result.status = void 0 + if (result.order === '') result.order = void 0 + if (result.direction === '') result.direction = void 0 + if (result.match === '') result.match = void 0 + if (result.tag_match === '') result.tag_match = void 0 + if (result.deploy === '') result.deploy = void 0 if (result.operation === 'update_dns_record') { - if (result.content === '') result.content = undefined - if (result.name === '') result.name = undefined - if (result.comment === '') result.comment = undefined + if (result.content === '') result.content = void 0 + if (result.name === '') result.name = void 0 + if (result.comment === '') result.comment = void 0 } - - /** - * A blank optional number must reach the tool as `undefined`, not as - * `Number('')` — which is `0`, a value the tools then forward because - * they test presence rather than truthiness. `0` is out of range for - * `ttl` and silently rewrites an MX record's `priority`. - */ const numericFields = [ 'ttl', 'priority', @@ -2680,15 +4558,12 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, 'requestsPerPeriod', 'mitigationTimeout', 'precedence', - ] as const - for (const field of numericFields) { - if (result[field] === '' || result[field] == null) { - result[field] = undefined - } else { - result[field] = Number(result[field]) - } - } - + 'client_secret_version', + 'score_per_period', + ] + for (const field of numericFields) + if (result[field] === '' || result[field] == null) result[field] = void 0 + else result[field] = Number(result[field]) const booleanFields = [ 'enabled', 'exact', @@ -2699,270 +4574,797 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, 'purposeJustificationRequired', 'requestsToOrigin', 'is_deleted', - ] as const - for (const field of booleanFields) { - if (result[field] === 'true') result[field] = true - else if (result[field] === 'false') result[field] = false - else if (result[field] === '') result[field] = undefined - } - + 'allow_authenticate_via_warp', + 'allow_iframe', + 'clearComment', + 'comment_absent', + 'comment_present', + 'dry_run', + 'eager_redirect_cookie_setting', + 'enable_binding_cookie', + 'force', + 'http_only_cookie_attribute', + 'include_shadow_metadata', + 'is_default', + 'options_preflight_bypass', + 'path_cookie_attribute', + 'paused', + 'private_routing', + 'service_auth_401_redirect', + 'skip_app_launcher_login_page', + 'skip_interstitial', + 'use_clientless_isolation_app_launcher_url', + ] + for (const field of booleanFields) + if (result[field] === 'true') result[field] = !0 + else if (result[field] === 'false') result[field] = !1 + else if (result[field] === '') result[field] = void 0 const optionalStringFields = [ 'phase', 'action', 'locationHint', 'storageClass', 'jurisdiction', - ] as const - for (const field of optionalStringFields) { - if (result[field] === '') result[field] = undefined - } - + 'account_name', + 'app_launcher_logo_url', + 'bg_color', + 'comment_endswith', + 'comment_exact', + 'comment_startswith', + 'config_src', + 'content_contains', + 'content_endswith', + 'content_startswith', + 'custom_non_identity_deny_url', + 'description', + 'duration', + 'header_bg_color', + 'id', + 'kind', + 'name', + 'name_contains', + 'name_endswith', + 'name_startswith', + 'order', + 'previous_client_secret_expires_at', + 'read_service_tokens_from_header', + 'ref', + 'saasApp', + 'same_site_cookie_attribute', + 'scim_enabled', + 'score_response_header_name', + 'script', + 'shadowed_by_name', + 'shadowing_name', + 'tag_absent', + 'tag_contains', + 'tag_endswith', + 'tag_present', + 'tag_startswith', + 'targetCriteria', + 'target_attributes', + 'tunnel_secret', + 'type', + ] + for (const field of optionalStringFields) if (result[field] === '') result[field] = void 0 return result }, }, - }, - inputs: { - operation: { type: 'string', description: 'Operation to perform' }, - apiKey: { type: 'string', description: 'Cloudflare API token' }, - zoneId: { type: 'string', description: 'Zone ID' }, - accountId: { type: 'string', description: 'Cloudflare account ID' }, - zoneType: { + }, + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + apiKey: { type: 'string', description: 'Cloudflare API token' }, + zoneId: { type: 'string', description: 'Zone ID' }, + accountId: { type: 'string', description: 'Cloudflare account ID' }, + updateZoneType: { + type: 'string', + description: 'New zone type; leave unchanged to update another property', + }, + zoneType: { + type: 'string', + description: + 'Zone type to create (full, partial, or secondary). Cloudflare also defines an internal type, which is not creatable here but can appear on zones returned by reads', + }, + order: { type: 'string', description: 'Sort field when listing zones' }, + direction: { type: 'string', description: 'Sort direction (asc, desc)' }, + match: { type: 'string', description: 'Match logic for filters (any, all)' }, + recordId: { type: 'string', description: 'DNS record ID' }, + name: { type: 'string', description: 'Domain or record name' }, + type: { type: 'string', description: 'DNS record type' }, + recordType: { type: 'string', description: 'DNS record type for record creation' }, + recordProxied: { + type: 'string', + description: 'Whether the created DNS record is proxied through Cloudflare', + }, + certificateStatus: { type: 'string', description: 'Certificate pack status filter' }, + dnsOrder: { type: 'string', description: 'Sort field when listing DNS records' }, + recordTags: { type: 'string', description: 'Tags applied to a created DNS record' }, + updateRecordType: { + type: 'string', + description: 'Record type a replaced DNS record ends up with', + }, + updateRecordName: { + type: 'string', + description: 'Record name a replaced DNS record ends up with', + }, + updateRecordContent: { + type: 'string', + description: 'Content a replaced DNS record ends up with', + }, + updateRecordProxied: { + type: 'string', + description: 'Whether a replaced DNS record ends up proxied through Cloudflare', + }, + updateRecordTags: { type: 'string', description: 'Tags a replaced DNS record ends up with' }, + updateRuleEnabled: { + type: 'string', + description: 'Whether a replaced WAF or rate limiting rule ends up enabled', + }, + r2Cursor: { type: 'string', description: 'Pagination cursor when listing R2 buckets' }, + rulesetCursor: { type: 'string', description: 'Pagination cursor when listing rulesets' }, + workerTagFilter: { type: 'string', description: 'Tag filter when listing Worker scripts' }, + accessAppTags: { type: 'string', description: 'Tag names applied to an Access application' }, + listNameFilter: { + type: 'string', + description: + 'Name filter shared by the Access application, group, service token, and tunnel list operations', + }, + accessAppDomainFilter: { + type: 'string', + description: 'Domain filter when listing Access applications', + }, + tunnelStatus: { type: 'string', description: 'Status filter when listing tunnels' }, + appType: { type: 'string', description: 'Access application type' }, + updateAppType: { + type: 'string', + description: 'Access application type a replaced application ends up with', + }, + updatePolicyDecision: { + type: 'string', + description: 'Decision a replaced Access policy ends up applying', + }, + rateLimitAction: { + type: 'string', + description: 'Action applied once a rate limit is exceeded', + }, + updateRateLimitAction: { + type: 'string', + description: 'Action a replaced rate limiting rule ends up applying', + }, + content: { type: 'string', description: 'DNS record content' }, + ttl: { type: 'number', description: 'Time to live in seconds' }, + proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, + priority: { + type: 'number', + description: + 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority inside the record content instead', + }, + comment: { type: 'string', description: 'Record comment' }, + search: { type: 'string', description: 'Free-text search across record properties' }, + tag: { type: 'string', description: 'Filter by an exact tag name' }, + tag_match: { type: 'string', description: 'Tag filter match logic (any, all)' }, + commentFilter: { type: 'string', description: 'Filter records by comment content' }, + settingId: { type: 'string', description: 'Zone setting ID' }, + settingIds: { + type: 'string', + description: 'Comma-separated zone setting IDs to read, or blank for the default set', + }, + value: { type: 'string', description: 'Setting value' }, + since: { type: 'string', description: 'Start date for analytics' }, + until: { type: 'string', description: 'End date for analytics' }, + metrics: { type: 'string', description: 'Comma-separated metrics to retrieve' }, + dimensions: { type: 'string', description: 'Comma-separated dimensions to group by' }, + filters: { type: 'string', description: 'Filters to apply (e.g., queryType==A)' }, + sort: { type: 'string', description: 'Sort order for results' }, + limit: { type: 'number', description: 'Maximum number of results' }, + status: { type: 'string', description: 'Status filter when listing zones' }, + page: { type: 'number', description: 'Page number for pagination' }, + per_page: { type: 'number', description: 'Number of results per page' }, + deploy: { + type: 'string', + description: 'Filter certificates by deployment environment (staging, production)', + }, + purge_everything: { type: 'boolean', description: 'Purge all cached content' }, + files: { type: 'string', description: 'Comma-separated URLs to purge' }, + tags: { type: 'string', description: 'Comma-separated DNS record tags' }, + hosts: { type: 'string', description: 'Comma-separated hostnames to purge' }, + prefixes: { type: 'string', description: 'Comma-separated URL prefixes to purge' }, + rulesetId: { type: 'string', description: 'Ruleset ID' }, + ruleId: { type: 'string', description: 'Rule ID within a ruleset' }, + phase: { type: 'string', description: 'Ruleset phase' }, + rulesetName: { type: 'string', description: 'Name for a newly created ruleset' }, + kind: { type: 'string', description: 'Ruleset kind for ruleset creation' }, + rules: { type: 'string', description: 'JSON array of rules to seed a new ruleset with' }, + action: { type: 'string', description: 'Action a rule performs' }, + expression: { type: 'string', description: 'Cloudflare filter expression' }, + description: { type: 'string', description: 'Rule description' }, + enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, + ref: { type: 'string', description: 'Rule reference tag' }, + actionParameters: { type: 'string', description: 'JSON action parameters for a rule' }, + rateLimitActionParameters: { + type: 'string', + description: 'JSON action parameters a replaced rate limiting rule ends up with', + }, + ratelimit: { + type: 'string', + description: 'JSON rate limiting configuration to preserve when replacing a rule', + }, + logging: { + type: 'string', + description: 'JSON logging configuration to preserve when replacing a rule', + }, + position: { type: 'string', description: 'JSON position object for a new rule' }, + characteristics: { + type: 'string', + description: 'Comma-separated rate limiting counting characteristics', + }, + period: { type: 'number', description: 'Rate limiting counting period in seconds' }, + requestsPerPeriod: { + type: 'number', + description: 'Requests allowed within the rate limiting period', + }, + mitigationTimeout: { + type: 'number', + description: 'Seconds the rate limiting action stays applied', + }, + counting_expression: { + type: 'string', + description: 'Expression selecting which requests are counted', + }, + requestsToOrigin: { + type: 'boolean', + description: 'Whether only requests reaching the origin are counted', + }, + appId: { type: 'string', description: 'Access application ID' }, + policyId: { type: 'string', description: 'Access policy ID' }, + serviceTokenId: { type: 'string', description: 'Access service token ID' }, + domain: { type: 'string', description: 'Hostname and path secured by Access' }, + aud: { type: 'string', description: 'Access application audience tag' }, + exact: { type: 'boolean', description: 'Whether Access list filters must match exactly' }, + sessionDuration: { type: 'string', description: 'Access session duration' }, + allowedIdps: { type: 'string', description: 'Comma-separated identity provider IDs' }, + appLauncherVisible: { + type: 'boolean', + description: 'Whether the application appears in the App Launcher', + }, + autoRedirectToIdentity: { + type: 'boolean', + description: 'Whether users skip the identity provider picker', + }, + customDenyMessage: { type: 'string', description: 'Message shown when access is denied' }, + customDenyUrl: { type: 'string', description: 'URL denied users are redirected to' }, + logoUrl: { type: 'string', description: 'Application logo URL' }, + policies: { type: 'string', description: 'JSON array of policies to attach' }, + saasApp: { + type: 'string', + description: 'JSON SaaS configuration for a saas-typed Access application', + }, + targetCriteria: { + type: 'string', + description: 'JSON target criteria for an infrastructure- or rdp-typed Access application', + }, + decision: { type: 'string', description: 'Access policy decision' }, + include: { type: 'string', description: 'JSON array of Access rules evaluated with OR logic' }, + exclude: { type: 'string', description: 'JSON array of Access rules evaluated with NOT logic' }, + require: { type: 'string', description: 'JSON array of Access rules evaluated with AND logic' }, + precedence: { type: 'number', description: 'Access policy evaluation order' }, + approvalRequired: { + type: 'boolean', + description: 'Whether an approver must grant each access request', + }, + isolationRequired: { + type: 'boolean', + description: 'Whether sessions must run in a remote isolated browser', + }, + purposeJustificationRequired: { + type: 'boolean', + description: 'Whether users must state a reason for access', + }, + purposeJustificationPrompt: { + type: 'string', + description: 'Prompt shown when a justification is required', + }, + duration: { type: 'string', description: 'Service token lifetime' }, + bucketName: { type: 'string', description: 'R2 bucket name' }, + locationHint: { type: 'string', description: 'R2 bucket location hint' }, + storageClass: { type: 'string', description: 'R2 default storage class' }, + jurisdiction: { type: 'string', description: 'R2 data-residency jurisdiction' }, + name_contains: { type: 'string', description: 'Filter R2 buckets by name substring' }, + start_after: { type: 'string', description: 'R2 bucket name to start listing after' }, + cursor: { type: 'string', description: 'Pagination cursor' }, + scriptName: { type: 'string', description: 'Workers script name' }, + tunnelId: { type: 'string', description: 'Cloudflare Tunnel ID' }, + uuid: { type: 'string', description: 'Filter tunnels by UUID' }, + is_deleted: { type: 'boolean', description: 'Whether to return deleted tunnels' }, + include_prefix: { type: 'string', description: 'Only include tunnels with this name prefix' }, + exclude_prefix: { type: 'string', description: 'Exclude tunnels with this name prefix' }, + existed_at: { type: 'string', description: 'Return tunnels that existed at this timestamp' }, + was_active_at: { + type: 'string', + description: 'Return tunnels that were active at this timestamp', + }, + was_inactive_at: { type: 'string', + description: 'Return tunnels that were inactive at this timestamp', + }, + accessApplicationDestinations: { + type: 'json', description: - 'Zone type to create (full, partial, or secondary). Cloudflare also defines an internal type, which is not creatable here but can appear on zones returned by reads', + 'JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id.', }, - order: { type: 'string', description: 'Sort field when listing zones' }, - direction: { type: 'string', description: 'Sort direction (asc, desc)' }, - match: { type: 'string', description: 'Match logic for filters (any, all)' }, - recordId: { type: 'string', description: 'DNS record ID' }, - name: { type: 'string', description: 'Domain or record name' }, - type: { type: 'string', description: 'DNS record type' }, - recordType: { type: 'string', description: 'DNS record type for record creation' }, - recordProxied: { + accessApplicationOauthConfiguration: { + type: 'json', + description: + 'JSON object. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant.', + }, + accessApplicationSelfHostedDomains: { + type: 'json', + description: + 'JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored.', + }, + accessApplicationUserPopulations: { + type: 'json', + description: 'JSON array. The single user population associated with this application.', + }, + accessApplicationAllowAuthenticateViaWarp: { + type: 'boolean', + description: + 'When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication.', + }, + accessApplicationAllowIframe: { + type: 'boolean', + description: 'Enables loading application content in an iFrame.', + }, + accessApplicationCorsHeaders: { + type: 'json', + description: + 'JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age.', + }, + accessApplicationCustomNonIdentityDenyUrl: { type: 'string', - description: 'Whether the created DNS record is proxied through Cloudflare', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules.', }, - certificateStatus: { type: 'string', description: 'Certificate pack status filter' }, - dnsOrder: { type: 'string', description: 'Sort field when listing DNS records' }, - recordTags: { type: 'string', description: 'Tags applied to a created DNS record' }, - updateRecordType: { + accessApplicationCustomPages: { + type: 'json', + description: + 'JSON array. The custom pages that will be displayed when applicable for this application', + }, + accessApplicationEagerRedirectCookieSetting: { + type: 'boolean', + description: + 'Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior.', + }, + accessApplicationEnableBindingCookie: { + type: 'boolean', + description: + 'Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks.', + }, + accessApplicationHttpOnlyCookieAttribute: { + type: 'boolean', + description: + 'Enables the HttpOnly cookie attribute, which increases security against XSS attacks.', + }, + accessApplicationMfaConfig: { + type: 'json', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, + accessApplicationOptionsPreflightBypass: { + type: 'boolean', + description: + 'Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set.', + }, + accessApplicationPathCookieAttribute: { + type: 'boolean', + description: + "Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default", + }, + accessApplicationReadServiceTokensFromHeader: { type: 'string', - description: 'Record type a replaced DNS record ends up with', + description: + 'Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the (CF-Access-Client-Id, CF-Access-Client-Secret) pair of headers. The header value will be interpreted as a json object similar to: { "cf-access-client-id": "", "cf-access-client-secret": "" }', }, - updateRecordName: { + accessApplicationSameSiteCookieAttribute: { type: 'string', - description: 'Record name a replaced DNS record ends up with', + description: + 'Sets the SameSite cookie setting, which provides increased security against CSRF attacks.', }, - updateRecordContent: { + accessApplicationScimConfig: { + type: 'json', + description: + 'JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri.', + }, + accessApplicationServiceAuth401Redirect: { + type: 'boolean', + description: + 'Returns a 401 status code when the request is blocked by a Service Auth policy.', + }, + accessApplicationSkipInterstitial: { + type: 'boolean', + description: 'Enables automatic authentication through cloudflared.', + }, + accessApplicationUseClientlessIsolationAppLauncherUrl: { + type: 'boolean', + description: + 'Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application.', + }, + accessApplicationAppLauncherLogoUrl: { type: 'string', - description: 'Content a replaced DNS record ends up with', + description: 'The image URL of the logo shown in the App Launcher header.', }, - updateRecordProxied: { + accessApplicationBgColor: { type: 'string', - description: 'Whether a replaced DNS record ends up proxied through Cloudflare', + description: 'The background color of the App Launcher page.', }, - updateRecordTags: { type: 'string', description: 'Tags a replaced DNS record ends up with' }, - updateRuleEnabled: { + accessApplicationFooterLinks: { + type: 'json', + description: 'JSON array. The links in the App Launcher footer. Fields: name, url.', + }, + accessApplicationHeaderBgColor: { type: 'string', - description: 'Whether a replaced WAF or rate limiting rule ends up enabled', + description: 'The background color of the App Launcher header.', }, - r2Cursor: { type: 'string', description: 'Pagination cursor when listing R2 buckets' }, - rulesetCursor: { type: 'string', description: 'Pagination cursor when listing rulesets' }, - workerTagFilter: { type: 'string', description: 'Tag filter when listing Worker scripts' }, - accessAppTags: { type: 'string', description: 'Tag names applied to an Access application' }, - listNameFilter: { + accessApplicationLandingPageDesign: { + type: 'json', + description: + 'JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title.', + }, + accessApplicationSkipAppLauncherLoginPage: { + type: 'boolean', + description: 'Determines when to skip the App Launcher landing page.', + }, + accessGroupExclude: { + type: 'json', + description: + 'JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + accessGroupInclude: { + type: 'json', + description: + 'JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + accessGroupIsDefault: { type: 'boolean', description: 'Whether this is the default group' }, + accessGroupName: { type: 'string', description: 'The name of the Access group.' }, + accessGroupRequire: { + type: 'json', + description: + 'JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + accessPolicyApprovalGroups: { + type: 'json', + description: + 'JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid.', + }, + accessPolicyConnectionRules: { + type: 'json', + description: + 'JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh.', + }, + accessPolicyMfaConfig: { + type: 'json', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, + accessServiceTokenClientSecretVersion: { + type: 'number', + description: + 'A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately.', + }, + accessServiceTokenEnabled: { + type: 'boolean', + description: + 'Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved and can be re-enabled. A service token reported as leaked is disabled automatically and cannot be re-enabled until its secret is rotated; attempting to do so returns a 409. Defaults to enabled when omitted on create.', + }, + accessServiceTokenPreviousClientSecretExpiresAt: { type: 'string', description: - 'Name filter shared by the Access application, group, service token, and tunnel list operations', + 'The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set.', }, - accessAppDomainFilter: { + dnsRecordSettings: { + type: 'json', + description: + 'JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname.', + }, + dnsRecordPrivateRouting: { + type: 'boolean', + description: 'Enables private network routing to the origin.', + }, + dnsRecordData: { + type: 'json', + description: + 'JSON object. Structured record data; fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint.', + }, + dnsRecordIncludeShadowMetadata: { + type: 'boolean', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + rateLimitRuleActionparameters: { + type: 'json', + description: + "JSON object. The parameters configuring the rule's action. Fields: response, algorithms, id, matched_data, overrides, cookie_fields, raw_response_fields, request_fields, response_fields, transformed_request_fields, from_list, from_value, headers, uri, host_header, origin, sni, increment, content_type, status_code, content, asset_name, immutable, max-age, must-revalidate, must-understand, no-cache, no-store, no-transform, private, proxy-revalidate, public, s-maxage, stale-if-error, stale-while-revalidate, additional_cacheable_ports, browser_ttl, cache, cache_key, cache_reserve, edge_ttl, origin_cache_control, origin_error_page_passthru, origin_range_requests, read_timeout, respect_strong_etags, serve_stale, shared_dictionary, strip_etags, strip_last_modified, strip_set_cookie, vary, operation, values, expression, automatic_https_rewrites, autominify, bic, content_converter, disable_apps, disable_pay_per_crawl, disable_rum, disable_zaraz, email_obfuscation, fonts, hotlink_protection, mirage, opportunistic_encryption, polish, redirects_for_ai_training, request_body_buffering, response_body_buffering, rocket_loader, security_level, server_side_excludes, ssl, sxg, webmcp_enabled, webmcp_packs, phase, phases, products, rules, ruleset, rulesets, link_maze.", + }, + rateLimitRuleExposedCredentialCheck: { + type: 'json', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + rateLimitRuleId: { type: 'string', description: 'The unique ID of the rule.' }, + rateLimitRuleLogging: { + type: 'json', + description: + "JSON object. An object configuring the rule's logging behavior. Fields: enabled.", + }, + rateLimitRuleRef: { type: 'string', - description: 'Domain filter when listing Access applications', + description: "The reference of the rule (the rule's ID by default).", }, - tunnelStatus: { type: 'string', description: 'Status filter when listing tunnels' }, - - appType: { type: 'string', description: 'Access application type' }, - updateAppType: { + rateLimitRulePosition: { + type: 'json', + description: + 'JSON object. An object configuring where the rule will be placed. Fields: before, after, index.', + }, + rateLimitRuleScorePerPeriod: { + type: 'number', + description: + 'The score threshold per period for which the action will be executed the first time.', + }, + rateLimitRuleScoreResponseHeaderName: { type: 'string', - description: 'Access application type a replaced application ends up with', + description: + 'A response header name provided by the origin, which contains the score to increment rate limit counter with.', }, - updatePolicyDecision: { + rateLimitRuleDryRun: { type: 'boolean', description: 'dry run' }, + rulesetRuleExposedCredentialCheck: { + type: 'json', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + rulesetRuleId: { type: 'string', description: 'The unique ID of the rule.' }, + rulesetRuleLogging: { + type: 'json', + description: + "JSON object. An object configuring the rule's logging behavior. Fields: enabled.", + }, + rulesetRuleRatelimit: { + type: 'json', + description: + "JSON object. An object configuring the rule's rate limit behavior. Fields: characteristics, counting_expression, mitigation_timeout, period, requests_per_period, requests_to_origin, score_per_period, score_response_header_name.", + }, + rulesetRuleDryRun: { type: 'boolean', description: 'dry run' }, + rulesetDryRun: { type: 'boolean', description: 'dry run' }, + tunnelConfigSrc: { type: 'string', - description: 'Decision a replaced Access policy ends up applying', + description: + 'Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Allowed values: local, cloudflare.', }, - rateLimitAction: { + tunnelName: { type: 'string', description: 'A user-friendly name for a tunnel.' }, + tunnelTunnelSecret: { type: 'string', - description: 'Action applied once a rate limit is exceeded', + description: + 'Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string.', }, - updateRateLimitAction: { + workerRoutePattern: { type: 'string', - description: 'Action a replaced rate limiting rule ends up applying', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', }, - content: { type: 'string', description: 'DNS record content' }, - ttl: { type: 'number', description: 'Time to live in seconds' }, - proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, - priority: { + workerRouteScript: { + type: 'string', + description: 'Name of the script to run if the route matches.', + }, + groupId: { type: 'string', description: 'Group id' }, + deleteRulesetRuleDryRun: { type: 'boolean', description: 'dry run' }, + deleteRulesetDryRun: { + type: 'boolean', + description: + 'Validates the request without persisting changes when set to `true`. Responses that normally return 200 return `result: null`; endpoints that normally return 204 continue to return 204.', + }, + routeId: { type: 'string', description: 'Route id' }, + deleteWorkerScriptForce: { + type: 'boolean', + description: + 'If true, delete the Worker even when other Workers still reference it. Service bindings in those Workers may be left broken. Durable Object namespaces implemented by the deleted Worker are deleted even if other Workers reference them.', + }, + getDnsRecordIncludeShadowMetadata: { + type: 'boolean', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + listAccessApplicationsTargetAttributes: { + type: 'string', + description: 'Target Criteria attributes in key=value format.', + }, + listAccessIdentityProvidersScimEnabled: { + type: 'string', + description: + 'Indicates to Access to only retrieve identity providers that have the System for Cross-Domain Identity Management (SCIM) enabled.', + }, + listAccessIdentityProvidersPage: { type: 'number', description: 'Page number of results.' }, + listAccessIdentityProvidersPerPage: { type: 'number', + description: 'Number of results per page.', + }, + listDnsRecordsNameContains: { + type: 'string', + description: 'Substring of the DNS record name. Name filters are case-insensitive.', + }, + listDnsRecordsNameStartswith: { + type: 'string', + description: 'Prefix of the DNS record name. Name filters are case-insensitive.', + }, + listDnsRecordsNameEndswith: { + type: 'string', + description: 'Suffix of the DNS record name. Name filters are case-insensitive.', + }, + listDnsRecordsContentContains: { + type: 'string', + description: 'Substring of the DNS record content. Content filters are case-insensitive.', + }, + listDnsRecordsContentStartswith: { + type: 'string', + description: 'Prefix of the DNS record content. Content filters are case-insensitive.', + }, + listDnsRecordsContentEndswith: { + type: 'string', + description: 'Suffix of the DNS record content. Content filters are case-insensitive.', + }, + listDnsRecordsCommentPresent: { + type: 'boolean', + description: 'If this parameter is present, only records *with* a comment are returned.', + }, + listDnsRecordsCommentAbsent: { + type: 'boolean', + description: 'If this parameter is present, only records *without* a comment are returned.', + }, + listDnsRecordsCommentExact: { + type: 'string', + description: 'Exact value of the DNS record comment. Comment filters are case-insensitive.', + }, + listDnsRecordsCommentStartswith: { + type: 'string', + description: 'Prefix of the DNS record comment. Comment filters are case-insensitive.', + }, + listDnsRecordsCommentEndswith: { + type: 'string', + description: 'Suffix of the DNS record comment. Comment filters are case-insensitive.', + }, + listDnsRecordsTagPresent: { + type: 'string', + description: + 'Name of a tag which must be present on the DNS record. Tag filters are case-insensitive.', + }, + listDnsRecordsTagAbsent: { + type: 'string', description: - 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority inside the record content instead', + 'Name of a tag which must *not* be present on the DNS record. Tag filters are case-insensitive.', }, - comment: { type: 'string', description: 'Record comment' }, - search: { type: 'string', description: 'Free-text search across record properties' }, - tag: { type: 'string', description: 'Filter by an exact tag name' }, - tag_match: { type: 'string', description: 'Tag filter match logic (any, all)' }, - commentFilter: { type: 'string', description: 'Filter records by comment content' }, - settingId: { type: 'string', description: 'Zone setting ID' }, - settingIds: { + listDnsRecordsTagContains: { type: 'string', - description: 'Comma-separated zone setting IDs to read, or blank for the default set', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value contains ``. Tag filters are case-insensitive.', }, - value: { type: 'string', description: 'Setting value' }, - since: { type: 'string', description: 'Start date for analytics' }, - until: { type: 'string', description: 'End date for analytics' }, - metrics: { type: 'string', description: 'Comma-separated metrics to retrieve' }, - dimensions: { type: 'string', description: 'Comma-separated dimensions to group by' }, - filters: { type: 'string', description: 'Filters to apply (e.g., queryType==A)' }, - sort: { type: 'string', description: 'Sort order for results' }, - limit: { type: 'number', description: 'Maximum number of results' }, - status: { type: 'string', description: 'Status filter when listing zones' }, - page: { type: 'number', description: 'Page number for pagination' }, - per_page: { type: 'number', description: 'Number of results per page' }, - deploy: { + listDnsRecordsTagStartswith: { type: 'string', - description: 'Filter certificates by deployment environment (staging, production)', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value starts with ``. Tag filters are case-insensitive.', }, - purge_everything: { type: 'boolean', description: 'Purge all cached content' }, - files: { type: 'string', description: 'Comma-separated URLs to purge' }, - tags: { type: 'string', description: 'Comma-separated DNS record tags' }, - hosts: { type: 'string', description: 'Comma-separated hostnames to purge (Enterprise only)' }, - prefixes: { + listDnsRecordsTagEndswith: { type: 'string', - description: 'Comma-separated URL prefixes to purge (Enterprise only)', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value ends with ``. Tag filters are case-insensitive.', }, - rulesetId: { type: 'string', description: 'Ruleset ID' }, - ruleId: { type: 'string', description: 'Rule ID within a ruleset' }, - phase: { type: 'string', description: 'Ruleset phase' }, - rulesetName: { type: 'string', description: 'Name for a newly created ruleset' }, - kind: { type: 'string', description: 'Ruleset kind for ruleset creation' }, - rules: { type: 'string', description: 'JSON array of rules to seed a new ruleset with' }, - action: { type: 'string', description: 'Action a rule performs' }, - expression: { type: 'string', description: 'Cloudflare filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag' }, - actionParameters: { type: 'string', description: 'JSON action parameters for a rule' }, - rateLimitActionParameters: { + listDnsRecordsIncludeShadowMetadata: { + type: 'boolean', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + listDnsRecordsShadowedByName: { type: 'string', - description: 'JSON action parameters a replaced rate limiting rule ends up with', + description: + 'Filters the response to records at or below the specified NS delegation name. NS, DS, and NSEC records at the delegation name are excluded because they are not shadowed by that delegation. Those record types are included only when they exist below the delegation. The value must be a non-apex subdomain of the zone. Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', }, - ratelimit: { + listDnsRecordsShadowingName: { type: 'string', - description: 'JSON rate limiting configuration to preserve when replacing a rule', + description: + 'Returns NS records that shadow the given name, searching at the name itself and each of its ancestor names within the zone, excluding the zone apex. The value must be a subdomain of the zone; the zone apex is not accepted. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', }, - logging: { + listR2BucketsOrder: { type: 'string', - description: 'JSON logging configuration to preserve when replacing a rule', + description: 'Order buckets by name. Allowed values: name.', }, - position: { type: 'string', description: 'JSON position object for a new rule' }, - characteristics: { + listZonesType: { type: 'string', - description: 'Comma-separated rate limiting counting characteristics', + description: 'Comma-separated zone types: full, partial, secondary, internal', }, - period: { type: 'number', description: 'Rate limiting counting period in seconds' }, - requestsPerPeriod: { - type: 'number', - description: 'Requests allowed within the rate limiting period', + listZonesAccountName: { + type: 'string', + description: + 'An account Name. Optional filter operators can be provided to extend refine the search: * `equal` (default) * `not_equal` * `starts_with` * `ends_with` * `contains` * `starts_with_case_sensitive` * `ends_with_case_sensitive` * `contains_case_sensitive`', }, - mitigationTimeout: { - type: 'number', - description: 'Seconds the rate limiting action stays applied', + rotateAccessServiceTokenPreviousClientSecretExpiresAt: { + type: 'string', + description: + 'The expiration of the previous `client_secret`. If not provided, it defaults to the current timestamp in order to immediately expire the previous secret. If the service token was reported as leaked, this must not be in the future; the leaked secret is discarded immediately.', }, - counting_expression: { + accessServiceTokenDuration: { type: 'string', - description: 'Expression selecting which requests are counted', + description: + 'The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us (or µs), ms, s, m, h. The default is 1 year in hours (8760h).', }, - requestsToOrigin: { - type: 'boolean', - description: 'Whether only requests reaching the origin are counted', + accessServiceTokenName: { type: 'string', description: 'The name of the service token.' }, + dnsRecordClearcomment: { type: 'boolean', description: 'Clear the stored DNS record comment' }, + r2BucketCorsRules: { + type: 'json', + description: 'JSON array. rules Fields: allowed, exposeHeaders, id, maxAgeSeconds.', }, - appId: { type: 'string', description: 'Access application ID' }, - policyId: { type: 'string', description: 'Access policy ID' }, - serviceTokenId: { type: 'string', description: 'Access service token ID' }, - domain: { type: 'string', description: 'Hostname and path secured by Access' }, - aud: { type: 'string', description: 'Access application audience tag' }, - exact: { type: 'boolean', description: 'Whether Access list filters must match exactly' }, - sessionDuration: { type: 'string', description: 'Access session duration' }, - allowedIdps: { type: 'string', description: 'Comma-separated identity provider IDs' }, - appLauncherVisible: { - type: 'boolean', - description: 'Whether the application appears in the App Launcher', + r2BucketLifecycleRules: { + type: 'json', + description: + 'JSON array. rules Fields: abortMultipartUploadsTransition, conditions, deleteObjectsTransition, enabled, id, storageClassTransitions.', }, - autoRedirectToIdentity: { - type: 'boolean', - description: 'Whether users skip the identity provider picker', + rulesetRulePosition: { + type: 'json', + description: + 'JSON object. An object configuring where the rule will be placed. Fields: before, after, index.', }, - customDenyMessage: { type: 'string', description: 'Message shown when access is denied' }, - customDenyUrl: { type: 'string', description: 'URL denied users are redirected to' }, - logoUrl: { type: 'string', description: 'Application logo URL' }, - policies: { type: 'string', description: 'JSON array of policies to attach' }, - saasApp: { + rulesetDescription: { type: 'string', - description: 'JSON SaaS configuration for a saas-typed Access application', + description: 'An informative description of the ruleset.', }, - targetCriteria: { - type: 'string', - description: 'JSON target criteria for an infrastructure- or rdp-typed Access application', + rulesetRules: { + type: 'json', + description: + 'JSON array. The list of rules in the ruleset. Fields: action, action_parameters, categories, description, enabled, exposed_credential_check, expression, id, last_updated, logging, ratelimit, ref, version.', }, - decision: { type: 'string', description: 'Access policy decision' }, - include: { type: 'string', description: 'JSON array of Access rules evaluated with OR logic' }, - exclude: { type: 'string', description: 'JSON array of Access rules evaluated with NOT logic' }, - require: { type: 'string', description: 'JSON array of Access rules evaluated with AND logic' }, - precedence: { type: 'number', description: 'Access policy evaluation order' }, - approvalRequired: { - type: 'boolean', - description: 'Whether an approver must grant each access request', + tunnelConfigurationConfig: { + type: 'json', + description: + 'JSON object. The tunnel configuration and ingress rules. Fields: ingress, originRequest, warp-routing.', }, - isolationRequired: { + zoneSettingEnabled: { type: 'boolean', - description: 'Whether sessions must run in a remote isolated browser', + description: + 'Enrollment value for ssl_recommender; this setting uses enabled instead of value', }, - purposeJustificationRequired: { + zonePaused: { type: 'boolean', - description: 'Whether users must state a reason for access', + description: + 'Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits.', }, - purposeJustificationPrompt: { - type: 'string', - description: 'Prompt shown when a justification is required', + zonePlan: { + type: 'json', + description: + "JSON object. (Deprecated) Please use the `/zones/{zone_id}/subscription` API to update a zone's plan. Changing this value will create/cancel associated subscriptions. To view available plans for this zone, see Zone Plans. Fields: id.", }, - duration: { type: 'string', description: 'Service token lifetime' }, - bucketName: { type: 'string', description: 'R2 bucket name' }, - locationHint: { type: 'string', description: 'R2 bucket location hint' }, - storageClass: { type: 'string', description: 'R2 default storage class' }, - jurisdiction: { type: 'string', description: 'R2 data-residency jurisdiction' }, - name_contains: { type: 'string', description: 'Filter R2 buckets by name substring' }, - start_after: { type: 'string', description: 'R2 bucket name to start listing after' }, - cursor: { type: 'string', description: 'Pagination cursor' }, - scriptName: { type: 'string', description: 'Workers script name' }, - tunnelId: { type: 'string', description: 'Cloudflare Tunnel ID' }, - uuid: { type: 'string', description: 'Filter tunnels by UUID' }, - is_deleted: { type: 'boolean', description: 'Whether to return deleted tunnels' }, - include_prefix: { type: 'string', description: 'Only include tunnels with this name prefix' }, - exclude_prefix: { type: 'string', description: 'Exclude tunnels with this name prefix' }, - existed_at: { type: 'string', description: 'Return tunnels that existed at this timestamp' }, - was_active_at: { + zoneVanityNameServers: { + type: 'json', + description: + 'JSON array. An array of domains used for custom name servers. This is only available for Business and Enterprise plans.', + }, + }, + outputs: { + zone_id: { type: 'string', - description: 'Return tunnels that were active at this timestamp', + description: 'Legacy DNS response zone ID when returned by Cloudflare', }, - was_inactive_at: { + zone_name: { type: 'string', - description: 'Return tunnels that were inactive at this timestamp', + description: 'Legacy DNS response zone name when returned by Cloudflare', + }, + locked: { + type: 'boolean', + description: 'Legacy DNS response lock flag when returned by Cloudflare', }, - }, - outputs: { zones: { type: 'json', description: 'List of zones/domains' }, records: { type: 'json', description: 'List of DNS records' }, certificates: { type: 'json', description: 'List of SSL/TLS certificate packs' }, - settings: { type: 'json', description: 'List of zone settings' }, + settings: { + type: 'json', + description: + 'DNS record settings, Worker configuration, or zone settings depending on the operation', + }, unreadable: { type: 'json', description: 'Requested zone settings Cloudflare refused, with the reason for each', @@ -2979,16 +5381,16 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, 'Per-metric DNS analytics maximums. Cloudflare documents this as currently always an empty object', }, query: { type: 'json', description: 'Echo of the DNS analytics query parameters sent' }, - validation_errors: { type: 'json', description: 'Validation issues for certificate packs' }, - data: { type: 'json', description: 'Raw analytics data rows from the DNS analytics report' }, + data: { + type: 'json', + description: 'Structured DNS record data, or DNS analytics rows depending on the operation', + }, data_lag: { type: 'number', description: 'Processing lag in seconds before analytics data becomes available', }, rows: { type: 'number', description: 'Total number of rows in the DNS analytics result set' }, id: { type: 'string', description: 'Resource ID' }, - zone_id: { type: 'string', description: 'Zone ID the record belongs to' }, - zone_name: { type: 'string', description: 'Zone domain name' }, name: { type: 'string', description: 'Resource name' }, status: { type: 'string', description: 'Resource status' }, paused: { type: 'boolean', description: 'Whether the zone is paused' }, @@ -3017,7 +5419,6 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, proxiable: { type: 'boolean', description: 'Whether the record can be proxied' }, proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, ttl: { type: 'number', description: 'TTL in seconds (1 = automatic)' }, - locked: { type: 'boolean', description: 'Whether the record is locked' }, priority: { type: 'number', description: 'Record priority, returned for MX and URI records' }, comment: { type: 'string', description: 'Record comment' }, tags: { type: 'json', description: 'Tags associated with the record or cache tags to purge' }, @@ -3136,15 +5537,200 @@ Return ONLY the JSON array - no explanations, no markdown fences.`, tun_type: { type: 'string', description: 'Tunnel type' }, remote_config: { type: 'boolean', description: 'Whether the tunnel is remotely managed' }, deleted_at: { type: 'string', description: 'Tunnel deletion timestamp' }, - conns_active_at: { + conns_active_at: { type: 'string', description: 'When the tunnel last had active connections' }, + conns_inactive_at: { type: 'string', description: 'When the tunnel last lost all connections' }, + connections: { type: 'json', description: 'Active connector connections for the tunnel' }, + oauth_configuration: { + type: 'json', + description: + '**Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access.', + }, + user_populations: { + type: 'json', + description: 'The single user population associated with this application.', + }, + allow_authenticate_via_warp: { + type: 'boolean', + description: + 'When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication.', + }, + allow_iframe: { + type: 'boolean', + description: 'Enables loading application content in an iFrame.', + }, + cors_headers: { type: 'json', description: 'cors headers' }, + custom_non_identity_deny_url: { + type: 'string', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules.', + }, + custom_pages: { + type: 'json', + description: 'The custom pages that will be displayed when applicable for this application', + }, + eager_redirect_cookie_setting: { + type: 'boolean', + description: + 'Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior.', + }, + enable_binding_cookie: { + type: 'boolean', + description: + 'Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks.', + }, + http_only_cookie_attribute: { + type: 'boolean', + description: + 'Enables the HttpOnly cookie attribute, which increases security against XSS attacks.', + }, + mfa_config: { + type: 'json', + description: 'Configures multi-factor authentication (MFA) settings.', + }, + options_preflight_bypass: { + type: 'boolean', + description: + 'Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set.', + }, + path_cookie_attribute: { + type: 'boolean', + description: + "Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default", + }, + read_service_tokens_from_header: { type: 'string', - description: 'When the tunnel last had active connections', + description: + 'Allows matching Access Service Tokens passed HTTP in a single header with this name.', }, - conns_inactive_at: { + same_site_cookie_attribute: { type: 'string', - description: 'When the tunnel last lost all connections', + description: + 'Sets the SameSite cookie setting, which provides increased security against CSRF attacks.', }, - connections: { type: 'json', description: 'Active connector connections for the tunnel' }, + scim_config: { + type: 'json', + description: + 'Configuration for provisioning to this application via SCIM. This is currently in closed beta.', + }, + service_auth_401_redirect: { + type: 'boolean', + description: + 'Returns a 401 status code when the request is blocked by a Service Auth policy.', + }, + skip_interstitial: { + type: 'boolean', + description: 'Enables automatic authentication through cloudflared.', + }, + use_clientless_isolation_app_launcher_url: { + type: 'boolean', + description: + 'Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application.', + }, + saas_app: { type: 'json', description: 'saas app' }, + app_launcher_logo_url: { + type: 'string', + description: 'The image URL of the logo shown in the App Launcher header.', + }, + bg_color: { type: 'string', description: 'The background color of the App Launcher page.' }, + footer_links: { type: 'json', description: 'The links in the App Launcher footer.' }, + header_bg_color: { + type: 'string', + description: 'The background color of the App Launcher header.', + }, + landing_page_design: { + type: 'json', + description: 'The design of the App Launcher landing page shown to users when they log in.', + }, + skip_app_launcher_login_page: { + type: 'boolean', + description: 'Determines when to skip the App Launcher landing page.', + }, + target_criteria: { type: 'json', description: 'target criteria' }, + is_default: { + type: 'json', + description: + 'Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules.', + }, + approval_groups: { + type: 'json', + description: 'Administrators who can approve a temporary authentication request.', + }, + connection_rules: { + type: 'json', + description: + 'The rules that define how users may connect to the targets secured by your application.', + }, + private_routing: { + type: 'boolean', + description: 'Enables private network routing to the origin.', + }, + metadata: { type: 'json', description: 'Metadata associated with the tunnel.' }, + pattern: { + type: 'string', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', + }, + script: { type: 'string', description: 'Name of the script to run if the route matches.' }, + cname_suffix: { + type: 'string', + description: 'Allows the customer to use a custom apex. *Tenants Only Configuration*.', + }, + original_dnshost: { + type: 'string', + description: 'DNS host at the time of switching to Cloudflare.', + }, + original_registrar: { + type: 'string', + description: 'Registrar for the domain at the time of switching to Cloudflare.', + }, + tenant: { + type: 'json', + description: + 'The root organizational unit that this zone belongs to (such as a tenant or organization).', + }, + tenant_unit: { + type: 'json', + description: + 'The immediate parent organizational unit that this zone belongs to (such as under a tenant or sub-organization).', + }, + verification_key: { type: 'string', description: 'Verification key for partial zone setup.' }, + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + leak_report_url: { + type: 'string', + description: + 'Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked.', + }, + leak_reported_at: { + type: 'string', + description: + "When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked.", + }, + leak_reporter: { + type: 'string', + description: + 'The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked.', + }, + token: { type: 'string', description: 'Token for connecting cloudflared to the tunnel' }, + annotations: { + type: 'json', + description: + 'Annotations for the Worker version. Annotations are not inherited across settings updates; omitting this field means the new version will have no annotations.', + }, + cache_options: { + type: 'json', + description: + 'Global CacheW configuration for the Worker. When caching is on, the platform provisions a `cloudflare.app` zone for the Worker. A `type: worker` entry in the `exports` map can override this value for a single entrypoint.', + }, + exports: { + type: 'json', + description: + 'Declarative exports for the Worker, keyed by export name. Worker entrypoint entries (`type: worker`) carry cache configuration for that entrypoint. Durable Object entries (`type: durable-object`) are also configured here and drive namespace reconciliation. At most 100 entries; class names are at most 128 characters.', + }, + exports_reconciliation: { + type: 'json', + description: 'Summary of what the declarative exports reconciliation did on this upload.', + }, + result_info: { type: 'json', description: 'Pagination metadata returned by Cloudflare' }, }, } diff --git a/apps/sim/lib/internal/cloudflare/operations/get-zone-settings.ts b/apps/sim/lib/internal/cloudflare/operations/get-zone-settings.ts index 5f4860882ed..4722472c8eb 100644 --- a/apps/sim/lib/internal/cloudflare/operations/get-zone-settings.ts +++ b/apps/sim/lib/internal/cloudflare/operations/get-zone-settings.ts @@ -1,4 +1,5 @@ import { getErrorMessage } from '@sim/utils/errors' +import { readResponseJsonWithLimit } from '@/lib/core/utils/stream-limits' import type { InternalToolOperationImplementation } from '@/lib/internal/tool-operations/types' import { mapZoneSetting, zoneSettingUrl } from '@/tools/cloudflare/get_zone_settings' import type { @@ -36,8 +37,11 @@ export const executeGetZoneSettingsOperation: InternalToolOperationImplementatio headers, signal, }) - const data = (await response.json()) as CloudflareEnvelope - if (!data.success) { + const data = await readResponseJsonWithLimit>( + response, + { maxBytes: 1024 * 1024, label: 'Cloudflare zone setting' } + ) + if (!response.ok || !data.success || !data.result) { return { settingId, error: cloudflareErrorMessage(data, `Failed to read zone setting ${settingId}`), diff --git a/apps/sim/tools/cloudflare/cloudflare.test.ts b/apps/sim/tools/cloudflare/cloudflare.test.ts index e7dc79830b6..23c4109a8f6 100644 --- a/apps/sim/tools/cloudflare/cloudflare.test.ts +++ b/apps/sim/tools/cloudflare/cloudflare.test.ts @@ -222,6 +222,13 @@ describe('a shared subBlock id means the same thing everywhere', () => { 'appId', 'bucketName', 'rulesetId', + 'recordId', + 'policyId', + 'serviceTokenId', + 'groupId', + 'routeId', + 'scriptName', + 'tunnelId', ]) /** @@ -848,21 +855,18 @@ describe('zone settings are read through the endpoints Cloudflare still supports ]) }) - it('keeps a crafted zone ID inside the zone path segment', async () => { + it('rejects a crafted zone ID before making a provider request', async () => { const fetchMock = vi .spyOn(globalThis, 'fetch') .mockImplementation(async (input) => settingEnvelope(String(input).split('/').pop()!, 'on')) - await executeGetZoneSettingsOperation({ + const result = await executeGetZoneSettingsOperation({ zoneId: '../accounts', apiKey, settingIds: 'ssl', } as never) - - expect(fetchMock).toHaveBeenCalledWith( - 'https://api.cloudflare.com/client/v4/zones/..%2Faccounts/settings/ssl', - expect.any(Object) - ) + expect(result.success).toBe(false) + expect(fetchMock).not.toHaveBeenCalled() }) it('does not let a dot-segment setting ID escape the settings endpoint', async () => { @@ -875,7 +879,7 @@ describe('zone settings are read through the endpoints Cloudflare still supports } as never)) as { success: boolean; error?: string } expect(out.success).toBe(false) - expect(out.error).toMatch(/setting ID must identify a resource/) + expect(out.error).toMatch(/settingId/) expect(fetchMock).not.toHaveBeenCalled() }) @@ -968,6 +972,21 @@ describe('zone settings are read through the endpoints Cloudflare still supports expect(out.error).toBe('Invalid zone identifier') }) + it('rejects a setting response whose declared size exceeds the per-setting cap', async () => { + vi.spyOn(globalThis, 'fetch').mockResolvedValue( + new Response(JSON.stringify({ success: true, result: { id: 'ssl', value: 'full' } }), { + headers: { 'Content-Length': String(1024 * 1024 + 1) }, + }) + ) + const result = await executeGetZoneSettingsOperation({ + zoneId: 'z1', + apiKey, + settingIds: 'ssl', + } as never) + expect(result.success).toBe(false) + expect(result.error).toMatch(/exceed|limit|large/i) + }) + it('refuses an unbounded fan-out instead of issuing the requests', async () => { const fetchMock = vi.spyOn(globalThis, 'fetch') @@ -1054,3 +1073,76 @@ describe('list transforms survive a non-array result', () => { expect(out.output[key]).toEqual([]) }) }) + +describe('Cloudflare review regressions', () => { + it.each(['create_access_application', 'update_access_application'])( + 'preserves existing SaaS and target inputs through %s request mapping', + (operation) => { + const tool = + operation === 'create_access_application' + ? cloudflareTools.cloudflareCreateAccessApplicationTool + : cloudflareTools.cloudflareUpdateAccessApplicationTool + const saasApp = { auth_type: 'saml', consumer_service_url: 'https://example.com/acs' } + const targetCriteria = [ + { port: 22, protocol: 'SSH', target_attributes: { hostname: ['example'] } }, + ] + const mapped = mapFor(operation, { + saasApp: JSON.stringify(saasApp), + targetCriteria: JSON.stringify(targetCriteria), + }) + expect(tool.request.body?.(mapped as never)).toMatchObject({ + saas_app: saasApp, + target_criteria: targetCriteria, + }) + } + ) + + it('keeps a pause-only zone update limited to that setting', () => { + const mapped = mapFor('update_zone', { zoneId: 'zone', zonePaused: 'true' }) + const body = cloudflareTools.cloudflareUpdateZoneTool.request.body?.(mapped as never) + expect(body).toEqual({ paused: true }) + }) + + it.each([true, false])('returns the ssl_recommender enabled value %s', async (enabled) => { + const transform = cloudflareTools.cloudflareUpdateZoneSettingTool.transformResponse + if (!transform) throw new Error('Expected response transform') + const result = await transform( + new Response( + JSON.stringify({ + success: true, + result: { id: 'ssl_recommender', enabled }, + }) + ) + ) + expect(result.output.value).toBe(String(enabled)) + }) +}) + +describe('Cloudflare response envelopes and conditional inputs', () => { + it.each([undefined, null])('accepts confirmed group deletion with result %s', async (result) => { + const transform = cloudflareTools.cloudflareDeleteAccessGroupTool.transformResponse + if (!transform) throw new Error('Expected response transform') + const response = await transform(envelope(result)) + expect(response.success).toBe(true) + expect(response.output.id).toBeNull() + }) + + it.each([undefined, null, 'true'])( + 'rejects an Access list envelope with success %s', + async (success) => { + const transform = cloudflareTools.cloudflareListAccessApplicationsTool.transformResponse + if (!transform) throw new Error('Expected response transform') + const response = await transform(new Response(JSON.stringify({ success, result: [] }))) + expect(response.success).toBe(false) + } + ) + + it.each([ + { settingId: 'ssl_recommender', field: 'enabled' }, + { settingId: 'ssl', field: 'value' }, + ])('rejects $settingId updates without $field', ({ settingId, field }) => { + const body = cloudflareTools.cloudflareUpdateZoneSettingTool.request.body + if (!body) throw new Error('Expected request body') + expect(() => body({ apiKey, zoneId: 'zone', settingId })).toThrow(field) + }) +}) diff --git a/apps/sim/tools/cloudflare/create_access_application.ts b/apps/sim/tools/cloudflare/create_access_application.ts index 0ecf0f12e43..15204d5d8ba 100644 --- a/apps/sim/tools/cloudflare/create_access_application.ts +++ b/apps/sim/tools/cloudflare/create_access_application.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { ACCESS_APPLICATION_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessApplicationResponse, CloudflareCreateAccessApplicationParams, @@ -5,13 +7,14 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyAccessApplication, - mapAccessApplication, + mapCloudflareFields, parseCsvParam, parseJsonArrayParam, parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createAccessApplicationTool: ToolConfig< CloudflareCreateAccessApplicationParams, @@ -24,6 +27,188 @@ export const createAccessApplicationTool: ToolConfig< version: '1.0.0', params: { + destinations: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id.', + }, + oauth_configuration: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Required for end_user applications. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant.', + }, + self_hosted_domains: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored.', + }, + user_populations: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Required for end_user applications. The single user population associated with this application.', + }, + allow_authenticate_via_warp: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication.', + }, + allow_iframe: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables loading application content in an iFrame.', + }, + cors_headers: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age.', + }, + custom_non_identity_deny_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules.', + }, + custom_pages: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. The custom pages that will be displayed when applicable for this application', + }, + eager_redirect_cookie_setting: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior.', + }, + enable_binding_cookie: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks.', + }, + http_only_cookie_attribute: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Enables the HttpOnly cookie attribute, which increases security against XSS attacks.', + }, + mfa_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, + options_preflight_bypass: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set.', + }, + path_cookie_attribute: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + "Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default", + }, + read_service_tokens_from_header: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the (CF-Access-Client-Id, CF-Access-Client-Secret) pair of headers. The header value will be interpreted as a json object similar to: { "cf-access-client-id": "", "cf-access-client-secret": "" }', + }, + same_site_cookie_attribute: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Sets the SameSite cookie setting, which provides increased security against CSRF attacks.', + }, + scim_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri.', + }, + service_auth_401_redirect: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Returns a 401 status code when the request is blocked by a Service Auth policy.', + }, + skip_interstitial: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables automatic authentication through cloudflared.', + }, + use_clientless_isolation_app_launcher_url: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application.', + }, + app_launcher_logo_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The image URL of the logo shown in the App Launcher header.', + }, + bg_color: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The background color of the App Launcher page.', + }, + footer_links: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'JSON array. The links in the App Launcher footer. Fields: name, url.', + }, + header_bg_color: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The background color of the App Launcher header.', + }, + landing_page_design: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title.', + }, + skip_app_launcher_login_page: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Determines when to skip the App Launcher landing page.', + }, accountId: { type: 'string', required: true, @@ -35,7 +220,7 @@ export const createAccessApplicationTool: ToolConfig< required: true, visibility: 'user-or-llm', description: - 'Application type: self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be created through the API', + 'Application type: self_hosted, end_user, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be created through the API', }, domain: { type: 'string', @@ -130,7 +315,7 @@ export const createAccessApplicationTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps`, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -171,88 +356,90 @@ export const createAccessApplicationTool: ToolConfig< const targetCriteria = parseJsonArrayParam(params.targetCriteria, 'Target Criteria') if (targetCriteria) body.target_criteria = targetCriteria + if (params.destinations !== undefined && params.destinations !== '') + body.destinations = parseJsonArrayParam(params.destinations, 'destinations') + if (params.oauth_configuration !== undefined && params.oauth_configuration !== '') + body.oauth_configuration = parseJsonObjectParam( + params.oauth_configuration, + 'oauth_configuration' + ) + if (params.self_hosted_domains !== undefined && params.self_hosted_domains !== '') + body.self_hosted_domains = parseJsonArrayParam( + params.self_hosted_domains, + 'self_hosted_domains' + ) + if (params.user_populations !== undefined && params.user_populations !== '') + body.user_populations = parseJsonArrayParam(params.user_populations, 'user_populations') + if (params.allow_authenticate_via_warp !== undefined) + body.allow_authenticate_via_warp = params.allow_authenticate_via_warp + if (params.allow_iframe !== undefined) body.allow_iframe = params.allow_iframe + if (params.cors_headers !== undefined && params.cors_headers !== '') + body.cors_headers = parseJsonObjectParam(params.cors_headers, 'cors_headers') + if ( + params.custom_non_identity_deny_url !== undefined && + params.custom_non_identity_deny_url !== '' + ) + body.custom_non_identity_deny_url = params.custom_non_identity_deny_url + if (params.custom_pages !== undefined && params.custom_pages !== '') + body.custom_pages = parseJsonArrayParam(params.custom_pages, 'custom_pages') + if (params.eager_redirect_cookie_setting !== undefined) + body.eager_redirect_cookie_setting = params.eager_redirect_cookie_setting + if (params.enable_binding_cookie !== undefined) + body.enable_binding_cookie = params.enable_binding_cookie + if (params.http_only_cookie_attribute !== undefined) + body.http_only_cookie_attribute = params.http_only_cookie_attribute + if (params.mfa_config !== undefined && params.mfa_config !== '') + body.mfa_config = parseJsonObjectParam(params.mfa_config, 'mfa_config') + if (params.options_preflight_bypass !== undefined) + body.options_preflight_bypass = params.options_preflight_bypass + if (params.path_cookie_attribute !== undefined) + body.path_cookie_attribute = params.path_cookie_attribute + if ( + params.read_service_tokens_from_header !== undefined && + params.read_service_tokens_from_header !== '' + ) + body.read_service_tokens_from_header = params.read_service_tokens_from_header + if ( + params.same_site_cookie_attribute !== undefined && + params.same_site_cookie_attribute !== '' + ) + body.same_site_cookie_attribute = params.same_site_cookie_attribute + if (params.scim_config !== undefined && params.scim_config !== '') + body.scim_config = parseJsonObjectParam(params.scim_config, 'scim_config') + if (params.service_auth_401_redirect !== undefined) + body.service_auth_401_redirect = params.service_auth_401_redirect + if (params.skip_interstitial !== undefined) body.skip_interstitial = params.skip_interstitial + if (params.use_clientless_isolation_app_launcher_url !== undefined) + body.use_clientless_isolation_app_launcher_url = + params.use_clientless_isolation_app_launcher_url + if (params.app_launcher_logo_url !== undefined && params.app_launcher_logo_url !== '') + body.app_launcher_logo_url = params.app_launcher_logo_url + if (params.bg_color !== undefined && params.bg_color !== '') body.bg_color = params.bg_color + if (params.footer_links !== undefined && params.footer_links !== '') + body.footer_links = parseJsonArrayParam(params.footer_links, 'footer_links') + if (params.header_bg_color !== undefined && params.header_bg_color !== '') + body.header_bg_color = params.header_bg_color + if (params.landing_page_design !== undefined && params.landing_page_design !== '') + body.landing_page_design = parseJsonObjectParam( + params.landing_page_design, + 'landing_page_design' + ) + if (params.skip_app_launcher_login_page !== undefined) + body.skip_app_launcher_login_page = params.skip_app_launcher_login_page return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyAccessApplication(), - error: cloudflareErrorMessage(data, 'Failed to create Access application'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_APPLICATION_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to create access application') } + : {}), } - - return { success: true, output: mapAccessApplication(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Created Access application identifier' }, - name: { type: 'string', description: 'Application name', optional: true }, - domain: { - type: 'string', - description: 'Primary hostname and path secured by Access', - optional: true, - }, - type: { type: 'string', description: 'Application type', optional: true }, - aud: { type: 'string', description: 'Audience tag used to verify Access JWTs', optional: true }, - session_duration: { - type: 'string', - description: 'How long an Access session stays valid', - optional: true, - }, - allowed_idps: { - type: 'array', - description: 'Identity provider IDs users may authenticate with', - items: { type: 'string', description: 'Identity provider ID' }, - optional: true, - }, - app_launcher_visible: { - type: 'boolean', - description: 'Whether the app appears in the App Launcher', - optional: true, - }, - auto_redirect_to_identity: { - type: 'boolean', - description: 'Whether users skip the identity provider picker', - optional: true, - }, - custom_deny_message: { - type: 'string', - description: 'Message shown when access is denied', - optional: true, - }, - custom_deny_url: { - type: 'string', - description: 'URL users are redirected to when access is denied', - optional: true, - }, - logo_url: { type: 'string', description: 'Logo image URL', optional: true }, - self_hosted_domains: { - type: 'array', - description: - 'Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application', - items: { type: 'string', description: 'Hostname and path' }, - optional: true, - }, - destinations: { - type: 'json', - description: 'Public and private destinations secured by the application', - optional: true, - }, - tags: { - type: 'array', - description: 'Tags categorizing the application', - items: { type: 'string', description: 'Tag name' }, - optional: true, - }, - policies: { - type: 'json', - description: 'Access policies attached to the application', - optional: true, - }, }, + outputs: ACCESS_APPLICATION_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_access_group.ts b/apps/sim/tools/cloudflare/create_access_group.ts new file mode 100644 index 00000000000..397d61fb7b4 --- /dev/null +++ b/apps/sim/tools/cloudflare/create_access_group.ts @@ -0,0 +1,95 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareCreateAccessGroupParams, + CloudflareCreateAccessGroupResponse, +} from '@/tools/cloudflare/operation-types' +import { ACCESS_GROUP_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + parseJsonArrayParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const createAccessGroupTool: ToolConfig< + CloudflareCreateAccessGroupParams, + CloudflareCreateAccessGroupResponse +> = { + id: 'cloudflare_create_access_group', + name: 'Cloudflare Create Access Group', + description: 'Creates a new Access group.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + exclude: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + include: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + is_default: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether this is the default group', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The name of the Access group.', + }, + require: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/groups`, + method: 'POST', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + exclude: parseJsonArrayParam(params.exclude, 'exclude'), + include: parseJsonArrayParam(params.include, 'include'), + is_default: params.is_default, + name: params.name, + require: parseJsonArrayParam(params.require, 'require'), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_GROUP_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create access group') } : {}), + } + }, + outputs: ACCESS_GROUP_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/create_access_policy.ts b/apps/sim/tools/cloudflare/create_access_policy.ts index 6cb6d6db8ce..06566573047 100644 --- a/apps/sim/tools/cloudflare/create_access_policy.ts +++ b/apps/sim/tools/cloudflare/create_access_policy.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { ACCESS_POLICY_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessPolicyResponse, CloudflareCreateAccessPolicyParams, @@ -5,11 +7,13 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyAccessPolicy, - mapAccessPolicy, + mapCloudflareFields, parseJsonArrayParam, + parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createAccessPolicyTool: ToolConfig< CloudflareCreateAccessPolicyParams, @@ -22,6 +26,27 @@ export const createAccessPolicyTool: ToolConfig< version: '1.0.0', params: { + approval_groups: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid.', + }, + connection_rules: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh.', + }, + mfa_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, accountId: { type: 'string', required: true, @@ -114,7 +139,7 @@ export const createAccessPolicyTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}/policies`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}/policies`, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -146,70 +171,26 @@ export const createAccessPolicyTool: ToolConfig< body.purpose_justification_prompt = params.purposeJustificationPrompt } + if (params.approval_groups !== undefined && params.approval_groups !== '') + body.approval_groups = parseJsonArrayParam(params.approval_groups, 'approval_groups') + if (params.connection_rules !== undefined && params.connection_rules !== '') + body.connection_rules = parseJsonObjectParam(params.connection_rules, 'connection_rules') + if (params.mfa_config !== undefined && params.mfa_config !== '') + body.mfa_config = parseJsonObjectParam(params.mfa_config, 'mfa_config') return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyAccessPolicy(), - error: cloudflareErrorMessage(data, 'Failed to create Access policy'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_POLICY_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to create access policy') } + : {}), } - - return { success: true, output: mapAccessPolicy(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Created policy identifier' }, - name: { type: 'string', description: 'Policy name', optional: true }, - decision: { - type: 'string', - description: 'Decision the policy applies: allow, deny, non_identity, or bypass', - optional: true, - }, - precedence: { - type: 'number', - description: 'Evaluation order of the policy within the application', - optional: true, - }, - include: { - type: 'json', - description: 'Rules evaluated with OR logic', - optional: true, - }, - exclude: { type: 'json', description: 'Rules evaluated with NOT logic', optional: true }, - require: { type: 'json', description: 'Rules evaluated with AND logic', optional: true }, - session_duration: { - type: 'string', - description: 'How long a session granted by this policy stays valid', - optional: true, - }, - approval_required: { - type: 'boolean', - description: 'Whether an approver must grant each access request', - optional: true, - }, - isolation_required: { - type: 'boolean', - description: 'Whether the session must run in a remote browser', - optional: true, - }, - purpose_justification_required: { - type: 'boolean', - description: 'Whether users must state a reason for access', - optional: true, - }, - purpose_justification_prompt: { - type: 'string', - description: 'Prompt shown when a justification is required', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, }, + outputs: ACCESS_POLICY_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_access_service_token.ts b/apps/sim/tools/cloudflare/create_access_service_token.ts index dc6487411c7..a1f60c65305 100644 --- a/apps/sim/tools/cloudflare/create_access_service_token.ts +++ b/apps/sim/tools/cloudflare/create_access_service_token.ts @@ -1,9 +1,17 @@ +import { isRecordLike } from '@sim/utils/object' +import { SERVICE_TOKEN_SECRET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateAccessServiceTokenParams, CloudflareCreateAccessServiceTokenResponse, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createAccessServiceTokenTool: ToolConfig< CloudflareCreateAccessServiceTokenParams, @@ -16,6 +24,27 @@ export const createAccessServiceTokenTool: ToolConfig< version: '1.0.0', params: { + client_secret_version: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately.', + }, + enabled: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved and can be re-enabled. A service token reported as leaked is disabled automatically and cannot be re-enabled until its secret is rotated; attempting to do so returns a 409. Defaults to enabled when omitted on create.', + }, + previous_client_secret_expires_at: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set.', + }, accountId: { type: 'string', required: true, @@ -45,79 +74,34 @@ export const createAccessServiceTokenTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/service_tokens`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens`, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { const body: Record = { name: params.name } if (params.duration) body.duration = params.duration + if (params.client_secret_version !== undefined) + body.client_secret_version = params.client_secret_version + if (params.enabled !== undefined) body.enabled = params.enabled + if ( + params.previous_client_secret_expires_at !== undefined && + params.previous_client_secret_expires_at !== '' + ) + body.previous_client_secret_expires_at = params.previous_client_secret_expires_at return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - name: null, - client_id: null, - client_secret: null, - duration: null, - enabled: null, - expires_at: null, - last_seen_at: null, - created_at: null, - updated_at: null, - }, - error: cloudflareErrorMessage(data, 'Failed to create Access service token'), - } - } - - const token = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: token?.id ?? '', - name: token?.name ?? null, - client_id: token?.client_id ?? null, - client_secret: token?.client_secret ?? null, - duration: token?.duration ?? null, - enabled: token?.enabled ?? null, - expires_at: token?.expires_at ?? null, - last_seen_at: token?.last_seen_at ?? null, - created_at: token?.created_at ?? null, - updated_at: token?.updated_at ?? null, - }, + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_SECRET_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to create access service token') } + : {}), } }, - - outputs: { - id: { type: 'string', description: 'Created service token identifier' }, - name: { type: 'string', description: 'Service token name', optional: true }, - client_id: { - type: 'string', - description: 'Client ID sent in the CF-Access-Client-Id header', - optional: true, - }, - client_secret: { - type: 'string', - description: - 'Client secret sent in the CF-Access-Client-Secret header. Returned only once, at creation', - optional: true, - }, - duration: { - type: 'string', - description: 'How long the token stays valid before it expires', - optional: true, - }, - enabled: { type: 'boolean', description: 'Whether the token is active', optional: true }, - expires_at: { type: 'string', description: 'Expiry timestamp', optional: true }, - last_seen_at: { type: 'string', description: 'When the token was last used', optional: true }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, - }, + outputs: SERVICE_TOKEN_SECRET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_dns_record.ts b/apps/sim/tools/cloudflare/create_dns_record.ts index 9fb75216ec8..ea8342feb36 100644 --- a/apps/sim/tools/cloudflare/create_dns_record.ts +++ b/apps/sim/tools/cloudflare/create_dns_record.ts @@ -1,8 +1,19 @@ +import { isRecordLike } from '@sim/utils/object' +import { DNS_RECORD_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateDnsRecordParams, CloudflareCreateDnsRecordResponse, } from '@/tools/cloudflare/types' +import { + appendParam, + cloudflareErrorMessage, + mapCloudflareFields, + parseCsvParam, + parseJsonObjectParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createDnsRecordTool: ToolConfig< CloudflareCreateDnsRecordParams, @@ -14,6 +25,33 @@ export const createDnsRecordTool: ToolConfig< version: '1.0.0', params: { + settings: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname.', + }, + private_routing: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables private network routing to the origin.', + }, + data: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Structured record data. The available fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint.', + }, + include_shadow_metadata: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, zoneId: { type: 'string', required: true, @@ -34,7 +72,7 @@ export const createDnsRecordTool: ToolConfig< }, content: { type: 'string', - required: true, + required: false, visibility: 'user-or-llm', description: 'DNS record content (e.g., IP address for A records, target for CNAME)', }, @@ -55,7 +93,7 @@ export const createDnsRecordTool: ToolConfig< required: false, visibility: 'user-or-llm', description: - 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority, weight, port, and target inside the record content instead', + 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; use the data object for structured records such as SRV (priority, weight, port, target)', }, comment: { type: 'string', @@ -78,8 +116,13 @@ export const createDnsRecordTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/dns_records`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_records` + ) + appendParam(url, 'include_shadow_metadata', params.include_shadow_metadata) + return url.toString() + }, method: 'POST', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, @@ -89,129 +132,31 @@ export const createDnsRecordTool: ToolConfig< const body: Record = { type: params.type, name: params.name, - content: params.content, } + if (params.content !== undefined && params.content !== '') body.content = params.content if (params.ttl !== undefined) body.ttl = Number(params.ttl) if (params.proxied !== undefined) body.proxied = params.proxied if (params.priority !== undefined) body.priority = Number(params.priority) if (params.comment) body.comment = params.comment - if (params.tags) { - const tagList = String(params.tags) - .split(',') - .map((t) => t.trim()) - .filter(Boolean) - if (tagList.length > 0) body.tags = tagList - } + const tags = parseCsvParam(params.tags) + if (tags) body.tags = tags + if (params.settings !== undefined && params.settings !== '') + body.settings = parseJsonObjectParam(params.settings, 'settings') + if (params.private_routing !== undefined) body.private_routing = params.private_routing + if (params.data !== undefined && params.data !== '') + body.data = parseJsonObjectParam(params.data, 'data') return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - zone_id: '', - zone_name: '', - type: '', - name: '', - content: '', - proxiable: false, - proxied: false, - ttl: 0, - locked: false, - priority: undefined, - comment: null, - tags: [], - comment_modified_on: null, - tags_modified_on: null, - meta: null, - created_on: '', - modified_on: '', - }, - error: data.errors?.[0]?.message ?? 'Failed to create DNS record', - } - } - - const record = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: record?.id ?? '', - zone_id: record?.zone_id ?? '', - zone_name: record?.zone_name ?? '', - type: record?.type ?? '', - name: record?.name ?? '', - content: record?.content ?? '', - proxiable: record?.proxiable ?? false, - proxied: record?.proxied ?? false, - ttl: record?.ttl ?? 0, - locked: record?.locked ?? false, - priority: record?.priority ?? null, - comment: record?.comment ?? null, - tags: record?.tags ?? [], - comment_modified_on: record?.comment_modified_on ?? null, - tags_modified_on: record?.tags_modified_on ?? null, - meta: record?.meta ?? null, - created_on: record?.created_on ?? '', - modified_on: record?.modified_on ?? '', - }, + success, + output: mapCloudflareFields(data.result, DNS_RECORD_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create dns record') } : {}), } }, - - outputs: { - id: { type: 'string', description: 'Unique identifier for the created DNS record' }, - zone_id: { type: 'string', description: 'The ID of the zone the record belongs to' }, - zone_name: { type: 'string', description: 'The name of the zone' }, - type: { type: 'string', description: 'DNS record type (A, AAAA, CNAME, MX, TXT, etc.)' }, - name: { type: 'string', description: 'DNS record hostname' }, - content: { - type: 'string', - description: 'DNS record value (e.g., IP address, target hostname)', - }, - proxiable: { - type: 'boolean', - description: 'Whether the record can be proxied through Cloudflare', - }, - proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, - ttl: { type: 'number', description: 'Time to live in seconds (1 = automatic)' }, - locked: { type: 'boolean', description: 'Whether the record is locked' }, - priority: { - type: 'number', - description: 'Record priority, returned for MX and URI records', - optional: true, - }, - comment: { type: 'string', description: 'Comment associated with the record', optional: true }, - tags: { - type: 'array', - description: 'Tags associated with the record', - items: { type: 'string', description: 'Tag value' }, - }, - comment_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the comment was last modified', - optional: true, - }, - tags_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when tags were last modified', - optional: true, - }, - meta: { - type: 'object', - description: 'Record metadata', - optional: true, - properties: { - source: { type: 'string', description: 'Source of the DNS record' }, - }, - }, - created_on: { type: 'string', description: 'ISO 8601 timestamp when the record was created' }, - modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the record was last modified', - }, - }, + outputs: DNS_RECORD_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_r2_bucket.ts b/apps/sim/tools/cloudflare/create_r2_bucket.ts index 66524353208..3502b517237 100644 --- a/apps/sim/tools/cloudflare/create_r2_bucket.ts +++ b/apps/sim/tools/cloudflare/create_r2_bucket.ts @@ -1,9 +1,17 @@ +import { isRecordLike } from '@sim/utils/object' +import { R2_BUCKET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateR2BucketParams, CloudflareR2BucketResponse, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createR2BucketTool: ToolConfig< CloudflareCreateR2BucketParams, @@ -58,7 +66,7 @@ export const createR2BucketTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/r2/buckets`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets`, method: 'POST', headers: (params) => { const headers = cloudflareHeaders(params.apiKey) @@ -74,52 +82,13 @@ export const createR2BucketTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - name: '', - creation_date: null, - location: null, - storage_class: null, - jurisdiction: null, - }, - error: cloudflareErrorMessage(data, 'Failed to create R2 bucket'), - } - } - - const bucket = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - name: bucket?.name ?? '', - creation_date: bucket?.creation_date ?? null, - location: bucket?.location ?? null, - storage_class: bucket?.storage_class ?? null, - jurisdiction: bucket?.jurisdiction ?? null, - }, + success, + output: mapCloudflareFields(data.result, R2_BUCKET_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create r2 bucket') } : {}), } }, - - outputs: { - name: { type: 'string', description: 'Created bucket name' }, - creation_date: { type: 'string', description: 'Creation timestamp', optional: true }, - location: { - type: 'string', - description: 'Location the bucket was created in', - optional: true, - }, - storage_class: { - type: 'string', - description: 'Default storage class (Standard or InfrequentAccess)', - optional: true, - }, - jurisdiction: { - type: 'string', - description: 'Data-residency jurisdiction (default, eu, or fedramp)', - optional: true, - }, - }, + outputs: R2_BUCKET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_rate_limit_rule.ts b/apps/sim/tools/cloudflare/create_rate_limit_rule.ts index d75a3246bde..47b38a6d516 100644 --- a/apps/sim/tools/cloudflare/create_rate_limit_rule.ts +++ b/apps/sim/tools/cloudflare/create_rate_limit_rule.ts @@ -1,15 +1,20 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateRateLimitRuleParams, CloudflareRulesetResponse, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, parseCsvParam, + parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createRateLimitRuleTool: ToolConfig< CloudflareCreateRateLimitRuleParams, @@ -22,6 +27,66 @@ export const createRateLimitRuleTool: ToolConfig< version: '1.0.0', params: { + actionParameters: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + "JSON object. The parameters configuring the rule's action. Fields: response, algorithms, id, matched_data, overrides, cookie_fields, raw_response_fields, request_fields, response_fields, transformed_request_fields, from_list, from_value, headers, uri, host_header, origin, sni, increment, content_type, status_code, content, asset_name, immutable, max-age, must-revalidate, must-understand, no-cache, no-store, no-transform, private, proxy-revalidate, public, s-maxage, stale-if-error, stale-while-revalidate, additional_cacheable_ports, browser_ttl, cache, cache_key, cache_reserve, edge_ttl, origin_cache_control, origin_error_page_passthru, origin_range_requests, read_timeout, respect_strong_etags, serve_stale, shared_dictionary, strip_etags, strip_last_modified, strip_set_cookie, vary, operation, values, expression, automatic_https_rewrites, autominify, bic, content_converter, disable_apps, disable_pay_per_crawl, disable_rum, disable_zaraz, email_obfuscation, fonts, hotlink_protection, mirage, opportunistic_encryption, polish, redirects_for_ai_training, request_body_buffering, response_body_buffering, rocket_loader, security_level, server_side_excludes, ssl, sxg, webmcp_enabled, webmcp_packs, phase, phases, products, rules, ruleset, rulesets, link_maze.", + }, + exposed_credential_check: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + id: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The unique ID of the rule.', + }, + logging: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + "JSON object. An object configuring the rule's logging behavior. Fields: enabled.", + }, + ref: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: "The reference of the rule (the rule's ID by default).", + }, + position: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. An object configuring where the rule will be placed. Fields: before, after, index.', + }, + score_per_period: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'The score threshold per period for which the action will be executed the first time.', + }, + score_response_header_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A response header name provided by the origin, which contains the score to increment rate limit counter with.', + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -110,8 +175,13 @@ export const createRateLimitRuleTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}/rules`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}/rules` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -141,72 +211,40 @@ export const createRateLimitRuleTool: ToolConfig< if (params.description) body.description = params.description if (params.enabled !== undefined) body.enabled = params.enabled + if (params.actionParameters !== undefined && params.actionParameters !== '') + body.action_parameters = parseJsonObjectParam(params.actionParameters, 'actionParameters') + if (params.exposed_credential_check !== undefined && params.exposed_credential_check !== '') + body.exposed_credential_check = parseJsonObjectParam( + params.exposed_credential_check, + 'exposed_credential_check' + ) + if (params.id !== undefined && params.id !== '') body.id = params.id + if (params.logging !== undefined && params.logging !== '') + body.logging = parseJsonObjectParam(params.logging, 'logging') + if (params.ref !== undefined && params.ref !== '') body.ref = params.ref + if (params.position !== undefined && params.position !== '') + body.position = parseJsonObjectParam(params.position, 'position') + if (params.score_per_period !== undefined) + ratelimit.score_per_period = params.score_per_period + if (params.score_response_header_name !== undefined) + ratelimit.score_response_header_name = params.score_response_header_name return body }, }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to create rate limiting rule'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to create rate limit rule') } + : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset ID of the http_ratelimit entry point' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind' }, - phase: { type: 'string', description: 'Phase the ruleset runs in (http_ratelimit)' }, - version: { type: 'string', description: 'Ruleset version after the change', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rate limiting rules after the change, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { type: 'string', description: 'Action applied once the limit is exceeded' }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters', - optional: true, - }, - expression: { type: 'string', description: 'Filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration applied to the rule', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_ruleset.ts b/apps/sim/tools/cloudflare/create_ruleset.ts index 0666c44b499..d4a5da074bd 100644 --- a/apps/sim/tools/cloudflare/create_ruleset.ts +++ b/apps/sim/tools/cloudflare/create_ruleset.ts @@ -1,15 +1,19 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateRulesetParams, CloudflareRulesetResponse, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, parseJsonArrayParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createRulesetTool: ToolConfig< CloudflareCreateRulesetParams, @@ -22,6 +26,12 @@ export const createRulesetTool: ToolConfig< version: '1.0.0', params: { + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -70,7 +80,13 @@ export const createRulesetTool: ToolConfig< }, request: { - url: (params) => `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -88,80 +104,17 @@ export const createRulesetTool: ToolConfig< }, }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to create ruleset'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create ruleset') } : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules contained in the ruleset, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { - type: 'string', - description: 'Action the rule performs (e.g., block, challenge, log, skip, execute)', - }, - action_parameters: { - type: 'json', - description: - 'Action-specific parameters, including managed-ruleset overrides on execute rules', - optional: true, - }, - expression: { - type: 'string', - description: - 'Filter expression selecting matching requests. Empty on managed-ruleset rules', - }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { - type: 'string', - description: 'Rule reference tag that survives rule updates', - optional: true, - }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration for rules in the http_ratelimit phase', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_ruleset_rule.ts b/apps/sim/tools/cloudflare/create_ruleset_rule.ts index 4ff7bb34156..846ab0cb45c 100644 --- a/apps/sim/tools/cloudflare/create_ruleset_rule.ts +++ b/apps/sim/tools/cloudflare/create_ruleset_rule.ts @@ -1,15 +1,19 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateRulesetRuleParams, CloudflareRulesetResponse, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const createRulesetRuleTool: ToolConfig< CloudflareCreateRulesetRuleParams, @@ -22,6 +26,39 @@ export const createRulesetRuleTool: ToolConfig< version: '1.0.0', params: { + exposed_credential_check: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + id: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The unique ID of the rule.', + }, + logging: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + "JSON object. An object configuring the rule's logging behavior. Fields: enabled.", + }, + ratelimit: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + "JSON object. An object configuring the rule's rate limit behavior. Fields: characteristics, counting_expression, mitigation_timeout, period, requests_per_period, requests_to_origin, score_per_period, score_response_header_name.", + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -89,8 +126,13 @@ export const createRulesetRuleTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}/rules`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}/rules` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'POST', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -108,72 +150,31 @@ export const createRulesetRuleTool: ToolConfig< const position = parseJsonObjectParam(params.position, 'Position') if (position) body.position = position + if (params.exposed_credential_check !== undefined && params.exposed_credential_check !== '') + body.exposed_credential_check = parseJsonObjectParam( + params.exposed_credential_check, + 'exposed_credential_check' + ) + if (params.id !== undefined && params.id !== '') body.id = params.id + if (params.logging !== undefined && params.logging !== '') + body.logging = parseJsonObjectParam(params.logging, 'logging') + if (params.ratelimit !== undefined && params.ratelimit !== '') + body.ratelimit = parseJsonObjectParam(params.ratelimit, 'ratelimit') return body }, }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to create ruleset rule'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create ruleset rule') } : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version after the change', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules in the ruleset after the change, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { type: 'string', description: 'Action the rule performs' }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters', - optional: true, - }, - expression: { type: 'string', description: 'Filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/create_tunnel.ts b/apps/sim/tools/cloudflare/create_tunnel.ts new file mode 100644 index 00000000000..c39404dc6a6 --- /dev/null +++ b/apps/sim/tools/cloudflare/create_tunnel.ts @@ -0,0 +1,80 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareCreateTunnelParams, + CloudflareCreateTunnelResponse, +} from '@/tools/cloudflare/operation-types' +import { TUNNEL_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const createTunnelTool: ToolConfig< + CloudflareCreateTunnelParams, + CloudflareCreateTunnelResponse +> = { + id: 'cloudflare_create_tunnel', + name: 'Cloudflare Create Tunnel', + description: + 'Creates a remotely or locally managed Cloudflare Tunnel in an account. After creation, retrieve its token and run cloudflared to establish the connector connection.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + config_src: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Allowed values: local, cloudflare.', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'A user-friendly name for a tunnel.', + }, + tunnel_secret: { + type: 'string', + required: false, + visibility: 'user-only', + description: + 'Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel`, + method: 'POST', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + config_src: params.config_src, + name: params.name, + tunnel_secret: params.tunnel_secret, + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, TUNNEL_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create tunnel') } : {}), + } + }, + outputs: TUNNEL_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/create_worker_route.ts b/apps/sim/tools/cloudflare/create_worker_route.ts new file mode 100644 index 00000000000..dc748e04ae1 --- /dev/null +++ b/apps/sim/tools/cloudflare/create_worker_route.ts @@ -0,0 +1,68 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareCreateWorkerRouteParams, + CloudflareCreateWorkerRouteResponse, +} from '@/tools/cloudflare/operation-types' +import { WORKER_ROUTE_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const createWorkerRouteTool: ToolConfig< + CloudflareCreateWorkerRouteParams, + CloudflareCreateWorkerRouteResponse +> = { + id: 'cloudflare_create_worker_route', + name: 'Cloudflare Create Worker Route', + description: 'Creates a route that maps a URL pattern to a Worker.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + pattern: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', + }, + script: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Name of the script to run if the route matches.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/workers/routes`, + method: 'POST', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ pattern: params.pattern, script: params.script }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, WORKER_ROUTE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create worker route') } : {}), + } + }, + outputs: WORKER_ROUTE_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/create_zone.ts b/apps/sim/tools/cloudflare/create_zone.ts index 39c71742d82..f3077d31a5e 100644 --- a/apps/sim/tools/cloudflare/create_zone.ts +++ b/apps/sim/tools/cloudflare/create_zone.ts @@ -1,7 +1,14 @@ +import { isRecordLike } from '@sim/utils/object' +import { ZONE_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareCreateZoneParams, CloudflareCreateZoneResponse, } from '@/tools/cloudflare/types' +import { + cloudflareErrorMessage, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' export const createZoneTool: ToolConfig = @@ -29,7 +36,7 @@ export const createZoneTool: ToolConfig { const body: Record = { name: params.name, - account: { id: params.accountId }, + account: { id: params.accountId.trim() }, } if (params.type) body.type = params.type return body @@ -57,190 +64,13 @@ export const createZoneTool: ToolConfig { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - name: '', - status: '', - paused: false, - type: '', - name_servers: [], - original_name_servers: [], - created_on: '', - modified_on: '', - activated_on: '', - development_mode: 0, - plan: { - id: '', - name: '', - price: 0, - is_subscribed: false, - frequency: '', - currency: '', - legacy_id: '', - }, - account: { id: '', name: '' }, - owner: { id: '', name: '', type: '' }, - meta: { - cdn_only: false, - custom_certificate_quota: 0, - dns_only: false, - foundation_dns: false, - page_rule_quota: 0, - phishing_detected: false, - step: 0, - }, - vanity_name_servers: [], - permissions: [], - }, - error: data.errors?.[0]?.message ?? 'Failed to create zone', - } - } - - const zone = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: zone?.id ?? '', - name: zone?.name ?? '', - status: zone?.status ?? '', - paused: zone?.paused ?? false, - type: zone?.type ?? '', - name_servers: zone?.name_servers ?? [], - original_name_servers: zone?.original_name_servers ?? [], - created_on: zone?.created_on ?? '', - modified_on: zone?.modified_on ?? '', - activated_on: zone?.activated_on ?? '', - development_mode: zone?.development_mode ?? 0, - plan: { - id: zone?.plan?.id ?? '', - name: zone?.plan?.name ?? '', - price: zone?.plan?.price ?? 0, - is_subscribed: zone?.plan?.is_subscribed ?? false, - frequency: zone?.plan?.frequency ?? '', - currency: zone?.plan?.currency ?? '', - legacy_id: zone?.plan?.legacy_id ?? '', - }, - account: { - id: zone?.account?.id ?? '', - name: zone?.account?.name ?? '', - }, - owner: { - id: zone?.owner?.id ?? '', - name: zone?.owner?.name ?? '', - type: zone?.owner?.type ?? '', - }, - meta: { - cdn_only: zone?.meta?.cdn_only ?? false, - custom_certificate_quota: zone?.meta?.custom_certificate_quota ?? 0, - dns_only: zone?.meta?.dns_only ?? false, - foundation_dns: zone?.meta?.foundation_dns ?? false, - page_rule_quota: zone?.meta?.page_rule_quota ?? 0, - phishing_detected: zone?.meta?.phishing_detected ?? false, - step: zone?.meta?.step ?? 0, - }, - vanity_name_servers: zone?.vanity_name_servers ?? [], - permissions: zone?.permissions ?? [], - }, + success, + output: mapCloudflareFields(data.result, ZONE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to create zone') } : {}), } }, - - outputs: { - id: { type: 'string', description: 'Created zone ID' }, - name: { type: 'string', description: 'Domain name' }, - status: { - type: 'string', - description: 'Zone status (initializing, pending, active, moved)', - }, - paused: { type: 'boolean', description: 'Whether the zone is paused' }, - type: { type: 'string', description: 'Zone type (full, partial, secondary, or internal)' }, - name_servers: { - type: 'array', - description: 'Assigned Cloudflare name servers', - items: { type: 'string', description: 'Name server hostname' }, - }, - original_name_servers: { - type: 'array', - description: 'Original name servers before moving to Cloudflare', - items: { type: 'string', description: 'Name server hostname' }, - optional: true, - }, - created_on: { type: 'string', description: 'ISO 8601 date when the zone was created' }, - modified_on: { - type: 'string', - description: 'ISO 8601 date when the zone was last modified', - }, - activated_on: { - type: 'string', - description: 'ISO 8601 date when the zone was activated', - optional: true, - }, - development_mode: { - type: 'number', - description: 'Seconds remaining in development mode (0 = off)', - }, - plan: { - type: 'object', - description: 'Zone plan information', - properties: { - id: { type: 'string', description: 'Plan identifier' }, - name: { type: 'string', description: 'Plan name' }, - price: { type: 'number', description: 'Plan price' }, - is_subscribed: { - type: 'boolean', - description: 'Whether the zone is subscribed to the plan', - }, - frequency: { type: 'string', description: 'Plan billing frequency' }, - currency: { type: 'string', description: 'Plan currency' }, - legacy_id: { type: 'string', description: 'Legacy plan identifier' }, - }, - }, - account: { - type: 'object', - description: 'Account the zone belongs to', - properties: { - id: { type: 'string', description: 'Account identifier' }, - name: { type: 'string', description: 'Account name' }, - }, - }, - owner: { - type: 'object', - description: 'Zone owner information', - properties: { - id: { type: 'string', description: 'Owner identifier' }, - name: { type: 'string', description: 'Owner name' }, - type: { type: 'string', description: 'Owner type' }, - }, - }, - meta: { - type: 'object', - description: 'Zone metadata', - properties: { - cdn_only: { type: 'boolean', description: 'Whether the zone is CDN only' }, - custom_certificate_quota: { type: 'number', description: 'Custom certificate quota' }, - dns_only: { type: 'boolean', description: 'Whether the zone is DNS only' }, - foundation_dns: { type: 'boolean', description: 'Whether foundation DNS is enabled' }, - page_rule_quota: { type: 'number', description: 'Page rule quota' }, - phishing_detected: { type: 'boolean', description: 'Whether phishing was detected' }, - step: { type: 'number', description: 'Current setup step' }, - }, - optional: true, - }, - vanity_name_servers: { - type: 'array', - description: 'Custom vanity name servers', - items: { type: 'string', description: 'Vanity name server hostname' }, - optional: true, - }, - permissions: { - type: 'array', - description: 'User permissions for the zone', - items: { type: 'string', description: 'Permission string' }, - optional: true, - }, - }, + outputs: ZONE_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/delete_access_application.ts b/apps/sim/tools/cloudflare/delete_access_application.ts index 00c03ab1258..434f11dc37f 100644 --- a/apps/sim/tools/cloudflare/delete_access_application.ts +++ b/apps/sim/tools/cloudflare/delete_access_application.ts @@ -4,6 +4,7 @@ import type { } from '@/tools/cloudflare/types' import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteAccessApplicationTool: ToolConfig< CloudflareDeleteAccessApplicationParams, @@ -38,7 +39,7 @@ export const deleteAccessApplicationTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}`, method: 'DELETE', headers: (params) => cloudflareHeaders(params.apiKey), }, @@ -46,7 +47,7 @@ export const deleteAccessApplicationTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { id: '' }, diff --git a/apps/sim/tools/cloudflare/delete_access_group.ts b/apps/sim/tools/cloudflare/delete_access_group.ts new file mode 100644 index 00000000000..e3031bde42e --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_access_group.ts @@ -0,0 +1,60 @@ +import type { + CloudflareDeleteAccessGroupParams, + CloudflareDeleteAccessGroupResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteAccessGroupTool: ToolConfig< + CloudflareDeleteAccessGroupParams, + CloudflareDeleteAccessGroupResponse +> = { + id: 'cloudflare_delete_access_group', + name: 'Cloudflare Delete Access Group', + description: 'Deletes an Access group.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + groupId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Group id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/groups/${safeUrlPathSegment(params.groupId, 'groupId')}`, + method: 'DELETE', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true + return { + success, + output: mapCloudflareFields(data.result, { + id: { type: 'string', nullable: true, description: 'UUID.' }, + } as const), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to delete access group') } : {}), + } + }, + outputs: { id: { type: 'string', nullable: true, description: 'UUID.' } }, +} diff --git a/apps/sim/tools/cloudflare/delete_access_policy.ts b/apps/sim/tools/cloudflare/delete_access_policy.ts index f13889c6a3b..72a5153fa2b 100644 --- a/apps/sim/tools/cloudflare/delete_access_policy.ts +++ b/apps/sim/tools/cloudflare/delete_access_policy.ts @@ -4,6 +4,7 @@ import type { } from '@/tools/cloudflare/types' import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteAccessPolicyTool: ToolConfig< CloudflareDeleteAccessPolicyParams, @@ -44,7 +45,7 @@ export const deleteAccessPolicyTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}/policies/${params.policyId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}/policies/${safeUrlPathSegment(params.policyId, 'policyId')}`, method: 'DELETE', headers: (params) => cloudflareHeaders(params.apiKey), }, @@ -52,7 +53,7 @@ export const deleteAccessPolicyTool: ToolConfig< transformResponse: async (response: Response) => { const data = await response.json() - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { id: '' }, diff --git a/apps/sim/tools/cloudflare/delete_dns_record.ts b/apps/sim/tools/cloudflare/delete_dns_record.ts index d333255f682..7745cdeb007 100644 --- a/apps/sim/tools/cloudflare/delete_dns_record.ts +++ b/apps/sim/tools/cloudflare/delete_dns_record.ts @@ -3,6 +3,7 @@ import type { CloudflareDeleteDnsRecordResponse, } from '@/tools/cloudflare/types' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteDnsRecordTool: ToolConfig< CloudflareDeleteDnsRecordParams, @@ -36,7 +37,7 @@ export const deleteDnsRecordTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/dns_records/${params.recordId.trim()}`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_records/${safeUrlPathSegment(params.recordId, 'recordId')}`, method: 'DELETE', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, @@ -56,7 +57,7 @@ export const deleteDnsRecordTool: ToolConfig< * body if Cloudflare ever starts sending the full envelope here. * https://developers.cloudflare.com/api/resources/dns/subresources/records/methods/delete/ */ - if (data.success === false) { + if (!response.ok || data.success === false || !data.result) { return { success: false, output: { id: '' }, diff --git a/apps/sim/tools/cloudflare/delete_r2_bucket.ts b/apps/sim/tools/cloudflare/delete_r2_bucket.ts index a239b0f1a35..6aff7fb1c10 100644 --- a/apps/sim/tools/cloudflare/delete_r2_bucket.ts +++ b/apps/sim/tools/cloudflare/delete_r2_bucket.ts @@ -4,6 +4,7 @@ import type { } from '@/tools/cloudflare/types' import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteR2BucketTool: ToolConfig< CloudflareDeleteR2BucketParams, @@ -44,7 +45,7 @@ export const deleteR2BucketTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/r2/buckets/${encodeURIComponent(params.bucketName)}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}`, method: 'DELETE', headers: (params) => { const headers = cloudflareHeaders(params.apiKey) @@ -56,7 +57,7 @@ export const deleteR2BucketTool: ToolConfig< transformResponse: async (response: Response, params) => { const data = await response.json() - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { name: '' }, diff --git a/apps/sim/tools/cloudflare/delete_r2_bucket_cors.ts b/apps/sim/tools/cloudflare/delete_r2_bucket_cors.ts new file mode 100644 index 00000000000..dd9183d2ad4 --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_r2_bucket_cors.ts @@ -0,0 +1,70 @@ +import type { + CloudflareDeleteR2BucketCorsParams, + CloudflareDeleteR2BucketCorsResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteR2BucketCorsTool: ToolConfig< + CloudflareDeleteR2BucketCorsParams, + CloudflareDeleteR2BucketCorsResponse +> = { + id: 'cloudflare_delete_r2_bucket_cors', + name: 'Cloudflare Delete R2 Bucket Cors', + description: 'Delete the CORS policy for a bucket.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + bucketName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Bucket name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + jurisdiction: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Jurisdiction where objects in this bucket are guaranteed to be stored.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}/cors`, + method: 'DELETE', + headers: (params) => ({ + ...cloudflareHeaders(params.apiKey), + ...(params.jurisdiction ? { 'cf-r2-jurisdiction': params.jurisdiction } : {}), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true + return { + success, + output: { success }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to delete r2 bucket cors') } + : {}), + } + }, + outputs: { + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + }, +} diff --git a/apps/sim/tools/cloudflare/delete_ruleset.ts b/apps/sim/tools/cloudflare/delete_ruleset.ts new file mode 100644 index 00000000000..d05bcf00cf7 --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_ruleset.ts @@ -0,0 +1,73 @@ +import type { + CloudflareDeleteRulesetParams, + CloudflareDeleteRulesetResponse, +} from '@/tools/cloudflare/operation-types' +import { + appendParam, + cloudflareErrorMessage, + cloudflareHeaders, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteRulesetTool: ToolConfig< + CloudflareDeleteRulesetParams, + CloudflareDeleteRulesetResponse +> = { + id: 'cloudflare_delete_ruleset', + name: 'Cloudflare Delete Ruleset', + description: 'Deletes all versions of an existing zone ruleset.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + rulesetId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Ruleset id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Validates the request without persisting changes when set to `true`. Responses that normally return 200 return `result: null`; endpoints that normally return 204 continue to return 204.', + }, + }, + request: { + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, + method: 'DELETE', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + if (response.status === 204) return { success: true, output: { success: true } } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true + return { + success, + output: { success }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to delete ruleset') } : {}), + } + }, + outputs: { + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + }, +} diff --git a/apps/sim/tools/cloudflare/delete_ruleset_rule.ts b/apps/sim/tools/cloudflare/delete_ruleset_rule.ts index 68ec2c45f9b..697f2448edd 100644 --- a/apps/sim/tools/cloudflare/delete_ruleset_rule.ts +++ b/apps/sim/tools/cloudflare/delete_ruleset_rule.ts @@ -1,14 +1,18 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareDeleteRulesetRuleParams, CloudflareRulesetResponse, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteRulesetRuleTool: ToolConfig< CloudflareDeleteRulesetRuleParams, @@ -21,6 +25,12 @@ export const deleteRulesetRuleTool: ToolConfig< version: '1.0.0', params: { + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -48,70 +58,28 @@ export const deleteRulesetRuleTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}/rules/${params.ruleId.trim()}`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}/rules/${safeUrlPathSegment(params.ruleId, 'ruleId')}` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'DELETE', headers: (params) => cloudflareHeaders(params.apiKey), }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to delete ruleset rule'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to delete ruleset rule') } : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version after the change', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules remaining in the ruleset, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { type: 'string', description: 'Action the rule performs' }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters', - optional: true, - }, - expression: { type: 'string', description: 'Filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { type: 'json', description: 'Rate limiting configuration', optional: true }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/delete_tunnel.ts b/apps/sim/tools/cloudflare/delete_tunnel.ts new file mode 100644 index 00000000000..38853dc533c --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_tunnel.ts @@ -0,0 +1,61 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareDeleteTunnelParams, + CloudflareDeleteTunnelResponse, +} from '@/tools/cloudflare/operation-types' +import { TUNNEL_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteTunnelTool: ToolConfig< + CloudflareDeleteTunnelParams, + CloudflareDeleteTunnelResponse +> = { + id: 'cloudflare_delete_tunnel', + name: 'Cloudflare Delete Tunnel', + description: + 'Permanently deletes a Cloudflare Tunnel from an account. The tunnel must have no active connections.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + tunnelId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Tunnel id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}`, + method: 'DELETE', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, TUNNEL_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to delete tunnel') } : {}), + } + }, + outputs: TUNNEL_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/delete_worker_route.ts b/apps/sim/tools/cloudflare/delete_worker_route.ts new file mode 100644 index 00000000000..ee12fd801ac --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_worker_route.ts @@ -0,0 +1,61 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareDeleteWorkerRouteParams, + CloudflareDeleteWorkerRouteResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteWorkerRouteTool: ToolConfig< + CloudflareDeleteWorkerRouteParams, + CloudflareDeleteWorkerRouteResponse +> = { + id: 'cloudflare_delete_worker_route', + name: 'Cloudflare Delete Worker Route', + description: 'Deletes a Worker route.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + routeId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Route id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/workers/routes/${safeUrlPathSegment(params.routeId, 'routeId')}`, + method: 'DELETE', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, { + id: { type: 'string', nullable: true, description: 'Identifier.' }, + } as const), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to delete worker route') } : {}), + } + }, + outputs: { id: { type: 'string', nullable: true, description: 'Identifier.' } }, +} diff --git a/apps/sim/tools/cloudflare/delete_worker_script.ts b/apps/sim/tools/cloudflare/delete_worker_script.ts new file mode 100644 index 00000000000..4bdc5cc85db --- /dev/null +++ b/apps/sim/tools/cloudflare/delete_worker_script.ts @@ -0,0 +1,74 @@ +import type { + CloudflareDeleteWorkerScriptParams, + CloudflareDeleteWorkerScriptResponse, +} from '@/tools/cloudflare/operation-types' +import { + appendParam, + cloudflareErrorMessage, + cloudflareHeaders, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const deleteWorkerScriptTool: ToolConfig< + CloudflareDeleteWorkerScriptParams, + CloudflareDeleteWorkerScriptResponse +> = { + id: 'cloudflare_delete_worker_script', + name: 'Cloudflare Delete Worker Script', + description: 'Delete your worker. This call has no response body on a successful delete.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + scriptName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Script name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + force: { + type: 'boolean', + required: false, + visibility: 'user-only', + description: + 'If true, delete the Worker even when other Workers still reference it. Service bindings in those Workers may be left broken. Durable Object namespaces implemented by the deleted Worker are deleted even if other Workers reference them.', + }, + }, + request: { + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/workers/scripts/${safeUrlPathSegment(params.scriptName, 'scriptName')}` + ) + appendParam(url, 'force', params.force) + return url.toString() + }, + method: 'DELETE', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response, { allowEmptySuccess: true }) + const success = response.ok && data.success === true + return { + success, + output: { success }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to delete worker script') } + : {}), + } + }, + outputs: { + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + }, +} diff --git a/apps/sim/tools/cloudflare/delete_zone.ts b/apps/sim/tools/cloudflare/delete_zone.ts index 06ddf1d42cb..ffca1186253 100644 --- a/apps/sim/tools/cloudflare/delete_zone.ts +++ b/apps/sim/tools/cloudflare/delete_zone.ts @@ -3,6 +3,7 @@ import type { CloudflareDeleteZoneResponse, } from '@/tools/cloudflare/types' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const deleteZoneTool: ToolConfig = { @@ -27,7 +28,8 @@ export const deleteZoneTool: ToolConfig `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}`, + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}`, method: 'DELETE', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, @@ -38,7 +40,7 @@ export const deleteZoneTool: ToolConfig { const data = await response.json() - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { id: '' }, diff --git a/apps/sim/tools/cloudflare/dns_analytics.ts b/apps/sim/tools/cloudflare/dns_analytics.ts index b21fe318265..5ff36a4b48d 100644 --- a/apps/sim/tools/cloudflare/dns_analytics.ts +++ b/apps/sim/tools/cloudflare/dns_analytics.ts @@ -5,6 +5,7 @@ import type { } from '@/tools/cloudflare/types' import { readCloudflareResponse } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const dnsAnalyticsTool: ToolConfig< CloudflareDnsAnalyticsParams, @@ -80,7 +81,7 @@ export const dnsAnalyticsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/dns_analytics/report` + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_analytics/report` ) if (params.since) url.searchParams.append('since', params.since) if (params.until) url.searchParams.append('until', params.until) @@ -101,7 +102,7 @@ export const dnsAnalyticsTool: ToolConfig< transformResponse: async (response: Response) => { const data = await readCloudflareResponse(response) - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { diff --git a/apps/sim/tools/cloudflare/get_access_application.ts b/apps/sim/tools/cloudflare/get_access_application.ts index 71f1989c713..8fd4fdbce43 100644 --- a/apps/sim/tools/cloudflare/get_access_application.ts +++ b/apps/sim/tools/cloudflare/get_access_application.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { ACCESS_APPLICATION_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessApplicationResponse, CloudflareGetAccessApplicationParams, @@ -5,10 +7,11 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyAccessApplication, - mapAccessApplication, + mapCloudflareFields, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getAccessApplicationTool: ToolConfig< CloudflareGetAccessApplicationParams, @@ -43,93 +46,21 @@ export const getAccessApplicationTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyAccessApplication(), - error: cloudflareErrorMessage(data, 'Failed to get Access application'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_APPLICATION_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get access application') } + : {}), } - - return { success: true, output: mapAccessApplication(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Access application identifier' }, - name: { type: 'string', description: 'Application name', optional: true }, - domain: { - type: 'string', - description: 'Primary hostname and path secured by Access', - optional: true, - }, - type: { - type: 'string', - description: 'Application type (e.g., self_hosted, saas, ssh, app_launcher, bookmark)', - optional: true, - }, - aud: { type: 'string', description: 'Audience tag used to verify Access JWTs', optional: true }, - session_duration: { - type: 'string', - description: 'How long an Access session stays valid (e.g., 24h)', - optional: true, - }, - allowed_idps: { - type: 'array', - description: 'Identity provider IDs users may authenticate with', - items: { type: 'string', description: 'Identity provider ID' }, - optional: true, - }, - app_launcher_visible: { - type: 'boolean', - description: 'Whether the app appears in the App Launcher', - optional: true, - }, - auto_redirect_to_identity: { - type: 'boolean', - description: 'Whether users skip the identity provider picker', - optional: true, - }, - custom_deny_message: { - type: 'string', - description: 'Message shown when access is denied', - optional: true, - }, - custom_deny_url: { - type: 'string', - description: 'URL users are redirected to when access is denied', - optional: true, - }, - logo_url: { type: 'string', description: 'Logo image URL', optional: true }, - self_hosted_domains: { - type: 'array', - description: - 'Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application', - items: { type: 'string', description: 'Hostname and path' }, - optional: true, - }, - destinations: { - type: 'json', - description: 'Public and private destinations secured by the application', - optional: true, - }, - tags: { - type: 'array', - description: 'Tags categorizing the application', - items: { type: 'string', description: 'Tag name' }, - optional: true, - }, - policies: { - type: 'json', - description: 'Access policies attached to the application', - optional: true, - }, }, + outputs: ACCESS_APPLICATION_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_access_group.ts b/apps/sim/tools/cloudflare/get_access_group.ts new file mode 100644 index 00000000000..db652d20dda --- /dev/null +++ b/apps/sim/tools/cloudflare/get_access_group.ts @@ -0,0 +1,60 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetAccessGroupParams, + CloudflareGetAccessGroupResponse, +} from '@/tools/cloudflare/operation-types' +import { ACCESS_GROUP_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getAccessGroupTool: ToolConfig< + CloudflareGetAccessGroupParams, + CloudflareGetAccessGroupResponse +> = { + id: 'cloudflare_get_access_group', + name: 'Cloudflare Get Access Group', + description: 'Fetches a single Access group.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + groupId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Group id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/groups/${safeUrlPathSegment(params.groupId, 'groupId')}`, + method: 'GET', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_GROUP_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get access group') } : {}), + } + }, + outputs: ACCESS_GROUP_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_access_policy.ts b/apps/sim/tools/cloudflare/get_access_policy.ts new file mode 100644 index 00000000000..39762ed0d5f --- /dev/null +++ b/apps/sim/tools/cloudflare/get_access_policy.ts @@ -0,0 +1,67 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetAccessPolicyParams, + CloudflareGetAccessPolicyResponse, +} from '@/tools/cloudflare/operation-types' +import { ACCESS_POLICY_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getAccessPolicyTool: ToolConfig< + CloudflareGetAccessPolicyParams, + CloudflareGetAccessPolicyResponse +> = { + id: 'cloudflare_get_access_policy', + name: 'Cloudflare Get Access Policy', + description: + 'Fetches a single Access policy configured for an application. Returns both exclusively owned and reusable policies used by the application.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + appId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'App id', + }, + policyId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Policy id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}/policies/${safeUrlPathSegment(params.policyId, 'policyId')}`, + method: 'GET', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_POLICY_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get access policy') } : {}), + } + }, + outputs: ACCESS_POLICY_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_access_service_token.ts b/apps/sim/tools/cloudflare/get_access_service_token.ts new file mode 100644 index 00000000000..d78813c4557 --- /dev/null +++ b/apps/sim/tools/cloudflare/get_access_service_token.ts @@ -0,0 +1,62 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetAccessServiceTokenParams, + CloudflareGetAccessServiceTokenResponse, +} from '@/tools/cloudflare/operation-types' +import { SERVICE_TOKEN_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getAccessServiceTokenTool: ToolConfig< + CloudflareGetAccessServiceTokenParams, + CloudflareGetAccessServiceTokenResponse +> = { + id: 'cloudflare_get_access_service_token', + name: 'Cloudflare Get Access Service Token', + description: 'Fetches a single service token.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + serviceTokenId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Service token id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens/${safeUrlPathSegment(params.serviceTokenId, 'serviceTokenId')}`, + method: 'GET', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get access service token') } + : {}), + } + }, + outputs: SERVICE_TOKEN_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_dns_record.ts b/apps/sim/tools/cloudflare/get_dns_record.ts new file mode 100644 index 00000000000..594682ba5fe --- /dev/null +++ b/apps/sim/tools/cloudflare/get_dns_record.ts @@ -0,0 +1,73 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetDnsRecordParams, + CloudflareGetDnsRecordResponse, +} from '@/tools/cloudflare/operation-types' +import { DNS_RECORD_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + appendParam, + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getDnsRecordTool: ToolConfig< + CloudflareGetDnsRecordParams, + CloudflareGetDnsRecordResponse +> = { + id: 'cloudflare_get_dns_record', + name: 'Cloudflare Get Dns Record', + description: 'Retrieves details for a specific DNS record in the zone.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + recordId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Dns record id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + include_shadow_metadata: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + }, + request: { + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_records/${safeUrlPathSegment(params.recordId, 'recordId')}` + ) + appendParam(url, 'include_shadow_metadata', params.include_shadow_metadata) + return url.toString() + }, + method: 'GET', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, DNS_RECORD_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get dns record') } : {}), + } + }, + outputs: DNS_RECORD_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_r2_bucket.ts b/apps/sim/tools/cloudflare/get_r2_bucket.ts index f144a34f608..f325f9da0fb 100644 --- a/apps/sim/tools/cloudflare/get_r2_bucket.ts +++ b/apps/sim/tools/cloudflare/get_r2_bucket.ts @@ -1,9 +1,17 @@ +import { isRecordLike } from '@sim/utils/object' +import { R2_BUCKET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetR2BucketParams, CloudflareR2BucketResponse, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getR2BucketTool: ToolConfig = { @@ -42,7 +50,7 @@ export const getR2BucketTool: ToolConfig - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/r2/buckets/${encodeURIComponent(params.bucketName)}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}`, method: 'GET', headers: (params) => { const headers = cloudflareHeaders(params.apiKey) @@ -52,53 +60,13 @@ export const getR2BucketTool: ToolConfig { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - name: '', - creation_date: null, - location: null, - storage_class: null, - jurisdiction: null, - }, - error: cloudflareErrorMessage(data, 'Failed to get R2 bucket'), - } - } - - const bucket = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - name: bucket?.name ?? '', - creation_date: bucket?.creation_date ?? null, - location: bucket?.location ?? null, - storage_class: bucket?.storage_class ?? null, - jurisdiction: bucket?.jurisdiction ?? null, - }, + success, + output: mapCloudflareFields(data.result, R2_BUCKET_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get r2 bucket') } : {}), } }, - - outputs: { - name: { type: 'string', description: 'Bucket name' }, - creation_date: { type: 'string', description: 'Creation timestamp', optional: true }, - location: { - type: 'string', - description: - 'Location hint the bucket was created with (apac, eeur, enam, weur, wnam, or oc)', - optional: true, - }, - storage_class: { - type: 'string', - description: 'Default storage class (Standard or InfrequentAccess)', - optional: true, - }, - jurisdiction: { - type: 'string', - description: 'Data-residency jurisdiction (default, eu, or fedramp)', - optional: true, - }, - }, + outputs: R2_BUCKET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_r2_bucket_cors.ts b/apps/sim/tools/cloudflare/get_r2_bucket_cors.ts new file mode 100644 index 00000000000..2d1fdc36700 --- /dev/null +++ b/apps/sim/tools/cloudflare/get_r2_bucket_cors.ts @@ -0,0 +1,69 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetR2BucketCorsParams, + CloudflareGetR2BucketCorsResponse, +} from '@/tools/cloudflare/operation-types' +import { R2_CORS_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getR2BucketCorsTool: ToolConfig< + CloudflareGetR2BucketCorsParams, + CloudflareGetR2BucketCorsResponse +> = { + id: 'cloudflare_get_r2_bucket_cors', + name: 'Cloudflare Get R2 Bucket Cors', + description: 'Get the CORS policy for a bucket.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + bucketName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Bucket name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + jurisdiction: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Jurisdiction where objects in this bucket are guaranteed to be stored.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}/cors`, + method: 'GET', + headers: (params) => ({ + ...cloudflareHeaders(params.apiKey), + ...(params.jurisdiction ? { 'cf-r2-jurisdiction': params.jurisdiction } : {}), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, R2_CORS_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get r2 bucket cors') } : {}), + } + }, + outputs: R2_CORS_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_r2_bucket_lifecycle.ts b/apps/sim/tools/cloudflare/get_r2_bucket_lifecycle.ts new file mode 100644 index 00000000000..2a9489e3581 --- /dev/null +++ b/apps/sim/tools/cloudflare/get_r2_bucket_lifecycle.ts @@ -0,0 +1,71 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetR2BucketLifecycleParams, + CloudflareGetR2BucketLifecycleResponse, +} from '@/tools/cloudflare/operation-types' +import { R2_LIFECYCLE_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getR2BucketLifecycleTool: ToolConfig< + CloudflareGetR2BucketLifecycleParams, + CloudflareGetR2BucketLifecycleResponse +> = { + id: 'cloudflare_get_r2_bucket_lifecycle', + name: 'Cloudflare Get R2 Bucket Lifecycle', + description: 'Get object lifecycle rules for a bucket.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + bucketName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Bucket name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + jurisdiction: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Jurisdiction where objects in this bucket are guaranteed to be stored.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}/lifecycle`, + method: 'GET', + headers: (params) => ({ + ...cloudflareHeaders(params.apiKey), + ...(params.jurisdiction ? { 'cf-r2-jurisdiction': params.jurisdiction } : {}), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, R2_LIFECYCLE_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get r2 bucket lifecycle') } + : {}), + } + }, + outputs: R2_LIFECYCLE_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_ruleset.ts b/apps/sim/tools/cloudflare/get_ruleset.ts index badc225f26e..ce6270d2aaa 100644 --- a/apps/sim/tools/cloudflare/get_ruleset.ts +++ b/apps/sim/tools/cloudflare/get_ruleset.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetRulesetParams, CloudflareRulesetResponse, @@ -5,10 +7,11 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getRulesetTool: ToolConfig = { id: 'cloudflare_get_ruleset', @@ -40,85 +43,19 @@ export const getRulesetTool: ToolConfig - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to get ruleset'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get ruleset') } : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules contained in the ruleset, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { - type: 'string', - description: 'Action the rule performs (e.g., block, challenge, log, skip, execute)', - }, - action_parameters: { - type: 'json', - description: - 'Action-specific parameters, including managed-ruleset overrides on execute rules', - optional: true, - }, - expression: { - type: 'string', - description: - 'Filter expression selecting matching requests. Empty on managed-ruleset rules', - }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { - type: 'string', - description: 'Rule reference tag that survives rule updates', - optional: true, - }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration for rules in the http_ratelimit phase', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_ruleset_entrypoint.ts b/apps/sim/tools/cloudflare/get_ruleset_entrypoint.ts index 87e460390a3..692edd30f38 100644 --- a/apps/sim/tools/cloudflare/get_ruleset_entrypoint.ts +++ b/apps/sim/tools/cloudflare/get_ruleset_entrypoint.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetRulesetEntrypointParams, CloudflareRulesetResponse, @@ -5,10 +7,11 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getRulesetEntrypointTool: ToolConfig< CloudflareGetRulesetEntrypointParams, @@ -44,85 +47,21 @@ export const getRulesetEntrypointTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/phases/${params.phase.trim()}/entrypoint`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/phases/${safeUrlPathSegment(params.phase, 'phase')}/entrypoint`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to get phase entry point ruleset'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get ruleset entrypoint') } + : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Entry point ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules contained in the ruleset, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { - type: 'string', - description: 'Action the rule performs (e.g., block, challenge, log, skip, execute)', - }, - action_parameters: { - type: 'json', - description: - 'Action-specific parameters, including managed-ruleset overrides on execute rules', - optional: true, - }, - expression: { - type: 'string', - description: - 'Filter expression selecting matching requests. Empty on managed-ruleset rules', - }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { - type: 'string', - description: 'Rule reference tag that survives rule updates', - optional: true, - }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration for rules in the http_ratelimit phase', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_tunnel.ts b/apps/sim/tools/cloudflare/get_tunnel.ts index cf0faf957f0..894b40dcba8 100644 --- a/apps/sim/tools/cloudflare/get_tunnel.ts +++ b/apps/sim/tools/cloudflare/get_tunnel.ts @@ -1,6 +1,14 @@ +import { isRecordLike } from '@sim/utils/object' +import { TUNNEL_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetTunnelParams, CloudflareTunnelResponse } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getTunnelTool: ToolConfig = { id: 'cloudflare_get_tunnel', @@ -32,102 +40,19 @@ export const getTunnelTool: ToolConfig - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/cfd_tunnel/${params.tunnelId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - name: null, - account_tag: null, - config_src: null, - status: null, - tun_type: null, - remote_config: null, - metadata: null, - created_at: null, - deleted_at: null, - conns_active_at: null, - conns_inactive_at: null, - connections: null, - }, - error: cloudflareErrorMessage(data, 'Failed to get tunnel'), - } - } - - const tunnel = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: tunnel?.id ?? '', - name: tunnel?.name ?? null, - account_tag: tunnel?.account_tag ?? null, - config_src: tunnel?.config_src ?? null, - status: tunnel?.status ?? null, - tun_type: tunnel?.tun_type ?? null, - remote_config: tunnel?.remote_config ?? null, - metadata: tunnel?.metadata ?? null, - created_at: tunnel?.created_at ?? null, - deleted_at: tunnel?.deleted_at ?? null, - conns_active_at: tunnel?.conns_active_at ?? null, - conns_inactive_at: tunnel?.conns_inactive_at ?? null, - connections: tunnel?.connections ?? null, - }, + success, + output: mapCloudflareFields(data.result, TUNNEL_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get tunnel') } : {}), } }, - - outputs: { - id: { type: 'string', description: 'Tunnel identifier' }, - name: { type: 'string', description: 'Tunnel name', optional: true }, - account_tag: { type: 'string', description: 'Account the tunnel belongs to', optional: true }, - config_src: { - type: 'string', - description: 'Where the tunnel configuration lives: local or cloudflare', - optional: true, - }, - status: { - type: 'string', - description: 'Tunnel health: inactive, degraded, healthy, or down', - optional: true, - }, - tun_type: { - type: 'string', - description: 'Tunnel type, e.g. cfd_tunnel, warp_connector, or warp', - optional: true, - }, - remote_config: { - type: 'boolean', - description: 'Whether the tunnel is remotely managed', - optional: true, - }, - metadata: { - type: 'json', - description: 'Metadata associated with the tunnel', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - deleted_at: { type: 'string', description: 'Deletion timestamp', optional: true }, - conns_active_at: { - type: 'string', - description: 'When the tunnel last had active connections', - optional: true, - }, - conns_inactive_at: { - type: 'string', - description: 'When the tunnel last lost all connections', - optional: true, - }, - connections: { - type: 'json', - description: 'Active connector connections for the tunnel', - optional: true, - }, - }, + outputs: TUNNEL_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_tunnel_configuration.ts b/apps/sim/tools/cloudflare/get_tunnel_configuration.ts index 8b76c3590a8..5134512c77e 100644 --- a/apps/sim/tools/cloudflare/get_tunnel_configuration.ts +++ b/apps/sim/tools/cloudflare/get_tunnel_configuration.ts @@ -1,9 +1,17 @@ +import { isRecordLike } from '@sim/utils/object' +import { TUNNEL_CONFIGURATION_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetTunnelConfigurationParams, CloudflareGetTunnelConfigurationResponse, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getTunnelConfigurationTool: ToolConfig< CloudflareGetTunnelConfigurationParams, @@ -38,62 +46,21 @@ export const getTunnelConfigurationTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/cfd_tunnel/${params.tunnelId.trim()}/configurations`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}/configurations`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - tunnel_id: '', - account_id: '', - version: null, - source: null, - created_at: null, - config: null, - }, - error: cloudflareErrorMessage(data, 'Failed to get tunnel configuration'), - } - } - - const result = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - tunnel_id: result?.tunnel_id ?? '', - account_id: result?.account_id ?? '', - version: result?.version ?? null, - source: result?.source ?? null, - created_at: result?.created_at ?? null, - config: result?.config ?? null, - }, + success, + output: mapCloudflareFields(data.result, TUNNEL_CONFIGURATION_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get tunnel configuration') } + : {}), } }, - - outputs: { - tunnel_id: { type: 'string', description: 'Tunnel the configuration belongs to' }, - account_id: { type: 'string', description: 'Account the tunnel belongs to' }, - version: { - type: 'number', - description: 'Configuration version, incremented on every change', - optional: true, - }, - source: { - type: 'string', - description: 'Where the configuration is managed: local or cloudflare', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - config: { - type: 'json', - description: - 'Tunnel configuration with ingress rules, originRequest defaults, and warp-routing settings', - optional: true, - }, - }, + outputs: TUNNEL_CONFIGURATION_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_tunnel_token.ts b/apps/sim/tools/cloudflare/get_tunnel_token.ts new file mode 100644 index 00000000000..6abaf87a948 --- /dev/null +++ b/apps/sim/tools/cloudflare/get_tunnel_token.ts @@ -0,0 +1,64 @@ +import type { + CloudflareGetTunnelTokenParams, + CloudflareGetTunnelTokenResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getTunnelTokenTool: ToolConfig< + CloudflareGetTunnelTokenParams, + CloudflareGetTunnelTokenResponse +> = { + id: 'cloudflare_get_tunnel_token', + name: 'Cloudflare Get Tunnel Token', + description: + 'Gets the connector token used to run a remotely managed Cloudflare Tunnel with cloudflared.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Cloudflare account ID', + }, + tunnelId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Cloudflare Tunnel ID', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}/token`, + method: 'GET', + headers: (params) => cloudflareHeaders(params.apiKey), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && typeof data.result === 'string' + return { + success, + output: { token: typeof data.result === 'string' ? data.result : null }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get tunnel token') } : {}), + } + }, + outputs: { + token: { + type: 'string', + nullable: true, + description: 'Token for connecting cloudflared to the tunnel', + }, + }, +} diff --git a/apps/sim/tools/cloudflare/get_worker_route.ts b/apps/sim/tools/cloudflare/get_worker_route.ts new file mode 100644 index 00000000000..666a6eb533c --- /dev/null +++ b/apps/sim/tools/cloudflare/get_worker_route.ts @@ -0,0 +1,60 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareGetWorkerRouteParams, + CloudflareGetWorkerRouteResponse, +} from '@/tools/cloudflare/operation-types' +import { WORKER_ROUTE_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const getWorkerRouteTool: ToolConfig< + CloudflareGetWorkerRouteParams, + CloudflareGetWorkerRouteResponse +> = { + id: 'cloudflare_get_worker_route', + name: 'Cloudflare Get Worker Route', + description: 'Returns information about a Worker route, including URL pattern and Worker.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + routeId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Route id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/workers/routes/${safeUrlPathSegment(params.routeId, 'routeId')}`, + method: 'GET', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, WORKER_ROUTE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get worker route') } : {}), + } + }, + outputs: WORKER_ROUTE_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/get_worker_script_settings.ts b/apps/sim/tools/cloudflare/get_worker_script_settings.ts index dcc787391cf..611b851503f 100644 --- a/apps/sim/tools/cloudflare/get_worker_script_settings.ts +++ b/apps/sim/tools/cloudflare/get_worker_script_settings.ts @@ -1,9 +1,17 @@ +import { isRecordLike } from '@sim/utils/object' +import { WORKER_SETTINGS_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetWorkerScriptSettingsParams, CloudflareGetWorkerScriptSettingsResponse, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getWorkerScriptSettingsTool: ToolConfig< CloudflareGetWorkerScriptSettingsParams, @@ -38,94 +46,21 @@ export const getWorkerScriptSettingsTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/workers/scripts/${encodeURIComponent(params.scriptName)}/settings`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/workers/scripts/${safeUrlPathSegment(params.scriptName, 'scriptName')}/settings`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - bindings: null, - compatibility_date: null, - compatibility_flags: null, - limits: null, - logpush: null, - migrations: null, - observability: null, - placement: null, - tags: null, - tail_consumers: null, - usage_model: null, - }, - error: cloudflareErrorMessage(data, 'Failed to get Worker script settings'), - } - } - - const settings = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - bindings: settings?.bindings ?? null, - compatibility_date: settings?.compatibility_date ?? null, - compatibility_flags: settings?.compatibility_flags ?? null, - limits: settings?.limits ?? null, - logpush: settings?.logpush ?? null, - migrations: settings?.migrations ?? null, - observability: settings?.observability ?? null, - placement: settings?.placement ?? null, - tags: settings?.tags ?? null, - tail_consumers: settings?.tail_consumers ?? null, - usage_model: settings?.usage_model ?? null, - }, + success, + output: mapCloudflareFields(data.result, WORKER_SETTINGS_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to get worker script settings') } + : {}), } }, - - outputs: { - bindings: { - type: 'json', - description: 'Resource bindings available to the script (KV, R2, D1, secrets, and more)', - optional: true, - }, - compatibility_date: { - type: 'string', - description: 'Workers runtime compatibility date', - optional: true, - }, - compatibility_flags: { - type: 'array', - description: 'Workers runtime compatibility flags', - items: { type: 'string', description: 'Compatibility flag' }, - optional: true, - }, - limits: { type: 'json', description: 'CPU and other execution limits', optional: true }, - logpush: { type: 'boolean', description: 'Whether Workers Logpush is enabled', optional: true }, - migrations: { type: 'json', description: 'Durable Object migrations', optional: true }, - observability: { - type: 'json', - description: 'Observability and log-sampling configuration', - optional: true, - }, - placement: { type: 'json', description: 'Smart placement configuration', optional: true }, - tags: { - type: 'array', - description: 'Tags attached to the script', - items: { type: 'string', description: 'Tag name' }, - optional: true, - }, - tail_consumers: { - type: 'json', - description: "Workers that consume this script's tail events", - optional: true, - }, - usage_model: { - type: 'string', - description: 'Billing usage model', - optional: true, - }, - }, + outputs: WORKER_SETTINGS_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_zone.ts b/apps/sim/tools/cloudflare/get_zone.ts index 5d58a922991..7c6c3003f20 100644 --- a/apps/sim/tools/cloudflare/get_zone.ts +++ b/apps/sim/tools/cloudflare/get_zone.ts @@ -1,5 +1,13 @@ +import { isRecordLike } from '@sim/utils/object' +import { ZONE_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareGetZoneParams, CloudflareGetZoneResponse } from '@/tools/cloudflare/types' +import { + cloudflareErrorMessage, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const getZoneTool: ToolConfig = { id: 'cloudflare_get_zone', @@ -23,7 +31,8 @@ export const getZoneTool: ToolConfig `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}`, + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}`, method: 'GET', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, @@ -32,187 +41,13 @@ export const getZoneTool: ToolConfig { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - name: '', - status: '', - paused: false, - type: '', - name_servers: [], - original_name_servers: [], - created_on: '', - modified_on: '', - activated_on: '', - development_mode: 0, - plan: { - id: '', - name: '', - price: 0, - is_subscribed: false, - frequency: '', - currency: '', - legacy_id: '', - }, - account: { id: '', name: '' }, - owner: { id: '', name: '', type: '' }, - meta: { - cdn_only: false, - custom_certificate_quota: 0, - dns_only: false, - foundation_dns: false, - page_rule_quota: 0, - phishing_detected: false, - step: 0, - }, - vanity_name_servers: [], - permissions: [], - }, - error: data.errors?.[0]?.message ?? 'Failed to get zone', - } - } - - const zone = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: zone?.id ?? '', - name: zone?.name ?? '', - status: zone?.status ?? '', - paused: zone?.paused ?? false, - type: zone?.type ?? '', - name_servers: zone?.name_servers ?? [], - original_name_servers: zone?.original_name_servers ?? [], - created_on: zone?.created_on ?? '', - modified_on: zone?.modified_on ?? '', - activated_on: zone?.activated_on ?? '', - development_mode: zone?.development_mode ?? 0, - plan: { - id: zone?.plan?.id ?? '', - name: zone?.plan?.name ?? '', - price: zone?.plan?.price ?? 0, - is_subscribed: zone?.plan?.is_subscribed ?? false, - frequency: zone?.plan?.frequency ?? '', - currency: zone?.plan?.currency ?? '', - legacy_id: zone?.plan?.legacy_id ?? '', - }, - account: { - id: zone?.account?.id ?? '', - name: zone?.account?.name ?? '', - }, - owner: { - id: zone?.owner?.id ?? '', - name: zone?.owner?.name ?? '', - type: zone?.owner?.type ?? '', - }, - meta: { - cdn_only: zone?.meta?.cdn_only ?? false, - custom_certificate_quota: zone?.meta?.custom_certificate_quota ?? 0, - dns_only: zone?.meta?.dns_only ?? false, - foundation_dns: zone?.meta?.foundation_dns ?? false, - page_rule_quota: zone?.meta?.page_rule_quota ?? 0, - phishing_detected: zone?.meta?.phishing_detected ?? false, - step: zone?.meta?.step ?? 0, - }, - vanity_name_servers: zone?.vanity_name_servers ?? [], - permissions: zone?.permissions ?? [], - }, + success, + output: mapCloudflareFields(data.result, ZONE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to get zone') } : {}), } }, - - outputs: { - id: { type: 'string', description: 'Zone ID' }, - name: { type: 'string', description: 'Domain name' }, - status: { - type: 'string', - description: 'Zone status (initializing, pending, active, moved)', - }, - paused: { type: 'boolean', description: 'Whether the zone is paused' }, - type: { type: 'string', description: 'Zone type (full, partial, secondary, or internal)' }, - name_servers: { - type: 'array', - description: 'Assigned Cloudflare name servers', - items: { type: 'string', description: 'Name server hostname' }, - }, - original_name_servers: { - type: 'array', - description: 'Original name servers before moving to Cloudflare', - items: { type: 'string', description: 'Name server hostname' }, - optional: true, - }, - created_on: { type: 'string', description: 'ISO 8601 date when the zone was created' }, - modified_on: { type: 'string', description: 'ISO 8601 date when the zone was last modified' }, - activated_on: { - type: 'string', - description: 'ISO 8601 date when the zone was activated', - optional: true, - }, - development_mode: { - type: 'number', - description: 'Seconds remaining in development mode (0 = off)', - }, - plan: { - type: 'object', - description: 'Zone plan information', - properties: { - id: { type: 'string', description: 'Plan identifier' }, - name: { type: 'string', description: 'Plan name' }, - price: { type: 'number', description: 'Plan price' }, - is_subscribed: { - type: 'boolean', - description: 'Whether the zone is subscribed to the plan', - }, - frequency: { type: 'string', description: 'Plan billing frequency' }, - currency: { type: 'string', description: 'Plan currency' }, - legacy_id: { type: 'string', description: 'Legacy plan identifier' }, - }, - }, - account: { - type: 'object', - description: 'Account the zone belongs to', - properties: { - id: { type: 'string', description: 'Account identifier' }, - name: { type: 'string', description: 'Account name' }, - }, - }, - owner: { - type: 'object', - description: 'Zone owner information', - properties: { - id: { type: 'string', description: 'Owner identifier' }, - name: { type: 'string', description: 'Owner name' }, - type: { type: 'string', description: 'Owner type' }, - }, - }, - meta: { - type: 'object', - description: 'Zone metadata', - properties: { - cdn_only: { type: 'boolean', description: 'Whether the zone is CDN only' }, - custom_certificate_quota: { type: 'number', description: 'Custom certificate quota' }, - dns_only: { type: 'boolean', description: 'Whether the zone is DNS only' }, - foundation_dns: { type: 'boolean', description: 'Whether foundation DNS is enabled' }, - page_rule_quota: { type: 'number', description: 'Page rule quota' }, - phishing_detected: { type: 'boolean', description: 'Whether phishing was detected' }, - step: { type: 'number', description: 'Current setup step' }, - }, - optional: true, - }, - vanity_name_servers: { - type: 'array', - description: 'Custom vanity name servers', - items: { type: 'string', description: 'Vanity name server hostname' }, - optional: true, - }, - permissions: { - type: 'array', - description: 'User permissions for the zone', - items: { type: 'string', description: 'Permission string' }, - optional: true, - }, - }, + outputs: ZONE_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/get_zone_settings.ts b/apps/sim/tools/cloudflare/get_zone_settings.ts index 11d3f8526aa..150cc111aad 100644 --- a/apps/sim/tools/cloudflare/get_zone_settings.ts +++ b/apps/sim/tools/cloudflare/get_zone_settings.ts @@ -6,18 +6,11 @@ import type { import { DEFAULT_ZONE_SETTING_IDS, MAX_ZONE_SETTING_IDS } from '@/tools/cloudflare/utils' import { createInternalToolOperationInput } from '@/tools/operation-input' import type { InternalToolConfig } from '@/tools/types' - -function encodePathSegment(value: string, label: string): string { - const normalized = value.trim() - if (!normalized || normalized === '.' || normalized === '..') { - throw new Error(`${label} must identify a resource`) - } - return encodeURIComponent(normalized) -} +import { safeUrlPathSegment } from '@/tools/url-path' /** Builds the per-setting endpoint Cloudflare directs integrations at. */ export function zoneSettingUrl(zoneId: string, settingId: string): string { - return `https://api.cloudflare.com/client/v4/zones/${encodePathSegment(zoneId, 'Cloudflare zone ID')}/settings/${encodePathSegment(settingId, 'Cloudflare setting ID')}` + return `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(zoneId, 'zoneId')}/settings/${safeUrlPathSegment(settingId, 'settingId')}` } /** @@ -26,12 +19,11 @@ export function zoneSettingUrl(zoneId: string, settingId: string): string { * keep every entry in the list a string. */ export function mapZoneSetting(settingId: string, setting: CloudflareRawZoneSetting | undefined) { + const value = settingId === 'ssl_recommender' ? setting?.enabled : setting?.value return { id: setting?.id ?? settingId, value: - typeof setting?.value === 'object' && setting.value !== null - ? JSON.stringify(setting.value) - : String(setting?.value ?? ''), + typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value ?? ''), editable: setting?.editable ?? false, modified_on: setting?.modified_on ?? '', ...(setting?.time_remaining != null ? { time_remaining: setting.time_remaining } : {}), @@ -86,7 +78,7 @@ export const getZoneSettingsTool: InternalToolConfig< }, value: { type: 'string', - description: `Setting value as a string. Simple values returned as-is (e.g., "full", "on"). Complex values are JSON-stringified (e.g., {"css":"on","html":"on","js":"on"}).`, + description: `Setting value as a string. Simple values returned as-is (e.g., "full", "on"). SSL Recommender returns its enabled flag. Complex values are JSON-stringified (e.g., {"css":"on","html":"on","js":"on"}).`, }, editable: { type: 'boolean', diff --git a/apps/sim/tools/cloudflare/index.ts b/apps/sim/tools/cloudflare/index.ts index d19e5f28ba6..f37f19eeb71 100644 --- a/apps/sim/tools/cloudflare/index.ts +++ b/apps/sim/tools/cloudflare/index.ts @@ -1,97 +1,78 @@ -import { createAccessApplicationTool } from '@/tools/cloudflare/create_access_application' -import { createAccessPolicyTool } from '@/tools/cloudflare/create_access_policy' -import { createAccessServiceTokenTool } from '@/tools/cloudflare/create_access_service_token' -import { createDnsRecordTool } from '@/tools/cloudflare/create_dns_record' -import { createR2BucketTool } from '@/tools/cloudflare/create_r2_bucket' -import { createRateLimitRuleTool } from '@/tools/cloudflare/create_rate_limit_rule' -import { createRulesetTool } from '@/tools/cloudflare/create_ruleset' -import { createRulesetRuleTool } from '@/tools/cloudflare/create_ruleset_rule' -import { createZoneTool } from '@/tools/cloudflare/create_zone' -import { deleteAccessApplicationTool } from '@/tools/cloudflare/delete_access_application' -import { deleteAccessPolicyTool } from '@/tools/cloudflare/delete_access_policy' -import { deleteDnsRecordTool } from '@/tools/cloudflare/delete_dns_record' -import { deleteR2BucketTool } from '@/tools/cloudflare/delete_r2_bucket' -import { deleteRulesetRuleTool } from '@/tools/cloudflare/delete_ruleset_rule' -import { deleteZoneTool } from '@/tools/cloudflare/delete_zone' -import { dnsAnalyticsTool } from '@/tools/cloudflare/dns_analytics' -import { getAccessApplicationTool } from '@/tools/cloudflare/get_access_application' -import { getR2BucketTool } from '@/tools/cloudflare/get_r2_bucket' -import { getRulesetTool } from '@/tools/cloudflare/get_ruleset' -import { getRulesetEntrypointTool } from '@/tools/cloudflare/get_ruleset_entrypoint' -import { getTunnelTool } from '@/tools/cloudflare/get_tunnel' -import { getTunnelConfigurationTool } from '@/tools/cloudflare/get_tunnel_configuration' -import { getWorkerScriptSettingsTool } from '@/tools/cloudflare/get_worker_script_settings' -import { getZoneTool } from '@/tools/cloudflare/get_zone' -import { getZoneSettingsTool } from '@/tools/cloudflare/get_zone_settings' -import { listAccessApplicationsTool } from '@/tools/cloudflare/list_access_applications' -import { listAccessGroupsTool } from '@/tools/cloudflare/list_access_groups' -import { listAccessIdentityProvidersTool } from '@/tools/cloudflare/list_access_identity_providers' -import { listAccessPoliciesTool } from '@/tools/cloudflare/list_access_policies' -import { listAccessServiceTokensTool } from '@/tools/cloudflare/list_access_service_tokens' -import { listCertificatesTool } from '@/tools/cloudflare/list_certificates' -import { listDnsRecordsTool } from '@/tools/cloudflare/list_dns_records' -import { listManagedRulesetOverridesTool } from '@/tools/cloudflare/list_managed_ruleset_overrides' -import { listR2BucketsTool } from '@/tools/cloudflare/list_r2_buckets' -import { listRateLimitRulesTool } from '@/tools/cloudflare/list_rate_limit_rules' -import { listRulesetsTool } from '@/tools/cloudflare/list_rulesets' -import { listTunnelsTool } from '@/tools/cloudflare/list_tunnels' -import { listWorkerRoutesTool } from '@/tools/cloudflare/list_worker_routes' -import { listWorkerScriptsTool } from '@/tools/cloudflare/list_worker_scripts' -import { listZonesTool } from '@/tools/cloudflare/list_zones' -import { purgeCacheTool } from '@/tools/cloudflare/purge_cache' -import { revokeAccessServiceTokenTool } from '@/tools/cloudflare/revoke_access_service_token' -import { updateAccessApplicationTool } from '@/tools/cloudflare/update_access_application' -import { updateAccessPolicyTool } from '@/tools/cloudflare/update_access_policy' -import { updateDnsRecordTool } from '@/tools/cloudflare/update_dns_record' -import { updateRateLimitRuleTool } from '@/tools/cloudflare/update_rate_limit_rule' -import { updateRulesetRuleTool } from '@/tools/cloudflare/update_ruleset_rule' -import { updateZoneSettingTool } from '@/tools/cloudflare/update_zone_setting' - -export const cloudflareCreateAccessApplicationTool = createAccessApplicationTool -export const cloudflareCreateAccessPolicyTool = createAccessPolicyTool -export const cloudflareCreateAccessServiceTokenTool = createAccessServiceTokenTool -export const cloudflareCreateDnsRecordTool = createDnsRecordTool -export const cloudflareCreateR2BucketTool = createR2BucketTool -export const cloudflareCreateRateLimitRuleTool = createRateLimitRuleTool -export const cloudflareCreateRulesetTool = createRulesetTool -export const cloudflareCreateRulesetRuleTool = createRulesetRuleTool -export const cloudflareCreateZoneTool = createZoneTool -export const cloudflareDeleteAccessApplicationTool = deleteAccessApplicationTool -export const cloudflareDeleteAccessPolicyTool = deleteAccessPolicyTool -export const cloudflareDeleteDnsRecordTool = deleteDnsRecordTool -export const cloudflareDeleteR2BucketTool = deleteR2BucketTool -export const cloudflareDeleteRulesetRuleTool = deleteRulesetRuleTool -export const cloudflareDeleteZoneTool = deleteZoneTool -export const cloudflareDnsAnalyticsTool = dnsAnalyticsTool -export const cloudflareGetAccessApplicationTool = getAccessApplicationTool -export const cloudflareGetR2BucketTool = getR2BucketTool -export const cloudflareGetRulesetTool = getRulesetTool -export const cloudflareGetRulesetEntrypointTool = getRulesetEntrypointTool -export const cloudflareGetTunnelTool = getTunnelTool -export const cloudflareGetTunnelConfigurationTool = getTunnelConfigurationTool -export const cloudflareGetWorkerScriptSettingsTool = getWorkerScriptSettingsTool -export const cloudflareGetZoneTool = getZoneTool -export const cloudflareGetZoneSettingsTool = getZoneSettingsTool -export const cloudflareListAccessApplicationsTool = listAccessApplicationsTool -export const cloudflareListAccessGroupsTool = listAccessGroupsTool -export const cloudflareListAccessIdentityProvidersTool = listAccessIdentityProvidersTool -export const cloudflareListAccessPoliciesTool = listAccessPoliciesTool -export const cloudflareListAccessServiceTokensTool = listAccessServiceTokensTool -export const cloudflareListCertificatesTool = listCertificatesTool -export const cloudflareListDnsRecordsTool = listDnsRecordsTool -export const cloudflareListManagedRulesetOverridesTool = listManagedRulesetOverridesTool -export const cloudflareListR2BucketsTool = listR2BucketsTool -export const cloudflareListRateLimitRulesTool = listRateLimitRulesTool -export const cloudflareListRulesetsTool = listRulesetsTool -export const cloudflareListTunnelsTool = listTunnelsTool -export const cloudflareListWorkerRoutesTool = listWorkerRoutesTool -export const cloudflareListWorkerScriptsTool = listWorkerScriptsTool -export const cloudflareListZonesTool = listZonesTool -export const cloudflarePurgeCacheTool = purgeCacheTool -export const cloudflareRevokeAccessServiceTokenTool = revokeAccessServiceTokenTool -export const cloudflareUpdateAccessApplicationTool = updateAccessApplicationTool -export const cloudflareUpdateAccessPolicyTool = updateAccessPolicyTool -export const cloudflareUpdateDnsRecordTool = updateDnsRecordTool -export const cloudflareUpdateRateLimitRuleTool = updateRateLimitRuleTool -export const cloudflareUpdateRulesetRuleTool = updateRulesetRuleTool -export const cloudflareUpdateZoneSettingTool = updateZoneSettingTool +export { createAccessApplicationTool as cloudflareCreateAccessApplicationTool } from './create_access_application' +export { createAccessGroupTool as cloudflareCreateAccessGroupTool } from './create_access_group' +export { createAccessPolicyTool as cloudflareCreateAccessPolicyTool } from './create_access_policy' +export { createAccessServiceTokenTool as cloudflareCreateAccessServiceTokenTool } from './create_access_service_token' +export { createDnsRecordTool as cloudflareCreateDnsRecordTool } from './create_dns_record' +export { createR2BucketTool as cloudflareCreateR2BucketTool } from './create_r2_bucket' +export { createRateLimitRuleTool as cloudflareCreateRateLimitRuleTool } from './create_rate_limit_rule' +export { createRulesetTool as cloudflareCreateRulesetTool } from './create_ruleset' +export { createRulesetRuleTool as cloudflareCreateRulesetRuleTool } from './create_ruleset_rule' +export { createTunnelTool as cloudflareCreateTunnelTool } from './create_tunnel' +export { createWorkerRouteTool as cloudflareCreateWorkerRouteTool } from './create_worker_route' +export { createZoneTool as cloudflareCreateZoneTool } from './create_zone' +export { deleteAccessApplicationTool as cloudflareDeleteAccessApplicationTool } from './delete_access_application' +export { deleteAccessGroupTool as cloudflareDeleteAccessGroupTool } from './delete_access_group' +export { deleteAccessPolicyTool as cloudflareDeleteAccessPolicyTool } from './delete_access_policy' +export { deleteDnsRecordTool as cloudflareDeleteDnsRecordTool } from './delete_dns_record' +export { deleteR2BucketTool as cloudflareDeleteR2BucketTool } from './delete_r2_bucket' +export { deleteR2BucketCorsTool as cloudflareDeleteR2BucketCorsTool } from './delete_r2_bucket_cors' +export { deleteRulesetTool as cloudflareDeleteRulesetTool } from './delete_ruleset' +export { deleteRulesetRuleTool as cloudflareDeleteRulesetRuleTool } from './delete_ruleset_rule' +export { deleteTunnelTool as cloudflareDeleteTunnelTool } from './delete_tunnel' +export { deleteWorkerRouteTool as cloudflareDeleteWorkerRouteTool } from './delete_worker_route' +export { deleteWorkerScriptTool as cloudflareDeleteWorkerScriptTool } from './delete_worker_script' +export { deleteZoneTool as cloudflareDeleteZoneTool } from './delete_zone' +export { dnsAnalyticsTool as cloudflareDnsAnalyticsTool } from './dns_analytics' +export { getAccessApplicationTool as cloudflareGetAccessApplicationTool } from './get_access_application' +export { getAccessGroupTool as cloudflareGetAccessGroupTool } from './get_access_group' +export { getAccessPolicyTool as cloudflareGetAccessPolicyTool } from './get_access_policy' +export { getAccessServiceTokenTool as cloudflareGetAccessServiceTokenTool } from './get_access_service_token' +export { getDnsRecordTool as cloudflareGetDnsRecordTool } from './get_dns_record' +export { getR2BucketTool as cloudflareGetR2BucketTool } from './get_r2_bucket' +export { getR2BucketCorsTool as cloudflareGetR2BucketCorsTool } from './get_r2_bucket_cors' +export { getR2BucketLifecycleTool as cloudflareGetR2BucketLifecycleTool } from './get_r2_bucket_lifecycle' +export { getRulesetTool as cloudflareGetRulesetTool } from './get_ruleset' +export { getRulesetEntrypointTool as cloudflareGetRulesetEntrypointTool } from './get_ruleset_entrypoint' +export { getTunnelTool as cloudflareGetTunnelTool } from './get_tunnel' +export { getTunnelConfigurationTool as cloudflareGetTunnelConfigurationTool } from './get_tunnel_configuration' +export { getTunnelTokenTool as cloudflareGetTunnelTokenTool } from './get_tunnel_token' +export { getWorkerRouteTool as cloudflareGetWorkerRouteTool } from './get_worker_route' +export { getWorkerScriptSettingsTool as cloudflareGetWorkerScriptSettingsTool } from './get_worker_script_settings' +export { getZoneTool as cloudflareGetZoneTool } from './get_zone' +export { getZoneSettingsTool as cloudflareGetZoneSettingsTool } from './get_zone_settings' +export { listAccessApplicationsTool as cloudflareListAccessApplicationsTool } from './list_access_applications' +export { listAccessGroupsTool as cloudflareListAccessGroupsTool } from './list_access_groups' +export { listAccessIdentityProvidersTool as cloudflareListAccessIdentityProvidersTool } from './list_access_identity_providers' +export { listAccessPoliciesTool as cloudflareListAccessPoliciesTool } from './list_access_policies' +export { listAccessServiceTokensTool as cloudflareListAccessServiceTokensTool } from './list_access_service_tokens' +export { listCertificatesTool as cloudflareListCertificatesTool } from './list_certificates' +export { listDnsRecordsTool as cloudflareListDnsRecordsTool } from './list_dns_records' +export { listManagedRulesetOverridesTool as cloudflareListManagedRulesetOverridesTool } from './list_managed_ruleset_overrides' +export { listR2BucketsTool as cloudflareListR2BucketsTool } from './list_r2_buckets' +export { listRateLimitRulesTool as cloudflareListRateLimitRulesTool } from './list_rate_limit_rules' +export { listRulesetsTool as cloudflareListRulesetsTool } from './list_rulesets' +export { listTunnelsTool as cloudflareListTunnelsTool } from './list_tunnels' +export { listWorkerRoutesTool as cloudflareListWorkerRoutesTool } from './list_worker_routes' +export { listWorkerScriptsTool as cloudflareListWorkerScriptsTool } from './list_worker_scripts' +export { listZonesTool as cloudflareListZonesTool } from './list_zones' +export type * from './operation-types' +export { purgeCacheTool as cloudflarePurgeCacheTool } from './purge_cache' +export { refreshAccessServiceTokenTool as cloudflareRefreshAccessServiceTokenTool } from './refresh_access_service_token' +export { revokeAccessServiceTokenTool as cloudflareRevokeAccessServiceTokenTool } from './revoke_access_service_token' +export { rotateAccessServiceTokenTool as cloudflareRotateAccessServiceTokenTool } from './rotate_access_service_token' +export type * from './types' +export { updateAccessApplicationTool as cloudflareUpdateAccessApplicationTool } from './update_access_application' +export { updateAccessGroupTool as cloudflareUpdateAccessGroupTool } from './update_access_group' +export { updateAccessPolicyTool as cloudflareUpdateAccessPolicyTool } from './update_access_policy' +export { updateAccessServiceTokenTool as cloudflareUpdateAccessServiceTokenTool } from './update_access_service_token' +export { updateDnsRecordTool as cloudflareUpdateDnsRecordTool } from './update_dns_record' +export { updateR2BucketCorsTool as cloudflareUpdateR2BucketCorsTool } from './update_r2_bucket_cors' +export { updateR2BucketLifecycleTool as cloudflareUpdateR2BucketLifecycleTool } from './update_r2_bucket_lifecycle' +export { updateRateLimitRuleTool as cloudflareUpdateRateLimitRuleTool } from './update_rate_limit_rule' +export { updateRulesetTool as cloudflareUpdateRulesetTool } from './update_ruleset' +export { updateRulesetRuleTool as cloudflareUpdateRulesetRuleTool } from './update_ruleset_rule' +export { updateTunnelTool as cloudflareUpdateTunnelTool } from './update_tunnel' +export { updateTunnelConfigurationTool as cloudflareUpdateTunnelConfigurationTool } from './update_tunnel_configuration' +export { updateWorkerRouteTool as cloudflareUpdateWorkerRouteTool } from './update_worker_route' +export { updateZoneTool as cloudflareUpdateZoneTool } from './update_zone' +export { updateZoneSettingTool as cloudflareUpdateZoneSettingTool } from './update_zone_setting' diff --git a/apps/sim/tools/cloudflare/list_access_applications.ts b/apps/sim/tools/cloudflare/list_access_applications.ts index 97938fcd247..d3b89858e96 100644 --- a/apps/sim/tools/cloudflare/list_access_applications.ts +++ b/apps/sim/tools/cloudflare/list_access_applications.ts @@ -1,3 +1,4 @@ +import { ACCESS_APPLICATION_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListAccessApplicationsParams, CloudflareListAccessApplicationsResponse, @@ -6,9 +7,11 @@ import { appendParam, cloudflareErrorMessage, cloudflareHeaders, - mapAccessApplication, + mapCloudflareFields, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listAccessApplicationsTool: ToolConfig< CloudflareListAccessApplicationsParams, @@ -21,6 +24,12 @@ export const listAccessApplicationsTool: ToolConfig< version: '1.0.0', params: { + target_attributes: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Target Criteria attributes in key=value format.', + }, accountId: { type: 'string', required: true, @@ -80,7 +89,7 @@ export const listAccessApplicationsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps` ) appendParam(url, 'name', params.name) appendParam(url, 'domain', params.domain) @@ -89,6 +98,7 @@ export const listAccessApplicationsTool: ToolConfig< if (params.exact !== undefined) url.searchParams.append('exact', String(params.exact)) appendParam(url, 'page', params.page) appendParam(url, 'per_page', params.per_page) + appendParam(url, 'target_attributes', params.target_attributes) return url.toString() }, method: 'GET', @@ -96,109 +106,38 @@ export const listAccessApplicationsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { applications: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Access applications'), - } - } - - const applications = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - applications: applications.map(mapAccessApplication), - total_count: data.result_info?.total_count ?? applications.length, + applications: rows.map((row) => mapCloudflareFields(row, ACCESS_APPLICATION_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to list access applications') } + : {}), } }, - outputs: { applications: { type: 'array', - description: 'Access applications in the account', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Access application identifier' }, - name: { type: 'string', description: 'Application name', optional: true }, - domain: { - type: 'string', - description: 'Primary hostname and path secured by Access', - optional: true, - }, - type: { - type: 'string', - description: 'Application type (e.g., self_hosted, saas, ssh, app_launcher, bookmark)', - optional: true, - }, - aud: { - type: 'string', - description: 'Audience tag used to verify Access JWTs', - optional: true, - }, - session_duration: { - type: 'string', - description: 'How long an Access session stays valid (e.g., 24h)', - optional: true, - }, - allowed_idps: { - type: 'array', - description: 'Identity provider IDs users may authenticate with', - items: { type: 'string', description: 'Identity provider ID' }, - optional: true, - }, - app_launcher_visible: { - type: 'boolean', - description: 'Whether the app appears in the App Launcher', - optional: true, - }, - auto_redirect_to_identity: { - type: 'boolean', - description: 'Whether users skip the identity provider picker', - optional: true, - }, - custom_deny_message: { - type: 'string', - description: 'Message shown when access is denied', - optional: true, - }, - custom_deny_url: { - type: 'string', - description: 'URL users are redirected to when access is denied', - optional: true, - }, - logo_url: { type: 'string', description: 'Logo image URL', optional: true }, - self_hosted_domains: { - type: 'array', - description: - 'Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application', - items: { type: 'string', description: 'Hostname and path' }, - optional: true, - }, - destinations: { - type: 'json', - description: 'Public and private destinations secured by the application', - optional: true, - }, - tags: { - type: 'array', - description: 'Tags categorizing the application', - items: { type: 'string', description: 'Tag name' }, - optional: true, - }, - policies: { - type: 'json', - description: 'Access policies attached to the application', - optional: true, - }, - }, - }, + description: 'Applications', + items: { type: 'object', properties: ACCESS_APPLICATION_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of Access applications' }, }, } diff --git a/apps/sim/tools/cloudflare/list_access_groups.ts b/apps/sim/tools/cloudflare/list_access_groups.ts index 65ed2b03cb2..18048f36944 100644 --- a/apps/sim/tools/cloudflare/list_access_groups.ts +++ b/apps/sim/tools/cloudflare/list_access_groups.ts @@ -1,15 +1,17 @@ +import { ACCESS_GROUP_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListAccessGroupsParams, CloudflareListAccessGroupsResponse, - CloudflareRawAccessGroup, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listAccessGroupsTool: ToolConfig< CloudflareListAccessGroupsParams, @@ -63,7 +65,7 @@ export const listAccessGroupsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/groups` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/groups` ) appendParam(url, 'name', params.name) appendParam(url, 'search', params.search) @@ -76,63 +78,36 @@ export const listAccessGroupsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { groups: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Access groups'), - } - } - - const groups = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - groups: groups.map((group) => ({ - id: group.id ?? '', - name: group.name ?? null, - is_default: group.is_default ?? null, - include: group.include ?? null, - exclude: group.exclude ?? null, - require: group.require ?? null, - created_at: group.created_at ?? null, - updated_at: group.updated_at ?? null, - })), - total_count: data.result_info?.total_count ?? groups.length, + groups: rows.map((row) => mapCloudflareFields(row, ACCESS_GROUP_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list access groups') } : {}), } }, - outputs: { groups: { type: 'array', - description: 'Access groups in the account', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Access group identifier' }, - name: { type: 'string', description: 'Group name', optional: true }, - is_default: { - type: 'json', - description: - 'Rules that place this group in every Access application by default. Cloudflare returns an array of rule objects here, not a boolean', - optional: true, - }, - include: { - type: 'json', - description: 'Rules evaluated with OR logic', - optional: true, - }, - exclude: { type: 'json', description: 'Rules evaluated with NOT logic', optional: true }, - require: { type: 'json', description: 'Rules evaluated with AND logic', optional: true }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, - }, - }, + description: 'Groups', + items: { type: 'object', properties: ACCESS_GROUP_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of Access groups' }, }, } diff --git a/apps/sim/tools/cloudflare/list_access_identity_providers.ts b/apps/sim/tools/cloudflare/list_access_identity_providers.ts index c6568fcb499..33aabc0c307 100644 --- a/apps/sim/tools/cloudflare/list_access_identity_providers.ts +++ b/apps/sim/tools/cloudflare/list_access_identity_providers.ts @@ -1,14 +1,17 @@ +import { IDENTITY_PROVIDER_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListAccessIdentityProvidersParams, CloudflareListAccessIdentityProvidersResponse, - CloudflareRawAccessIdentityProvider, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listAccessIdentityProvidersTool: ToolConfig< CloudflareListAccessIdentityProvidersParams, @@ -21,6 +24,25 @@ export const listAccessIdentityProvidersTool: ToolConfig< version: '1.0.0', params: { + scim_enabled: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Indicates to Access to only retrieve identity providers that have the System for Cross-Domain Identity Management (SCIM) enabled.', + }, + page: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Page number of results.', + }, + per_page: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Number of results per page.', + }, accountId: { type: 'string', required: true, @@ -36,77 +58,52 @@ export const listAccessIdentityProvidersTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/identity_providers`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/identity_providers` + ) + appendParam(url, 'scim_enabled', params.scim_enabled) + appendParam(url, 'page', params.page) + appendParam(url, 'per_page', params.per_page) + return url.toString() + }, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { identity_providers: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Access identity providers'), - } - } - - const providers = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - identity_providers: providers.map((provider) => ({ - id: provider.id ?? '', - name: provider.name ?? null, - type: provider.type ?? null, - read_only: provider.read_only ?? null, - config: provider.config ?? null, - scim_config: provider.scim_config ?? null, - })), - total_count: data.result_info?.total_count ?? providers.length, + identity_providers: rows.map((row) => mapCloudflareFields(row, IDENTITY_PROVIDER_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to list access identity providers') } + : {}), } }, - outputs: { identity_providers: { type: 'array', - description: 'Identity providers configured for Access', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Identity provider identifier' }, - name: { - type: 'string', - description: 'Display name shown to users on the login page', - optional: true, - }, - type: { - type: 'string', - description: 'Provider type, e.g. azureAD, okta, google, saml, oidc, or onetimepin', - optional: true, - }, - read_only: { - type: 'boolean', - description: 'Whether the provider is immutable through the API', - optional: true, - }, - config: { - type: 'json', - description: 'Provider-specific configuration parameters', - optional: true, - }, - scim_config: { - type: 'json', - description: 'SCIM user and group provisioning configuration', - optional: true, - }, - }, - }, + description: 'Identity providers', + items: { type: 'object', properties: IDENTITY_PROVIDER_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of identity providers' }, }, } diff --git a/apps/sim/tools/cloudflare/list_access_policies.ts b/apps/sim/tools/cloudflare/list_access_policies.ts index 0ec5e0c645c..147801d5576 100644 --- a/apps/sim/tools/cloudflare/list_access_policies.ts +++ b/apps/sim/tools/cloudflare/list_access_policies.ts @@ -1,3 +1,4 @@ +import { ACCESS_POLICY_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListAccessPoliciesParams, CloudflareListAccessPoliciesResponse, @@ -6,9 +7,11 @@ import { appendParam, cloudflareErrorMessage, cloudflareHeaders, - mapAccessPolicy, + mapCloudflareFields, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listAccessPoliciesTool: ToolConfig< CloudflareListAccessPoliciesParams, @@ -56,7 +59,7 @@ export const listAccessPoliciesTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}/policies` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}/policies` ) appendParam(url, 'page', params.page) appendParam(url, 'per_page', params.per_page) @@ -67,91 +70,38 @@ export const listAccessPoliciesTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { policies: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Access policies'), - } - } - - const policies = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - policies: policies.map(mapAccessPolicy), - total_count: data.result_info?.total_count ?? policies.length, + policies: rows.map((row) => mapCloudflareFields(row, ACCESS_POLICY_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to list access policies') } + : {}), } }, - outputs: { policies: { type: 'array', - description: 'Access policies attached to the application', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Policy identifier' }, - name: { type: 'string', description: 'Policy name', optional: true }, - decision: { - type: 'string', - description: 'Decision the policy applies: allow, deny, non_identity, or bypass', - optional: true, - }, - precedence: { - type: 'number', - description: 'Evaluation order of the policy within the application', - optional: true, - }, - include: { - type: 'json', - description: 'Rules evaluated with OR logic — matching any one selects the policy', - optional: true, - }, - exclude: { - type: 'json', - description: 'Rules evaluated with NOT logic — matching any one rejects the request', - optional: true, - }, - require: { - type: 'json', - description: 'Rules evaluated with AND logic — all must match', - optional: true, - }, - session_duration: { - type: 'string', - description: 'How long a session granted by this policy stays valid', - optional: true, - }, - approval_required: { - type: 'boolean', - description: 'Whether an approver must grant each access request', - optional: true, - }, - isolation_required: { - type: 'boolean', - description: 'Whether the session must run in a remote browser', - optional: true, - }, - purpose_justification_required: { - type: 'boolean', - description: 'Whether users must state a reason for access', - optional: true, - }, - purpose_justification_prompt: { - type: 'string', - description: 'Prompt shown when a justification is required', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, - }, - }, + description: 'Policies', + items: { type: 'object', properties: ACCESS_POLICY_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of policies' }, }, } diff --git a/apps/sim/tools/cloudflare/list_access_service_tokens.ts b/apps/sim/tools/cloudflare/list_access_service_tokens.ts index 75e0737752a..58ef747f985 100644 --- a/apps/sim/tools/cloudflare/list_access_service_tokens.ts +++ b/apps/sim/tools/cloudflare/list_access_service_tokens.ts @@ -1,15 +1,17 @@ +import { RESULT_INFO_OUTPUTS, SERVICE_TOKEN_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListAccessServiceTokensParams, CloudflareListAccessServiceTokensResponse, - CloudflareRawAccessServiceToken, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listAccessServiceTokensTool: ToolConfig< CloudflareListAccessServiceTokensParams, @@ -63,7 +65,7 @@ export const listAccessServiceTokensTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/service_tokens` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens` ) appendParam(url, 'name', params.name) appendParam(url, 'search', params.search) @@ -76,68 +78,38 @@ export const listAccessServiceTokensTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { service_tokens: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Access service tokens'), - } - } - - const tokens = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - service_tokens: tokens.map((token) => ({ - id: token.id ?? '', - name: token.name ?? null, - client_id: token.client_id ?? null, - duration: token.duration ?? null, - enabled: token.enabled ?? null, - expires_at: token.expires_at ?? null, - last_seen_at: token.last_seen_at ?? null, - created_at: token.created_at ?? null, - updated_at: token.updated_at ?? null, - })), - total_count: data.result_info?.total_count ?? tokens.length, + service_tokens: rows.map((row) => mapCloudflareFields(row, SERVICE_TOKEN_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to list access service tokens') } + : {}), } }, - outputs: { service_tokens: { type: 'array', - description: 'Access service tokens in the account', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Service token identifier' }, - name: { type: 'string', description: 'Service token name', optional: true }, - client_id: { - type: 'string', - description: 'Client ID sent in the CF-Access-Client-Id header', - optional: true, - }, - duration: { - type: 'string', - description: 'How long the token stays valid before it expires', - optional: true, - }, - enabled: { type: 'boolean', description: 'Whether the token is active', optional: true }, - expires_at: { type: 'string', description: 'Expiry timestamp', optional: true }, - last_seen_at: { - type: 'string', - description: 'When the token was last used', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, - }, - }, + description: 'Service tokens', + items: { type: 'object', properties: SERVICE_TOKEN_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of service tokens' }, }, } diff --git a/apps/sim/tools/cloudflare/list_certificates.ts b/apps/sim/tools/cloudflare/list_certificates.ts index 4a8d104b289..115dc4dace5 100644 --- a/apps/sim/tools/cloudflare/list_certificates.ts +++ b/apps/sim/tools/cloudflare/list_certificates.ts @@ -1,10 +1,15 @@ +import { CERTIFICATE_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListCertificatesParams, CloudflareListCertificatesResponse, - CloudflareRawCertificatePack, } from '@/tools/cloudflare/types' -import { readCloudflareResponse } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listCertificatesTool: ToolConfig< CloudflareListCertificatesParams, @@ -58,7 +63,7 @@ export const listCertificatesTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/ssl/certificate_packs` + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/ssl/certificate_packs` ) if (params.status) url.searchParams.append('status', params.status) if (params.page) url.searchParams.append('page', String(params.page)) @@ -74,231 +79,36 @@ export const listCertificatesTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { certificates: [], total_count: 0 }, - error: data.errors?.[0]?.message ?? 'Failed to list certificates', - } - } - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - certificates: (Array.isArray(data.result) ? data.result : []).map((cert) => ({ - id: cert.id ?? '', - type: cert.type ?? '', - hosts: cert.hosts ?? [], - primary_certificate: cert.primary_certificate ?? '', - status: cert.status ?? '', - certificates: - cert.certificates?.map((c) => ({ - id: c.id ?? '', - hosts: c.hosts ?? [], - issuer: c.issuer ?? '', - signature: c.signature ?? '', - status: c.status ?? '', - bundle_method: c.bundle_method ?? '', - zone_id: c.zone_id ?? '', - uploaded_on: c.uploaded_on ?? '', - modified_on: c.modified_on ?? '', - expires_on: c.expires_on ?? '', - priority: c.priority ?? 0, - geo_restrictions: c.geo_restrictions ?? undefined, - })) ?? [], - cloudflare_branding: cert.cloudflare_branding ?? false, - validation_method: cert.validation_method ?? '', - validity_days: cert.validity_days ?? 0, - certificate_authority: cert.certificate_authority ?? '', - validation_errors: - cert.validation_errors?.map((e) => ({ - message: e.message ?? '', - })) ?? [], - validation_records: - cert.validation_records?.map((r) => ({ - cname: r.cname ?? '', - cname_target: r.cname_target ?? '', - emails: r.emails ?? [], - http_body: r.http_body ?? '', - http_url: r.http_url ?? '', - status: r.status ?? '', - txt_name: r.txt_name ?? '', - txt_value: r.txt_value ?? '', - })) ?? [], - dcv_delegation_records: - cert.dcv_delegation_records?.map((r) => ({ - cname: r.cname ?? '', - cname_target: r.cname_target ?? '', - emails: r.emails ?? [], - http_body: r.http_body ?? '', - http_url: r.http_url ?? '', - status: r.status ?? '', - txt_name: r.txt_name ?? '', - txt_value: r.txt_value ?? '', - })) ?? [], - })), - total_count: data.result_info?.total_count ?? data.result?.length ?? 0, + certificates: rows.map((row) => mapCloudflareFields(row, CERTIFICATE_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list certificates') } : {}), } }, - outputs: { certificates: { type: 'array', - description: 'List of SSL/TLS certificate packs', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Certificate pack ID' }, - type: { type: 'string', description: 'Certificate type (e.g., "universal", "advanced")' }, - hosts: { - type: 'array', - description: 'Hostnames covered by this certificate pack', - items: { - type: 'string', - description: 'Hostname', - }, - }, - primary_certificate: { - type: 'string', - description: 'ID of the primary certificate in the pack', - optional: true, - }, - status: { - type: 'string', - description: 'Certificate pack status (e.g., "active", "pending")', - }, - certificates: { - type: 'array', - description: 'Individual certificates within the pack', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Certificate ID' }, - hosts: { - type: 'array', - description: 'Hostnames covered by this certificate', - items: { type: 'string', description: 'Hostname' }, - }, - issuer: { type: 'string', description: 'Certificate issuer' }, - signature: { - type: 'string', - description: 'Signature algorithm (e.g., "ECDSAWithSHA256")', - }, - status: { type: 'string', description: 'Certificate status' }, - bundle_method: { - type: 'string', - description: 'Bundle method (e.g., "ubiquitous")', - }, - zone_id: { type: 'string', description: 'Zone ID the certificate belongs to' }, - uploaded_on: { type: 'string', description: 'Upload date (ISO 8601)' }, - modified_on: { type: 'string', description: 'Last modified date (ISO 8601)' }, - expires_on: { type: 'string', description: 'Expiration date (ISO 8601)' }, - priority: { - type: 'number', - description: 'Certificate priority order', - optional: true, - }, - geo_restrictions: { - type: 'object', - description: 'Geographic restrictions for the certificate', - optional: true, - properties: { - label: { - type: 'string', - description: 'Geographic restriction label', - }, - }, - }, - }, - }, - }, - cloudflare_branding: { - type: 'boolean', - description: 'Whether Cloudflare branding is enabled on the certificate', - optional: true, - }, - validation_method: { - type: 'string', - description: 'Validation method (e.g., "txt", "http", "cname")', - optional: true, - }, - validity_days: { - type: 'number', - description: 'Validity period in days', - optional: true, - }, - certificate_authority: { - type: 'string', - description: 'Certificate authority (e.g., "lets_encrypt", "google")', - optional: true, - }, - validation_errors: { - type: 'array', - description: 'Validation issues for the certificate pack', - optional: true, - items: { - type: 'object', - properties: { - message: { - type: 'string', - description: 'Validation error message', - }, - }, - }, - }, - validation_records: { - type: 'array', - description: 'Validation records for the certificate pack', - optional: true, - items: { - type: 'object', - properties: { - cname: { type: 'string', description: 'CNAME record name' }, - cname_target: { type: 'string', description: 'CNAME record target' }, - emails: { - type: 'array', - description: 'Email addresses for validation', - items: { type: 'string', description: 'Email address' }, - }, - http_body: { type: 'string', description: 'HTTP validation body content' }, - http_url: { type: 'string', description: 'HTTP validation URL' }, - status: { type: 'string', description: 'Validation record status' }, - txt_name: { type: 'string', description: 'TXT record name' }, - txt_value: { type: 'string', description: 'TXT record value' }, - }, - }, - }, - dcv_delegation_records: { - type: 'array', - description: 'Domain control validation delegation records', - optional: true, - items: { - type: 'object', - properties: { - cname: { type: 'string', description: 'CNAME record name' }, - cname_target: { type: 'string', description: 'CNAME record target' }, - emails: { - type: 'array', - description: 'Email addresses for validation', - items: { type: 'string', description: 'Email address' }, - }, - http_body: { type: 'string', description: 'HTTP validation body content' }, - http_url: { type: 'string', description: 'HTTP validation URL' }, - status: { type: 'string', description: 'Delegation record status' }, - txt_name: { type: 'string', description: 'TXT record name' }, - txt_value: { type: 'string', description: 'TXT record value' }, - }, - }, - }, - }, - }, + description: 'Certificates', + items: { type: 'object', properties: CERTIFICATE_OUTPUTS }, }, total_count: { type: 'number', - description: 'Total number of certificate packs', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, }, } diff --git a/apps/sim/tools/cloudflare/list_dns_records.ts b/apps/sim/tools/cloudflare/list_dns_records.ts index 1c726d4c990..03a15f655b5 100644 --- a/apps/sim/tools/cloudflare/list_dns_records.ts +++ b/apps/sim/tools/cloudflare/list_dns_records.ts @@ -1,10 +1,16 @@ +import { DNS_RECORD_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListDnsRecordsParams, CloudflareListDnsRecordsResponse, - CloudflareRawDnsRecord, } from '@/tools/cloudflare/types' -import { readCloudflareResponse } from '@/tools/cloudflare/utils' +import { + appendParam, + cloudflareErrorMessage, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listDnsRecordsTool: ToolConfig< CloudflareListDnsRecordsParams, @@ -16,6 +22,128 @@ export const listDnsRecordsTool: ToolConfig< version: '1.0.0', params: { + name_contains: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Substring of the DNS record name. Name filters are case-insensitive.', + }, + name_startswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Prefix of the DNS record name. Name filters are case-insensitive.', + }, + name_endswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Suffix of the DNS record name. Name filters are case-insensitive.', + }, + content_contains: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Substring of the DNS record content. Content filters are case-insensitive.', + }, + content_startswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Prefix of the DNS record content. Content filters are case-insensitive.', + }, + content_endswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Suffix of the DNS record content. Content filters are case-insensitive.', + }, + comment_present: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'If this parameter is present, only records *with* a comment are returned.', + }, + comment_absent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'If this parameter is present, only records *without* a comment are returned.', + }, + comment_exact: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Exact value of the DNS record comment. Comment filters are case-insensitive.', + }, + comment_startswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Prefix of the DNS record comment. Comment filters are case-insensitive.', + }, + comment_endswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Suffix of the DNS record comment. Comment filters are case-insensitive.', + }, + tag_present: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Name of a tag which must be present on the DNS record. Tag filters are case-insensitive.', + }, + tag_absent: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Name of a tag which must *not* be present on the DNS record. Tag filters are case-insensitive.', + }, + tag_contains: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value contains ``. Tag filters are case-insensitive.', + }, + tag_startswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value starts with ``. Tag filters are case-insensitive.', + }, + tag_endswith: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A tag and value, of the form `:`. The API will only return DNS records that have a tag named `` whose value ends with ``. Tag filters are case-insensitive.', + }, + include_shadow_metadata: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + shadowed_by_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Filters the response to records at or below the specified NS delegation name. NS, DS, and NSEC records at the delegation name are excluded because they are not shadowed by that delegation. Those record types are included only when they exist below the delegation. The value must be a non-apex subdomain of the zone. Requires `include_shadow_metadata=true`. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, + shadowing_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Returns NS records that shadow the given name, searching at the name itself and each of its ancestor names within the zone, excluding the zone apex. The value must be a subdomain of the zone; the zone apex is not accepted. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, zoneId: { type: 'string', required: true, @@ -86,7 +214,7 @@ export const listDnsRecordsTool: ToolConfig< type: 'string', required: false, visibility: 'user-or-llm', - description: 'Filter by an exact tag name', + description: 'Filter by tag name, or an exact name:value pair (e.g., team:DNS)', }, tag_match: { type: 'string', @@ -112,7 +240,7 @@ export const listDnsRecordsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/dns_records` + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_records` ) if (params.type) url.searchParams.append('type', params.type) if (params.name) url.searchParams.append('name.exact', params.name) @@ -124,9 +252,28 @@ export const listDnsRecordsTool: ToolConfig< if (params.order) url.searchParams.append('order', params.order) if (params.proxied !== undefined) url.searchParams.append('proxied', String(params.proxied)) if (params.search) url.searchParams.append('search', params.search) - if (params.tag) url.searchParams.append('tag.exact', params.tag) + if (params.tag) url.searchParams.append('tag', params.tag) if (params.tag_match) url.searchParams.append('tag_match', params.tag_match) if (params.commentFilter) url.searchParams.append('comment.contains', params.commentFilter) + appendParam(url, 'name.contains', params.name_contains) + appendParam(url, 'name.startswith', params.name_startswith) + appendParam(url, 'name.endswith', params.name_endswith) + appendParam(url, 'content.contains', params.content_contains) + appendParam(url, 'content.startswith', params.content_startswith) + appendParam(url, 'content.endswith', params.content_endswith) + if (params.comment_present === true) url.searchParams.set('comment.present', '') + if (params.comment_absent === true) url.searchParams.set('comment.absent', '') + appendParam(url, 'comment.exact', params.comment_exact) + appendParam(url, 'comment.startswith', params.comment_startswith) + appendParam(url, 'comment.endswith', params.comment_endswith) + appendParam(url, 'tag.present', params.tag_present) + appendParam(url, 'tag.absent', params.tag_absent) + appendParam(url, 'tag.contains', params.tag_contains) + appendParam(url, 'tag.startswith', params.tag_startswith) + appendParam(url, 'tag.endswith', params.tag_endswith) + appendParam(url, 'include_shadow_metadata', params.include_shadow_metadata) + appendParam(url, 'shadowed_by_name', params.shadowed_by_name) + appendParam(url, 'shadowing_name', params.shadowing_name) return url.toString() }, method: 'GET', @@ -137,108 +284,36 @@ export const listDnsRecordsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { records: [], total_count: 0 }, - error: data.errors?.[0]?.message ?? 'Failed to list DNS records', - } - } - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - records: (Array.isArray(data.result) ? data.result : []).map((record) => ({ - id: record.id ?? '', - zone_id: record.zone_id ?? '', - zone_name: record.zone_name ?? '', - type: record.type ?? '', - name: record.name ?? '', - content: record.content ?? '', - proxiable: record.proxiable ?? false, - proxied: record.proxied ?? false, - ttl: record.ttl ?? 0, - locked: record.locked ?? false, - priority: record.priority ?? null, - comment: record.comment ?? null, - tags: record.tags ?? [], - comment_modified_on: record.comment_modified_on ?? null, - tags_modified_on: record.tags_modified_on ?? null, - meta: record.meta ?? null, - created_on: record.created_on ?? '', - modified_on: record.modified_on ?? '', - })), - total_count: data.result_info?.total_count ?? data.result?.length ?? 0, + records: rows.map((row) => mapCloudflareFields(row, DNS_RECORD_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list dns records') } : {}), } }, - outputs: { records: { type: 'array', - description: 'List of DNS records', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Unique identifier for the DNS record' }, - zone_id: { type: 'string', description: 'The ID of the zone the record belongs to' }, - zone_name: { type: 'string', description: 'The name of the zone' }, - type: { type: 'string', description: 'Record type (A, AAAA, CNAME, MX, TXT, etc.)' }, - name: { type: 'string', description: 'Record name (e.g., example.com)' }, - content: { type: 'string', description: 'Record content (e.g., IP address)' }, - proxiable: { type: 'boolean', description: 'Whether the record can be proxied' }, - proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, - ttl: { type: 'number', description: 'TTL in seconds (1 = automatic)' }, - locked: { type: 'boolean', description: 'Whether the record is locked' }, - priority: { - type: 'number', - description: 'Record priority, returned for MX and URI records', - optional: true, - }, - comment: { - type: 'string', - description: 'Comment associated with the record', - optional: true, - }, - tags: { - type: 'array', - description: 'Tags associated with the record', - items: { type: 'string', description: 'Tag value' }, - }, - comment_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the comment was last modified', - optional: true, - }, - tags_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when tags were last modified', - optional: true, - }, - meta: { - type: 'object', - description: 'Record metadata', - optional: true, - properties: { - source: { type: 'string', description: 'Source of the DNS record' }, - }, - }, - created_on: { - type: 'string', - description: 'ISO 8601 timestamp when the record was created', - }, - modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the record was last modified', - }, - }, - }, + description: 'Records', + items: { type: 'object', properties: DNS_RECORD_OUTPUTS }, }, total_count: { type: 'number', - description: 'Total number of DNS records matching the query', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, }, } diff --git a/apps/sim/tools/cloudflare/list_managed_ruleset_overrides.ts b/apps/sim/tools/cloudflare/list_managed_ruleset_overrides.ts index 603a58d2990..ae53f29c97e 100644 --- a/apps/sim/tools/cloudflare/list_managed_ruleset_overrides.ts +++ b/apps/sim/tools/cloudflare/list_managed_ruleset_overrides.ts @@ -9,6 +9,7 @@ import { readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listManagedRulesetOverridesTool: ToolConfig< CloudflareListManagedRulesetOverridesParams, @@ -37,7 +38,7 @@ export const listManagedRulesetOverridesTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/phases/http_request_firewall_managed/entrypoint`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/phases/http_request_firewall_managed/entrypoint`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, @@ -45,7 +46,7 @@ export const listManagedRulesetOverridesTool: ToolConfig< transformResponse: async (response: Response) => { const data = await readCloudflareResponse(response) - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { ruleset_id: '', deployments: [], total_count: 0 }, diff --git a/apps/sim/tools/cloudflare/list_r2_buckets.ts b/apps/sim/tools/cloudflare/list_r2_buckets.ts index cd73043771d..3278340842a 100644 --- a/apps/sim/tools/cloudflare/list_r2_buckets.ts +++ b/apps/sim/tools/cloudflare/list_r2_buckets.ts @@ -1,15 +1,18 @@ +import { toRecord } from '@sim/utils/object' +import { R2_BUCKET_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListR2BucketsParams, CloudflareListR2BucketsResponse, - CloudflareRawR2Bucket, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listR2BucketsTool: ToolConfig< CloudflareListR2BucketsParams, @@ -22,6 +25,12 @@ export const listR2BucketsTool: ToolConfig< version: '1.0.0', params: { + order: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Order buckets by name. Allowed values: name.', + }, accountId: { type: 'string', required: true, @@ -75,7 +84,7 @@ export const listR2BucketsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/r2/buckets` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets` ) appendParam(url, 'name_contains', params.name_contains) appendParam(url, 'start_after', params.start_after) @@ -84,7 +93,7 @@ export const listR2BucketsTool: ToolConfig< appendParam(url, 'per_page', params.per_page) // `direction` only means something alongside an ordering field, and `name` // is the sole value Cloudflare documents for `order`. - if (params.direction) url.searchParams.append('order', 'name') + appendParam(url, 'order', params.order || (params.direction ? 'name' : undefined)) return url.toString() }, method: 'GET', @@ -96,65 +105,45 @@ export const listR2BucketsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse<{ buckets?: CloudflareRawR2Bucket[] }>(response) - - if (!data.success) { - return { - success: false, - output: { buckets: [], cursor: null }, - error: cloudflareErrorMessage(data, 'Failed to list R2 buckets'), - } - } - - const buckets = Array.isArray(data.result?.buckets) ? data.result.buckets : [] - + const data = await readCloudflareResponse(response) + const raw = toRecord(data.result).buckets + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - buckets: buckets.map((bucket) => ({ - name: bucket.name ?? '', - creation_date: bucket.creation_date ?? null, - location: bucket.location ?? null, - storage_class: bucket.storage_class ?? null, - jurisdiction: bucket.jurisdiction ?? null, - })), + buckets: rows.map((row) => mapCloudflareFields(row, R2_BUCKET_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, cursor: data.result_info?.cursor ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list r2 buckets') } : {}), } }, - outputs: { buckets: { type: 'array', - description: 'R2 buckets in the account', - items: { - type: 'object', - properties: { - name: { type: 'string', description: 'Bucket name' }, - creation_date: { type: 'string', description: 'Creation timestamp', optional: true }, - location: { - type: 'string', - description: - 'Location hint the bucket was created with (apac, eeur, enam, weur, wnam, or oc)', - optional: true, - }, - storage_class: { - type: 'string', - description: 'Default storage class (Standard or InfrequentAccess)', - optional: true, - }, - jurisdiction: { - type: 'string', - description: 'Data-residency jurisdiction (default, eu, or fedramp)', - optional: true, - }, + description: 'Buckets', + items: { type: 'object', properties: R2_BUCKET_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total active buckets in the requested jurisdiction, independent of filtering or pagination. Eventually consistent for accounts with elevated bucket limits. Falls back to this page’s bucket count when the API omits the total.', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: { + ...RESULT_INFO_OUTPUTS, + total_count: { + ...RESULT_INFO_OUTPUTS.total_count, + description: + 'Total active buckets in the requested jurisdiction, independent of filtering or pagination. Eventually consistent for accounts with elevated bucket limits.', }, }, }, - cursor: { - type: 'string', - description: 'Pagination cursor to pass to the next call', - optional: true, - }, + cursor: { type: 'string', description: 'Cursor for the next page', nullable: true }, }, } diff --git a/apps/sim/tools/cloudflare/list_rate_limit_rules.ts b/apps/sim/tools/cloudflare/list_rate_limit_rules.ts index 09a723c58ec..4d7263cceb3 100644 --- a/apps/sim/tools/cloudflare/list_rate_limit_rules.ts +++ b/apps/sim/tools/cloudflare/list_rate_limit_rules.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListRateLimitRulesParams, CloudflareRulesetResponse, @@ -5,10 +7,11 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listRateLimitRulesTool: ToolConfig< CloudflareListRateLimitRulesParams, @@ -37,83 +40,21 @@ export const listRateLimitRulesTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/phases/http_ratelimit/entrypoint`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/phases/http_ratelimit/entrypoint`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to list rate limiting rules'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to list rate limit rules') } + : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { - type: 'string', - description: 'Ruleset ID of the http_ratelimit entry point, needed to create or edit rules', - }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind' }, - phase: { type: 'string', description: 'Phase the ruleset runs in (http_ratelimit)' }, - version: { type: 'string', description: 'Ruleset version', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rate limiting rules, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { - type: 'string', - description: 'Action applied once the rate limit is exceeded', - }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters, such as a custom block response', - optional: true, - }, - expression: { - type: 'string', - description: 'Filter expression selecting the requests the rule applies to', - }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: - 'Rate limiting configuration (characteristics, period, requests_per_period, mitigation_timeout, counting_expression, requests_to_origin)', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/list_rulesets.ts b/apps/sim/tools/cloudflare/list_rulesets.ts index 25cffb0a1ee..745969aaaf6 100644 --- a/apps/sim/tools/cloudflare/list_rulesets.ts +++ b/apps/sim/tools/cloudflare/list_rulesets.ts @@ -1,15 +1,17 @@ +import { LIST_RULESETS_OUTPUTS, RESULT_INFO_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListRulesetsParams, CloudflareListRulesetsResponse, - CloudflareRawRuleset, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listRulesetsTool: ToolConfig< CloudflareListRulesetsParams, @@ -52,7 +54,7 @@ export const listRulesetsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets` + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets` ) appendParam(url, 'per_page', params.per_page) appendParam(url, 'cursor', params.cursor) @@ -63,69 +65,38 @@ export const listRulesetsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { rulesets: [], total_count: 0, cursor: null }, - error: cloudflareErrorMessage(data, 'Failed to list rulesets'), - } - } - - const rulesets = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - rulesets: rulesets.map((ruleset) => ({ - id: ruleset.id ?? '', - name: ruleset.name ?? '', - description: ruleset.description ?? '', - kind: ruleset.kind ?? '', - phase: ruleset.phase ?? '', - version: ruleset.version ?? null, - last_updated: ruleset.last_updated ?? null, - })), - total_count: rulesets.length, + rulesets: rows.map((row) => mapCloudflareFields(row, LIST_RULESETS_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, cursor: data.result_info?.cursors?.after ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list rulesets') } : {}), } }, - outputs: { rulesets: { type: 'array', - description: 'Rulesets defined on the zone', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { - type: 'string', - description: 'Ruleset kind (managed, custom, root, or zone)', - }, - phase: { - type: 'string', - description: - 'Phase the ruleset runs in (e.g., http_request_firewall_custom, http_request_firewall_managed, http_ratelimit)', - }, - version: { type: 'string', description: 'Ruleset version', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - }, - }, + description: 'Rulesets', + items: { type: 'object', properties: LIST_RULESETS_OUTPUTS }, }, - total_count: { type: 'number', description: 'Number of rulesets returned on this page' }, - cursor: { - type: 'string', - description: 'Cursor to pass to the next call to read the following page, when more remain', - optional: true, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, + cursor: { type: 'string', description: 'Cursor for the next page', nullable: true }, }, } diff --git a/apps/sim/tools/cloudflare/list_tunnels.ts b/apps/sim/tools/cloudflare/list_tunnels.ts index 14f8821e1da..4a850e3c1d4 100644 --- a/apps/sim/tools/cloudflare/list_tunnels.ts +++ b/apps/sim/tools/cloudflare/list_tunnels.ts @@ -1,15 +1,17 @@ +import { RESULT_INFO_OUTPUTS, TUNNEL_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListTunnelsParams, CloudflareListTunnelsResponse, - CloudflareRawTunnel, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listTunnelsTool: ToolConfig< CloudflareListTunnelsParams, @@ -105,7 +107,7 @@ export const listTunnelsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/cfd_tunnel` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel` ) appendParam(url, 'name', params.name) appendParam(url, 'status', params.status) @@ -127,100 +129,36 @@ export const listTunnelsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { tunnels: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list tunnels'), - } - } - - const tunnels = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - tunnels: tunnels.map((tunnel) => ({ - id: tunnel.id ?? '', - name: tunnel.name ?? null, - account_tag: tunnel.account_tag ?? null, - config_src: tunnel.config_src ?? null, - status: tunnel.status ?? null, - tun_type: tunnel.tun_type ?? null, - remote_config: tunnel.remote_config ?? null, - metadata: tunnel.metadata ?? null, - created_at: tunnel.created_at ?? null, - deleted_at: tunnel.deleted_at ?? null, - conns_active_at: tunnel.conns_active_at ?? null, - conns_inactive_at: tunnel.conns_inactive_at ?? null, - connections: tunnel.connections ?? null, - })), - total_count: data.result_info?.total_count ?? tunnels.length, + tunnels: rows.map((row) => mapCloudflareFields(row, TUNNEL_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list tunnels') } : {}), } }, - outputs: { tunnels: { type: 'array', - description: 'Cloudflare Tunnels in the account', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Tunnel identifier' }, - name: { type: 'string', description: 'Tunnel name', optional: true }, - account_tag: { - type: 'string', - description: 'Account the tunnel belongs to', - optional: true, - }, - config_src: { - type: 'string', - description: 'Where the tunnel configuration lives: local or cloudflare', - optional: true, - }, - status: { - type: 'string', - description: 'Tunnel health: inactive, degraded, healthy, or down', - optional: true, - }, - tun_type: { - type: 'string', - description: 'Tunnel type, e.g. cfd_tunnel, warp_connector, or warp', - optional: true, - }, - remote_config: { - type: 'boolean', - description: 'Whether the tunnel is remotely managed', - optional: true, - }, - metadata: { - type: 'json', - description: 'Metadata associated with the tunnel', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - deleted_at: { type: 'string', description: 'Deletion timestamp', optional: true }, - conns_active_at: { - type: 'string', - description: 'When the tunnel last had active connections', - optional: true, - }, - conns_inactive_at: { - type: 'string', - description: 'When the tunnel last lost all connections', - optional: true, - }, - connections: { - type: 'json', - description: 'Active connector connections for the tunnel', - optional: true, - }, - }, - }, + description: 'Tunnels', + items: { type: 'object', properties: TUNNEL_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Total number of tunnels' }, }, } diff --git a/apps/sim/tools/cloudflare/list_worker_routes.ts b/apps/sim/tools/cloudflare/list_worker_routes.ts index 96dffef09f9..68cdfcf7858 100644 --- a/apps/sim/tools/cloudflare/list_worker_routes.ts +++ b/apps/sim/tools/cloudflare/list_worker_routes.ts @@ -1,14 +1,16 @@ +import { RESULT_INFO_OUTPUTS, WORKER_ROUTE_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListWorkerRoutesParams, CloudflareListWorkerRoutesResponse, - CloudflareRawWorkerRoute, } from '@/tools/cloudflare/types' import { cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listWorkerRoutesTool: ToolConfig< CloudflareListWorkerRoutesParams, @@ -38,57 +40,42 @@ export const listWorkerRoutesTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/workers/routes`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/workers/routes`, method: 'GET', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { routes: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Worker routes'), - } - } - - const routes = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - routes: routes.map((route) => ({ - id: route.id ?? '', - pattern: route.pattern ?? '', - script: route.script ?? null, - })), - total_count: routes.length, + routes: rows.map((row) => mapCloudflareFields(row, WORKER_ROUTE_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list worker routes') } : {}), } }, - outputs: { routes: { type: 'array', - description: 'Workers routes on the zone', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Route identifier' }, - pattern: { - type: 'string', - description: 'URL pattern the route matches, e.g. example.com/*', - }, - script: { - type: 'string', - description: 'Name of the Workers script handling the route', - optional: true, - }, - }, - }, + description: 'Routes', + items: { type: 'object', properties: WORKER_ROUTE_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Number of routes returned' }, }, } diff --git a/apps/sim/tools/cloudflare/list_worker_scripts.ts b/apps/sim/tools/cloudflare/list_worker_scripts.ts index c41bfdd2542..993993c0804 100644 --- a/apps/sim/tools/cloudflare/list_worker_scripts.ts +++ b/apps/sim/tools/cloudflare/list_worker_scripts.ts @@ -1,15 +1,17 @@ +import { RESULT_INFO_OUTPUTS, WORKER_SCRIPT_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListWorkerScriptsParams, CloudflareListWorkerScriptsResponse, - CloudflareRawWorkerScript, } from '@/tools/cloudflare/types' import { appendParam, cloudflareErrorMessage, cloudflareHeaders, + mapCloudflareFields, readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const listWorkerScriptsTool: ToolConfig< CloudflareListWorkerScriptsParams, @@ -46,7 +48,7 @@ export const listWorkerScriptsTool: ToolConfig< request: { url: (params) => { const url = new URL( - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/workers/scripts` + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/workers/scripts` ) appendParam(url, 'tags', params.tags) return url.toString() @@ -56,103 +58,36 @@ export const listWorkerScriptsTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { scripts: [], total_count: 0 }, - error: cloudflareErrorMessage(data, 'Failed to list Worker scripts'), - } - } - - const scripts = Array.isArray(data.result) ? data.result : [] - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - scripts: scripts.map((script) => ({ - id: script.id ?? '', - tag: script.tag ?? null, - etag: script.etag ?? null, - created_on: script.created_on ?? null, - modified_on: script.modified_on ?? null, - usage_model: script.usage_model ?? null, - placement_mode: script.placement_mode ?? null, - logpush: script.logpush ?? null, - has_assets: script.has_assets ?? null, - has_modules: script.has_modules ?? null, - compatibility_date: script.compatibility_date ?? null, - compatibility_flags: script.compatibility_flags ?? null, - routes: script.routes ?? null, - tail_consumers: script.tail_consumers ?? null, - })), - total_count: scripts.length, + scripts: rows.map((row) => mapCloudflareFields(row, WORKER_SCRIPT_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list worker scripts') } : {}), } }, - outputs: { scripts: { type: 'array', - description: 'Workers scripts in the account', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Script name' }, - tag: { - type: 'string', - description: 'Immutable script identifier, distinct from the script name', - optional: true, - }, - etag: { type: 'string', description: 'Hash of the script content', optional: true }, - created_on: { type: 'string', description: 'Creation timestamp', optional: true }, - modified_on: { type: 'string', description: 'Last deployment timestamp', optional: true }, - usage_model: { - type: 'string', - description: 'Billing usage model (standard, bundled, or unbound)', - optional: true, - }, - placement_mode: { - type: 'string', - description: 'Smart placement mode (smart or targeted)', - optional: true, - }, - logpush: { - type: 'boolean', - description: 'Whether Workers Logpush is enabled', - optional: true, - }, - has_assets: { - type: 'boolean', - description: 'Whether the script ships static assets', - optional: true, - }, - has_modules: { - type: 'boolean', - description: 'Whether the script uses ES modules', - optional: true, - }, - compatibility_date: { - type: 'string', - description: 'Workers runtime compatibility date', - optional: true, - }, - compatibility_flags: { - type: 'array', - description: 'Workers runtime compatibility flags', - items: { type: 'string', description: 'Compatibility flag' }, - optional: true, - }, - routes: { type: 'json', description: 'Routes the script is bound to', optional: true }, - tail_consumers: { - type: 'json', - description: "Workers that consume this script's tail events", - optional: true, - }, - }, - }, + description: 'Scripts', + items: { type: 'object', properties: WORKER_SCRIPT_OUTPUTS }, + }, + total_count: { + type: 'number', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, - total_count: { type: 'number', description: 'Number of scripts returned' }, }, } diff --git a/apps/sim/tools/cloudflare/list_zones.ts b/apps/sim/tools/cloudflare/list_zones.ts index 89615fed4e0..6664490c942 100644 --- a/apps/sim/tools/cloudflare/list_zones.ts +++ b/apps/sim/tools/cloudflare/list_zones.ts @@ -1,18 +1,36 @@ +import { RESULT_INFO_OUTPUTS, ZONE_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareListZonesParams, CloudflareListZonesResponse, - CloudflareRawZone, } from '@/tools/cloudflare/types' -import { readCloudflareResponse } from '@/tools/cloudflare/utils' +import { + appendParam, + cloudflareErrorMessage, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' export const listZonesTool: ToolConfig = { id: 'cloudflare_list_zones', name: 'Cloudflare List Zones', - description: 'Lists all zones (domains) in the Cloudflare account.', + description: 'Lists one page of zones (domains) in the Cloudflare account.', version: '1.0.0', params: { + type: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated zone types: full, partial, secondary, internal', + }, + account_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Account name; prefix the value with an operator, e.g. contains:Test. Supported operators: * `equal` (default) * `not_equal` * `starts_with` * `ends_with` * `contains` * `starts_with_case_sensitive` * `ends_with_case_sensitive` * `contains_case_sensitive`', + }, name: { type: 'string', required: false, @@ -76,10 +94,12 @@ export const listZonesTool: ToolConfig { - const data = await readCloudflareResponse(response) - - if (!data.success) { - return { - success: false, - output: { zones: [], total_count: 0 }, - error: data.errors?.[0]?.message ?? 'Failed to list zones', - } - } - + const data = await readCloudflareResponse(response) + const raw = data.result + const rows = Array.isArray(raw) ? raw : [] + const success = response.ok && data.success === true && Array.isArray(raw) return { - success: true, + success, output: { - zones: (Array.isArray(data.result) ? data.result : []).map((zone) => ({ - id: zone.id ?? '', - name: zone.name ?? '', - status: zone.status ?? '', - paused: zone.paused ?? false, - type: zone.type ?? '', - name_servers: zone.name_servers ?? [], - original_name_servers: zone.original_name_servers ?? [], - created_on: zone.created_on ?? '', - modified_on: zone.modified_on ?? '', - activated_on: zone.activated_on ?? '', - development_mode: zone.development_mode ?? 0, - plan: { - id: zone.plan?.id ?? '', - name: zone.plan?.name ?? '', - price: zone.plan?.price ?? 0, - is_subscribed: zone.plan?.is_subscribed ?? false, - frequency: zone.plan?.frequency ?? '', - currency: zone.plan?.currency ?? '', - legacy_id: zone.plan?.legacy_id ?? '', - }, - account: { - id: zone.account?.id ?? '', - name: zone.account?.name ?? '', - }, - owner: { - id: zone.owner?.id ?? '', - name: zone.owner?.name ?? '', - type: zone.owner?.type ?? '', - }, - meta: { - cdn_only: zone.meta?.cdn_only ?? false, - custom_certificate_quota: zone.meta?.custom_certificate_quota ?? 0, - dns_only: zone.meta?.dns_only ?? false, - foundation_dns: zone.meta?.foundation_dns ?? false, - page_rule_quota: zone.meta?.page_rule_quota ?? 0, - phishing_detected: zone.meta?.phishing_detected ?? false, - step: zone.meta?.step ?? 0, - }, - vanity_name_servers: zone.vanity_name_servers ?? [], - permissions: zone.permissions ?? [], - })), - total_count: data.result_info?.total_count ?? data.result?.length ?? 0, + zones: rows.map((row) => mapCloudflareFields(row, ZONE_OUTPUTS)), + total_count: data.result_info?.total_count ?? rows.length, + result_info: data.result_info ?? null, }, + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to list zones') } : {}), } }, - outputs: { zones: { type: 'array', - description: 'List of zones/domains', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Zone ID' }, - name: { type: 'string', description: 'Domain name' }, - status: { - type: 'string', - description: 'Zone status (initializing, pending, active, moved)', - }, - paused: { type: 'boolean', description: 'Whether the zone is paused' }, - type: { - type: 'string', - description: 'Zone type (full, partial, secondary, or internal)', - }, - name_servers: { - type: 'array', - description: 'Assigned Cloudflare name servers', - items: { type: 'string', description: 'Name server hostname' }, - }, - original_name_servers: { - type: 'array', - description: 'Original name servers before moving to Cloudflare', - items: { type: 'string', description: 'Name server hostname' }, - optional: true, - }, - created_on: { type: 'string', description: 'ISO 8601 date when the zone was created' }, - modified_on: { - type: 'string', - description: 'ISO 8601 date when the zone was last modified', - }, - activated_on: { - type: 'string', - description: 'ISO 8601 date when the zone was activated', - optional: true, - }, - development_mode: { - type: 'number', - description: 'Seconds remaining in development mode (0 = off)', - }, - plan: { - type: 'object', - description: 'Zone plan information', - properties: { - id: { type: 'string', description: 'Plan identifier' }, - name: { type: 'string', description: 'Plan name' }, - price: { type: 'number', description: 'Plan price' }, - is_subscribed: { - type: 'boolean', - description: 'Whether the zone is subscribed to the plan', - }, - frequency: { type: 'string', description: 'Plan billing frequency' }, - currency: { type: 'string', description: 'Plan currency' }, - legacy_id: { type: 'string', description: 'Legacy plan identifier' }, - }, - }, - account: { - type: 'object', - description: 'Account the zone belongs to', - properties: { - id: { type: 'string', description: 'Account identifier' }, - name: { type: 'string', description: 'Account name' }, - }, - }, - owner: { - type: 'object', - description: 'Zone owner information', - properties: { - id: { type: 'string', description: 'Owner identifier' }, - name: { type: 'string', description: 'Owner name' }, - type: { type: 'string', description: 'Owner type' }, - }, - }, - meta: { - type: 'object', - description: 'Zone metadata', - properties: { - cdn_only: { type: 'boolean', description: 'Whether the zone is CDN only' }, - custom_certificate_quota: { type: 'number', description: 'Custom certificate quota' }, - dns_only: { type: 'boolean', description: 'Whether the zone is DNS only' }, - foundation_dns: { type: 'boolean', description: 'Whether foundation DNS is enabled' }, - page_rule_quota: { type: 'number', description: 'Page rule quota' }, - phishing_detected: { type: 'boolean', description: 'Whether phishing was detected' }, - step: { type: 'number', description: 'Current setup step' }, - }, - optional: true, - }, - vanity_name_servers: { - type: 'array', - description: 'Custom vanity name servers', - items: { type: 'string', description: 'Vanity name server hostname' }, - optional: true, - }, - permissions: { - type: 'array', - description: 'User permissions for the zone', - items: { type: 'string', description: 'Permission string' }, - optional: true, - }, - }, - }, + description: 'Zones', + items: { type: 'object', properties: ZONE_OUTPUTS }, }, total_count: { type: 'number', - description: 'Total number of zones matching the query', + description: + 'Total matching resources, or the number of resources returned on this page when the API omits a total', + }, + result_info: { + type: 'json', + description: 'Pagination metadata returned by Cloudflare', + nullable: true, + properties: RESULT_INFO_OUTPUTS, }, }, } diff --git a/apps/sim/tools/cloudflare/operation-types.ts b/apps/sim/tools/cloudflare/operation-types.ts new file mode 100644 index 00000000000..673a4c05773 --- /dev/null +++ b/apps/sim/tools/cloudflare/operation-types.ts @@ -0,0 +1,336 @@ +import type { + ACCESS_GROUP_OUTPUTS, + ACCESS_POLICY_OUTPUTS, + DNS_RECORD_OUTPUTS, + R2_CORS_OUTPUTS, + R2_LIFECYCLE_OUTPUTS, + RULESET_OUTPUTS, + SERVICE_TOKEN_OUTPUTS, + SERVICE_TOKEN_SECRET_OUTPUTS, + TUNNEL_CONFIGURATION_OUTPUTS, + TUNNEL_OUTPUTS, + WORKER_ROUTE_OUTPUTS, + ZONE_OUTPUTS, +} from '@/tools/cloudflare/outputs' +import type { CloudflareOutput } from '@/tools/cloudflare/utils' +import type { ToolResponse } from '@/tools/types' + +export interface CloudflareGetTunnelTokenParams { + accountId: string + tunnelId: string + apiKey: string +} + +export interface CloudflareGetTunnelTokenResponse extends ToolResponse { + output: { token: string | null } +} + +export interface CloudflareGetDnsRecordParams { + zoneId: string + recordId: string + apiKey: string + include_shadow_metadata?: boolean +} + +export interface CloudflareGetDnsRecordResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateZoneParams { + zoneId: string + apiKey: string + paused?: boolean + plan?: string | Record | unknown[] + type?: string + vanity_name_servers?: string | Record | unknown[] +} + +export interface CloudflareUpdateZoneResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateRulesetParams { + zoneId: string + rulesetId: string + apiKey: string + description?: string + rules?: string | Record | unknown[] + dry_run?: boolean +} + +export interface CloudflareUpdateRulesetResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareDeleteRulesetParams { + zoneId: string + rulesetId: string + apiKey: string + dry_run?: boolean +} + +export interface CloudflareDeleteRulesetResponse extends ToolResponse { + output: { success: boolean } +} + +export interface CloudflareGetAccessPolicyParams { + accountId: string + appId: string + policyId: string + apiKey: string +} + +export interface CloudflareGetAccessPolicyResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareGetAccessGroupParams { + accountId: string + groupId: string + apiKey: string +} + +export interface CloudflareGetAccessGroupResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareCreateAccessGroupParams { + accountId: string + apiKey: string + exclude?: string | Record | unknown[] + include: string | Record | unknown[] + is_default?: boolean + name: string + require?: string | Record | unknown[] +} + +export interface CloudflareCreateAccessGroupResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateAccessGroupParams { + accountId: string + groupId: string + apiKey: string + exclude?: string | Record | unknown[] + include: string | Record | unknown[] + is_default?: boolean + name: string + require?: string | Record | unknown[] +} + +export interface CloudflareUpdateAccessGroupResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareDeleteAccessGroupParams { + accountId: string + groupId: string + apiKey: string +} + +export interface CloudflareDeleteAccessGroupResponse extends ToolResponse { + output: { id: string | null } +} + +export interface CloudflareGetAccessServiceTokenParams { + accountId: string + serviceTokenId: string + apiKey: string +} + +export interface CloudflareGetAccessServiceTokenResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateAccessServiceTokenParams { + accountId: string + serviceTokenId: string + apiKey: string + client_secret_version?: number + duration?: string + enabled?: boolean + name?: string + previous_client_secret_expires_at?: string +} + +export interface CloudflareUpdateAccessServiceTokenResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareRefreshAccessServiceTokenParams { + accountId: string + serviceTokenId: string + apiKey: string +} + +export interface CloudflareRefreshAccessServiceTokenResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareRotateAccessServiceTokenParams { + accountId: string + serviceTokenId: string + apiKey: string + previous_client_secret_expires_at?: string +} + +export interface CloudflareRotateAccessServiceTokenResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareGetWorkerRouteParams { + zoneId: string + routeId: string + apiKey: string +} + +export interface CloudflareGetWorkerRouteResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareCreateWorkerRouteParams { + zoneId: string + apiKey: string + pattern: string + script?: string +} + +export interface CloudflareCreateWorkerRouteResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateWorkerRouteParams { + zoneId: string + routeId: string + apiKey: string + pattern: string + script?: string +} + +export interface CloudflareUpdateWorkerRouteResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareDeleteWorkerRouteParams { + zoneId: string + routeId: string + apiKey: string +} + +export interface CloudflareDeleteWorkerRouteResponse extends ToolResponse { + output: { id: string | null } +} + +export interface CloudflareDeleteWorkerScriptParams { + accountId: string + scriptName: string + apiKey: string + force?: boolean +} + +export interface CloudflareDeleteWorkerScriptResponse extends ToolResponse { + output: { success: boolean } +} + +export interface CloudflareCreateTunnelParams { + accountId: string + apiKey: string + config_src?: string + name: string + tunnel_secret?: string +} + +export interface CloudflareCreateTunnelResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateTunnelParams { + accountId: string + tunnelId: string + apiKey: string + name?: string + tunnel_secret?: string +} + +export interface CloudflareUpdateTunnelResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareDeleteTunnelParams { + accountId: string + tunnelId: string + apiKey: string +} + +export interface CloudflareDeleteTunnelResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateTunnelConfigurationParams { + accountId: string + tunnelId: string + apiKey: string + config?: string | Record | unknown[] +} + +export interface CloudflareUpdateTunnelConfigurationResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareGetR2BucketCorsParams { + accountId: string + bucketName: string + apiKey: string + jurisdiction?: string +} + +export interface CloudflareGetR2BucketCorsResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateR2BucketCorsParams { + accountId: string + bucketName: string + apiKey: string + rules?: string | Record | unknown[] + jurisdiction?: string +} + +export interface CloudflareUpdateR2BucketCorsResponse extends ToolResponse { + output: { success: boolean } +} + +export interface CloudflareDeleteR2BucketCorsParams { + accountId: string + bucketName: string + apiKey: string + jurisdiction?: string +} + +export interface CloudflareDeleteR2BucketCorsResponse extends ToolResponse { + output: { success: boolean } +} + +export interface CloudflareGetR2BucketLifecycleParams { + accountId: string + bucketName: string + apiKey: string + jurisdiction?: string +} + +export interface CloudflareGetR2BucketLifecycleResponse extends ToolResponse { + output: CloudflareOutput +} + +export interface CloudflareUpdateR2BucketLifecycleParams { + accountId: string + bucketName: string + apiKey: string + rules?: string | Record | unknown[] + jurisdiction?: string +} + +export interface CloudflareUpdateR2BucketLifecycleResponse extends ToolResponse { + output: { success: boolean } +} diff --git a/apps/sim/tools/cloudflare/outputs.ts b/apps/sim/tools/cloudflare/outputs.ts new file mode 100644 index 00000000000..7d469354461 --- /dev/null +++ b/apps/sim/tools/cloudflare/outputs.ts @@ -0,0 +1,6602 @@ +import type { ToolOutputProperty } from '@/tools/types' + +const ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_PROPERTIES_FIELDS = { + group: { + type: 'json', + description: 'group', + properties: { + id: { + type: 'string', + description: 'The ID of a previously created Access group.', + optional: false, + }, + }, + optional: true, + }, + any_valid_service_token: { + type: 'json', + description: 'An empty object which matches on all service tokens.', + optional: true, + }, + auth_context: { + type: 'json', + description: 'auth context', + properties: { + ac_id: { + type: 'string', + description: 'The ACID of an Authentication context.', + optional: false, + }, + id: { + type: 'string', + description: 'The ID of an Authentication context.', + optional: false, + }, + identity_provider_id: { + type: 'string', + description: 'The ID of your Azure identity provider.', + optional: false, + }, + }, + optional: true, + }, + auth_method: { + type: 'json', + description: 'auth method', + properties: { + auth_method: { + type: 'string', + description: + 'The type of authentication method https://datatracker.ietf.org/doc/html/rfc8176#section-2.', + optional: false, + }, + }, + optional: true, + }, + azureAD: { + type: 'json', + description: 'azureAD', + properties: { + id: { + type: 'string', + description: 'The ID of an Azure group.', + optional: false, + }, + identity_provider_id: { + type: 'string', + description: 'The ID of your Azure identity provider.', + optional: false, + }, + }, + optional: true, + }, + certificate: { + type: 'json', + description: 'certificate', + optional: true, + }, + common_name: { + type: 'json', + description: 'common name', + properties: { + common_name: { + type: 'string', + description: 'The common name to match.', + optional: false, + }, + }, + optional: true, + }, + geo: { + type: 'json', + description: 'geo', + properties: { + country_code: { + type: 'string', + description: 'The country code that should be matched.', + optional: false, + }, + }, + optional: true, + }, + device_posture: { + type: 'json', + description: 'device posture', + properties: { + account_id: { + type: 'string', + description: 'Identifier.', + optional: true, + }, + integration_uid: { + type: 'string', + description: 'The ID of a device posture integration.', + optional: false, + }, + }, + optional: true, + }, + email_domain: { + type: 'json', + description: 'email domain', + properties: { + domain: { + type: 'string', + description: 'The email domain to match.', + optional: false, + }, + }, + optional: true, + }, + email_list: { + type: 'json', + description: 'email list', + properties: { + id: { + type: 'string', + description: 'The ID of a previously created email list.', + optional: false, + }, + }, + optional: true, + }, + email: { + type: 'json', + description: 'email', + properties: { + email: { + type: 'string', + description: 'The email of the user.', + optional: false, + }, + }, + optional: true, + }, + everyone: { + type: 'json', + description: 'An empty object which matches on all users.', + optional: true, + }, + external_evaluation: { + type: 'json', + description: 'external evaluation', + properties: { + evaluate_url: { + type: 'string', + description: 'The API endpoint containing your business logic.', + optional: false, + }, + keys_url: { + type: 'string', + description: + 'The API endpoint containing the key that Access uses to verify that the response came from your API.', + optional: false, + }, + }, + optional: true, + }, + 'github-organization': { + type: 'json', + description: 'github-organization', + properties: { + identity_provider_id: { + type: 'string', + description: 'The ID of your Github identity provider.', + optional: false, + }, + name: { + type: 'string', + description: 'The name of the organization.', + optional: false, + }, + team: { + type: 'string', + description: 'The name of the team', + optional: true, + }, + }, + optional: true, + }, + gsuite: { + type: 'json', + description: 'gsuite', + properties: { + email: { + type: 'string', + description: 'The email of the Google Workspace group.', + optional: false, + }, + identity_provider_id: { + type: 'string', + description: 'The ID of your Google Workspace identity provider.', + optional: false, + }, + }, + optional: true, + }, + login_method: { + type: 'json', + description: 'login method', + properties: { + id: { + type: 'string', + description: 'The ID of an identity provider.', + optional: false, + }, + }, + optional: true, + }, + ip_list: { + type: 'json', + description: 'ip list', + properties: { + id: { + type: 'string', + description: 'The ID of a previously created IP list.', + optional: false, + }, + }, + optional: true, + }, + ip: { + type: 'json', + description: 'ip', + properties: { + ip: { + type: 'string', + description: 'An IPv4 or IPv6 CIDR block.', + optional: false, + }, + }, + optional: true, + }, + okta: { + type: 'json', + description: 'okta', + properties: { + identity_provider_id: { + type: 'string', + description: 'The ID of your Okta identity provider.', + optional: false, + }, + name: { + type: 'string', + description: 'The name of the Okta group.', + optional: false, + }, + }, + optional: true, + }, + saml: { + type: 'json', + description: 'saml', + properties: { + attribute_name: { + type: 'string', + description: 'The name of the SAML attribute.', + optional: false, + }, + attribute_value: { + type: 'string', + description: 'The SAML attribute value to look for.', + optional: false, + }, + identity_provider_id: { + type: 'string', + description: 'The ID of your SAML identity provider.', + optional: false, + }, + }, + optional: true, + }, + oidc: { + type: 'json', + description: 'oidc', + properties: { + claim_name: { + type: 'string', + description: 'The name of the OIDC claim.', + optional: false, + }, + claim_value: { + type: 'string', + description: 'The OIDC claim value to look for.', + optional: false, + }, + identity_provider_id: { + type: 'string', + description: 'The ID of your OIDC identity provider.', + optional: false, + }, + }, + optional: true, + }, + service_token: { + type: 'json', + description: 'service token', + properties: { + token_id: { + type: 'string', + description: 'The ID of a Service Token.', + optional: false, + }, + }, + optional: true, + }, + linked_app_token: { + type: 'json', + description: 'linked app token', + properties: { + app_uid: { + type: 'string', + description: 'The ID of an Access OIDC SaaS application', + optional: false, + }, + }, + optional: true, + }, + user_risk_score: { + type: 'json', + description: 'user risk score', + properties: { + user_risk_score: { + type: 'array', + description: + 'A list of risk score levels to match. Values can be low, medium, high, or unscored.', + items: { + type: 'string', + description: 'user risk score item Values: low, medium, high, unscored.', + }, + optional: false, + }, + }, + optional: true, + }, + cloudflare_account_member: { + type: 'json', + description: 'cloudflare account member', + properties: { + account_id: { + type: 'string', + description: 'Identifier.', + optional: true, + }, + }, + optional: true, + }, +} as const + +const ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS = { + type: 'json', + description: + 'Matches users who are members of a specific Cloudflare account. Requires a Cloudflare identity provider.', + properties: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_PROPERTIES_FIELDS, +} as const + +const ACCESS_GROUP_OUTPUTS_INCLUDE_FIELDS = { + type: 'array', + description: + 'Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, +} as const + +const ACCESS_GROUP_OUTPUTS_IS_DEFAULT_FIELDS = { + type: 'array', + description: + 'Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, +} as const + +const CERTIFICATE_OUTPUTS_DCV_DELEGATION_RECORDS_ITEMS_PROPERTIES_FIELDS = { + cname: { + type: 'string', + description: 'The CNAME record hostname for DCV delegation.', + optional: true, + }, + cname_target: { + type: 'string', + description: 'The CNAME record target value for DCV delegation.', + optional: true, + }, + emails: { + type: 'array', + description: + 'The set of email addresses that the certificate authority (CA) will use to complete domain validation.', + items: { + type: 'string', + description: 'emails item', + }, + optional: true, + }, + http_body: { + type: 'string', + description: + 'The content that the certificate authority (CA) will expect to find at the http_url during the domain validation.', + optional: true, + }, + http_url: { + type: 'string', + description: 'The url that will be checked during domain validation.', + optional: true, + }, + status: { + type: 'string', + description: 'Status of the validation record.', + optional: true, + }, + txt_name: { + type: 'string', + description: + 'The hostname that the certificate authority (CA) will check for a TXT record during domain validation .', + optional: true, + }, + txt_value: { + type: 'string', + description: + 'The TXT record that the certificate authority (CA) will check during domain validation.', + optional: true, + }, +} as const + +const CERTIFICATE_OUTPUTS_DCV_DELEGATION_RECORDS_ITEMS_FIELDS = { + type: 'json', + description: "Certificate's required validation record.", + properties: CERTIFICATE_OUTPUTS_DCV_DELEGATION_RECORDS_ITEMS_PROPERTIES_FIELDS, +} as const + +const TUNNEL_CONFIGURATION_OUTPUTS_CONFIG_PROPERTIES_INGRESS_ITEMS_PROPERTIES_ORIGINREQUEST_PROPERTIES_FIELDS = + { + access: { + type: 'json', + description: + "For all L7 requests to this hostname, cloudflared will validate each request's Cf-Access-Jwt-Assertion request header.", + properties: { + audTag: { + type: 'array', + description: + 'Access applications that are allowed to reach this hostname for this Tunnel. Audience tags can be identified in the dashboard or via the List Access policies API.', + items: { + type: 'string', + description: 'audTag item', + }, + optional: false, + }, + required: { + type: 'boolean', + description: 'Deny traffic that has not fulfilled Access authorization.', + optional: true, + }, + teamName: { + type: 'string', + description: 'teamName', + optional: false, + }, + }, + optional: true, + }, + caPool: { + type: 'string', + description: + 'Path to the certificate authority (CA) for the certificate of your origin. This option should be used only if your certificate is not signed by Cloudflare.', + optional: true, + }, + connectTimeout: { + type: 'number', + description: + 'Timeout for establishing a new TCP connection to your origin server. This excludes the time taken to establish TLS, which is controlled by tlsTimeout.', + optional: true, + }, + disableChunkedEncoding: { + type: 'boolean', + description: 'Disables chunked transfer encoding. Useful if you are running a WSGI server.', + optional: true, + }, + http2Origin: { + type: 'boolean', + description: 'Attempt to connect to origin using HTTP2. Origin must be configured as https.', + optional: true, + }, + httpHostHeader: { + type: 'string', + description: 'Sets the HTTP Host header on requests sent to the local service.', + optional: true, + }, + keepAliveConnections: { + type: 'number', + description: + 'Maximum number of idle keepalive connections between Tunnel and your origin. This does not restrict the total number of concurrent connections.', + optional: true, + }, + keepAliveTimeout: { + type: 'number', + description: 'Timeout after which an idle keepalive connection can be discarded.', + optional: true, + }, + matchSNItoHost: { + type: 'boolean', + description: 'Auto configure the Hostname on the origin server certificate.', + optional: true, + }, + noHappyEyeballs: { + type: 'boolean', + description: + 'Disable the \u201chappy eyeballs\u201d algorithm for IPv4/IPv6 fallback if your local network has misconfigured one of the protocols.', + optional: true, + }, + noTLSVerify: { + type: 'boolean', + description: + 'Disables TLS verification of the certificate presented by your origin. Will allow any certificate from the origin to be accepted.', + optional: true, + }, + originServerName: { + type: 'string', + description: 'Hostname that cloudflared should expect from your origin server certificate.', + optional: true, + }, + proxyType: { + type: 'string', + description: + 'cloudflared starts a proxy server to translate HTTP traffic into TCP when proxying, for example, SSH or RDP. This configures what type of proxy will be started. Valid options are: "" for the regular proxy and "socks" for a SOCKS5 proxy.', + optional: true, + }, + tcpKeepAlive: { + type: 'number', + description: + 'The timeout after which a TCP keepalive packet is sent on a connection between Tunnel and the origin server.', + optional: true, + }, + tlsTimeout: { + type: 'number', + description: + 'Timeout for completing a TLS handshake to your origin server, if you have chosen to connect Tunnel to an HTTPS server.', + optional: true, + }, + } as const + +const TUNNEL_CONFIGURATION_OUTPUTS_CONFIG_PROPERTIES_INGRESS_ITEMS_PROPERTIES_ORIGINREQUEST_FIELDS = + { + type: 'json', + description: + 'Configuration parameters for the public hostname specific connection settings between cloudflared and origin server.', + properties: + TUNNEL_CONFIGURATION_OUTPUTS_CONFIG_PROPERTIES_INGRESS_ITEMS_PROPERTIES_ORIGINREQUEST_PROPERTIES_FIELDS, + optional: true, + } as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_LOGS_PROPERTIES_FIELDS = { + destinations: { + type: 'array', + description: 'A list of destinations where logs will be exported to.', + items: { + type: 'string', + description: 'destinations item', + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether logs are enabled for the Worker.', + optional: false, + }, + head_sampling_rate: { + type: 'number', + description: 'The sampling rate for logs. From 0 to 1 (1 = 100%, 0.1 = 10%). Default is 1.', + optional: true, + }, + invocation_logs: { + type: 'boolean', + description: + 'Whether [invocation logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/#invocation-logs) are enabled for the Worker.', + optional: false, + }, + persist: { + type: 'boolean', + description: 'Whether log persistence is enabled for the Worker.', + optional: true, + }, +} as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_LOGS_FIELDS = { + type: 'json', + description: 'Log settings for the Worker.', + properties: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_LOGS_PROPERTIES_FIELDS, + optional: true, +} as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_TRACES_PROPERTIES_FIELDS = { + destinations: { + type: 'array', + description: 'A list of destinations where traces will be exported to.', + items: { + type: 'string', + description: 'destinations item', + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether traces are enabled for the Worker.', + optional: true, + }, + head_sampling_rate: { + type: 'number', + description: 'The sampling rate for traces. From 0 to 1 (1 = 100%, 0.1 = 10%). Default is 1.', + optional: true, + }, + persist: { + type: 'boolean', + description: 'Whether trace persistence is enabled for the Worker.', + optional: true, + }, + propagation_policy: { + type: 'string', + description: + 'Controls how inbound trace context (traceparent/tracestate) headers on incoming requests are handled.', + optional: true, + }, +} as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_TRACES_FIELDS = { + type: 'json', + description: 'Trace settings for the Worker.', + properties: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_TRACES_PROPERTIES_FIELDS, + optional: true, +} as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_FIELDS = { + enabled: { + type: 'boolean', + description: 'Whether observability is enabled for the Worker.', + optional: false, + }, + head_sampling_rate: { + type: 'number', + description: + 'The sampling rate for incoming requests. From 0 to 1 (1 = 100%, 0.1 = 10%). Default is 1.', + optional: true, + }, + issues: { + type: 'json', + description: 'Real-time Issues settings for the Worker.', + properties: { + enabled: { + type: 'boolean', + description: 'Whether real-time Issues are enabled for the Worker.', + optional: true, + }, + }, + optional: true, + }, + logs: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_LOGS_FIELDS, + redact_query_string: { + type: 'boolean', + description: 'Whether query strings are removed from request URLs in logs and traces.', + optional: true, + }, + traces: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_TRACES_FIELDS, +} as const + +const WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_FIELDS = { + type: 'json', + description: 'Observability settings for the Worker.', + properties: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_PROPERTIES_FIELDS, + nullable: true, +} as const + +export const ACCESS_APPLICATION_OUTPUTS = { + aud: { + type: 'string', + description: 'Audience tag.', + nullable: true, + }, + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + id: { + type: 'string', + description: 'UUID.', + nullable: true, + }, + updated_at: { + type: 'string', + description: 'updated at', + nullable: true, + }, + allowed_idps: { + type: 'array', + description: + 'The identity providers your users can select when connecting to this application. Defaults to all IdPs configured in your account.', + items: { + type: 'string', + description: 'The identity providers selected for application.', + }, + }, + destinations: { + type: 'array', + description: + 'List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored.', + items: { + type: 'json', + description: + 'Protects the preview deployments of all Cloudflare Workers on the account with Access.', + properties: { + overrides: { + type: 'array', + description: + 'Rules that override how Access handles requests to this destination. Each rule can make a matching path public, bypassing Access authentication. Overrides are supported for public destinations and Worker destinations.', + items: { + type: 'json', + description: 'overrides item', + properties: { + behavior: { + type: 'string', + description: 'The behavior to apply to matching requests. Values: public.', + optional: false, + }, + path_pattern: { + type: 'string', + description: + 'The request path pattern to match. Wildcards (`*`) are supported, but each path segment may have at most one wildcard. Unlike the `uri` in public destinations, override path patterns do not implicitly cover subpaths; to do that, use a wildcard.', + optional: false, + }, + }, + }, + optional: true, + }, + type: { + type: 'string', + description: + 'type Values: public, private, via_mcp_server_portal, worker, preview_worker, all_workers, all_preview_workers.', + optional: true, + }, + uri: { + type: 'string', + description: + "The URI of the destination. Public destinations' URIs can include a domain and path with [wildcards](https://developers.cloudflare.com/cloudflare-one/policies/access/app-paths/).", + optional: true, + }, + cidr: { + type: 'string', + description: 'The CIDR range of the destination. Single IPs will be computed as /32.', + optional: true, + }, + hostname: { + type: 'string', + description: + 'The hostname of the destination. Matches a valid SNI served by an HTTPS origin.', + optional: true, + }, + l4_protocol: { + type: 'string', + description: + 'The L4 protocol of the destination. When omitted, both UDP and TCP traffic will match. Values: tcp, udp.', + optional: true, + }, + port_range: { + type: 'string', + description: + 'The port range of the destination. Can be a single port or a range of ports. When omitted, all ports will match.', + optional: true, + }, + vnet_id: { + type: 'string', + description: 'The VNET ID to match the destination. When omitted, all VNETs will match.', + optional: true, + }, + mcp_server_id: { + type: 'string', + description: 'The MCP server id configured in ai-controls.', + optional: true, + }, + worker_id: { + type: 'string', + description: + 'The ID of the Cloudflare Worker whose preview deployments to protect with Access.', + optional: true, + }, + }, + }, + }, + domain: { + type: 'string', + description: + 'The primary hostname and path secured by Access. This domain will be displayed if the app is visible in the App Launcher.', + nullable: true, + }, + name: { + type: 'string', + description: 'The name of the application.', + nullable: true, + }, + oauth_configuration: { + type: 'json', + description: + '**Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access.', + properties: { + dynamic_client_registration: { + type: 'json', + description: 'Settings for OAuth dynamic client registration.', + properties: { + allow_any_on_localhost: { + type: 'boolean', + description: 'Allows any client with redirect URIs on localhost.', + optional: true, + }, + allow_any_on_loopback: { + type: 'boolean', + description: 'Allows any client with redirect URIs on 127.0.0.1.', + optional: true, + }, + allowed_uris: { + type: 'array', + description: + 'The URIs that are allowed as redirect URIs for dynamically registered clients. HTTP and HTTPS paths may end in `/*` to match all sub-paths. Custom-scheme URIs must be explicitly configured and match exactly.', + items: { + type: 'string', + description: 'allowed uris item', + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether dynamic client registration is enabled.', + optional: true, + }, + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: + 'Whether the OAuth configuration is enabled for this application. When set to `false`, Access will not handle OAuth for this application. Defaults to `true` if omitted. Values: True.', + optional: true, + }, + grant: { + type: 'json', + description: 'Settings for OAuth grant behavior.', + properties: { + access_token_lifetime: { + type: 'string', + description: + 'The lifetime of the access token. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or \u00b5s), ms, s, m, h.', + optional: true, + }, + session_duration: { + type: 'string', + description: + 'The duration of the OAuth session. Must be in the format `300ms` or `2h45m`. Valid time units are ns, us (or \u00b5s), ms, s, m, h.', + optional: true, + }, + }, + optional: true, + }, + }, + nullable: true, + }, + self_hosted_domains: { + type: 'array', + description: + 'List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored.', + items: { + type: 'string', + description: 'A domain that Access will secure.', + }, + }, + type: { + type: 'string', + description: + 'The application type. Values: end_user, self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, dash_sso, infrastructure, rdp, mcp, mcp_portal, proxy_endpoint.', + nullable: true, + }, + user_populations: { + type: 'array', + description: 'The single user population associated with this application.', + items: { + type: 'string', + description: 'UUID.', + }, + }, + allow_authenticate_via_warp: { + type: 'boolean', + description: + 'When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication.', + nullable: true, + }, + allow_iframe: { + type: 'boolean', + description: 'Enables loading application content in an iFrame.', + nullable: true, + }, + app_launcher_visible: { + type: 'boolean', + description: 'Displays the application in the App Launcher.', + nullable: true, + }, + auto_redirect_to_identity: { + type: 'boolean', + description: + 'When set to `true`, users skip the identity provider selection step during login. You must specify only one identity provider in allowed_idps.', + nullable: true, + }, + cors_headers: { + type: 'json', + description: 'cors headers', + properties: { + allow_all_headers: { + type: 'boolean', + description: 'Allows all HTTP request headers.', + optional: true, + }, + allow_all_methods: { + type: 'boolean', + description: 'Allows all HTTP request methods.', + optional: true, + }, + allow_all_origins: { + type: 'boolean', + description: 'Allows all origins.', + optional: true, + }, + allow_credentials: { + type: 'boolean', + description: + 'When set to `true`, includes credentials (cookies, authorization headers, or TLS client certificates) with requests.', + optional: true, + }, + allowed_headers: { + type: 'array', + description: 'Allowed HTTP request headers.', + items: { + type: 'string', + description: 'allowed headers item', + }, + optional: true, + }, + allowed_methods: { + type: 'array', + description: 'Allowed HTTP request methods.', + items: { + type: 'string', + description: + 'allowed methods item Values: GET, POST, HEAD, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH.', + }, + optional: true, + }, + allowed_origins: { + type: 'array', + description: 'Allowed origins.', + items: { + type: 'string', + description: 'allowed origins item', + }, + optional: true, + }, + max_age: { + type: 'number', + description: + 'The maximum number of seconds the results of a preflight request can be cached.', + optional: true, + }, + }, + nullable: true, + }, + custom_deny_message: { + type: 'string', + description: + 'The custom error message shown to a user when they are denied access to the application.', + nullable: true, + }, + custom_deny_url: { + type: 'string', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing identity-based rules.', + nullable: true, + }, + custom_non_identity_deny_url: { + type: 'string', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules.', + nullable: true, + }, + custom_pages: { + type: 'array', + description: 'The custom pages that will be displayed when applicable for this application', + items: { + type: 'string', + description: 'The custom pages selected for application.', + }, + }, + eager_redirect_cookie_setting: { + type: 'boolean', + description: + 'Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior.', + nullable: true, + }, + enable_binding_cookie: { + type: 'boolean', + description: + 'Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks.', + nullable: true, + }, + http_only_cookie_attribute: { + type: 'boolean', + description: + 'Enables the HttpOnly cookie attribute, which increases security against XSS attacks.', + nullable: true, + }, + logo_url: { + type: 'string', + description: 'The image URL for the logo shown in the App Launcher dashboard.', + nullable: true, + }, + mfa_config: { + type: 'json', + description: 'Configures multi-factor authentication (MFA) settings.', + properties: { + allowed_authenticators: { + type: 'array', + description: 'Lists the MFA methods that users can authenticate with.', + items: { + type: 'string', + description: 'allowed authenticators item Values: totp, biometrics, security_key.', + }, + optional: true, + }, + mfa_disabled: { + type: 'boolean', + description: + 'Indicates whether to disable MFA for this resource. This option is available at the application and policy level.', + optional: true, + }, + session_duration: { + type: 'string', + description: + 'Defines the duration of an MFA session. Must be in minutes (m) or hours (h). Minimum: 0m. Maximum: 720h (30 days). Examples:`5m` or `24h`.', + optional: true, + }, + }, + nullable: true, + }, + options_preflight_bypass: { + type: 'boolean', + description: + 'Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set.', + nullable: true, + }, + path_cookie_attribute: { + type: 'boolean', + description: + "Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default", + nullable: true, + }, + read_service_tokens_from_header: { + type: 'string', + description: + 'Allows matching Access Service Tokens passed HTTP in a single header with this name.', + nullable: true, + }, + same_site_cookie_attribute: { + type: 'string', + description: + 'Sets the SameSite cookie setting, which provides increased security against CSRF attacks.', + nullable: true, + }, + scim_config: { + type: 'json', + description: + 'Configuration for provisioning to this application via SCIM. This is currently in closed beta.', + properties: { + authentication: { + type: 'json', + description: 'Multiple authentication schemes', + properties: { + password: { + type: 'string', + description: 'Password used to authenticate with the remote SCIM service.', + optional: true, + }, + scheme: { + type: 'string', + description: + 'The authentication scheme to use when making SCIM requests to this application. Values: httpbasic, oauthbearertoken, oauth2, access_service_token.', + optional: true, + }, + user: { + type: 'string', + description: 'User name used to authenticate with the remote SCIM service.', + optional: true, + }, + token: { + type: 'string', + description: 'Token used to authenticate with the remote SCIM service.', + optional: true, + }, + authorization_url: { + type: 'string', + description: 'URL used to generate the auth code used during token generation.', + optional: true, + }, + client_id: { + type: 'string', + description: + 'Client ID of the Access service token used to authenticate with the remote service.', + optional: true, + }, + client_secret: { + type: 'string', + description: + 'Client secret of the Access service token used to authenticate with the remote service.', + optional: true, + }, + scopes: { + type: 'array', + description: + 'The authorization scopes to request when generating the token used to authenticate with the remove SCIM service.', + items: { + type: 'string', + description: 'scopes item', + }, + optional: true, + }, + token_url: { + type: 'string', + description: + 'URL used to generate the token used to authenticate with the remote SCIM service.', + optional: true, + }, + }, + optional: true, + }, + deactivate_on_delete: { + type: 'boolean', + description: + "If false, propagates DELETE requests to the target application for SCIM resources. If true, sets 'active' to false on the SCIM resource. Note: Some targets do not support DELETE operations.", + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether SCIM provisioning is turned on for this application.', + optional: true, + }, + idp_uid: { + type: 'string', + description: + 'The UID of the IdP to use as the source for SCIM resources to provision to this application.', + optional: false, + }, + mappings: { + type: 'array', + description: + 'A list of mappings to apply to SCIM resources before provisioning them in this application. These can transform or filter the resources to be provisioned.', + items: { + type: 'json', + description: + 'Transformations and filters applied to resources before they are provisioned in the remote SCIM service.', + properties: { + enabled: { + type: 'boolean', + description: 'Whether or not this mapping is enabled.', + optional: true, + }, + filter: { + type: 'string', + description: + 'A [SCIM filter expression](https://datatracker.ietf.org/doc/html/rfc7644#section-3.4.2.2) that matches resources that should be provisioned to this application.', + optional: true, + }, + operations: { + type: 'json', + description: 'Whether or not this mapping applies to creates, updates, or deletes.', + properties: { + create: { + type: 'boolean', + description: 'Whether or not this mapping applies to create (POST) operations.', + optional: true, + }, + delete: { + type: 'boolean', + description: 'Whether or not this mapping applies to DELETE operations.', + optional: true, + }, + update: { + type: 'boolean', + description: + 'Whether or not this mapping applies to update (PATCH/PUT) operations.', + optional: true, + }, + }, + optional: true, + }, + schema: { + type: 'string', + description: 'Which SCIM resource type this mapping applies to.', + optional: false, + }, + strictness: { + type: 'string', + description: + 'The level of adherence to outbound resource schemas when provisioning to this mapping. \u2018Strict\u2019 removes unknown values, while \u2018passthrough\u2019 passes unknown values to the target. Values: strict, passthrough.', + optional: true, + }, + transform_jsonata: { + type: 'string', + description: + 'A [JSONata](https://jsonata.org/) expression that transforms the resource before provisioning it in the application.', + optional: true, + }, + }, + }, + optional: true, + }, + remote_uri: { + type: 'string', + description: "The base URI for the application's SCIM-compatible API.", + optional: false, + }, + }, + nullable: true, + }, + service_auth_401_redirect: { + type: 'boolean', + description: 'Returns a 401 status code when the request is blocked by a Service Auth policy.', + nullable: true, + }, + session_duration: { + type: 'string', + description: + 'The amount of time that tokens issued for this application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or \u00b5s), ms, s, m, h.', + nullable: true, + }, + skip_interstitial: { + type: 'boolean', + description: 'Enables automatic authentication through cloudflared.', + nullable: true, + }, + tags: { + type: 'array', + description: + 'The tags you want assigned to an application. Tags are used to filter applications in the App Launcher dashboard.', + items: { + type: 'string', + description: 'The tag associated with an application.', + }, + }, + use_clientless_isolation_app_launcher_url: { + type: 'boolean', + description: + 'Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application.', + nullable: true, + }, + policies: { + type: 'array', + description: 'policies', + items: { + type: 'json', + description: 'policies item', + properties: { + approval_groups: { + type: 'array', + description: 'Administrators who can approve a temporary authentication request.', + items: { + type: 'json', + description: + 'A group of email addresses that can approve a temporary authentication request.', + properties: { + approvals_needed: { + type: 'number', + description: 'The number of approvals needed to obtain access.', + optional: false, + }, + email_addresses: { + type: 'array', + description: 'A list of emails that can approve the access request.', + items: { + type: 'string', + description: 'email addresses item', + }, + optional: true, + }, + email_list_uuid: { + type: 'string', + description: 'The UUID of an re-usable email list.', + optional: true, + }, + }, + }, + optional: true, + }, + approval_required: { + type: 'boolean', + description: + 'Requires the user to request access from an administrator at the start of each session.', + optional: true, + }, + connection_rules: { + type: 'json', + description: + 'The rules that define how users may connect to targets secured by your application.', + properties: { + rdp: { + type: 'json', + description: + 'The RDP-specific rules that define clipboard behavior for RDP connections.', + properties: { + allowed_clipboard_local_to_remote_formats: { + type: 'array', + description: + 'Clipboard formats allowed when copying from local machine to remote RDP session.', + items: { + type: 'string', + description: 'Clipboard format for RDP connections. Values: text, file.', + }, + optional: true, + }, + allowed_clipboard_remote_to_local_formats: { + type: 'array', + description: + 'Clipboard formats allowed when copying from remote RDP session to local machine.', + items: { + type: 'string', + description: 'Clipboard format for RDP connections. Values: text, file.', + }, + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + isolation_required: { + type: 'boolean', + description: + "Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature.", + optional: true, + }, + mfa_config: { + type: 'json', + description: 'Configures multi-factor authentication (MFA) settings.', + properties: { + allowed_authenticators: { + type: 'array', + description: 'Lists the MFA methods that users can authenticate with.', + items: { + type: 'string', + description: 'allowed authenticators item Values: totp, biometrics, security_key.', + }, + optional: true, + }, + mfa_disabled: { + type: 'boolean', + description: + 'Indicates whether to disable MFA for this resource. This option is available at the application and policy level.', + optional: true, + }, + session_duration: { + type: 'string', + description: + 'Defines the duration of an MFA session. Must be in minutes (m) or hours (h). Minimum: 0m. Maximum: 720h (30 days). Examples:`5m` or `24h`.', + optional: true, + }, + }, + optional: true, + }, + purpose_justification_prompt: { + type: 'string', + description: 'A custom message that will appear on the purpose justification screen.', + optional: true, + }, + purpose_justification_required: { + type: 'boolean', + description: + 'Require users to enter a justification when they log in to the application.', + optional: true, + }, + session_duration: { + type: 'string', + description: + 'The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or \u00b5s), ms, s, m, h.', + optional: true, + }, + created_at: { + type: 'string', + description: 'created at', + optional: true, + }, + decision: { + type: 'string', + description: + 'The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass.', + optional: true, + }, + exclude: { + type: 'array', + description: + 'Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + optional: true, + }, + id: { + type: 'string', + description: 'The UUID of the policy', + optional: true, + }, + include: { + type: 'array', + description: + 'Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + optional: true, + }, + name: { + type: 'string', + description: 'The name of the Access policy.', + optional: true, + }, + require: { + type: 'array', + description: + 'Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + optional: true, + }, + updated_at: { + type: 'string', + description: 'updated at', + optional: true, + }, + account_id: { + type: 'string', + description: 'Identifier.', + optional: true, + }, + precedence: { + type: 'number', + description: + 'The order of execution for this policy. Must be unique for each policy within an app.', + optional: true, + }, + }, + }, + }, + saas_app: { + type: 'json', + description: 'saas app', + properties: { + auth_type: { + type: 'string', + description: + 'Identifier of the authentication protocol used for the saas app. Required for OIDC. Values: saml, oidc.', + optional: true, + }, + consumer_service_url: { + type: 'string', + description: + "The service provider's endpoint that is responsible for receiving and parsing a SAML assertion.", + optional: true, + }, + created_at: { + type: 'string', + description: 'created at', + optional: true, + }, + custom_attributes: { + type: 'array', + description: 'custom attributes', + items: { + type: 'json', + description: 'custom attributes item', + properties: { + friendly_name: { + type: 'string', + description: 'The SAML FriendlyName of the attribute.', + optional: true, + }, + name: { + type: 'string', + description: 'The name of the attribute.', + optional: true, + }, + name_format: { + type: 'string', + description: + 'A globally unique name for an identity or service provider. Values: urn:oasis:names:tc:SAML:2.0:attrname-format:unspecified, urn:oasis:names:tc:SAML:2.0:attrname-format:basic, urn:oasis:names:tc:SAML:2.0:attrname-format:uri.', + optional: true, + }, + required: { + type: 'boolean', + description: 'If the attribute is required when building a SAML assertion.', + optional: true, + }, + source: { + type: 'json', + description: 'source', + properties: { + name: { + type: 'string', + description: 'The name of the IdP attribute.', + optional: true, + }, + name_by_idp: { + type: 'array', + description: 'A mapping from IdP ID to attribute name.', + items: { + type: 'json', + description: 'name by idp item', + properties: { + idp_id: { + type: 'string', + description: 'The UID of the IdP.', + optional: true, + }, + source_name: { + type: 'string', + description: 'The name of the IdP provided attribute.', + optional: true, + }, + }, + }, + optional: true, + }, + }, + optional: true, + }, + }, + }, + optional: true, + }, + default_relay_state: { + type: 'string', + description: + 'The URL that the user will be redirected to after a successful login for IDP initiated logins.', + optional: true, + }, + idp_entity_id: { + type: 'string', + description: 'The unique identifier for your SaaS application.', + optional: true, + }, + name_id_format: { + type: 'string', + description: + 'The format of the name identifier sent to the SaaS application. Values: id, email.', + optional: true, + }, + name_id_transform_jsonata: { + type: 'string', + description: + "A [JSONata](https://jsonata.org/) expression that transforms an application's user identities into a NameID value for its SAML assertion. This expression should evaluate to a singular string. The output of this expression can override the `name_id_format` setting.", + optional: true, + }, + public_key: { + type: 'string', + description: 'The Access public certificate that will be used to verify your identity.', + optional: true, + }, + saml_attribute_transform_jsonata: { + type: 'string', + description: + "A [JSONata] (https://jsonata.org/) expression that transforms an application's user identities into attribute assertions in the SAML response.", + optional: true, + }, + sp_entity_id: { + type: 'string', + description: 'A globally unique name for an identity or service provider.', + optional: true, + }, + sso_endpoint: { + type: 'string', + description: 'The endpoint where your SaaS application will send login requests.', + optional: true, + }, + updated_at: { + type: 'string', + description: 'updated at', + optional: true, + }, + access_token_lifetime: { + type: 'string', + description: + 'The lifetime of the OIDC Access Token after creation. Valid units are m,h. Must be greater than or equal to 1m and less than or equal to 24h.', + optional: true, + }, + allow_pkce_without_client_secret: { + type: 'boolean', + description: + 'If client secret should be required on the token endpoint when authorization_code_with_pkce grant is used.', + optional: true, + }, + app_launcher_url: { + type: 'string', + description: 'The URL where this applications tile redirects users', + optional: true, + }, + client_id: { + type: 'string', + description: 'The application client id', + optional: true, + }, + client_secret: { + type: 'string', + description: 'The application client secret, only returned on POST request.', + optional: true, + }, + custom_claims: { + type: 'array', + description: 'custom claims', + items: { + type: 'json', + description: 'custom claims item', + properties: { + name: { + type: 'string', + description: 'The name of the claim.', + optional: true, + }, + required: { + type: 'boolean', + description: 'If the claim is required when building an OIDC token.', + optional: true, + }, + scope: { + type: 'string', + description: 'The scope of the claim. Values: groups, profile, email, openid.', + optional: true, + }, + source: { + type: 'json', + description: 'source', + properties: { + name: { + type: 'string', + description: 'The name of the IdP claim.', + optional: true, + }, + name_by_idp: { + type: 'json', + description: 'A mapping from IdP ID to claim name.', + optional: true, + }, + }, + optional: true, + }, + }, + }, + optional: true, + }, + grant_types: { + type: 'array', + description: 'The OIDC flows supported by this application', + items: { + type: 'string', + description: + 'grant types item Values: authorization_code, authorization_code_with_pkce, refresh_tokens, hybrid, implicit.', + }, + optional: true, + }, + group_filter_regex: { + type: 'string', + description: + 'A regex to filter Cloudflare groups returned in ID token and userinfo endpoint', + optional: true, + }, + hybrid_and_implicit_options: { + type: 'json', + description: 'hybrid and implicit options', + properties: { + return_access_token_from_authorization_endpoint: { + type: 'boolean', + description: + 'If an Access Token should be returned from the OIDC Authorization endpoint', + optional: true, + }, + return_id_token_from_authorization_endpoint: { + type: 'boolean', + description: 'If an ID Token should be returned from the OIDC Authorization endpoint', + optional: true, + }, + }, + optional: true, + }, + redirect_uris: { + type: 'array', + description: + "The permitted URL's for Cloudflare to return Authorization codes and Access/ID tokens", + items: { + type: 'string', + description: 'redirect uris item', + }, + optional: true, + }, + refresh_token_options: { + type: 'json', + description: 'refresh token options', + properties: { + lifetime: { + type: 'string', + description: + 'How long a refresh token will be valid for after creation. Valid units are m,h,d. Must be longer than 1m.', + optional: true, + }, + }, + optional: true, + }, + scopes: { + type: 'array', + description: + 'Define the user information shared with access, "offline_access" scope will be automatically enabled if refresh tokens are enabled', + items: { + type: 'string', + description: 'scopes item Values: openid, groups, email, profile.', + }, + optional: true, + }, + }, + nullable: true, + }, + app_launcher_logo_url: { + type: 'string', + description: 'The image URL of the logo shown in the App Launcher header.', + nullable: true, + }, + bg_color: { + type: 'string', + description: 'The background color of the App Launcher page.', + nullable: true, + }, + footer_links: { + type: 'array', + description: 'The links in the App Launcher footer.', + items: { + type: 'json', + description: 'footer links item', + properties: { + name: { + type: 'string', + description: 'The hypertext in the footer link.', + optional: false, + }, + url: { + type: 'string', + description: 'the hyperlink in the footer link.', + optional: false, + }, + }, + }, + }, + header_bg_color: { + type: 'string', + description: 'The background color of the App Launcher header.', + nullable: true, + }, + landing_page_design: { + type: 'json', + description: 'The design of the App Launcher landing page shown to users when they log in.', + properties: { + button_color: { + type: 'string', + description: 'The background color of the log in button on the landing page.', + optional: true, + }, + button_text_color: { + type: 'string', + description: 'The color of the text in the log in button on the landing page.', + optional: true, + }, + image_url: { + type: 'string', + description: 'The URL of the image shown on the landing page.', + optional: true, + }, + message: { + type: 'string', + description: 'The message shown on the landing page.', + optional: true, + }, + title: { + type: 'string', + description: 'The title shown on the landing page.', + optional: true, + }, + }, + nullable: true, + }, + skip_app_launcher_login_page: { + type: 'boolean', + description: 'Determines when to skip the App Launcher landing page.', + nullable: true, + }, + target_criteria: { + type: 'array', + description: 'target criteria', + items: { + type: 'json', + description: + 'Defines targets covered by the application. Use either the legacy top-level target_attributes format or the rule format, but not both. The rule format requires include; require and exclude are optional.', + properties: { + exclude: { + type: 'json', + description: + 'Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty.', + properties: { + tags: { + type: 'json', + description: "Map of target tag keys to values. Values within a key are OR'd.", + optional: true, + }, + target_attributes: { + type: 'json', + description: + 'Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key.', + properties: { + hostname: { + type: 'array', + description: 'hostname', + items: { + type: 'string', + description: 'hostname item', + }, + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + include: { + type: 'json', + description: + 'Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty.', + properties: { + tags: { + type: 'json', + description: "Map of target tag keys to values. Values within a key are OR'd.", + optional: true, + }, + target_attributes: { + type: 'json', + description: + 'Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key.', + properties: { + hostname: { + type: 'array', + description: 'hostname', + items: { + type: 'string', + description: 'hostname item', + }, + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + port: { + type: 'number', + description: + 'The port that the targets use for the chosen communication protocol. A port cannot be assigned to multiple protocols.', + optional: false, + }, + require: { + type: 'json', + description: + 'Selectors within an include, require, or exclude rule. At least one of target_attributes or tags must be non-empty.', + properties: { + tags: { + type: 'json', + description: "Map of target tag keys to values. Values within a key are OR'd.", + optional: true, + }, + target_attributes: { + type: 'json', + description: + 'Hostname selector map for include, require, or exclude rules. This is distinct from the deprecated top-level target_attributes field and only supports the hostname key.', + properties: { + hostname: { + type: 'array', + description: 'hostname', + items: { + type: 'string', + description: 'hostname item', + }, + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + target_attributes: { + type: 'json', + description: 'Contains a map of target attribute keys to target attribute values.', + optional: true, + }, + protocol: { + type: 'string', + description: 'The communication protocol your application secures. Values: RDP.', + optional: false, + }, + }, + }, + }, +} as const satisfies Record + +export const ACCESS_GROUP_OUTPUTS = { + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + exclude: { + type: 'array', + description: + 'Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + }, + id: { + type: 'string', + description: 'UUID.', + nullable: true, + }, + include: ACCESS_GROUP_OUTPUTS_INCLUDE_FIELDS, + is_default: ACCESS_GROUP_OUTPUTS_IS_DEFAULT_FIELDS, + name: { + type: 'string', + description: 'The name of the Access group.', + nullable: true, + }, + require: ACCESS_GROUP_OUTPUTS_IS_DEFAULT_FIELDS, + updated_at: { + type: 'string', + description: 'updated at', + nullable: true, + }, +} as const satisfies Record + +export const ACCESS_POLICY_OUTPUTS = { + approval_groups: { + type: 'array', + description: 'Administrators who can approve a temporary authentication request.', + items: { + type: 'json', + description: + 'A group of email addresses that can approve a temporary authentication request.', + properties: { + approvals_needed: { + type: 'number', + description: 'The number of approvals needed to obtain access.', + optional: false, + }, + email_addresses: { + type: 'array', + description: 'A list of emails that can approve the access request.', + items: { + type: 'string', + description: 'email addresses item', + }, + optional: true, + }, + email_list_uuid: { + type: 'string', + description: 'The UUID of an re-usable email list.', + optional: true, + }, + }, + }, + }, + approval_required: { + type: 'boolean', + description: + 'Requires the user to request access from an administrator at the start of each session.', + nullable: true, + }, + connection_rules: { + type: 'json', + description: + 'The rules that define how users may connect to the targets secured by your application.', + properties: { + rdp: { + type: 'json', + description: 'The RDP-specific rules that define clipboard behavior for RDP connections.', + properties: { + allowed_clipboard_local_to_remote_formats: { + type: 'array', + description: + 'Clipboard formats allowed when copying from local machine to remote RDP session.', + items: { + type: 'string', + description: 'Clipboard format for RDP connections. Values: text, file.', + }, + optional: true, + }, + allowed_clipboard_remote_to_local_formats: { + type: 'array', + description: + 'Clipboard formats allowed when copying from remote RDP session to local machine.', + items: { + type: 'string', + description: 'Clipboard format for RDP connections. Values: text, file.', + }, + optional: true, + }, + }, + optional: true, + }, + ssh: { + type: 'json', + description: + 'The SSH-specific rules that define how users may connect to the targets secured by your application.', + properties: { + allow_email_alias: { + type: 'boolean', + description: 'Enables using Identity Provider email alias as SSH username.', + optional: true, + }, + usernames: { + type: 'array', + description: 'Contains the Unix usernames that may be used when connecting over SSH.', + items: { + type: 'string', + description: 'usernames item', + }, + optional: false, + }, + }, + optional: true, + }, + }, + nullable: true, + }, + isolation_required: { + type: 'boolean', + description: + "Require this application to be served in an isolated browser for users matching this policy. 'Client Web Isolation' must be on for the account in order to use this feature.", + nullable: true, + }, + mfa_config: { + type: 'json', + description: + 'Configures multi-factor authentication (MFA) settings for infrastructure applications.', + properties: { + allowed_authenticators: { + type: 'array', + description: + 'Lists the MFA methods that users can authenticate with. For infrastructure applications, supported values are `piv_key` and `ssh_fido2_key`.', + items: { + type: 'string', + description: 'allowed authenticators item Values: piv_key, ssh_fido2_key.', + }, + optional: true, + }, + mfa_disabled: { + type: 'boolean', + description: + 'Indicates whether to disable MFA for this resource. This option is available at the application and policy level.', + optional: true, + }, + session_duration: { + type: 'string', + description: + 'Defines the duration of an MFA session. Must be in minutes (m) or hours (h). Minimum: 0m. Maximum: 720h (30 days). Examples: `5m` or `24h`.', + optional: true, + }, + }, + nullable: true, + }, + purpose_justification_prompt: { + type: 'string', + description: 'A custom message that will appear on the purpose justification screen.', + nullable: true, + }, + purpose_justification_required: { + type: 'boolean', + description: 'Require users to enter a justification when they log in to the application.', + nullable: true, + }, + session_duration: { + type: 'string', + description: + 'The amount of time that tokens issued for the application will be valid. Must be in the format `300ms` or `2h45m`. Valid time units are: ns, us (or \u00b5s), ms, s, m, h.', + nullable: true, + }, + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + decision: { + type: 'string', + description: + 'The action Access will take if a user matches this policy. Infrastructure application policies can only use the Allow action. Values: allow, deny, non_identity, bypass.', + nullable: true, + }, + exclude: { + type: 'array', + description: + 'Rules evaluated with a NOT logical operator. To match the policy, a user cannot meet any of the Exclude rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + }, + id: { + type: 'string', + description: 'The UUID of the policy', + nullable: true, + }, + include: ACCESS_GROUP_OUTPUTS_INCLUDE_FIELDS, + name: { + type: 'string', + description: 'The name of the Access policy.', + nullable: true, + }, + require: { + type: 'array', + description: + 'Rules evaluated with an AND logical operator. To match the policy, a user must meet all of the Require rules.', + items: ACCESS_APPLICATION_OUTPUTS_POLICIES_ITEMS_PROPERTIES_EXCLUDE_ITEMS_FIELDS, + }, + updated_at: { + type: 'string', + description: 'updated at', + nullable: true, + }, + account_id: { + type: 'string', + description: 'Identifier.', + nullable: true, + }, + precedence: { + type: 'number', + description: + 'The order of execution for this policy. Must be unique for each policy within an app.', + nullable: true, + }, +} as const satisfies Record + +export const CERTIFICATE_OUTPUTS = { + certificate_authority: { + type: 'string', + description: + 'Certificate Authority selected for the order. For information on any certificate authority specific details or restrictions [see this page for more details](https://developers.cloudflare.com/ssl/reference/certificate-authorities). Values: google, lets_encrypt, ssl_com.', + nullable: true, + }, + certificates: { + type: 'array', + description: 'Array of certificates in this pack.', + items: { + type: 'json', + description: 'An individual certificate within a certificate pack.', + properties: { + bundle_method: { + type: 'string', + description: 'Certificate bundle method.', + optional: true, + }, + expires_on: { + type: 'string', + description: 'When the certificate from the authority expires.', + optional: true, + }, + geo_restrictions: { + type: 'json', + description: 'Specify the region where your private key can be held locally.', + properties: { + label: { + type: 'string', + description: 'label Values: us, eu, highest_security.', + optional: true, + }, + }, + optional: true, + }, + hosts: { + type: 'array', + description: 'Hostnames covered by this certificate.', + items: { + type: 'string', + description: 'hosts item', + }, + optional: false, + }, + id: { + type: 'string', + description: 'Certificate identifier.', + optional: false, + }, + issuer: { + type: 'string', + description: 'The certificate authority that issued the certificate.', + optional: true, + }, + modified_on: { + type: 'string', + description: 'When the certificate was last modified.', + optional: true, + }, + priority: { + type: 'number', + description: 'The order/priority in which the certificate will be used.', + optional: true, + }, + signature: { + type: 'string', + description: 'The type of hash used for the certificate.', + optional: true, + }, + status: { + type: 'string', + description: 'Certificate status.', + optional: false, + }, + uploaded_on: { + type: 'string', + description: 'When the certificate was uploaded to Cloudflare.', + optional: true, + }, + zone_id: { + type: 'string', + description: 'Identifier.', + optional: true, + }, + }, + }, + }, + cloudflare_branding: { + type: 'boolean', + description: + 'Whether or not to add Cloudflare Branding for the order. This will add a subdomain of sni.cloudflaressl.com as the Common Name if set to true.', + nullable: true, + }, + dcv_delegation_records: { + type: 'array', + description: 'DCV Delegation records for domain validation.', + items: CERTIFICATE_OUTPUTS_DCV_DELEGATION_RECORDS_ITEMS_FIELDS, + }, + hosts: { + type: 'array', + description: + 'Comma separated list of valid host names for the certificate packs. Must contain the zone apex, may not contain more than 50 hosts, and may not be empty.', + items: { + type: 'string', + description: 'hosts item', + }, + }, + id: { + type: 'string', + description: 'The unique identifier for a certificate_pack.', + nullable: true, + }, + primary_certificate: { + type: 'string', + description: 'Identifier of the primary certificate in a pack.', + nullable: true, + }, + status: { + type: 'string', + description: 'Status of certificate pack.', + nullable: true, + }, + type: { + type: 'string', + description: + 'Type of certificate pack. Values: mh_custom, managed_hostname, sni_custom, universal, advanced, total_tls, keyless, legacy_custom.', + nullable: true, + }, + validation_errors: { + type: 'array', + description: + 'Domain validation errors that have been received by the certificate authority (CA).', + items: { + type: 'json', + description: 'validation errors item', + properties: { + message: { + type: 'string', + description: 'A domain validation error.', + optional: true, + }, + }, + }, + }, + validation_method: { + type: 'string', + description: 'Validation Method selected for the order. Values: txt, http, email.', + nullable: true, + }, + validation_records: { + type: 'array', + description: "Certificates' validation records.", + items: CERTIFICATE_OUTPUTS_DCV_DELEGATION_RECORDS_ITEMS_FIELDS, + }, + validity_days: { + type: 'number', + description: 'Validity Days selected for the order. Values: 14, 30, 90, 365.', + nullable: true, + }, +} as const satisfies Record + +export const DNS_RECORD_OUTPUTS = { + comment: { + type: 'string', + description: + 'Comments or notes about the DNS record. This field has no effect on DNS responses.', + nullable: true, + }, + name: { + type: 'string', + description: 'Complete DNS record name, including the zone name, in Punycode.', + nullable: true, + }, + proxied: { + type: 'boolean', + description: + 'Whether the record is receiving the performance and security benefits of Cloudflare.', + nullable: true, + }, + settings: { + type: 'json', + description: 'Settings for the DNS record.', + properties: { + ipv4_only: { + type: 'boolean', + description: + 'When enabled, only A records will be generated, and AAAA records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6.', + optional: true, + }, + ipv6_only: { + type: 'boolean', + description: + 'When enabled, only AAAA records will be generated, and A records will not be created. This setting is intended for exceptional cases. Note that this option only applies to proxied records and it has no effect on whether Cloudflare communicates with the origin using IPv4 or IPv6.', + optional: true, + }, + flatten_cname: { + type: 'boolean', + description: + 'If enabled, causes the CNAME record to be resolved externally and the resulting address records (e.g., A and AAAA) to be returned instead of the CNAME record itself. This setting is unavailable for proxied records, since they are always flattened.', + optional: true, + }, + }, + nullable: true, + }, + tags: { + type: 'array', + description: 'Custom tags for the DNS record. This field has no effect on DNS responses.', + items: { + type: 'string', + description: + 'Individual tag of the form name:value (the name must consist of only letters, numbers, underscores and hyphens)', + }, + }, + ttl: { + type: 'number', + description: + "Time To Live (TTL) of the DNS record in seconds. Setting to 1 means 'automatic'. Value must be between 60 and 86400, with the minimum reduced to 30 for Enterprise zones. Values: 1.", + nullable: true, + }, + content: { + type: 'string', + description: "Formatted URI content. See 'data' to set URI properties.", + nullable: true, + }, + private_routing: { + type: 'boolean', + description: 'Enables private network routing to the origin.', + nullable: true, + }, + type: { + type: 'string', + description: + 'Record type. Values: A, AAAA, CNAME, MX, NS, OPENPGPKEY, PTR, TXT, CAA, CERT, DNSKEY, DS, HTTPS, LOC, NAPTR, SMIMEA, SRV, SSHFP, SVCB, TLSA, URI.', + nullable: true, + }, + priority: { + type: 'number', + description: + 'Required for MX and URI records; ignored for other record types (but may still be returned by the API). Records with lower priorities are preferred. This field is to be deprecated in favor of the priority field within the data map.', + nullable: true, + }, + data: { + type: 'json', + description: 'Structured record data. The available fields depend on the DNS record type.', + properties: { + flags: { + type: 'json', + description: 'Flags.', + optional: true, + }, + tag: { + type: 'string', + description: + 'Name of the property controlled by this record (e.g.: issue, issuewild, iodef).', + optional: true, + }, + value: { + type: 'string', + description: 'Value.', + optional: true, + }, + algorithm: { + type: 'number', + description: 'Algorithm.', + optional: true, + }, + certificate: { + type: 'string', + description: 'Certificate.', + optional: true, + }, + key_tag: { + type: 'number', + description: 'Key Tag.', + optional: true, + }, + type: { + type: 'number', + description: 'Type.', + optional: true, + }, + protocol: { + type: 'number', + description: 'Protocol.', + optional: true, + }, + public_key: { + type: 'string', + description: 'Public Key.', + optional: true, + }, + digest: { + type: 'string', + description: 'Digest.', + optional: true, + }, + digest_type: { + type: 'number', + description: 'Digest Type.', + optional: true, + }, + priority: { + type: 'number', + description: 'Priority.', + optional: true, + }, + target: { + type: 'string', + description: 'The record content.', + optional: true, + }, + altitude: { + type: 'number', + description: 'Altitude of location in meters.', + optional: true, + }, + lat_degrees: { + type: 'number', + description: 'Degrees of latitude.', + optional: true, + }, + lat_direction: { + type: 'string', + description: 'Latitude direction. Values: N, S.', + optional: true, + }, + lat_minutes: { + type: 'number', + description: 'Minutes of latitude.', + optional: true, + }, + lat_seconds: { + type: 'number', + description: 'Seconds of latitude.', + optional: true, + }, + long_degrees: { + type: 'number', + description: 'Degrees of longitude.', + optional: true, + }, + long_direction: { + type: 'string', + description: 'Longitude direction. Values: E, W.', + optional: true, + }, + long_minutes: { + type: 'number', + description: 'Minutes of longitude.', + optional: true, + }, + long_seconds: { + type: 'number', + description: 'Seconds of longitude.', + optional: true, + }, + precision_horz: { + type: 'number', + description: 'Horizontal precision of location.', + optional: true, + }, + precision_vert: { + type: 'number', + description: 'Vertical precision of location.', + optional: true, + }, + size: { + type: 'number', + description: 'Size of location in meters.', + optional: true, + }, + order: { + type: 'number', + description: 'Order.', + optional: true, + }, + preference: { + type: 'number', + description: 'Preference.', + optional: true, + }, + regex: { + type: 'string', + description: 'Regex.', + optional: true, + }, + replacement: { + type: 'string', + description: 'Replacement.', + optional: true, + }, + service: { + type: 'string', + description: 'Service.', + optional: true, + }, + matching_type: { + type: 'number', + description: 'Matching Type.', + optional: true, + }, + selector: { + type: 'number', + description: 'Selector.', + optional: true, + }, + usage: { + type: 'number', + description: 'Usage.', + optional: true, + }, + port: { + type: 'number', + description: 'The port of the service.', + optional: true, + }, + weight: { + type: 'number', + description: 'The record weight.', + optional: true, + }, + fingerprint: { + type: 'string', + description: 'Fingerprint.', + optional: true, + }, + }, + nullable: true, + }, + comment_modified_on: { + type: 'string', + description: 'When the record comment was last modified. Omitted if there is no comment.', + nullable: true, + }, + created_on: { + type: 'string', + description: 'When the record was created.', + nullable: true, + }, + id: { + type: 'string', + description: 'Identifier.', + nullable: true, + }, + meta: { + type: 'json', + description: 'Extra Cloudflare-specific metadata about the record.', + properties: { + dead_glue: { + type: 'boolean', + description: + 'Whether this glue record is not served because a shallower NS delegation takes precedence over the deeper delegation that needs it.', + optional: true, + }, + is_glue: { + type: 'boolean', + description: + 'Whether this A or AAAA record is glue for a subdomain NS delegation. See [Glue records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records#glue-records).', + optional: true, + }, + shadowed_by: { + type: 'array', + description: + 'IDs of the NS records that shadow this record. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + items: { + type: 'string', + description: 'shadowed by item', + }, + optional: true, + }, + shadowed_records_count: { + type: 'number', + description: + 'Number of records shadowed by this NS delegation. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + optional: true, + }, + }, + nullable: true, + }, + modified_on: { + type: 'string', + description: 'When the record was last modified.', + nullable: true, + }, + proxiable: { + type: 'boolean', + description: 'Whether the record can be proxied by Cloudflare or not.', + nullable: true, + }, + tags_modified_on: { + type: 'string', + description: 'When the record tags were last modified. Omitted if there are no tags.', + nullable: true, + }, + zone_id: { + type: 'string', + description: 'Legacy DNS response zone ID when returned by Cloudflare', + nullable: true, + }, + zone_name: { + type: 'string', + description: 'Legacy DNS response zone name when returned by Cloudflare', + nullable: true, + }, + locked: { + type: 'boolean', + description: 'Legacy DNS response lock flag when returned by Cloudflare', + nullable: true, + }, +} as const satisfies Record + +export const IDENTITY_PROVIDER_OUTPUTS = { + config: { + type: 'json', + description: + 'The configuration parameters for the identity provider. To view the required parameters for a specific provider, refer to our [developer documentation](https://developers.cloudflare.com/cloudflare-one/identity/idp-integration/).', + properties: { + client_id: { + type: 'string', + description: 'Your OAuth Client ID', + optional: true, + }, + client_secret: { + type: 'string', + description: 'Your OAuth Client Secret', + optional: true, + }, + claims: { + type: 'array', + description: 'Custom claims', + items: { + type: 'string', + description: 'claims item', + }, + optional: true, + }, + email_claim_name: { + type: 'string', + description: 'The claim name for email in the id_token response.', + optional: true, + }, + conditional_access_enabled: { + type: 'boolean', + description: 'Should Cloudflare try to load authentication contexts from your account', + optional: true, + }, + directory_id: { + type: 'string', + description: 'Your Azure directory uuid', + optional: true, + }, + prompt: { + type: 'string', + description: + 'Configures the prompt behavior for Google authentication. Values: login, select_account, none, consent.', + optional: true, + }, + support_groups: { + type: 'boolean', + description: 'Should Cloudflare try to load groups from your account', + optional: true, + }, + centrify_account: { + type: 'string', + description: 'Your centrify account url', + optional: true, + }, + centrify_app_id: { + type: 'string', + description: 'Your centrify app id', + optional: true, + }, + apps_domain: { + type: 'string', + description: 'Your companies TLD', + optional: true, + }, + use_login_hint: { + type: 'boolean', + description: + 'Whether to use a previously authenticated Access email as a Google login hint when exactly one email matches the Workspace domain.', + optional: true, + }, + auth_url: { + type: 'string', + description: 'The authorization_endpoint URL of your IdP', + optional: true, + }, + certs_url: { + type: 'string', + description: 'The jwks_uri endpoint of your IdP to allow the IdP keys to sign the tokens', + optional: true, + }, + pkce_enabled: { + type: 'boolean', + description: 'Enable Proof Key for Code Exchange (PKCE)', + optional: true, + }, + scopes: { + type: 'array', + description: 'OAuth scopes', + items: { + type: 'string', + description: 'scopes item', + }, + optional: true, + }, + token_url: { + type: 'string', + description: 'The token_endpoint URL of your IdP', + optional: true, + }, + issuer_url: { + type: 'string', + description: 'IdP Entity ID or Issuer URL', + optional: true, + }, + authorization_server_id: { + type: 'string', + description: 'Your okta authorization server id', + optional: true, + }, + okta_account: { + type: 'string', + description: 'Your okta account url', + optional: true, + }, + onelogin_account: { + type: 'string', + description: 'Your OneLogin account url', + optional: true, + }, + ping_env_id: { + type: 'string', + description: 'Your PingOne environment identifier', + optional: true, + }, + attributes: { + type: 'array', + description: + 'A list of SAML attribute names that will be added to your signed JWT token and can be used in SAML policy rules.', + items: { + type: 'string', + description: 'attributes item', + }, + optional: true, + }, + email_attribute_name: { + type: 'string', + description: 'The attribute name for email in the SAML response.', + optional: true, + }, + enable_encryption: { + type: 'boolean', + description: 'Enable SAML assertion encryption.', + optional: true, + }, + force_authn: { + type: 'boolean', + description: + 'Asks the IdP to reauthenticate the user for each SAML authentication request.', + optional: true, + }, + header_attributes: { + type: 'array', + description: + 'Add a list of attribute names that will be returned in the response header from the Access callback.', + items: { + type: 'json', + description: 'header attributes item', + properties: { + attribute_name: { + type: 'string', + description: 'attribute name from the IDP', + optional: true, + }, + header_name: { + type: 'string', + description: 'header that will be added on the request to the origin', + optional: true, + }, + }, + }, + optional: true, + }, + idp_public_certs: { + type: 'array', + description: 'X509 certificate to verify the signature in the SAML authentication response', + items: { + type: 'string', + description: 'idp public certs item', + }, + optional: true, + }, + max_sso_url_length: { + type: 'number', + description: + 'The maximum URL length the IdP accepts for the SSO redirect URL. When the constructed SSO URL would exceed this length, the RelayState is stored server-side and a short nonce is passed to the IdP instead. Set this if your IdP enforces a URL length limit.', + optional: true, + }, + sign_request: { + type: 'boolean', + description: + 'Sign the SAML authentication request with Access credentials. To verify the signature, use the public key from the Access certs endpoints.', + optional: true, + }, + sso_target_url: { + type: 'string', + description: 'URL to send the SAML authentication requests to', + optional: true, + }, + redirect_url: { + type: 'string', + description: 'redirect url', + optional: true, + }, + restrict_to_account_members: { + type: 'boolean', + description: + 'When enabled, only users who are members of your Cloudflare account can authenticate through this identity provider. When disabled, any user with a Cloudflare account can authenticate, subject to your Access policies.', + optional: true, + }, + login_page_auto_prompt: { + type: 'boolean', + description: + 'When enabled, the Access login page automatically prompts the user to authenticate with a passkey.', + optional: true, + }, + }, + nullable: true, + }, + id: { + type: 'string', + description: 'UUID.', + nullable: true, + }, + name: { + type: 'string', + description: 'The name of the identity provider, shown to users on the login page.', + nullable: true, + }, + read_only: { + type: 'boolean', + description: + 'Indicates that the identity provider is immutable and cannot be updated or deleted via the API.', + nullable: true, + }, + saml_certificate_set: { + type: 'json', + description: + 'A SAML encryption certificate set containing current and optionally previous certificates for encryption key rotation.', + properties: { + created_at: { + type: 'string', + description: 'Timestamp when the certificate set was created', + optional: false, + }, + current_certificate: { + type: 'json', + description: 'A single SAML encryption certificate with metadata', + properties: { + is_current: { + type: 'boolean', + description: 'Indicates whether this is the currently active certificate', + optional: false, + }, + not_after: { + type: 'string', + description: + 'Certificate expiration date. Certificates are automatically rotated 30 days before expiration.', + optional: false, + }, + public_certificate: { + type: 'string', + description: + 'PEM-encoded X.509 certificate containing the public key. Configure this certificate in your external SAML Identity Provider to enable encryption.', + optional: false, + }, + uid: { + type: 'string', + description: 'Unique identifier for the certificate', + optional: false, + }, + }, + optional: true, + }, + previous_certificate: { + type: 'json', + description: + 'The previous certificate, maintained during rotation to ensure continuity. Null if no rotation has occurred. Mirrors the structure of `saml_certificate`.', + optional: true, + }, + uid: { + type: 'string', + description: 'Unique identifier for the certificate set', + optional: false, + }, + updated_at: { + type: 'string', + description: 'Timestamp when the certificate set was last updated (e.g., during rotation)', + optional: false, + }, + }, + nullable: true, + }, + saml_certificate_set_id: { + type: 'string', + description: + 'The UID of the SAML encryption certificate set assigned to this Identity Provider. Only present for SAML identity providers with encryption configured. Create a certificate set via POST to `/identity_providers/{id}/saml_certificate`.', + nullable: true, + }, + scim_config: { + type: 'json', + description: + 'The configuration settings for enabling a System for Cross-Domain Identity Management (SCIM) with the identity provider.', + properties: { + enabled: { + type: 'boolean', + description: 'A flag to enable or disable SCIM for the identity provider.', + optional: true, + }, + identity_update_behavior: { + type: 'string', + description: + 'Indicates how a SCIM event updates a user identity used for policy evaluation.', + optional: true, + }, + scim_base_url: { + type: 'string', + description: "The base URL of Cloudflare's SCIM V2.0 API endpoint.", + optional: true, + }, + seat_deprovision: { + type: 'boolean', + description: + "A flag to remove a user's seat in Zero Trust when they have been deprovisioned in the Identity Provider. This cannot be enabled unless user_deprovision is also enabled.", + optional: true, + }, + secret: { + type: 'string', + description: + 'A read-only token generated when the SCIM integration is enabled for the first time. It is redacted on subsequent requests. If you lose this you will need to refresh it at /access/identity_providers/:idpID/refresh_scim_secret.', + optional: true, + }, + user_deprovision: { + type: 'boolean', + description: + "A flag to enable revoking a user's session in Access and Gateway when they have been deprovisioned in the Identity Provider.", + optional: true, + }, + }, + nullable: true, + }, + type: { + type: 'string', + description: 'The type of identity provider.', + nullable: true, + }, +} as const satisfies Record + +export const LIST_RULESETS_OUTPUTS = { + description: { + type: 'string', + description: 'An informative description of the ruleset.', + nullable: true, + }, + id: { + type: 'string', + description: 'The unique ID of the ruleset.', + nullable: true, + }, + last_updated: { + type: 'string', + description: 'The timestamp of when the ruleset was last modified.', + nullable: true, + }, + name: { + type: 'string', + description: 'The human-readable name of the ruleset.', + nullable: true, + }, + version: { + type: 'string', + description: 'The version of the ruleset.', + nullable: true, + }, + kind: { + type: 'string', + description: 'The kind of the ruleset. Values: managed, custom, root, zone.', + nullable: true, + }, + phase: { + type: 'string', + description: 'The phase of the ruleset.', + nullable: true, + }, +} as const satisfies Record + +export const R2_BUCKET_OUTPUTS = { + creation_date: { + type: 'string', + description: 'Creation timestamp.', + nullable: true, + }, + jurisdiction: { + type: 'string', + description: + 'Jurisdiction where objects in this bucket are guaranteed to be stored. Values: default, eu, us, fedramp, fedramp-high.', + nullable: true, + }, + location: { + type: 'string', + description: 'Location of the bucket. Values: apac, eeur, enam, weur, wnam, oc.', + nullable: true, + }, + name: { + type: 'string', + description: 'Name of the bucket.', + nullable: true, + }, + storage_class: { + type: 'string', + description: + 'Storage class for newly uploaded objects, unless specified otherwise. Values: Standard, InfrequentAccess.', + nullable: true, + }, +} as const satisfies Record + +export const R2_CORS_OUTPUTS = { + rules: { + type: 'array', + description: 'rules', + items: { + type: 'json', + description: 'rules item', + properties: { + allowed: { + type: 'json', + description: 'Object specifying allowed origins, methods and headers for this CORS rule.', + properties: { + headers: { + type: 'array', + description: + 'Specifies the value for the Access-Control-Allow-Headers header R2 sets when requesting objects in this bucket from a browser. Cross-origin requests that include custom headers (e.g. x-user-id) should specify these headers as AllowedHeaders.', + items: { + type: 'string', + description: 'headers item', + }, + optional: true, + }, + methods: { + type: 'array', + description: + 'Specifies the value for the Access-Control-Allow-Methods header R2 sets when requesting objects in a bucket from a browser.', + items: { + type: 'string', + description: 'methods item Values: GET, PUT, POST, DELETE, HEAD.', + }, + optional: false, + }, + origins: { + type: 'array', + description: + 'Specifies the value for the Access-Control-Allow-Origin header R2 sets when requesting objects in a bucket from a browser.', + items: { + type: 'string', + description: 'origins item', + }, + optional: false, + }, + }, + optional: false, + }, + exposeHeaders: { + type: 'array', + description: + 'Specifies the headers that can be exposed back, and accessed by, the JavaScript making the cross-origin request. If you need to access headers beyond the safelisted response headers, such as Content-Encoding or cf-cache-status, you must specify it here.', + items: { + type: 'string', + description: 'exposeHeaders item', + }, + optional: true, + }, + id: { + type: 'string', + description: 'Identifier for this rule.', + optional: true, + }, + maxAgeSeconds: { + type: 'number', + description: + 'Specifies the amount of time (in seconds) browsers are allowed to cache CORS preflight responses. Browsers may limit this to 2 hours or less, even if the maximum value (86400) is specified.', + optional: true, + }, + }, + }, + }, +} as const satisfies Record + +export const R2_LIFECYCLE_OUTPUTS = { + rules: { + type: 'array', + description: 'rules', + items: { + type: 'json', + description: 'rules item', + properties: { + abortMultipartUploadsTransition: { + type: 'json', + description: 'Transition to abort ongoing multipart uploads.', + properties: { + condition: { + type: 'json', + description: + 'Condition for lifecycle transitions to apply after an object reaches an age in seconds.', + properties: { + maxAge: { + type: 'number', + description: 'maxAge', + optional: false, + }, + type: { + type: 'string', + description: 'type Values: Age.', + optional: false, + }, + }, + optional: true, + }, + }, + optional: true, + }, + conditions: { + type: 'json', + description: 'Conditions that apply to all transitions of this rule.', + properties: { + prefix: { + type: 'string', + description: + 'Transitions will only apply to objects/uploads in the bucket that start with the given prefix, an empty prefix can be provided to scope rule to all objects/uploads.', + optional: false, + }, + }, + optional: false, + }, + deleteObjectsTransition: { + type: 'json', + description: 'Transition to delete objects.', + properties: { + condition: { + type: 'json', + description: 'Condition for lifecycle transitions to apply on a specific date.', + properties: { + maxAge: { + type: 'number', + description: 'maxAge', + optional: true, + }, + type: { + type: 'string', + description: 'type Values: Age, Date.', + optional: false, + }, + date: { + type: 'string', + description: 'date', + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether or not this rule is in effect.', + optional: false, + }, + id: { + type: 'string', + description: 'Unique identifier for this rule.', + optional: false, + }, + storageClassTransitions: { + type: 'array', + description: 'Transitions to change the storage class of objects.', + items: { + type: 'json', + description: 'storageClassTransitions item', + properties: { + condition: { + type: 'json', + description: 'Condition for lifecycle transitions to apply on a specific date.', + properties: { + maxAge: { + type: 'number', + description: 'maxAge', + optional: true, + }, + type: { + type: 'string', + description: 'type Values: Age, Date.', + optional: false, + }, + date: { + type: 'string', + description: 'date', + optional: true, + }, + }, + optional: false, + }, + storageClass: { + type: 'string', + description: 'storageClass Values: InfrequentAccess.', + optional: false, + }, + }, + }, + optional: true, + }, + }, + }, + }, +} as const satisfies Record + +export const RESULT_INFO_OUTPUTS = { + page: { + type: 'number', + description: 'Current page', + optional: true, + }, + per_page: { + type: 'number', + description: 'Page size', + optional: true, + }, + count: { + type: 'number', + description: 'Count on the current page', + optional: true, + }, + total_count: { + type: 'number', + description: 'Total matching resources', + optional: true, + }, + total_pages: { + type: 'number', + description: 'Total pages', + optional: true, + }, + cursor: { + type: 'string', + description: 'Pagination cursor', + optional: true, + }, + cursors: { + type: 'json', + description: 'Directional pagination cursors', + optional: true, + properties: { + before: { + type: 'string', + optional: true, + }, + after: { + type: 'string', + optional: true, + }, + }, + }, +} as const satisfies Record + +export const RULESET_OUTPUTS = { + description: { + type: 'string', + description: 'An informative description of the ruleset.', + nullable: true, + }, + id: { + type: 'string', + description: 'The unique ID of the ruleset.', + nullable: true, + }, + last_updated: { + type: 'string', + description: 'The timestamp of when the ruleset was last modified.', + nullable: true, + }, + name: { + type: 'string', + description: 'The human-readable name of the ruleset.', + nullable: true, + }, + version: { + type: 'string', + description: 'The version of the ruleset.', + nullable: true, + }, + kind: { + type: 'string', + description: 'The kind of the ruleset. Values: managed, custom, root, zone.', + nullable: true, + }, + phase: { + type: 'string', + description: 'The phase of the ruleset.', + nullable: true, + }, + rules: { + type: 'array', + description: 'The list of rules in the ruleset.', + items: { + type: 'json', + description: 'rules item', + properties: { + action: { + type: 'string', + description: 'The action to perform when the rule matches.', + }, + action_parameters: { + type: 'json', + description: "The parameters configuring the rule's action.", + properties: { + response: { + type: 'json', + description: 'The response to show when the block is applied.', + properties: { + content: { + type: 'string', + description: 'The content to return.', + optional: false, + }, + content_type: { + type: 'string', + description: 'The type of the content to return.', + optional: false, + }, + status_code: { + type: 'number', + description: 'The status code to return.', + optional: false, + }, + }, + optional: true, + }, + algorithms: { + type: 'array', + description: 'Custom order for compression algorithms.', + items: { + type: 'json', + description: 'Compression algorithm to enable.', + properties: { + name: { + type: 'string', + description: + 'Name of the compression algorithm to enable. Values: none, auto, default, gzip, brotli, zstd.', + optional: true, + }, + }, + }, + optional: true, + }, + id: { + type: 'string', + description: 'The ID of the ruleset to execute.', + optional: true, + }, + matched_data: { + type: 'json', + description: 'The configuration to use for matched data logging.', + properties: { + public_key: { + type: 'string', + description: 'The public key to encrypt matched data logs with.', + optional: false, + }, + }, + optional: true, + }, + overrides: { + type: 'json', + description: 'A set of overrides to apply to the target ruleset.', + properties: { + action: { + type: 'string', + description: + 'An action to override all rules with. This option has lower precedence than rule and category overrides.', + optional: true, + }, + categories: { + type: 'array', + description: + 'A list of category-level overrides. This option has the second-highest precedence after rule-level overrides.', + items: { + type: 'json', + description: 'A category-level override.', + properties: { + action: { + type: 'string', + description: 'The action to override rules in the category with.', + optional: true, + }, + category: { + type: 'string', + description: 'The name of the category to override.', + optional: false, + }, + enabled: { + type: 'boolean', + description: 'Whether to enable execution of rules in the category.', + optional: true, + }, + sensitivity_level: { + type: 'string', + description: + 'The sensitivity level to use for rules in the category. This option is only applicable for DDoS phases. Values: default, medium, low, eoff.', + optional: true, + }, + }, + }, + optional: true, + }, + enabled: { + type: 'boolean', + description: + 'Whether to enable execution of all rules. This option has lower precedence than rule and category overrides.', + optional: true, + }, + rules: { + type: 'array', + description: + 'A list of rule-level overrides. This option has the highest precedence.', + items: { + type: 'json', + description: 'A rule-level override.', + properties: { + action: { + type: 'string', + description: 'The action to override the rule with.', + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether to enable execution of the rule.', + optional: true, + }, + id: { + type: 'string', + description: 'The ID of the rule to override.', + optional: false, + }, + score_threshold: { + type: 'number', + description: 'The score threshold to use for the rule.', + optional: true, + }, + sensitivity_level: { + type: 'string', + description: + 'The sensitivity level to use for the rule. This option is only applicable for DDoS phases. Values: default, medium, low, eoff.', + optional: true, + }, + }, + }, + optional: true, + }, + sensitivity_level: { + type: 'string', + description: + 'A sensitivity level to set for all rules. This option has lower precedence than rule and category overrides and is only applicable for DDoS phases. Values: default, medium, low, eoff.', + optional: true, + }, + }, + optional: true, + }, + cookie_fields: { + type: 'array', + description: 'The cookie fields to log.', + items: { + type: 'json', + description: 'The cookie field to log.', + properties: { + name: { + type: 'string', + description: 'The name of the cookie.', + optional: false, + }, + }, + }, + optional: true, + }, + raw_response_fields: { + type: 'array', + description: 'The raw response fields to log.', + items: { + type: 'json', + description: 'The raw response field to log.', + properties: { + name: { + type: 'string', + description: 'The name of the response header.', + optional: false, + }, + preserve_duplicates: { + type: 'boolean', + description: 'Whether to log duplicate values of the same header.', + optional: true, + }, + }, + }, + optional: true, + }, + request_fields: { + type: 'array', + description: 'The raw request fields to log.', + items: { + type: 'json', + description: 'The raw request field to log.', + properties: { + name: { + type: 'string', + description: 'The name of the header.', + optional: false, + }, + }, + }, + optional: true, + }, + response_fields: { + type: 'array', + description: 'The transformed response fields to log.', + items: { + type: 'json', + description: 'The transformed response field to log.', + properties: { + name: { + type: 'string', + description: 'The name of the response header.', + optional: false, + }, + preserve_duplicates: { + type: 'boolean', + description: 'Whether to log duplicate values of the same header.', + optional: true, + }, + }, + }, + optional: true, + }, + transformed_request_fields: { + type: 'array', + description: 'The transformed request fields to log.', + items: { + type: 'json', + description: 'The transformed request field to log.', + properties: { + name: { + type: 'string', + description: 'The name of the header.', + optional: false, + }, + }, + }, + optional: true, + }, + from_list: { + type: 'json', + description: 'A redirect based on a bulk list lookup.', + properties: { + key: { + type: 'string', + description: 'An expression that evaluates to the list lookup key.', + optional: false, + }, + name: { + type: 'string', + description: 'The name of the list to match against.', + optional: false, + }, + }, + optional: true, + }, + from_value: { + type: 'json', + description: 'A redirect based on the request properties.', + properties: { + preserve_query_string: { + type: 'boolean', + description: 'Whether to keep the query string of the original request.', + optional: true, + }, + status_code: { + type: 'number', + description: + 'The status code to use for the redirect. Values: 301, 302, 303, 307, 308.', + optional: true, + }, + target_url: { + type: 'json', + description: 'A URL to redirect the request to.', + properties: { + expression: { + type: 'string', + description: + 'An expression that evaluates to a URL to redirect the request to.', + optional: true, + }, + value: { + type: 'string', + description: 'A URL to redirect the request to.', + optional: true, + }, + }, + optional: false, + }, + }, + optional: true, + }, + headers: { + type: 'json', + description: 'A map of headers to rewrite.', + optional: true, + }, + uri: { + type: 'json', + description: 'A URI query rewrite.', + properties: { + path: { + type: 'json', + description: 'A URI path rewrite.', + properties: { + expression: { + type: 'string', + description: + 'An expression that evaluates to a value to rewrite the URI path to.', + optional: true, + }, + value: { + type: 'string', + description: 'A value to rewrite the URI path to.', + optional: true, + }, + }, + optional: true, + }, + query: { + type: 'json', + description: 'A URI query rewrite.', + properties: { + expression: { + type: 'string', + description: + 'An expression that evaluates to a value to rewrite the URI query to.', + optional: true, + }, + value: { + type: 'string', + description: 'A value to rewrite the URI query to.', + optional: true, + }, + }, + optional: true, + }, + origin: { + type: 'boolean', + description: 'Whether to propagate the rewritten URI to origin.', + optional: true, + }, + }, + optional: true, + }, + host_header: { + type: 'string', + description: 'A value to rewrite the HTTP host header to.', + optional: true, + }, + origin: { + type: 'json', + description: 'An origin to route to.', + properties: { + host: { + type: 'string', + description: 'A resolved host to route to.', + optional: true, + }, + port: { + type: 'number', + description: 'A destination port to route to.', + optional: true, + }, + }, + optional: true, + }, + sni: { + type: 'json', + description: 'A Server Name Indication (SNI) override.', + properties: { + value: { + type: 'string', + description: 'A value to override the SNI to.', + optional: false, + }, + }, + optional: true, + }, + increment: { + type: 'number', + description: + 'A delta to change the score by, which can be either positive or negative.', + optional: true, + }, + content_type: { + type: 'string', + description: + 'The content type header to set with the error response. Values: application/json, text/html, text/plain, text/xml.', + optional: true, + }, + status_code: { + type: 'number', + description: 'The status code to use for the error.', + optional: true, + }, + content: { + type: 'string', + description: 'The response content.', + optional: true, + }, + asset_name: { + type: 'string', + description: 'The name of a custom asset to serve as the error response.', + optional: true, + }, + immutable: { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + 'max-age': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + value: { + type: 'number', + description: 'The duration value in seconds for the directive.', + optional: true, + }, + }, + optional: true, + }, + 'must-revalidate': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + 'must-understand': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + 'no-cache': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + qualifiers: { + type: 'array', + description: + 'Optional list of header names to qualify the directive (e.g., for "private" or "no-cache" directives).', + items: { + type: 'string', + description: 'A header name to qualify the directive.', + }, + optional: true, + }, + }, + optional: true, + }, + 'no-store': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + 'no-transform': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + private: { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + qualifiers: { + type: 'array', + description: + 'Optional list of header names to qualify the directive (e.g., for "private" or "no-cache" directives).', + items: { + type: 'string', + description: 'A header name to qualify the directive.', + }, + optional: true, + }, + }, + optional: true, + }, + 'proxy-revalidate': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + public: { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + }, + optional: true, + }, + 's-maxage': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + value: { + type: 'number', + description: 'The duration value in seconds for the directive.', + optional: true, + }, + }, + optional: true, + }, + 'stale-if-error': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + value: { + type: 'number', + description: 'The duration value in seconds for the directive.', + optional: true, + }, + }, + optional: true, + }, + 'stale-while-revalidate': { + type: 'json', + description: 'Remove the directive.', + properties: { + cloudflare_only: { + type: 'boolean', + description: + 'Whether the directive should only be applied to the Cloudflare CDN cache.', + optional: true, + }, + operation: { + type: 'string', + description: + 'The operation to perform on the cache-control directive. Values: set, remove.', + optional: false, + }, + value: { + type: 'number', + description: 'The duration value in seconds for the directive.', + optional: true, + }, + }, + optional: true, + }, + additional_cacheable_ports: { + type: 'array', + description: 'A list of additional ports that caching should be enabled on.', + items: { + type: 'number', + description: 'A port to enable caching on.', + }, + optional: true, + }, + browser_ttl: { + type: 'json', + description: + 'How long client browsers should cache the response. Cloudflare cache purge will not purge content cached on client browsers, so high browser TTLs may lead to stale content.', + properties: { + default: { + type: 'number', + description: + 'The browser TTL (in seconds) if you choose the "override_origin" mode.', + optional: true, + }, + mode: { + type: 'string', + description: + 'The browser TTL mode. Values: respect_origin, bypass_by_default, override_origin, bypass.', + optional: false, + }, + }, + optional: true, + }, + cache: { + type: 'boolean', + description: + "Whether the request's response from the origin is eligible for caching. Caching itself will still depend on the cache control header and your other caching configurations.", + optional: true, + }, + cache_key: { + type: 'json', + description: + 'Which components of the request are included in or excluded from the cache key Cloudflare uses to store the response in cache.', + properties: { + cache_by_device_type: { + type: 'boolean', + description: + "Whether to separate cached content based on the visitor's device type.", + optional: true, + }, + cache_deception_armor: { + type: 'boolean', + description: + 'Whether to protect from web cache deception attacks, while allowing static assets to be cached.', + optional: true, + }, + custom_key: { + type: 'json', + description: + 'Which components of the request are included or excluded from the cache key.', + properties: { + cookie: { + type: 'json', + description: 'Which cookies to include in the cache key.', + properties: { + check_presence: { + type: 'array', + description: + 'A list of cookies to check for the presence of. The presence of these cookies is included in the cache key.', + items: { + type: 'string', + description: 'The name of the cookie to check for the presence of.', + }, + optional: true, + }, + include: { + type: 'array', + description: 'A list of cookies to include in the cache key.', + items: { + type: 'string', + description: 'The name of the cookie to include.', + }, + optional: true, + }, + }, + optional: true, + }, + header: { + type: 'json', + description: 'Which headers to include in the cache key.', + properties: { + check_presence: { + type: 'array', + description: + 'A list of headers to check for the presence of. The presence of these headers is included in the cache key.', + items: { + type: 'string', + description: 'The name of the header to check for the presence of.', + }, + optional: true, + }, + contains: { + type: 'json', + description: + 'A mapping of header names to a list of values. If a header is present in the request and contains any of the values provided, its value is included in the cache key.', + optional: true, + }, + exclude_origin: { + type: 'boolean', + description: 'Whether to exclude the origin header in the cache key.', + optional: true, + }, + include: { + type: 'array', + description: 'A list of headers to include in the cache key.', + items: { + type: 'string', + description: 'The name of the header to include.', + }, + optional: true, + }, + }, + optional: true, + }, + host: { + type: 'json', + description: 'How to use the host in the cache key.', + properties: { + resolved: { + type: 'boolean', + description: 'Whether to use the resolved host in the cache key.', + optional: true, + }, + }, + optional: true, + }, + query_string: { + type: 'json', + description: + 'Which query string parameters to include in or exclude from the cache key.', + properties: { + exclude: { + type: 'json', + description: + 'Which query string parameters to exclude from the cache key.', + properties: { + all: { + type: 'boolean', + description: + 'Whether to exclude all query string parameters from the cache key. Values: True.', + optional: true, + }, + list: { + type: 'array', + description: + 'A list of query string parameters to exclude from the cache key.', + items: { + type: 'string', + description: 'The name of the query string parameter to exclude.', + }, + optional: true, + }, + }, + optional: true, + }, + include: { + type: 'json', + description: 'Which query string parameters to include in the cache key.', + properties: { + all: { + type: 'boolean', + description: + 'Whether to include all query string parameters in the cache key. Values: True.', + optional: true, + }, + list: { + type: 'array', + description: + 'A list of query string parameters to include in the cache key.', + items: { + type: 'string', + description: 'The name of the query string parameter to include.', + }, + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + user: { + type: 'json', + description: + 'How to use characteristics of the request user agent in the cache key.', + properties: { + device_type: { + type: 'boolean', + description: + "Whether to use the user agent's device type in the cache key.", + optional: true, + }, + geo: { + type: 'boolean', + description: "Whether to use the user agents's country in the cache key.", + optional: true, + }, + lang: { + type: 'boolean', + description: "Whether to use the user agent's language in the cache key.", + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + ignore_query_strings_order: { + type: 'boolean', + description: + 'Whether to treat requests with the same query parameters the same, regardless of the order those query parameters are in.', + optional: true, + }, + }, + optional: true, + }, + cache_reserve: { + type: 'json', + description: + "Settings to determine whether the request's response from origin is eligible for Cache Reserve (requires a Cache Reserve add-on plan).", + properties: { + eligible: { + type: 'boolean', + description: + 'Whether Cache Reserve is enabled. If this is true and a request meets eligibility criteria, Cloudflare will write the resource to Cache Reserve.', + optional: false, + }, + minimum_file_size: { + type: 'number', + description: 'The minimum file size eligible for storage in Cache Reserve.', + optional: true, + }, + }, + optional: true, + }, + edge_ttl: { + type: 'json', + description: 'How long the Cloudflare edge network should cache the response.', + properties: { + default: { + type: 'number', + description: + 'The edge TTL (in seconds) if you choose the "override_origin" mode.', + optional: true, + }, + mode: { + type: 'string', + description: + 'The edge TTL mode. Values: respect_origin, bypass_by_default, override_origin.', + optional: false, + }, + status_code_ttl: { + type: 'array', + description: + 'A list of TTLs to apply to specific status codes or status code ranges.', + items: { + type: 'json', + description: 'status code ttl item', + properties: { + status_code: { + type: 'number', + description: 'A single status code to apply the TTL to.', + optional: true, + }, + status_code_range: { + type: 'json', + description: 'A range of status codes to apply the TTL to.', + properties: { + from: { + type: 'number', + description: 'The lower bound of the range.', + optional: true, + }, + to: { + type: 'number', + description: 'The upper bound of the range.', + optional: true, + }, + }, + optional: true, + }, + value: { + type: 'number', + description: + 'The time to cache the response for (in seconds). A value of 0 is equivalent to setting the cache control header with the value "no-cache". A value of -1 is equivalent to setting the cache control header with the value of "no-store".', + optional: false, + }, + }, + }, + optional: true, + }, + }, + optional: true, + }, + origin_cache_control: { + type: 'boolean', + description: 'Whether Cloudflare will aim to strictly adhere to RFC 7234.', + optional: true, + }, + origin_error_page_passthru: { + type: 'boolean', + description: + 'Whether to generate Cloudflare error pages for issues from the origin server.', + optional: true, + }, + origin_range_requests: { + type: 'json', + description: + 'Controls whether Cloudflare fetches a large asset from the origin as a series of range requests instead of one whole-body request.', + properties: { + mode: { + type: 'string', + description: + 'Whether to use range requests. `default` is the behaviour the zone gets without this rule. Values: on, off, default.', + optional: false, + }, + }, + optional: true, + }, + read_timeout: { + type: 'number', + description: + 'A timeout value between two successive read operations to use for your origin server. Historically, the timeout value between two read options from Cloudflare to an origin server is 100 seconds. If you are attempting to reduce HTTP 524 errors because of timeouts from an origin server, try increasing this timeout value.', + optional: true, + }, + respect_strong_etags: { + type: 'boolean', + description: + 'Whether Cloudflare should respect strong ETag (entity tag) headers. If false, Cloudflare converts strong ETag headers to weak ETag headers.', + optional: true, + }, + serve_stale: { + type: 'json', + description: 'When to serve stale content from cache.', + properties: { + disable_stale_while_updating: { + type: 'boolean', + description: + 'Whether Cloudflare should disable serving stale content while getting the latest content from the origin.', + optional: true, + }, + }, + optional: true, + }, + shared_dictionary: { + type: 'json', + description: + 'Configuration for shared dictionary compression. When set, Cloudflare injects Use-As-Dictionary headers on matching cacheable responses.', + properties: { + match_pattern: { + type: 'string', + description: + 'URL pattern for the Use-As-Dictionary match field. This pattern specifies which URLs can use this response as a dictionary.', + optional: false, + }, + }, + optional: true, + }, + strip_etags: { + type: 'boolean', + description: 'Whether to strip ETag headers from the origin response before caching.', + optional: true, + }, + strip_last_modified: { + type: 'boolean', + description: + 'Whether to strip Last-Modified headers from the origin response before caching.', + optional: true, + }, + strip_set_cookie: { + type: 'boolean', + description: + 'Whether to strip Set-Cookie headers from the origin response before caching.', + optional: true, + }, + vary: { + type: 'json', + description: + 'Controls how cached responses vary based on request headers. `default` is required by the API and applies to any Vary response header that does not have a per-header override.', + properties: { + default: { + type: 'json', + description: + 'Controls how response Vary headers without a per-header override contribute to the cache key.', + properties: { + action: { + type: 'string', + description: + 'How the header value is treated when building the cache key. Values: bypass, passthrough, normalize.', + optional: false, + }, + }, + optional: true, + }, + headers: { + type: 'json', + description: + 'A mapping of lowercase request header names to their vary configuration.', + optional: true, + }, + }, + optional: true, + }, + operation: { + type: 'string', + description: 'The operation to perform on the cache tags. Values: add, remove, set.', + optional: true, + }, + values: { + type: 'array', + description: 'A list of cache tag values.', + items: { + type: 'string', + description: 'A cache tag value.', + }, + optional: true, + }, + expression: { + type: 'string', + description: 'An expression that evaluates to an array of cache tag values.', + optional: true, + }, + automatic_https_rewrites: { + type: 'boolean', + description: 'Whether to enable Automatic HTTPS Rewrites.', + optional: true, + }, + autominify: { + type: 'json', + description: 'Which file extensions to minify automatically.', + properties: { + css: { + type: 'boolean', + description: 'Whether to minify CSS files.', + optional: true, + }, + html: { + type: 'boolean', + description: 'Whether to minify HTML files.', + optional: true, + }, + js: { + type: 'boolean', + description: 'Whether to minify JavaScript files.', + optional: true, + }, + }, + optional: true, + }, + bic: { + type: 'boolean', + description: 'Whether to enable Browser Integrity Check (BIC).', + optional: true, + }, + content_converter: { + type: 'boolean', + description: 'Whether to enable content conversion (e.g., HTML to Markdown).', + optional: true, + }, + disable_apps: { + type: 'boolean', + description: 'Whether to disable Cloudflare Apps. Values: True.', + optional: true, + }, + disable_pay_per_crawl: { + type: 'boolean', + description: 'Whether to disable Pay Per Crawl. Values: True.', + optional: true, + }, + disable_rum: { + type: 'boolean', + description: 'Whether to disable Real User Monitoring (RUM). Values: True.', + optional: true, + }, + disable_zaraz: { + type: 'boolean', + description: 'Whether to disable Zaraz. Values: True.', + optional: true, + }, + email_obfuscation: { + type: 'boolean', + description: 'Whether to enable Email Obfuscation.', + optional: true, + }, + fonts: { + type: 'boolean', + description: 'Whether to enable Cloudflare Fonts.', + optional: true, + }, + hotlink_protection: { + type: 'boolean', + description: 'Whether to enable Hotlink Protection.', + optional: true, + }, + mirage: { + type: 'boolean', + description: 'Whether to enable Mirage.', + optional: true, + }, + opportunistic_encryption: { + type: 'boolean', + description: 'Whether to enable Opportunistic Encryption.', + optional: true, + }, + polish: { + type: 'string', + description: 'The Polish level to configure. Values: off, lossless, lossy, webp.', + optional: true, + }, + redirects_for_ai_training: { + type: 'boolean', + description: + 'Whether to redirect verified AI training crawlers to canonical URLs found in the HTML response.', + optional: true, + }, + request_body_buffering: { + type: 'string', + description: 'The request body buffering mode. Values: none, standard, full.', + optional: true, + }, + response_body_buffering: { + type: 'string', + description: 'The response body buffering mode. Values: none, standard.', + optional: true, + }, + rocket_loader: { + type: 'boolean', + description: 'Whether to enable Rocket Loader.', + optional: true, + }, + security_level: { + type: 'string', + description: + 'The Security Level to configure. Values: off, essentially_off, low, medium, high, under_attack.', + optional: true, + }, + server_side_excludes: { + type: 'boolean', + description: 'Whether to enable Server-Side Excludes.', + optional: true, + }, + ssl: { + type: 'string', + description: + 'The SSL level to configure. Values: off, flexible, full, strict, origin_pull.', + optional: true, + }, + sxg: { + type: 'boolean', + description: 'Whether to enable Signed Exchanges (SXG).', + optional: true, + }, + webmcp_enabled: { + type: 'boolean', + description: + "Whether to serve the WebMCP bridge script, which exposes the page's tools to browser AI agents.", + optional: true, + }, + webmcp_packs: { + type: 'array', + description: + 'Bundled WebMCP tool packs to activate for matching requests. An empty array disables all packs. Omitting this parameter leaves the pack selection unchanged. Does not enable the WebMCP bridge itself.', + items: { + type: 'string', + description: 'A tool-pack identifier understood by the WebMCP interceptor.', + }, + optional: true, + }, + phase: { + type: 'string', + description: + 'A phase to skip the execution of. This option is only compatible with the products option. Values: current.', + optional: true, + }, + phases: { + type: 'array', + description: + 'A list of phases to skip the execution of. This option is incompatible with the rulesets option.', + items: { + type: 'string', + description: 'The phase to skip the execution of.', + }, + optional: true, + }, + products: { + type: 'array', + description: 'A list of legacy security products to skip the execution of.', + items: { + type: 'string', + description: + 'The name of a legacy security product to skip the execution of. Values: bic, hot, rateLimit, securityLevel, uaBlock, waf, zoneLockdown.', + }, + optional: true, + }, + rules: { + type: 'json', + description: + 'A mapping of ruleset IDs to a list of rule IDs in that ruleset to skip the execution of. This option is incompatible with the ruleset option.', + optional: true, + }, + ruleset: { + type: 'string', + description: + 'A ruleset to skip the execution of. This option is incompatible with the rulesets option. Values: current.', + optional: true, + }, + rulesets: { + type: 'array', + description: + 'A list of ruleset IDs to skip the execution of. This option is incompatible with the ruleset and phases options.', + items: { + type: 'string', + description: 'The ID of a ruleset to skip the execution of.', + }, + optional: true, + }, + link_maze: { + type: 'json', + description: 'Enables the link maze transformation on the response.', + optional: true, + }, + }, + nullable: true, + }, + categories: { + type: 'array', + description: 'The categories of the rule.', + items: { + type: 'string', + description: 'The category of a rule.', + }, + }, + description: { + type: 'string', + description: 'An informative description of the rule.', + }, + enabled: { + type: 'boolean', + description: 'Whether the rule should be executed.', + }, + exposed_credential_check: { + type: 'json', + description: 'Configuration for exposed credential checking.', + properties: { + password_expression: { + type: 'string', + description: 'An expression that selects the password used in the credentials check.', + optional: false, + }, + username_expression: { + type: 'string', + description: 'An expression that selects the user ID used in the credentials check.', + optional: false, + }, + }, + nullable: true, + }, + expression: { + type: 'string', + description: 'The expression defining which traffic will match the rule.', + }, + id: { + type: 'string', + description: 'The unique ID of the rule.', + }, + last_updated: { + type: 'string', + description: 'The timestamp of when the rule was last modified.', + nullable: true, + }, + logging: { + type: 'json', + description: "An object configuring the rule's logging behavior.", + properties: { + enabled: { + type: 'boolean', + description: 'Whether to generate a log when the rule matches.', + optional: false, + }, + }, + nullable: true, + }, + ratelimit: { + type: 'json', + description: "An object configuring the rule's rate limit behavior.", + properties: { + characteristics: { + type: 'array', + description: + 'Characteristics of the request on which the rate limit counter will be incremented.', + items: { + type: 'string', + description: 'The characteristic of the request.', + }, + optional: false, + }, + counting_expression: { + type: 'string', + description: + "An expression that defines when the rate limit counter should be incremented. It defaults to the same as the rule's expression.", + optional: true, + }, + mitigation_timeout: { + type: 'number', + description: + 'Period of time in seconds after which the action will be disabled following its first execution.', + optional: true, + }, + period: { + type: 'number', + description: 'Period in seconds over which the counter is being incremented.', + optional: false, + }, + requests_per_period: { + type: 'number', + description: + 'The threshold of requests per period after which the action will be executed for the first time.', + optional: true, + }, + requests_to_origin: { + type: 'boolean', + description: 'Whether counting is only performed when an origin is reached.', + optional: true, + }, + score_per_period: { + type: 'number', + description: + 'The score threshold per period for which the action will be executed the first time.', + optional: true, + }, + score_response_header_name: { + type: 'string', + description: + 'A response header name provided by the origin, which contains the score to increment rate limit counter with.', + optional: true, + }, + }, + nullable: true, + }, + ref: { + type: 'string', + description: "The reference of the rule (the rule's ID by default).", + nullable: true, + }, + version: { + type: 'string', + description: 'The version of the rule.', + nullable: true, + }, + }, + }, + }, +} as const satisfies Record + +export const SERVICE_TOKEN_OUTPUTS = { + client_id: { + type: 'string', + description: + 'The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header.', + nullable: true, + }, + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + duration: { + type: 'string', + description: + 'The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us (or \u00b5s), ms, s, m, h. The default is 1 year in hours (8760h).', + nullable: true, + }, + enabled: { + type: 'boolean', + description: 'Whether the service token is enabled.', + nullable: true, + }, + expires_at: { + type: 'string', + description: 'expires at', + nullable: true, + }, + id: { + type: 'string', + description: 'UUID.', + nullable: true, + }, + last_seen_at: { + type: 'string', + description: 'last seen at', + nullable: true, + }, + leak_report_url: { + type: 'string', + description: + 'Where the leaked `client_secret` was found, if provided by the reporter. Omitted if the token has not been reported as leaked.', + nullable: true, + }, + leak_reported_at: { + type: 'string', + description: + "When a secret scanning partner reported this service token's `client_secret` as leaked. A leaked service token is disabled and must be rotated before it can be re-enabled. Cleared once the secret is rotated. Omitted if the token has not been reported as leaked.", + nullable: true, + }, + leak_reporter: { + type: 'string', + description: + 'The secret scanning partner that reported the leak. Omitted if the token has not been reported as leaked.', + nullable: true, + }, + name: { + type: 'string', + description: 'The name of the service token.', + nullable: true, + }, + updated_at: { + type: 'string', + description: 'updated at', + nullable: true, + }, +} as const satisfies Record + +export const SERVICE_TOKEN_SECRET_OUTPUTS = { + client_id: { + type: 'string', + description: + 'The Client ID for the service token. Access will check for this value in the `CF-Access-Client-ID` request header.', + nullable: true, + }, + client_secret: { + type: 'string', + description: + 'The Client Secret for the service token. Access will check for this value in the `CF-Access-Client-Secret` request header.', + nullable: true, + }, + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + duration: { + type: 'string', + description: + 'The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us (or \u00b5s), ms, s, m, h. The default is 1 year in hours (8760h).', + nullable: true, + }, + enabled: { + type: 'boolean', + description: 'Whether the service token is enabled.', + nullable: true, + }, + id: { + type: 'string', + description: 'The ID of the service token.', + nullable: true, + }, + name: { + type: 'string', + description: 'The name of the service token.', + nullable: true, + }, + updated_at: { + type: 'string', + description: 'updated at', + nullable: true, + }, + expires_at: { + type: 'string', + description: + 'Service token expires at when returned by Cloudflare; retained for existing workflows', + nullable: true, + }, + last_seen_at: { + type: 'string', + description: + 'Service token last seen at when returned by Cloudflare; retained for existing workflows', + nullable: true, + }, +} as const satisfies Record + +export const TUNNEL_CONFIGURATION_OUTPUTS = { + account_id: { + type: 'string', + description: 'Identifier.', + nullable: true, + }, + config: { + type: 'json', + description: 'The tunnel configuration and ingress rules.', + properties: { + ingress: { + type: 'array', + description: + 'List of public hostname definitions. At least one ingress rule needs to be defined for the tunnel.', + items: { + type: 'json', + description: 'Public hostname', + properties: { + hostname: { + type: 'string', + description: 'Public hostname for this service.', + optional: false, + }, + originRequest: + TUNNEL_CONFIGURATION_OUTPUTS_CONFIG_PROPERTIES_INGRESS_ITEMS_PROPERTIES_ORIGINREQUEST_FIELDS, + path: { + type: 'string', + description: 'Requests with this path route to this public hostname.', + optional: true, + }, + service: { + type: 'string', + description: + "Protocol and address of destination server. Supported protocols: http://, https://, unix://, tcp://, ssh://, rdp://, unix+tls://, smb://. Alternatively can return a HTTP status code http_status:[code] e.g. 'http_status:404'.", + optional: false, + }, + }, + }, + optional: true, + }, + originRequest: + TUNNEL_CONFIGURATION_OUTPUTS_CONFIG_PROPERTIES_INGRESS_ITEMS_PROPERTIES_ORIGINREQUEST_FIELDS, + 'warp-routing': { + type: 'json', + description: + 'Enable private network access from WARP users to private network routes. This is enabled if the tunnel has an assigned route.', + properties: { + enabled: { + type: 'boolean', + description: 'enabled', + optional: true, + }, + }, + optional: true, + }, + }, + nullable: true, + }, + created_at: { + type: 'string', + description: 'created at', + nullable: true, + }, + source: { + type: 'string', + description: + "Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel's configuration on the Zero Trust dashboard. Values: local, cloudflare.", + nullable: true, + }, + tunnel_id: { + type: 'string', + description: 'UUID of the tunnel.', + nullable: true, + }, + version: { + type: 'number', + description: 'The version of the Tunnel Configuration.', + nullable: true, + }, +} as const satisfies Record + +export const TUNNEL_OUTPUTS = { + account_tag: { + type: 'string', + description: 'Cloudflare account ID', + nullable: true, + }, + config_src: { + type: 'string', + description: + 'Indicates if this is a locally or remotely configured tunnel. If `local`, manage the tunnel using a YAML file on the origin machine. If `cloudflare`, manage the tunnel on the Zero Trust dashboard. Values: local, cloudflare.', + nullable: true, + }, + connections: { + type: 'array', + description: "The Cloudflare Tunnel connections between your origin and Cloudflare's edge.", + items: { + type: 'json', + description: 'connections item', + properties: { + client_id: { + type: 'string', + description: 'UUID of the Cloudflare Tunnel connector.', + optional: true, + }, + client_version: { + type: 'string', + description: 'The cloudflared version used to establish this connection.', + optional: true, + }, + colo_name: { + type: 'string', + description: 'The Cloudflare data center used for this connection.', + optional: true, + }, + id: { + type: 'string', + description: 'UUID of the Cloudflare Tunnel connection.', + optional: true, + }, + is_pending_reconnect: { + type: 'boolean', + description: + 'Cloudflare continues to track connections for several minutes after they disconnect. This is an optimization to improve latency and reliability of reconnecting. If `true`, the connection has disconnected but is still being tracked. If `false`, the connection is actively serving traffic.', + optional: true, + }, + opened_at: { + type: 'string', + description: 'Timestamp of when the connection was established.', + optional: true, + }, + origin_ip: { + type: 'string', + description: 'The public IP address of the host running cloudflared.', + optional: true, + }, + uuid: { + type: 'string', + description: 'UUID of the Cloudflare Tunnel connection.', + optional: true, + }, + }, + }, + }, + conns_active_at: { + type: 'string', + description: + "Timestamp of when the tunnel established at least one connection to Cloudflare's edge. If `null`, the tunnel is inactive.", + nullable: true, + }, + conns_inactive_at: { + type: 'string', + description: + "Timestamp of when the tunnel became inactive (no connections to Cloudflare's edge). If `null`, the tunnel is active.", + nullable: true, + }, + created_at: { + type: 'string', + description: 'Timestamp of when the resource was created.', + nullable: true, + }, + deleted_at: { + type: 'string', + description: + 'Timestamp of when the resource was deleted. If `null`, the resource has not been deleted.', + nullable: true, + }, + id: { + type: 'string', + description: 'UUID of the tunnel.', + nullable: true, + }, + metadata: { + type: 'json', + description: 'Metadata associated with the tunnel.', + nullable: true, + }, + name: { + type: 'string', + description: 'A user-friendly name for a tunnel.', + nullable: true, + }, + remote_config: { + type: 'boolean', + description: + 'If `true`, the tunnel can be configured remotely from the Zero Trust dashboard. If `false`, the tunnel must be configured locally on the origin machine.', + nullable: true, + }, + status: { + type: 'string', + description: 'The status of the tunnel.', + nullable: true, + }, + tun_type: { + type: 'string', + description: + 'The type of tunnel. Values: cfd_tunnel, warp_connector, warp, magic, ip_sec, gre, cni.', + nullable: true, + }, +} as const satisfies Record + +export const WORKER_ROUTE_OUTPUTS = { + id: { + type: 'string', + description: 'Identifier.', + nullable: true, + }, + pattern: { + type: 'string', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', + nullable: true, + }, + script: { + type: 'string', + description: 'Name of the script to run if the route matches.', + nullable: true, + }, +} as const satisfies Record + +export const WORKER_SCRIPT_OUTPUTS = { + cache_options: { + type: 'json', + description: + 'Global CacheW configuration for the Worker. When caching is on, the platform provisions a `cloudflare.app` zone for the Worker. A `type: worker` entry in the `exports` map can override this value for a single entrypoint.', + properties: { + cross_version_cache: { + type: 'boolean', + description: + 'Whether cached responses are shared across Worker version uploads. This is independent of `enabled`. It can stay true while caching is off, so the preference survives turning caching off and back on.', + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether caching is enabled for this Worker.', + optional: false, + }, + }, + nullable: true, + }, + compatibility_date: { + type: 'string', + description: + 'Date indicating targeted support in the Workers runtime. Backwards incompatible fixes to the runtime following this date will not affect this Worker.', + nullable: true, + }, + compatibility_flags: { + type: 'array', + description: + 'Flags that enable or disable certain features in the Workers runtime. Used to enable upcoming features or opt in or out of specific changes not included in a `compatibility_date`.', + items: { + type: 'string', + description: 'Flag that enables or disables a specific feature in the Workers runtime.', + }, + }, + created_on: { + type: 'string', + description: 'When the script was created.', + nullable: true, + }, + etag: { + type: 'string', + description: 'Hashed script content, can be used in a If-None-Match header when updating.', + nullable: true, + }, + exports: { + type: 'json', + description: + 'Declarative exports for the Worker, keyed by export name. Worker entrypoint entries (`type: worker`) carry cache configuration for that entrypoint. Durable Object entries (`type: durable-object`) are also configured here and drive namespace reconciliation. At most 100 entries; class names are at most 128 characters.', + nullable: true, + }, + handlers: { + type: 'array', + description: 'The names of handlers exported as part of the default export.', + items: { + type: 'string', + description: 'handlers item', + }, + }, + has_assets: { + type: 'boolean', + description: 'Whether a Worker contains assets.', + nullable: true, + }, + has_modules: { + type: 'boolean', + description: 'Whether a Worker contains modules.', + nullable: true, + }, + id: { + type: 'string', + description: 'The name used to identify the script.', + nullable: true, + }, + last_deployed_from: { + type: 'string', + description: 'The client most recently used to deploy this Worker.', + nullable: true, + }, + logpush: { + type: 'boolean', + description: 'Whether Logpush is turned on for the Worker.', + nullable: true, + }, + migration_tag: { + type: 'string', + description: + 'The tag of the Durable Object migration that was most recently applied for this Worker.', + nullable: true, + }, + modified_on: { + type: 'string', + description: 'When the script was last modified.', + nullable: true, + }, + named_handlers: { + type: 'array', + description: + 'Named exports, such as Durable Object class implementations and named entrypoints.', + items: { + type: 'json', + description: 'named handlers item', + properties: { + handlers: { + type: 'array', + description: 'The names of handlers exported as part of the named export.', + items: { + type: 'string', + description: 'handlers item', + }, + optional: true, + }, + name: { + type: 'string', + description: 'The name of the export.', + optional: true, + }, + }, + }, + }, + observability: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_FIELDS, + placement: { + type: 'json', + description: + "Configuration for [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host.", + properties: { + mode: { + type: 'string', + description: 'Targeted placement mode. Values: smart, targeted.', + optional: true, + }, + region: { + type: 'string', + description: "Cloud region for targeted placement in format 'provider:region'.", + optional: true, + }, + hostname: { + type: 'string', + description: 'HTTP hostname for targeted placement.', + optional: true, + }, + host: { + type: 'string', + description: 'TCP host and port for targeted placement.', + optional: true, + }, + target: { + type: 'array', + description: 'Array of placement targets (currently limited to single target).', + items: { + type: 'json', + description: 'A target to run your Worker near.', + properties: { + region: { + type: 'string', + description: "Cloud region in format 'provider:region'.", + optional: true, + }, + hostname: { + type: 'string', + description: 'HTTP hostname for targeted placement.', + optional: true, + }, + host: { + type: 'string', + description: 'TCP host:port for targeted placement.', + optional: true, + }, + }, + }, + optional: true, + }, + last_analyzed_at: { + type: 'string', + description: + 'The last time the script was analyzed for [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement).', + optional: true, + }, + status: { + type: 'string', + description: + 'Status of [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement). Values: SUCCESS, UNSUPPORTED_APPLICATION, INSUFFICIENT_INVOCATIONS.', + optional: true, + }, + }, + nullable: true, + }, + placement_mode: { + type: 'string', + description: + "Configuration for [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host. Values: smart, targeted.", + nullable: true, + }, + placement_status: { + type: 'string', + description: + 'Status of [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement). Values: SUCCESS, UNSUPPORTED_APPLICATION, INSUFFICIENT_INVOCATIONS.', + nullable: true, + }, + tag: { + type: 'string', + description: 'The immutable ID of the script.', + nullable: true, + }, + tags: { + type: 'array', + description: 'Tags associated with the Worker.', + items: { + type: 'string', + description: 'tags item', + }, + }, + tail_consumers: { + type: 'array', + description: 'List of Workers that will consume logs from the attached Worker.', + items: { + type: 'json', + description: 'A reference to a script that will consume logs from the attached Worker.', + properties: { + environment: { + type: 'string', + description: 'Optional environment if the Worker utilizes one.', + optional: true, + }, + namespace: { + type: 'string', + description: 'Optional dispatch namespace the script belongs to.', + optional: true, + }, + service: { + type: 'string', + description: 'Name of Worker that is to be the consumer.', + optional: false, + }, + }, + }, + }, + usage_model: { + type: 'string', + description: 'Usage model for the Worker invocations. Values: standard, bundled, unbound.', + nullable: true, + }, + routes: { + type: 'array', + description: 'Routes associated with the Worker.', + items: { + type: 'json', + description: 'routes item', + properties: { + id: { + type: 'string', + description: 'Identifier.', + optional: false, + }, + pattern: { + type: 'string', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', + optional: false, + }, + script: { + type: 'string', + description: 'Name of the script to run if the route matches.', + optional: true, + }, + }, + }, + }, +} as const satisfies Record + +export const WORKER_SETTINGS_OUTPUTS = { + annotations: { + type: 'json', + description: + 'Annotations for the Worker version. Annotations are not inherited across settings updates; omitting this field means the new version will have no annotations.', + properties: { + 'workers/message': { + type: 'string', + description: 'Human-readable message about the version. Truncated to 1000 bytes if longer.', + optional: true, + }, + 'workers/tag': { + type: 'string', + description: 'User-provided identifier for the version. Maximum 100 bytes.', + optional: true, + }, + 'workers/triggered_by': { + type: 'string', + description: + 'Operation that triggered the creation of the version. This is read-only and set by the server.', + optional: true, + }, + }, + nullable: true, + }, + bindings: { + type: 'array', + description: + 'List of bindings attached to a Worker. You can find more about bindings on our docs: https://developers.cloudflare.com/workers/configuration/multipart-upload-metadata/#bindings.', + items: { + type: 'json', + description: 'A K2 stream binding. Available only to accounts enabled for K2.', + properties: { + name: { + type: 'string', + description: 'A JavaScript variable name for the binding.', + optional: false, + }, + type: { + type: 'string', + description: 'The kind of resource that the binding provides.', + optional: false, + }, + instance_name: { + type: 'string', + description: + 'The user-chosen instance name. Must exist at deploy time. The worker can search, chat, update, and manage items/jobs on this instance.', + optional: true, + }, + namespace: { + type: 'string', + description: 'The name of the dispatch namespace.', + optional: true, + }, + dataset: { + type: 'string', + description: 'The name of the dataset to bind to.', + optional: true, + }, + database_id: { + type: 'string', + description: 'Identifier of the D1 database to bind to.', + optional: true, + }, + id: { + type: 'string', + description: 'Identifier of the Hyperdrive connection to bind to.', + optional: true, + }, + part: { + type: 'string', + description: + 'The name of the file containing the WebAssembly module content. Only accepted for `service worker syntax` Workers.', + optional: true, + }, + outbound: { + type: 'json', + description: 'Outbound worker.', + properties: { + params: { + type: 'array', + description: + 'Pass information from the Dispatch Worker to the Outbound Worker through the parameters.', + items: { + type: 'json', + description: 'params item', + properties: { + name: { + type: 'string', + description: 'Name of the parameter.', + optional: false, + }, + }, + }, + optional: true, + }, + worker: { + type: 'json', + description: 'Outbound worker.', + properties: { + entrypoint: { + type: 'string', + description: 'Entrypoint to invoke on the outbound worker.', + optional: true, + }, + environment: { + type: 'string', + description: 'Environment of the outbound worker.', + optional: true, + }, + service: { + type: 'string', + description: 'Name of the outbound worker.', + optional: true, + }, + }, + optional: true, + }, + }, + optional: true, + }, + class_name: { + type: 'string', + description: + 'Class name of the Workflow. Should only be provided if the Workflow belongs to this script.', + optional: true, + }, + dispatch_namespace: { + type: 'string', + description: 'The dispatch namespace the Durable Object script belongs to.', + optional: true, + }, + environment: { + type: 'string', + description: 'Optional environment if the Worker utilizes one.', + optional: true, + }, + namespace_id: { + type: 'string', + description: 'Identifier of the rate limit namespace to bind to.', + optional: true, + }, + script_name: { + type: 'string', + description: + 'Script name that contains the Workflow. If not provided, defaults to this script name.', + optional: true, + }, + old_name: { + type: 'string', + description: + 'The old name of the inherited binding. If set, the binding will be renamed from `old_name` to `name` in the new version. If not set, the binding will keep the same name between versions.', + optional: true, + }, + version_id: { + type: 'string', + description: 'Identifier for the version to inherit the binding from.', + optional: true, + }, + json: { + type: 'json', + description: 'JSON data to use.', + optional: true, + }, + certificate_id: { + type: 'string', + description: 'Identifier of the certificate to bind to.', + optional: true, + }, + text: { + type: 'string', + description: 'The secret value to use.', + optional: true, + }, + pipeline: { + type: 'string', + description: 'Name of the Pipeline to bind to.', + optional: true, + }, + stream: { + type: 'string', + description: 'ID of a K2 stream owned by the account deploying the Worker.', + optional: true, + }, + queue_name: { + type: 'string', + description: 'Name of the Queue to bind to.', + optional: true, + }, + simple: { + type: 'json', + description: 'The rate limit configuration.', + properties: { + limit: { + type: 'number', + description: 'The limit (requests per period).', + optional: false, + }, + mitigation_timeout: { + type: 'number', + description: + 'Duration in seconds to apply the mitigation action after the rate limit is exceeded. Valid values are 0 (disabled), 10, or multiples of 60 up to 86400. Must be greater than or equal to the period when non-zero.', + optional: true, + }, + period: { + type: 'number', + description: 'The period in seconds.', + optional: false, + }, + }, + optional: true, + }, + bucket_name: { + type: 'string', + description: 'R2 bucket to bind to.', + optional: true, + }, + jurisdiction: { + type: 'string', + description: + 'The [jurisdiction](https://developers.cloudflare.com/r2/reference/data-location/#jurisdictional-restrictions) of the R2 bucket. Values: eu, fedramp, fedramp-high, us.', + optional: true, + }, + allowed_destination_addresses: { + type: 'array', + description: 'List of allowed destination addresses.', + items: { + type: 'string', + description: 'allowed destination addresses item', + }, + optional: true, + }, + allowed_sender_addresses: { + type: 'array', + description: 'List of allowed sender addresses.', + items: { + type: 'string', + description: 'allowed sender addresses item', + }, + optional: true, + }, + destination_address: { + type: 'string', + description: 'Destination address for the email.', + optional: true, + }, + entrypoint: { + type: 'string', + description: 'Entrypoint to invoke on the target Worker.', + optional: true, + }, + service: { + type: 'string', + description: 'Name of Worker to bind to.', + optional: true, + }, + index_name: { + type: 'string', + description: 'Name of the Vectorize index to bind to.', + optional: true, + }, + secret_name: { + type: 'string', + description: 'Name of the secret in the store.', + optional: true, + }, + store_id: { + type: 'string', + description: 'ID of the store containing the secret.', + optional: true, + }, + app_id: { + type: 'string', + description: 'ID of the Flagship app to bind to for feature flag evaluation.', + optional: true, + }, + algorithm: { + type: 'json', + description: + 'Algorithm-specific key parameters. [Learn more](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#algorithm).', + optional: true, + }, + format: { + type: 'string', + description: + 'Data format of the key. [Learn more](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#format). Values: raw, pkcs8, spki, jwk.', + optional: true, + }, + key_base64: { + type: 'string', + description: + 'Base64-encoded key data. Required if `format` is "raw", "pkcs8", or "spki".', + optional: true, + }, + key_jwk: { + type: 'json', + description: + 'Key data in [JSON Web Key](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#json_web_key) format. Required if `format` is "jwk".', + optional: true, + }, + usages: { + type: 'array', + description: + 'Allowed operations with the key. [Learn more](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#keyUsages).', + items: { + type: 'string', + description: + 'usages item Values: encrypt, decrypt, sign, verify, deriveKey, deriveBits, wrapKey, unwrapKey.', + }, + optional: true, + }, + workflow_name: { + type: 'string', + description: 'Name of the Workflow to bind to.', + optional: true, + }, + service_id: { + type: 'string', + description: 'Identifier of the VPC service to bind to.', + optional: true, + }, + identity: { + type: 'string', + description: + 'Enables Gateway identity for the binding. Requires network_id to be "cf1:network" and cannot be combined with tunnel_id. Values: runtime-email-alpha.', + optional: true, + }, + network_id: { + type: 'string', + description: + 'Identifier of the network to bind to. Only "cf1:network" is currently supported. Mutually exclusive with tunnel_id.', + optional: true, + }, + tunnel_id: { + type: 'string', + description: + 'UUID of the Cloudflare Tunnel to bind to. Mutually exclusive with network_id.', + optional: true, + }, + }, + }, + }, + cache_options: { + type: 'json', + description: + 'Global CacheW configuration for the Worker. When caching is on, the platform provisions a `cloudflare.app` zone for the Worker. A `type: worker` entry in the `exports` map can override this value for a single entrypoint.', + properties: { + cross_version_cache: { + type: 'boolean', + description: + 'Whether cached responses are shared across Worker version uploads. This is independent of `enabled`. It can stay true while caching is off, so the preference survives turning caching off and back on.', + optional: true, + }, + enabled: { + type: 'boolean', + description: 'Whether caching is enabled for this Worker.', + optional: false, + }, + }, + nullable: true, + }, + compatibility_date: { + type: 'string', + description: + 'Date indicating targeted support in the Workers runtime. Backwards incompatible fixes to the runtime following this date will not affect this Worker.', + nullable: true, + }, + compatibility_flags: { + type: 'array', + description: + 'Flags that enable or disable certain features in the Workers runtime. Used to enable upcoming features or opt in or out of specific changes not included in a `compatibility_date`.', + items: { + type: 'string', + description: 'compatibility flags item', + }, + }, + exports: { + type: 'json', + description: + 'Declarative exports for the Worker, keyed by export name. Worker entrypoint entries (`type: worker`) carry cache configuration for that entrypoint. Durable Object entries (`type: durable-object`) are also configured here and drive namespace reconciliation. At most 100 entries; class names are at most 128 characters.', + nullable: true, + }, + exports_reconciliation: { + type: 'json', + description: 'Summary of what the declarative exports reconciliation did on this upload.', + properties: { + created: { + type: 'array', + description: 'Class names for which a new namespace was provisioned.', + items: { + type: 'string', + description: 'created item', + }, + optional: false, + }, + deleted: { + type: 'array', + description: 'Class names whose namespace was deleted by a `deleted` tombstone.', + items: { + type: 'string', + description: 'deleted item', + }, + optional: false, + }, + info: { + type: 'array', + description: + 'Non-blocking info entries (stale tombstones, tombstone applied with class still in code). See `exports_reconciliation_info`.', + items: { + type: 'json', + description: + 'A non-blocking reconciliation info entry. Emitted for stale tombstones (a no-op on this deploy) and for tombstones applied with the source class still in code (the supported zero-downtime rollout pattern).', + properties: { + class: { + type: 'string', + description: 'The class name the info entry is about.', + optional: false, + }, + message: { + type: 'string', + description: 'Human-readable explanation.', + optional: false, + }, + namespace_id: { + type: 'string', + description: 'The provisioned namespace the entry relates to, when applicable.', + optional: true, + }, + referencing_scripts: { + type: 'array', + description: + 'Other Workers in the account that still bind to the affected class. Advisory: while non-empty the tombstone is not yet safe to remove \u2014 redeploy these Workers with bindings re-pointed first.', + items: { + type: 'string', + description: 'referencing scripts item', + }, + optional: true, + }, + scenario: { + type: 'string', + description: + 'Stable, machine-readable tag identifying which reconciliation scenario produced an error, warning, or info entry.', + optional: false, + }, + }, + }, + optional: false, + }, + removable_entries: { + type: 'array', + description: + 'Source class names whose tombstone entry is now stale and safe to delete from `exports` (no remaining referencing scripts).', + items: { + type: 'string', + description: 'removable entries item', + }, + optional: false, + }, + renamed: { + type: 'array', + description: 'Applied `renamed` tombstones.', + items: { + type: 'json', + description: 'A single applied `renamed` tombstone.', + properties: { + from: { + type: 'string', + description: 'The original (source) class name.', + optional: false, + }, + to: { + type: 'string', + description: 'The new class name (`renamed_to`).', + optional: false, + }, + }, + }, + optional: false, + }, + transfer_pending: { + type: 'array', + description: 'Phase-1 transfer hints recorded on the target side.', + items: { + type: 'json', + description: + 'A single phase-1 transfer hint recorded on the target side (a live `expecting-transfer` entry).', + properties: { + class: { + type: 'string', + description: 'The target-side class name awaiting transfer.', + optional: false, + }, + from: { + type: 'string', + description: 'The source script the namespace will be transferred from.', + optional: false, + }, + }, + }, + optional: false, + }, + transferred: { + type: 'array', + description: 'Committed `transferred` tombstones (phase-2).', + items: { + type: 'json', + description: 'A single committed `transferred` tombstone (phase-2 commit).', + properties: { + class: { + type: 'string', + description: 'The source class name that was transferred.', + optional: false, + }, + phase: { + type: 'string', + description: 'The transfer phase. Currently always `committed`. Values: committed.', + optional: false, + }, + to: { + type: 'string', + description: 'The destination script that now owns the namespace.', + optional: false, + }, + }, + }, + optional: false, + }, + updated: { + type: 'array', + description: 'Class names whose provisioned namespace was mutated in place.', + items: { + type: 'string', + description: 'updated item', + }, + optional: false, + }, + warnings: { + type: 'array', + description: 'Non-blocking warnings. See `exports_reconciliation_warning`.', + items: { + type: 'json', + description: + 'A non-blocking reconciliation warning. Reserved: no scenario populates this array today (`code_class_not_in_exports` is surfaced as info and `provisioned_class_missing_from_config` is a hard error). Clients should still surface any entries that appear.', + properties: { + class: { + type: 'string', + description: 'The class name the warning is about.', + optional: false, + }, + message: { + type: 'string', + description: 'Human-readable explanation of the warning.', + optional: false, + }, + namespace_id: { + type: 'string', + description: 'The provisioned namespace the warning relates to, when applicable.', + optional: true, + }, + scenario: { + type: 'string', + description: + 'Stable, machine-readable tag identifying which reconciliation scenario produced an error, warning, or info entry.', + optional: false, + }, + }, + }, + optional: false, + }, + }, + nullable: true, + }, + limits: { + type: 'json', + description: 'Limits to apply for this Worker.', + properties: { + cpu_ms: { + type: 'number', + description: 'The amount of CPU time this Worker can use in milliseconds.', + optional: true, + }, + subrequests: { + type: 'number', + description: 'The number of subrequests this Worker can make per request.', + optional: true, + }, + }, + nullable: true, + }, + logpush: { + type: 'boolean', + description: 'Whether Logpush is turned on for the Worker.', + nullable: true, + }, + migrations: { + type: 'json', + description: 'A single set of migrations to apply.', + properties: { + new_tag: { + type: 'string', + description: 'Tag to set as the latest migration tag.', + optional: true, + }, + old_tag: { + type: 'string', + description: + "Tag used to verify against the latest migration tag for this Worker. If they don't match, the upload is rejected.", + optional: true, + }, + deleted_classes: { + type: 'array', + description: 'A list of classes to delete Durable Object namespaces from.', + items: { + type: 'string', + description: 'deleted classes item', + }, + optional: true, + }, + new_classes: { + type: 'array', + description: 'A list of classes to create Durable Object namespaces from.', + items: { + type: 'string', + description: 'new classes item', + }, + optional: true, + }, + new_sqlite_classes: { + type: 'array', + description: 'A list of classes to create Durable Object namespaces with SQLite from.', + items: { + type: 'string', + description: 'new sqlite classes item', + }, + optional: true, + }, + renamed_classes: { + type: 'array', + description: 'A list of classes with Durable Object namespaces that were renamed.', + items: { + type: 'json', + description: 'renamed classes item', + properties: { + from: { + type: 'string', + description: 'from', + optional: true, + }, + to: { + type: 'string', + description: 'to', + optional: true, + }, + }, + }, + optional: true, + }, + transferred_classes: { + type: 'array', + description: + 'A list of transfers for Durable Object namespaces from a different Worker and class to a class defined in this Worker.', + items: { + type: 'json', + description: 'transferred classes item', + properties: { + from: { + type: 'string', + description: 'from', + optional: true, + }, + from_script: { + type: 'string', + description: 'from script', + optional: true, + }, + to: { + type: 'string', + description: 'to', + optional: true, + }, + }, + }, + optional: true, + }, + steps: { + type: 'array', + description: 'Migrations to apply in order.', + items: { + type: 'json', + description: 'steps item', + properties: { + deleted_classes: { + type: 'array', + description: 'A list of classes to delete Durable Object namespaces from.', + items: { + type: 'string', + description: 'deleted classes item', + }, + optional: true, + }, + new_classes: { + type: 'array', + description: 'A list of classes to create Durable Object namespaces from.', + items: { + type: 'string', + description: 'new classes item', + }, + optional: true, + }, + new_sqlite_classes: { + type: 'array', + description: + 'A list of classes to create Durable Object namespaces with SQLite from.', + items: { + type: 'string', + description: 'new sqlite classes item', + }, + optional: true, + }, + renamed_classes: { + type: 'array', + description: 'A list of classes with Durable Object namespaces that were renamed.', + items: { + type: 'json', + description: 'renamed classes item', + properties: { + from: { + type: 'string', + description: 'from', + optional: true, + }, + to: { + type: 'string', + description: 'to', + optional: true, + }, + }, + }, + optional: true, + }, + transferred_classes: { + type: 'array', + description: + 'A list of transfers for Durable Object namespaces from a different Worker and class to a class defined in this Worker.', + items: { + type: 'json', + description: 'transferred classes item', + properties: { + from: { + type: 'string', + description: 'from', + optional: true, + }, + from_script: { + type: 'string', + description: 'from script', + optional: true, + }, + to: { + type: 'string', + description: 'to', + optional: true, + }, + }, + }, + optional: true, + }, + }, + }, + optional: true, + }, + }, + nullable: true, + }, + observability: WORKER_SCRIPT_OUTPUTS_OBSERVABILITY_FIELDS, + placement: { + type: 'json', + description: + "Configuration for [Smart Placement](https://developers.cloudflare.com/workers/configuration/smart-placement). Specify mode='smart' for Smart Placement, or one of region/hostname/host.", + properties: { + mode: { + type: 'string', + description: 'Targeted placement mode. Values: smart, targeted.', + optional: true, + }, + region: { + type: 'string', + description: "Cloud region for targeted placement in format 'provider:region'.", + optional: true, + }, + hostname: { + type: 'string', + description: 'HTTP hostname for targeted placement.', + optional: true, + }, + host: { + type: 'string', + description: 'TCP host and port for targeted placement.', + optional: true, + }, + target: { + type: 'array', + description: 'Array of placement targets (currently limited to single target).', + items: { + type: 'json', + description: 'A target to run your Worker near.', + properties: { + region: { + type: 'string', + description: "Cloud region in format 'provider:region'.", + optional: true, + }, + hostname: { + type: 'string', + description: 'HTTP hostname for targeted placement.', + optional: true, + }, + host: { + type: 'string', + description: 'TCP host:port for targeted placement.', + optional: true, + }, + }, + }, + optional: true, + }, + }, + nullable: true, + }, + tags: { + type: 'array', + description: 'Tags associated with the Worker.', + items: { + type: 'string', + description: 'tags item', + }, + }, + tail_consumers: { + type: 'array', + description: 'List of Workers that will consume logs from the attached Worker.', + items: { + type: 'json', + description: 'A reference to a script that will consume logs from the attached Worker.', + properties: { + environment: { + type: 'string', + description: 'Optional environment if the Worker utilizes one.', + optional: true, + }, + namespace: { + type: 'string', + description: 'Optional dispatch namespace the script belongs to.', + optional: true, + }, + service: { + type: 'string', + description: 'Name of Worker that is to be the consumer.', + optional: false, + }, + }, + }, + }, + usage_model: { + type: 'string', + description: 'Usage model for the Worker invocations. Values: standard, bundled, unbound.', + nullable: true, + }, +} as const satisfies Record + +export const ZONE_OUTPUTS = { + account: { + type: 'json', + description: 'The account the zone belongs to.', + properties: { + id: { + type: 'string', + description: 'Identifier', + optional: true, + }, + name: { + type: 'string', + description: 'The name of the account.', + optional: true, + }, + }, + nullable: true, + }, + activated_on: { + type: 'string', + description: 'The last time proof of ownership was detected and the zone was made active.', + nullable: true, + }, + cname_suffix: { + type: 'string', + description: 'Allows the customer to use a custom apex. *Tenants Only Configuration*.', + nullable: true, + }, + created_on: { + type: 'string', + description: 'When the zone was created.', + nullable: true, + }, + development_mode: { + type: 'number', + description: + 'The interval (in seconds) from when development mode expires (positive integer) or last expired (negative integer) for the domain. If development mode has never been enabled, this value is 0.', + nullable: true, + }, + id: { + type: 'string', + description: 'Identifier', + nullable: true, + }, + meta: { + type: 'json', + description: 'Metadata about the zone.', + properties: { + cdn_only: { + type: 'boolean', + description: 'The zone is only configured for CDN.', + optional: true, + }, + custom_certificate_quota: { + type: 'number', + description: 'Number of Custom Certificates the zone can have.', + optional: true, + }, + dns_only: { + type: 'boolean', + description: 'The zone is only configured for DNS.', + optional: true, + }, + foundation_dns: { + type: 'boolean', + description: 'The zone is setup with Foundation DNS.', + optional: true, + }, + page_rule_quota: { + type: 'number', + description: 'Number of Page Rules a zone can have.', + optional: true, + }, + phishing_detected: { + type: 'boolean', + description: 'The zone has been flagged for phishing.', + optional: true, + }, + step: { + type: 'number', + description: 'step', + optional: true, + }, + }, + nullable: true, + }, + modified_on: { + type: 'string', + description: 'When the zone was last modified.', + nullable: true, + }, + name: { + type: 'string', + description: + 'The domain name. Per [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035#section-2.3.4) the overall zone name can be up to 253 characters, with each segment ("label") not exceeding 63 characters.', + nullable: true, + }, + name_servers: { + type: 'array', + description: 'The name servers Cloudflare assigns to a zone.', + items: { + type: 'string', + description: 'name servers item', + }, + }, + original_dnshost: { + type: 'string', + description: 'DNS host at the time of switching to Cloudflare.', + nullable: true, + }, + original_name_servers: { + type: 'array', + description: 'Original name servers before moving to Cloudflare.', + items: { + type: 'string', + description: 'original name servers item', + }, + }, + original_registrar: { + type: 'string', + description: 'Registrar for the domain at the time of switching to Cloudflare.', + nullable: true, + }, + owner: { + type: 'json', + description: 'The owner of the zone.', + properties: { + id: { + type: 'string', + description: 'Identifier', + optional: true, + }, + name: { + type: 'string', + description: 'Name of the owner.', + optional: true, + }, + type: { + type: 'string', + description: 'The type of owner.', + optional: true, + }, + }, + nullable: true, + }, + paused: { + type: 'boolean', + description: + 'Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits.', + nullable: true, + }, + permissions: { + type: 'array', + description: 'Legacy permissions based on legacy user membership information.', + items: { + type: 'string', + description: 'permissions item', + }, + }, + plan: { + type: 'json', + description: 'A Zones subscription information.', + properties: { + can_subscribe: { + type: 'boolean', + description: 'States if the subscription can be activated.', + optional: true, + }, + currency: { + type: 'string', + description: 'The denomination of the customer.', + optional: true, + }, + externally_managed: { + type: 'boolean', + description: 'If this Zone is managed by another company.', + optional: true, + }, + frequency: { + type: 'string', + description: 'How often the customer is billed.', + optional: true, + }, + id: { + type: 'string', + description: 'Identifier', + optional: true, + }, + is_subscribed: { + type: 'boolean', + description: 'States if the subscription active.', + optional: true, + }, + legacy_discount: { + type: 'boolean', + description: 'If the legacy discount applies to this Zone.', + optional: true, + }, + legacy_id: { + type: 'string', + description: 'The legacy name of the plan.', + optional: true, + }, + name: { + type: 'string', + description: 'Name of the owner.', + optional: true, + }, + price: { + type: 'number', + description: 'How much the customer is paying.', + optional: true, + }, + }, + nullable: true, + }, + status: { + type: 'string', + description: 'The zone status on Cloudflare. Values: initializing, pending, active, moved.', + nullable: true, + }, + tenant: { + type: 'json', + description: + 'The root organizational unit that this zone belongs to (such as a tenant or organization).', + properties: { + id: { + type: 'string', + description: 'Identifier', + optional: true, + }, + name: { + type: 'string', + description: 'The name of the Tenant account.', + optional: true, + }, + }, + nullable: true, + }, + tenant_unit: { + type: 'json', + description: + 'The immediate parent organizational unit that this zone belongs to (such as under a tenant or sub-organization).', + properties: { + id: { + type: 'string', + description: 'Identifier', + optional: true, + }, + }, + nullable: true, + }, + type: { + type: 'string', + description: + 'A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. Values: full, partial, secondary, internal.', + nullable: true, + }, + vanity_name_servers: { + type: 'array', + description: + 'An array of domains used for custom name servers. This is only available for Business and Enterprise plans.', + items: { + type: 'string', + description: 'vanity name servers item', + }, + }, + verification_key: { + type: 'string', + description: 'Verification key for partial zone setup.', + nullable: true, + }, +} as const satisfies Record diff --git a/apps/sim/tools/cloudflare/purge_cache.ts b/apps/sim/tools/cloudflare/purge_cache.ts index 144628b92b9..d26d4c165a8 100644 --- a/apps/sim/tools/cloudflare/purge_cache.ts +++ b/apps/sim/tools/cloudflare/purge_cache.ts @@ -2,7 +2,9 @@ import type { CloudflarePurgeCacheParams, CloudflarePurgeCacheResponse, } from '@/tools/cloudflare/types' +import { parseCsvParam, parseJsonArrayParam } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const purgeCacheTool: ToolConfig = { @@ -30,25 +32,26 @@ export const purgeCacheTool: ToolConfig - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/purge_cache`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/purge_cache`, method: 'POST', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, 'Content-Type': 'application/json', }), body: (params) => { - const body: Record = {} - if (params.files) { - const fileList = String(params.files) - .split(',') - .map((f) => f.trim()) - .filter(Boolean) - if (fileList.length > 0) body.files = fileList - } - if (params.tags) { - const tagList = String(params.tags) - .split(',') - .map((t) => t.trim()) - .filter(Boolean) - if (tagList.length > 0) body.tags = tagList - } - if (params.hosts) { - const hostList = String(params.hosts) - .split(',') - .map((h) => h.trim()) - .filter(Boolean) - if (hostList.length > 0) body.hosts = hostList - } - if (params.prefixes) { - const prefixList = String(params.prefixes) - .split(',') - .map((p) => p.trim()) - .filter(Boolean) - if (prefixList.length > 0) body.prefixes = prefixList + const body: Record = {} + const files = + Array.isArray(params.files) || + (typeof params.files === 'string' && params.files.trim().startsWith('[')) + ? parseJsonArrayParam(params.files, 'Files') + : parseCsvParam(params.files) + if (files?.length) body.files = files + for (const field of ['tags', 'hosts', 'prefixes'] as const) { + const values = parseCsvParam(params[field]) + if (values?.length) body[field] = values } const targets = Object.keys(body) @@ -140,7 +125,7 @@ export const purgeCacheTool: ToolConfig { const data = await response.json() - if (!data.success) { + if (!response.ok || data.success !== true) { return { success: false, output: { id: '' }, diff --git a/apps/sim/tools/cloudflare/refresh_access_service_token.ts b/apps/sim/tools/cloudflare/refresh_access_service_token.ts new file mode 100644 index 00000000000..6996eaff53f --- /dev/null +++ b/apps/sim/tools/cloudflare/refresh_access_service_token.ts @@ -0,0 +1,62 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareRefreshAccessServiceTokenParams, + CloudflareRefreshAccessServiceTokenResponse, +} from '@/tools/cloudflare/operation-types' +import { SERVICE_TOKEN_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const refreshAccessServiceTokenTool: ToolConfig< + CloudflareRefreshAccessServiceTokenParams, + CloudflareRefreshAccessServiceTokenResponse +> = { + id: 'cloudflare_refresh_access_service_token', + name: 'Cloudflare Refresh Access Service Token', + description: 'Refreshes the expiration of a service token.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + serviceTokenId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Service token id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens/${safeUrlPathSegment(params.serviceTokenId, 'serviceTokenId')}/refresh`, + method: 'POST', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to refresh access service token') } + : {}), + } + }, + outputs: SERVICE_TOKEN_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/request-boundary.test.ts b/apps/sim/tools/cloudflare/request-boundary.test.ts new file mode 100644 index 00000000000..a1cfc874036 --- /dev/null +++ b/apps/sim/tools/cloudflare/request-boundary.test.ts @@ -0,0 +1,45 @@ +import { describe, expect, it } from 'vitest' +import { createDnsRecordTool } from '@/tools/cloudflare/create_dns_record' +import { deleteDnsRecordTool } from '@/tools/cloudflare/delete_dns_record' +import { updateRulesetRuleTool } from '@/tools/cloudflare/update_ruleset_rule' + +describe('Cloudflare provider request boundaries', () => { + it('rejects a DNS deletion identifier that would address the collection instead', () => { + const url = deleteDnsRecordTool.request.url + if (typeof url !== 'function') throw new Error('Expected a parameterized URL') + expect(() => url({ apiKey: 'token', zoneId: 'zone', recordId: '..' })).toThrow(/recordId/) + }) + + it('rejects JSON null where a replacement rule requires action parameters', () => { + const body = updateRulesetRuleTool.request.body + if (!body) throw new Error('Expected a request body') + expect(() => + body({ + apiKey: 'token', + zoneId: 'zone', + rulesetId: 'ruleset', + ruleId: 'rule', + action: 'block', + expression: 'true', + actionParameters: 'null', + }) + ).toThrow(/must be a JSON object/) + }) + + it('preserves structured SRV data instead of sending an empty content value', () => { + const body = createDnsRecordTool.request.body + if (!body) throw new Error('Expected a request body') + const input = { + apiKey: 'token', + zoneId: 'zone', + type: 'SRV', + name: '_sip._tcp.example.com', + data: '{"priority":10,"weight":5,"port":5060,"target":"sip.example.com"}', + } + expect(body(input)).toEqual({ + type: 'SRV', + name: '_sip._tcp.example.com', + data: { priority: 10, weight: 5, port: 5060, target: 'sip.example.com' }, + }) + }) +}) diff --git a/apps/sim/tools/cloudflare/revoke_access_service_token.ts b/apps/sim/tools/cloudflare/revoke_access_service_token.ts index 2215d8d777a..a63e09b1b3c 100644 --- a/apps/sim/tools/cloudflare/revoke_access_service_token.ts +++ b/apps/sim/tools/cloudflare/revoke_access_service_token.ts @@ -1,9 +1,16 @@ +import { SERVICE_TOKEN_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessServiceTokenResponse, CloudflareRevokeAccessServiceTokenParams, } from '@/tools/cloudflare/types' -import { cloudflareErrorMessage, cloudflareHeaders } from '@/tools/cloudflare/utils' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const revokeAccessServiceTokenTool: ToolConfig< CloudflareRevokeAccessServiceTokenParams, @@ -38,62 +45,21 @@ export const revokeAccessServiceTokenTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/service_tokens/${params.serviceTokenId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens/${safeUrlPathSegment(params.serviceTokenId, 'serviceTokenId')}`, method: 'DELETE', headers: (params) => cloudflareHeaders(params.apiKey), }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - name: null, - client_id: null, - duration: null, - enabled: null, - expires_at: null, - last_seen_at: null, - created_at: null, - updated_at: null, - }, - error: cloudflareErrorMessage(data, 'Failed to revoke Access service token'), - } - } - - const token = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true return { - success: true, - output: { - id: token?.id ?? '', - name: token?.name ?? null, - client_id: token?.client_id ?? null, - duration: token?.duration ?? null, - enabled: token?.enabled ?? null, - expires_at: token?.expires_at ?? null, - last_seen_at: token?.last_seen_at ?? null, - created_at: token?.created_at ?? null, - updated_at: token?.updated_at ?? null, - }, + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to revoke access service token') } + : {}), } }, - - outputs: { - id: { type: 'string', description: 'Identifier of the revoked service token' }, - name: { type: 'string', description: 'Service token name', optional: true }, - client_id: { - type: 'string', - description: 'Client ID that is no longer accepted', - optional: true, - }, - duration: { type: 'string', description: 'Configured token lifetime', optional: true }, - enabled: { type: 'boolean', description: 'Whether the token was active', optional: true }, - expires_at: { type: 'string', description: 'Expiry timestamp', optional: true }, - last_seen_at: { type: 'string', description: 'When the token was last used', optional: true }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, - }, + outputs: SERVICE_TOKEN_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/rotate_access_service_token.ts b/apps/sim/tools/cloudflare/rotate_access_service_token.ts new file mode 100644 index 00000000000..ab0a74cc3ba --- /dev/null +++ b/apps/sim/tools/cloudflare/rotate_access_service_token.ts @@ -0,0 +1,76 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareRotateAccessServiceTokenParams, + CloudflareRotateAccessServiceTokenResponse, +} from '@/tools/cloudflare/operation-types' +import { SERVICE_TOKEN_SECRET_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const rotateAccessServiceTokenTool: ToolConfig< + CloudflareRotateAccessServiceTokenParams, + CloudflareRotateAccessServiceTokenResponse +> = { + id: 'cloudflare_rotate_access_service_token', + name: 'Cloudflare Rotate Access Service Token', + description: + 'Generates a new Client Secret. The previous secret expires immediately unless previous_client_secret_expires_at schedules a later expiration.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + serviceTokenId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Service token id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + previous_client_secret_expires_at: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The expiration of the previous `client_secret`. If not provided, it defaults to the current timestamp in order to immediately expire the previous secret. If the service token was reported as leaked, this must not be in the future; the leaked secret is discarded immediately.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens/${safeUrlPathSegment(params.serviceTokenId, 'serviceTokenId')}/rotate`, + method: 'POST', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + previous_client_secret_expires_at: + params.previous_client_secret_expires_at === '' + ? undefined + : params.previous_client_secret_expires_at, + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_SECRET_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to rotate access service token') } + : {}), + } + }, + outputs: SERVICE_TOKEN_SECRET_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/types.ts b/apps/sim/tools/cloudflare/types.ts index 88824b2cf80..0164caaa5c4 100644 --- a/apps/sim/tools/cloudflare/types.ts +++ b/apps/sim/tools/cloudflare/types.ts @@ -1,3 +1,23 @@ +import type { + ACCESS_APPLICATION_OUTPUTS, + ACCESS_GROUP_OUTPUTS, + ACCESS_POLICY_OUTPUTS, + CERTIFICATE_OUTPUTS, + DNS_RECORD_OUTPUTS, + IDENTITY_PROVIDER_OUTPUTS, + LIST_RULESETS_OUTPUTS, + R2_BUCKET_OUTPUTS, + RULESET_OUTPUTS, + SERVICE_TOKEN_OUTPUTS, + SERVICE_TOKEN_SECRET_OUTPUTS, + TUNNEL_CONFIGURATION_OUTPUTS, + TUNNEL_OUTPUTS, + WORKER_ROUTE_OUTPUTS, + WORKER_SCRIPT_OUTPUTS, + WORKER_SETTINGS_OUTPUTS, + ZONE_OUTPUTS, +} from '@/tools/cloudflare/outputs' +import type { CloudflareOutput } from '@/tools/cloudflare/utils' import type { ToolResponse } from '@/tools/types' interface CloudflareBaseParams { @@ -14,6 +34,7 @@ interface CloudflareResultInfo { per_page?: number count?: number total_count?: number + total_pages?: number cursor?: string cursors?: { before?: string @@ -67,233 +88,32 @@ export interface CloudflareRawRuleset { } /** Raw Cloudflare Access application payload. */ -export interface CloudflareRawAccessApplication { - id?: string - name?: string - domain?: string - type?: string - aud?: string - session_duration?: string - allowed_idps?: string[] - app_launcher_visible?: boolean - auto_redirect_to_identity?: boolean - custom_deny_message?: string - custom_deny_url?: string - logo_url?: string - self_hosted_domains?: string[] - destinations?: unknown[] - tags?: string[] - policies?: unknown[] -} /** Raw Cloudflare Access policy payload. */ -export interface CloudflareRawAccessPolicy { - id?: string - name?: string - decision?: string - precedence?: number - include?: unknown[] - exclude?: unknown[] - require?: unknown[] - session_duration?: string - approval_required?: boolean - isolation_required?: boolean - purpose_justification_required?: boolean - purpose_justification_prompt?: string - created_at?: string - updated_at?: string -} /** Raw Cloudflare Access group payload. */ -export interface CloudflareRawAccessGroup { - id?: string - name?: string - is_default?: unknown[] - include?: unknown[] - exclude?: unknown[] - require?: unknown[] - created_at?: string - updated_at?: string -} /** Raw Cloudflare Access identity provider payload. */ -export interface CloudflareRawAccessIdentityProvider { - id?: string - name?: string - type?: string - read_only?: boolean - config?: Record - scim_config?: Record -} /** Raw Cloudflare Access service token payload. `client_secret` only on create. */ -export interface CloudflareRawAccessServiceToken { - id?: string - name?: string - client_id?: string - client_secret?: string - duration?: string - enabled?: boolean - expires_at?: string - last_seen_at?: string - created_at?: string - updated_at?: string -} /** Raw R2 bucket payload. */ -export interface CloudflareRawR2Bucket { - name?: string - creation_date?: string - location?: string - storage_class?: string - jurisdiction?: string -} /** Raw Workers script payload from the list-scripts endpoint. */ -export interface CloudflareRawWorkerScript { - id?: string - tag?: string - etag?: string - created_on?: string - modified_on?: string - usage_model?: string - placement_mode?: string - logpush?: boolean - has_assets?: boolean - has_modules?: boolean - compatibility_date?: string - compatibility_flags?: string[] - routes?: unknown[] - tail_consumers?: unknown[] -} /** Raw Workers route payload. */ -export interface CloudflareRawWorkerRoute { - id?: string - pattern?: string - script?: string -} /** Raw Cloudflare Tunnel (cloudflared) payload. */ -export interface CloudflareRawTunnel { - id?: string - name?: string - account_tag?: string - config_src?: string - status?: string - tun_type?: string - remote_config?: boolean - metadata?: Record - created_at?: string - deleted_at?: string - conns_active_at?: string - conns_inactive_at?: string - connections?: unknown[] -} /** Raw zone payload from the zones endpoints. */ -export interface CloudflareRawZone { - id?: string - name?: string - status?: string - paused?: boolean - type?: string - name_servers?: string[] - original_name_servers?: string[] - created_on?: string - modified_on?: string - activated_on?: string - development_mode?: number - plan?: { - id?: string - name?: string - price?: number - is_subscribed?: boolean - frequency?: string - currency?: string - legacy_id?: string - } - account?: { id?: string; name?: string } - owner?: { id?: string; name?: string; type?: string } - meta?: { - cdn_only?: boolean - custom_certificate_quota?: number - dns_only?: boolean - foundation_dns?: boolean - page_rule_quota?: number - phishing_detected?: boolean - step?: number - } - vanity_name_servers?: string[] - permissions?: string[] -} /** Raw DNS record payload. */ -export interface CloudflareRawDnsRecord { - id?: string - zone_id?: string - zone_name?: string - type?: string - name?: string - content?: string - proxiable?: boolean - proxied?: boolean - ttl?: number - locked?: boolean - priority?: number - comment?: string - tags?: string[] - comment_modified_on?: string - tags_modified_on?: string - meta?: CloudflareDnsRecordMeta - created_on?: string - modified_on?: string -} /** Raw hostname-validation record shared by certificate pack validation fields. */ -interface CloudflareRawValidationRecord { - cname?: string - cname_target?: string - emails?: string[] - http_body?: string - http_url?: string - status?: string - txt_name?: string - txt_value?: string -} /** Raw certificate inside a certificate pack. */ -interface CloudflareRawCertificate { - id?: string - hosts?: string[] - issuer?: string - signature?: string - status?: string - bundle_method?: string - zone_id?: string - uploaded_on?: string - modified_on?: string - expires_on?: string - priority?: number - geo_restrictions?: CloudflareCertificateGeoRestrictions -} /** Raw certificate pack payload. */ -export interface CloudflareRawCertificatePack { - id?: string - type?: string - hosts?: string[] - primary_certificate?: string - status?: string - certificates?: CloudflareRawCertificate[] - cloudflare_branding?: boolean - validation_method?: string - validity_days?: number - certificate_authority?: string - validation_errors?: Array<{ message?: string }> - validation_records?: CloudflareRawValidationRecord[] - dcv_delegation_records?: CloudflareRawValidationRecord[] -} /** Raw DNS analytics aggregate block (`totals`, `min`, and `max` share this shape). */ interface CloudflareRawDnsAnalyticsAggregate { @@ -326,6 +146,9 @@ export interface CloudflareRawDnsAnalyticsReport { } export interface CloudflareListZonesParams extends CloudflareBaseParams { + type?: string + account_name?: string + name?: string status?: string page?: number @@ -336,57 +159,11 @@ export interface CloudflareListZonesParams extends CloudflareBaseParams { match?: string } -interface CloudflareZonePlan { - id: string - name: string - price: number - is_subscribed: boolean - frequency: string - currency: string - legacy_id: string -} - -interface CloudflareZoneMeta { - cdn_only: boolean - custom_certificate_quota: number - dns_only: boolean - foundation_dns: boolean - page_rule_quota: number - phishing_detected: boolean - step: number -} - -interface CloudflareZone { - id: string - name: string - status: string - paused: boolean - type: string - name_servers: string[] - original_name_servers?: string[] - created_on: string - modified_on: string - activated_on?: string - development_mode?: number - plan?: CloudflareZonePlan - account?: { - id: string - name: string - } - owner?: { - id: string - name: string - type: string - } - meta?: CloudflareZoneMeta - vanity_name_servers?: string[] - permissions?: string[] -} - export interface CloudflareListZonesResponse extends ToolResponse { output: { - zones: CloudflareZone[] + zones: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -395,32 +172,7 @@ export interface CloudflareGetZoneParams extends CloudflareBaseParams { } export interface CloudflareGetZoneResponse extends ToolResponse { - output: { - id: string - name: string - status: string - paused: boolean - type: string - name_servers: string[] - original_name_servers: string[] - created_on: string - modified_on: string - activated_on: string - development_mode: number - plan: CloudflareZonePlan - account: { - id: string - name: string - } - owner: { - id: string - name: string - type: string - } - meta: CloudflareZoneMeta - vanity_name_servers: string[] - permissions: string[] - } + output: CloudflareOutput } export interface CloudflareCreateZoneParams extends CloudflareBaseParams { @@ -430,32 +182,7 @@ export interface CloudflareCreateZoneParams extends CloudflareBaseParams { } export interface CloudflareCreateZoneResponse extends ToolResponse { - output: { - id: string - name: string - status: string - paused: boolean - type: string - name_servers: string[] - original_name_servers: string[] - created_on: string - modified_on: string - activated_on: string - development_mode: number - plan: CloudflareZonePlan - account: { - id: string - name: string - } - owner: { - id: string - name: string - type: string - } - meta: CloudflareZoneMeta - vanity_name_servers: string[] - permissions: string[] - } + output: CloudflareOutput } export interface CloudflareDeleteZoneParams extends CloudflareBaseParams { @@ -469,6 +196,26 @@ export interface CloudflareDeleteZoneResponse extends ToolResponse { } export interface CloudflareListDnsRecordsParams extends CloudflareBaseParams { + name_contains?: string + name_startswith?: string + name_endswith?: string + content_contains?: string + content_startswith?: string + content_endswith?: string + comment_present?: boolean + comment_absent?: boolean + comment_exact?: string + comment_startswith?: string + comment_endswith?: string + tag_present?: string + tag_absent?: string + tag_contains?: string + tag_startswith?: string + tag_endswith?: string + include_shadow_metadata?: boolean + shadowed_by_name?: string + shadowing_name?: string + zoneId: string type?: string name?: string @@ -485,43 +232,24 @@ export interface CloudflareListDnsRecordsParams extends CloudflareBaseParams { commentFilter?: string } -interface CloudflareDnsRecordMeta { - source: string -} - -interface CloudflareDnsRecord { - id: string - zone_id: string - zone_name: string - type: string - name: string - content: string - proxiable: boolean - proxied: boolean - ttl: number - locked: boolean - priority?: number | null - comment?: string | null - tags: string[] - comment_modified_on?: string | null - tags_modified_on?: string | null - meta?: CloudflareDnsRecordMeta | null - created_on: string - modified_on: string -} - export interface CloudflareListDnsRecordsResponse extends ToolResponse { output: { - records: CloudflareDnsRecord[] + records: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } export interface CloudflareCreateDnsRecordParams extends CloudflareBaseParams { + settings?: string | Record | unknown[] + private_routing?: boolean + data?: string | Record | unknown[] + include_shadow_metadata?: boolean + zoneId: string type: string name: string - content: string + content?: string ttl?: number proxied?: boolean priority?: number @@ -530,29 +258,16 @@ export interface CloudflareCreateDnsRecordParams extends CloudflareBaseParams { } export interface CloudflareCreateDnsRecordResponse extends ToolResponse { - output: { - id: string - zone_id: string - zone_name: string - type: string - name: string - content: string - proxiable: boolean - proxied: boolean - ttl: number - locked: boolean - priority?: number - comment?: string | null - tags: string[] - comment_modified_on?: string | null - tags_modified_on?: string | null - meta?: CloudflareDnsRecordMeta | null - created_on: string - modified_on: string - } + output: CloudflareOutput } export interface CloudflareUpdateDnsRecordParams extends CloudflareBaseParams { + clearComment?: boolean + settings?: string | Record | unknown[] + private_routing?: boolean + data?: string | Record | unknown[] + include_shadow_metadata?: boolean + zoneId: string recordId: string type?: string @@ -566,26 +281,7 @@ export interface CloudflareUpdateDnsRecordParams extends CloudflareBaseParams { } export interface CloudflareUpdateDnsRecordResponse extends ToolResponse { - output: { - id: string - zone_id: string - zone_name: string - type: string - name: string - content: string - proxiable: boolean - proxied: boolean - ttl: number - locked: boolean - priority?: number - comment?: string | null - tags: string[] - comment_modified_on?: string | null - tags_modified_on?: string | null - meta?: CloudflareDnsRecordMeta | null - created_on: string - modified_on: string - } + output: CloudflareOutput } export interface CloudflareDeleteDnsRecordParams extends CloudflareBaseParams { @@ -607,60 +303,11 @@ export interface CloudflareListCertificatesParams extends CloudflareBaseParams { deploy?: string } -interface CloudflareCertificateGeoRestrictions { - label: string -} - -interface CloudflareCertificate { - id: string - hosts: string[] - issuer: string - signature: string - status: string - bundle_method: string - zone_id: string - uploaded_on: string - modified_on: string - expires_on: string - priority?: number - geo_restrictions?: CloudflareCertificateGeoRestrictions -} - -interface CloudflareCertificateValidationError { - message: string -} - -interface CloudflareDcvDelegationRecord { - cname: string - cname_target: string - emails: string[] - http_body: string - http_url: string - status: string - txt_name: string - txt_value: string -} - -interface CloudflareCertificatePack { - id: string - type: string - hosts: string[] - primary_certificate: string - status: string - certificates: CloudflareCertificate[] - cloudflare_branding?: boolean - validation_method?: string - validity_days?: number - certificate_authority?: string - validation_errors?: CloudflareCertificateValidationError[] - validation_records?: CloudflareDcvDelegationRecord[] - dcv_delegation_records?: CloudflareDcvDelegationRecord[] -} - export interface CloudflareListCertificatesResponse extends ToolResponse { output: { - certificates: CloudflareCertificatePack[] + certificates: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -747,6 +394,7 @@ interface CloudflareZoneSetting { /** Raw zone setting payload, as returned by the per-setting endpoint. */ export interface CloudflareRawZoneSetting { + enabled?: boolean id?: string value?: unknown editable?: boolean @@ -770,7 +418,8 @@ export interface CloudflareGetZoneSettingsResponse extends ToolResponse { export interface CloudflareUpdateZoneSettingParams extends CloudflareBaseParams { zoneId: string settingId: string - value: string + enabled?: boolean + value?: string } export interface CloudflareUpdateZoneSettingResponse extends ToolResponse { @@ -789,53 +438,31 @@ export interface CloudflareListRulesetsParams extends CloudflareBaseParams { cursor?: string } -interface CloudflareRulesetSummary { - id: string - name: string - description: string - kind: string - phase: string - version: string | null - last_updated: string | null -} - export interface CloudflareListRulesetsResponse extends ToolResponse { output: { - rulesets: CloudflareRulesetSummary[] + rulesets: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null cursor: string | null } } -interface CloudflareRule { - id: string - version: string | null - action: string - action_parameters: Record | null - expression: string - description: string - enabled: boolean - ref: string | null - last_updated: string | null - categories: string[] - logging: Record | null - ratelimit: Record | null -} - -interface CloudflareRuleset extends CloudflareRulesetSummary { - rules: CloudflareRule[] -} - export interface CloudflareGetRulesetParams extends CloudflareBaseParams { zoneId: string rulesetId: string } export interface CloudflareRulesetResponse extends ToolResponse { - output: CloudflareRuleset + output: CloudflareOutput } export interface CloudflareCreateRulesetRuleParams extends CloudflareBaseParams { + exposed_credential_check?: string | Record | unknown[] + id?: string + logging?: string | Record | unknown[] + ratelimit?: string | Record | unknown[] + dry_run?: boolean + zoneId: string rulesetId: string action: string @@ -848,6 +475,10 @@ export interface CloudflareCreateRulesetRuleParams extends CloudflareBaseParams } export interface CloudflareUpdateRulesetRuleParams extends CloudflareBaseParams { + exposed_credential_check?: string | Record | unknown[] + position?: string | Record | unknown[] + dry_run?: boolean + zoneId: string rulesetId: string ruleId: string @@ -862,6 +493,8 @@ export interface CloudflareUpdateRulesetRuleParams extends CloudflareBaseParams } export interface CloudflareDeleteRulesetRuleParams extends CloudflareBaseParams { + dry_run?: boolean + zoneId: string rulesetId: string ruleId: string @@ -873,6 +506,8 @@ export interface CloudflareGetRulesetEntrypointParams extends CloudflareBasePara } export interface CloudflareCreateRulesetParams extends CloudflareBaseParams { + dry_run?: boolean + zoneId: string name: string phase: string @@ -905,6 +540,16 @@ export interface CloudflareListManagedRulesetOverridesResponse extends ToolRespo } export interface CloudflareCreateRateLimitRuleParams extends CloudflareBaseParams { + actionParameters?: string | Record | unknown[] + exposed_credential_check?: string | Record | unknown[] + id?: string + logging?: string | Record | unknown[] + ref?: string + position?: string | Record | unknown[] + score_per_period?: number + score_response_header_name?: string + dry_run?: boolean + zoneId: string rulesetId: string expression: string @@ -920,6 +565,12 @@ export interface CloudflareCreateRateLimitRuleParams extends CloudflareBaseParam } export interface CloudflareUpdateRateLimitRuleParams extends CloudflareBaseParams { + exposed_credential_check?: string | Record | unknown[] + position?: string | Record | unknown[] + score_per_period?: number + score_response_header_name?: string + dry_run?: boolean + zoneId: string rulesetId: string ruleId: string @@ -938,26 +589,9 @@ export interface CloudflareUpdateRateLimitRuleParams extends CloudflareBaseParam logging?: string } -interface CloudflareAccessApplication { - id: string - name: string | null - domain: string | null - type: string | null - aud: string | null - session_duration: string | null - allowed_idps: string[] | null - app_launcher_visible: boolean | null - auto_redirect_to_identity: boolean | null - custom_deny_message: string | null - custom_deny_url: string | null - logo_url: string | null - self_hosted_domains: string[] | null - destinations: unknown[] | null - tags: string[] | null - policies: unknown[] | null -} - export interface CloudflareListAccessApplicationsParams extends CloudflareBaseParams { + target_attributes?: string + accountId: string name?: string domain?: string @@ -970,8 +604,9 @@ export interface CloudflareListAccessApplicationsParams extends CloudflareBasePa export interface CloudflareListAccessApplicationsResponse extends ToolResponse { output: { - applications: CloudflareAccessApplication[] + applications: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -981,10 +616,38 @@ export interface CloudflareGetAccessApplicationParams extends CloudflareBasePara } export interface CloudflareAccessApplicationResponse extends ToolResponse { - output: CloudflareAccessApplication + output: CloudflareOutput } export interface CloudflareCreateAccessApplicationParams extends CloudflareBaseParams { + destinations?: string | Record | unknown[] + oauth_configuration?: string | Record | unknown[] + self_hosted_domains?: string | Record | unknown[] + user_populations?: string | Record | unknown[] + allow_authenticate_via_warp?: boolean + allow_iframe?: boolean + cors_headers?: string | Record | unknown[] + custom_non_identity_deny_url?: string + custom_pages?: string | Record | unknown[] + eager_redirect_cookie_setting?: boolean + enable_binding_cookie?: boolean + http_only_cookie_attribute?: boolean + mfa_config?: string | Record | unknown[] + options_preflight_bypass?: boolean + path_cookie_attribute?: boolean + read_service_tokens_from_header?: string + same_site_cookie_attribute?: string + scim_config?: string | Record | unknown[] + service_auth_401_redirect?: boolean + skip_interstitial?: boolean + use_clientless_isolation_app_launcher_url?: boolean + app_launcher_logo_url?: string + bg_color?: string + footer_links?: string | Record | unknown[] + header_bg_color?: string + landing_page_design?: string | Record | unknown[] + skip_app_launcher_login_page?: boolean + accountId: string type: string domain?: string @@ -1004,6 +667,34 @@ export interface CloudflareCreateAccessApplicationParams extends CloudflareBaseP export interface CloudflareUpdateAccessApplicationParams extends CloudflareCreateAccessApplicationParams { + destinations?: string | Record | unknown[] + oauth_configuration?: string | Record | unknown[] + self_hosted_domains?: string | Record | unknown[] + user_populations?: string | Record | unknown[] + allow_authenticate_via_warp?: boolean + allow_iframe?: boolean + cors_headers?: string | Record | unknown[] + custom_non_identity_deny_url?: string + custom_pages?: string | Record | unknown[] + eager_redirect_cookie_setting?: boolean + enable_binding_cookie?: boolean + http_only_cookie_attribute?: boolean + mfa_config?: string | Record | unknown[] + options_preflight_bypass?: boolean + path_cookie_attribute?: boolean + read_service_tokens_from_header?: string + same_site_cookie_attribute?: string + scim_config?: string | Record | unknown[] + service_auth_401_redirect?: boolean + skip_interstitial?: boolean + use_clientless_isolation_app_launcher_url?: boolean + app_launcher_logo_url?: string + bg_color?: string + footer_links?: string | Record | unknown[] + header_bg_color?: string + landing_page_design?: string | Record | unknown[] + skip_app_launcher_login_page?: boolean + appId: string } @@ -1018,23 +709,6 @@ export interface CloudflareDeletedIdResponse extends ToolResponse { } } -interface CloudflareAccessPolicy { - id: string - name: string | null - decision: string | null - precedence: number | null - include: unknown[] | null - exclude: unknown[] | null - require: unknown[] | null - session_duration: string | null - approval_required: boolean | null - isolation_required: boolean | null - purpose_justification_required: boolean | null - purpose_justification_prompt: string | null - created_at: string | null - updated_at: string | null -} - export interface CloudflareListAccessPoliciesParams extends CloudflareBaseParams { accountId: string appId: string @@ -1044,12 +718,17 @@ export interface CloudflareListAccessPoliciesParams extends CloudflareBaseParams export interface CloudflareListAccessPoliciesResponse extends ToolResponse { output: { - policies: CloudflareAccessPolicy[] + policies: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } export interface CloudflareCreateAccessPolicyParams extends CloudflareBaseParams { + approval_groups?: string | Record | unknown[] + connection_rules?: string | Record | unknown[] + mfa_config?: string | Record | unknown[] + accountId: string appId: string name: string @@ -1066,11 +745,15 @@ export interface CloudflareCreateAccessPolicyParams extends CloudflareBaseParams } export interface CloudflareUpdateAccessPolicyParams extends CloudflareCreateAccessPolicyParams { + approval_groups?: string | Record | unknown[] + connection_rules?: string | Record | unknown[] + mfa_config?: string | Record | unknown[] + policyId: string } export interface CloudflareAccessPolicyResponse extends ToolResponse { - output: CloudflareAccessPolicy + output: CloudflareOutput } export interface CloudflareDeleteAccessPolicyParams extends CloudflareBaseParams { @@ -1089,35 +772,25 @@ export interface CloudflareListAccessGroupsParams extends CloudflareBaseParams { export interface CloudflareListAccessGroupsResponse extends ToolResponse { output: { - groups: Array<{ - id: string - name: string | null - is_default: unknown[] | null - include: unknown[] | null - exclude: unknown[] | null - require: unknown[] | null - created_at: string | null - updated_at: string | null - }> + groups: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } export interface CloudflareListAccessIdentityProvidersParams extends CloudflareBaseParams { + scim_enabled?: string + page?: number + per_page?: number + accountId: string } export interface CloudflareListAccessIdentityProvidersResponse extends ToolResponse { output: { - identity_providers: Array<{ - id: string - name: string | null - type: string | null - read_only: boolean | null - config: Record | null - scim_config: Record | null - }> + identity_providers: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -1129,35 +802,26 @@ export interface CloudflareListAccessServiceTokensParams extends CloudflareBaseP per_page?: number } -interface CloudflareAccessServiceToken { - id: string - name: string | null - client_id: string | null - duration: string | null - enabled: boolean | null - expires_at: string | null - last_seen_at: string | null - created_at: string | null - updated_at: string | null -} - export interface CloudflareListAccessServiceTokensResponse extends ToolResponse { output: { - service_tokens: CloudflareAccessServiceToken[] + service_tokens: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } export interface CloudflareCreateAccessServiceTokenParams extends CloudflareBaseParams { + client_secret_version?: number + enabled?: boolean + previous_client_secret_expires_at?: string + accountId: string name: string duration?: string } export interface CloudflareCreateAccessServiceTokenResponse extends ToolResponse { - output: CloudflareAccessServiceToken & { - client_secret: string | null - } + output: CloudflareOutput } export interface CloudflareRevokeAccessServiceTokenParams extends CloudflareBaseParams { @@ -1166,18 +830,11 @@ export interface CloudflareRevokeAccessServiceTokenParams extends CloudflareBase } export interface CloudflareAccessServiceTokenResponse extends ToolResponse { - output: CloudflareAccessServiceToken -} - -interface CloudflareR2Bucket { - name: string - creation_date: string | null - location: string | null - storage_class: string | null - jurisdiction: string | null + output: CloudflareOutput } export interface CloudflareListR2BucketsParams extends CloudflareBaseParams { + order?: string accountId: string name_contains?: string start_after?: string @@ -1189,7 +846,9 @@ export interface CloudflareListR2BucketsParams extends CloudflareBaseParams { export interface CloudflareListR2BucketsResponse extends ToolResponse { output: { - buckets: CloudflareR2Bucket[] + buckets: CloudflareOutput[] + total_count: number + result_info: CloudflareResultInfo | null cursor: string | null } } @@ -1209,7 +868,7 @@ export interface CloudflareCreateR2BucketParams extends CloudflareBaseParams { } export interface CloudflareR2BucketResponse extends ToolResponse { - output: CloudflareR2Bucket + output: CloudflareOutput } export interface CloudflareDeleteR2BucketParams extends CloudflareBaseParams { @@ -1231,23 +890,9 @@ export interface CloudflareListWorkerScriptsParams extends CloudflareBaseParams export interface CloudflareListWorkerScriptsResponse extends ToolResponse { output: { - scripts: Array<{ - id: string - tag: string | null - etag: string | null - created_on: string | null - modified_on: string | null - usage_model: string | null - placement_mode: string | null - logpush: boolean | null - has_assets: boolean | null - has_modules: boolean | null - compatibility_date: string | null - compatibility_flags: string[] | null - routes: unknown[] | null - tail_consumers: unknown[] | null - }> + scripts: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -1257,19 +902,7 @@ export interface CloudflareGetWorkerScriptSettingsParams extends CloudflareBaseP } export interface CloudflareGetWorkerScriptSettingsResponse extends ToolResponse { - output: { - bindings: unknown[] | null - compatibility_date: string | null - compatibility_flags: string[] | null - limits: Record | null - logpush: boolean | null - migrations: Record | null - observability: Record | null - placement: Record | null - tags: string[] | null - tail_consumers: unknown[] | null - usage_model: string | null - } + output: CloudflareOutput } export interface CloudflareListWorkerRoutesParams extends CloudflareBaseParams { @@ -1278,31 +911,12 @@ export interface CloudflareListWorkerRoutesParams extends CloudflareBaseParams { export interface CloudflareListWorkerRoutesResponse extends ToolResponse { output: { - routes: Array<{ - id: string - pattern: string - script: string | null - }> + routes: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } -interface CloudflareTunnel { - id: string - name: string | null - account_tag: string | null - config_src: string | null - status: string | null - tun_type: string | null - remote_config: boolean | null - metadata: Record | null - created_at: string | null - deleted_at: string | null - conns_active_at: string | null - conns_inactive_at: string | null - connections: unknown[] | null -} - export interface CloudflareListTunnelsParams extends CloudflareBaseParams { accountId: string name?: string @@ -1320,8 +934,9 @@ export interface CloudflareListTunnelsParams extends CloudflareBaseParams { export interface CloudflareListTunnelsResponse extends ToolResponse { output: { - tunnels: CloudflareTunnel[] + tunnels: CloudflareOutput[] total_count: number + result_info: CloudflareResultInfo | null } } @@ -1331,7 +946,7 @@ export interface CloudflareGetTunnelParams extends CloudflareBaseParams { } export interface CloudflareTunnelResponse extends ToolResponse { - output: CloudflareTunnel + output: CloudflareOutput } export interface CloudflareGetTunnelConfigurationParams extends CloudflareBaseParams { @@ -1340,12 +955,5 @@ export interface CloudflareGetTunnelConfigurationParams extends CloudflareBasePa } export interface CloudflareGetTunnelConfigurationResponse extends ToolResponse { - output: { - tunnel_id: string - account_id: string - version: number | null - source: string | null - created_at: string | null - config: Record | null - } + output: CloudflareOutput } diff --git a/apps/sim/tools/cloudflare/update_access_application.ts b/apps/sim/tools/cloudflare/update_access_application.ts index 493476f2dcd..c2aa6f7e668 100644 --- a/apps/sim/tools/cloudflare/update_access_application.ts +++ b/apps/sim/tools/cloudflare/update_access_application.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { ACCESS_APPLICATION_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessApplicationResponse, CloudflareUpdateAccessApplicationParams, @@ -5,13 +7,14 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyAccessApplication, - mapAccessApplication, + mapCloudflareFields, parseCsvParam, parseJsonArrayParam, parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateAccessApplicationTool: ToolConfig< CloudflareUpdateAccessApplicationParams, @@ -24,6 +27,188 @@ export const updateAccessApplicationTool: ToolConfig< version: '1.0.0', params: { + destinations: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. List of destinations secured by Access. This supersedes `self_hosted_domains` to allow for more flexibility in defining different types of domains. If `destinations` are provided, then `self_hosted_domains` will be ignored. Fields: overrides, type, uri, cidr, hostname, l4_protocol, port_range, vnet_id, mcp_server_id, worker_id.', + }, + oauth_configuration: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Required for end_user applications. **Beta:** Optional configuration for managing an OAuth authorization flow controlled by Access. When set, Access will act as the OAuth authorization server for this application. Only compatible with OAuth clients that support [RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707) (Resource Indicators for OAuth 2.0). This feature is currently in beta. Fields: dynamic_client_registration, enabled, grant.', + }, + self_hosted_domains: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. List of public domains that Access will secure. This field is deprecated in favor of `destinations` and will be supported until **November 21, 2025.** If `destinations` are provided, then `self_hosted_domains` will be ignored.', + }, + user_populations: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Required for end_user applications. The single user population associated with this application.', + }, + allow_authenticate_via_warp: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'When set to true, users can authenticate to this application using their WARP session. When set to false this application will always require direct IdP authentication. This setting always overrides the organization setting for WARP authentication.', + }, + allow_iframe: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables loading application content in an iFrame.', + }, + cors_headers: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. cors headers Fields: allow_all_headers, allow_all_methods, allow_all_origins, allow_credentials, allowed_headers, allowed_methods, allowed_origins, max_age.', + }, + custom_non_identity_deny_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The custom URL a user is redirected to when they are denied access to the application when failing non-identity rules.', + }, + custom_pages: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. The custom pages that will be displayed when applicable for this application', + }, + eager_redirect_cookie_setting: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Preemptively sets the Access session cookie on every hostname in a multi-hostname self-hosted application during the initial redirect chain, rather than setting it lazily on first visit. Defaults to true. Set to false to disable the eager redirect cookie behavior.', + }, + enable_binding_cookie: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Enables the binding cookie, which increases security against compromised authorization tokens and CSRF attacks.', + }, + http_only_cookie_attribute: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Enables the HttpOnly cookie attribute, which increases security against XSS attacks.', + }, + mfa_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, + options_preflight_bypass: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Allows options preflight requests to bypass Access authentication and go directly to the origin. Cannot turn on if cors_headers is set.', + }, + path_cookie_attribute: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + "Enables cookie paths to scope an application's JWT to the application path. If disabled, the JWT will scope to the hostname by default", + }, + read_service_tokens_from_header: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Allows matching Access Service Tokens passed HTTP in a single header with this name. This works as an alternative to the (CF-Access-Client-Id, CF-Access-Client-Secret) pair of headers. The header value will be interpreted as a json object similar to: { "cf-access-client-id": "", "cf-access-client-secret": "" }', + }, + same_site_cookie_attribute: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Sets the SameSite cookie setting, which provides increased security against CSRF attacks.', + }, + scim_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for provisioning to this application via SCIM. This is currently in closed beta. Fields: authentication, deactivate_on_delete, enabled, idp_uid, mappings, remote_uri.', + }, + service_auth_401_redirect: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Returns a 401 status code when the request is blocked by a Service Auth policy.', + }, + skip_interstitial: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables automatic authentication through cloudflared.', + }, + use_clientless_isolation_app_launcher_url: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Determines if users can access this application via a clientless browser isolation URL. This allows users to access private domains without connecting to Gateway. The option requires Clientless Browser Isolation to be set up with policies that allow users of this application.', + }, + app_launcher_logo_url: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The image URL of the logo shown in the App Launcher header.', + }, + bg_color: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The background color of the App Launcher page.', + }, + footer_links: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'JSON array. The links in the App Launcher footer. Fields: name, url.', + }, + header_bg_color: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The background color of the App Launcher header.', + }, + landing_page_design: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. The design of the App Launcher landing page shown to users when they log in. Fields: button_color, button_text_color, image_url, message, title.', + }, + skip_app_launcher_login_page: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Determines when to skip the App Launcher landing page.', + }, accountId: { type: 'string', required: true, @@ -41,7 +226,7 @@ export const updateAccessApplicationTool: ToolConfig< required: true, visibility: 'user-or-llm', description: - 'Application type: self_hosted, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be written through the API', + 'Application type: self_hosted, end_user, saas, ssh, vnc, app_launcher, warp, biso, bookmark, infrastructure, rdp, mcp, mcp_portal, or proxy_endpoint. dash_sso has no request variant and cannot be written through the API', }, domain: { type: 'string', @@ -135,7 +320,7 @@ export const updateAccessApplicationTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}`, method: 'PUT', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -176,88 +361,90 @@ export const updateAccessApplicationTool: ToolConfig< const targetCriteria = parseJsonArrayParam(params.targetCriteria, 'Target Criteria') if (targetCriteria) body.target_criteria = targetCriteria + if (params.destinations !== undefined && params.destinations !== '') + body.destinations = parseJsonArrayParam(params.destinations, 'destinations') + if (params.oauth_configuration !== undefined && params.oauth_configuration !== '') + body.oauth_configuration = parseJsonObjectParam( + params.oauth_configuration, + 'oauth_configuration' + ) + if (params.self_hosted_domains !== undefined && params.self_hosted_domains !== '') + body.self_hosted_domains = parseJsonArrayParam( + params.self_hosted_domains, + 'self_hosted_domains' + ) + if (params.user_populations !== undefined && params.user_populations !== '') + body.user_populations = parseJsonArrayParam(params.user_populations, 'user_populations') + if (params.allow_authenticate_via_warp !== undefined) + body.allow_authenticate_via_warp = params.allow_authenticate_via_warp + if (params.allow_iframe !== undefined) body.allow_iframe = params.allow_iframe + if (params.cors_headers !== undefined && params.cors_headers !== '') + body.cors_headers = parseJsonObjectParam(params.cors_headers, 'cors_headers') + if ( + params.custom_non_identity_deny_url !== undefined && + params.custom_non_identity_deny_url !== '' + ) + body.custom_non_identity_deny_url = params.custom_non_identity_deny_url + if (params.custom_pages !== undefined && params.custom_pages !== '') + body.custom_pages = parseJsonArrayParam(params.custom_pages, 'custom_pages') + if (params.eager_redirect_cookie_setting !== undefined) + body.eager_redirect_cookie_setting = params.eager_redirect_cookie_setting + if (params.enable_binding_cookie !== undefined) + body.enable_binding_cookie = params.enable_binding_cookie + if (params.http_only_cookie_attribute !== undefined) + body.http_only_cookie_attribute = params.http_only_cookie_attribute + if (params.mfa_config !== undefined && params.mfa_config !== '') + body.mfa_config = parseJsonObjectParam(params.mfa_config, 'mfa_config') + if (params.options_preflight_bypass !== undefined) + body.options_preflight_bypass = params.options_preflight_bypass + if (params.path_cookie_attribute !== undefined) + body.path_cookie_attribute = params.path_cookie_attribute + if ( + params.read_service_tokens_from_header !== undefined && + params.read_service_tokens_from_header !== '' + ) + body.read_service_tokens_from_header = params.read_service_tokens_from_header + if ( + params.same_site_cookie_attribute !== undefined && + params.same_site_cookie_attribute !== '' + ) + body.same_site_cookie_attribute = params.same_site_cookie_attribute + if (params.scim_config !== undefined && params.scim_config !== '') + body.scim_config = parseJsonObjectParam(params.scim_config, 'scim_config') + if (params.service_auth_401_redirect !== undefined) + body.service_auth_401_redirect = params.service_auth_401_redirect + if (params.skip_interstitial !== undefined) body.skip_interstitial = params.skip_interstitial + if (params.use_clientless_isolation_app_launcher_url !== undefined) + body.use_clientless_isolation_app_launcher_url = + params.use_clientless_isolation_app_launcher_url + if (params.app_launcher_logo_url !== undefined && params.app_launcher_logo_url !== '') + body.app_launcher_logo_url = params.app_launcher_logo_url + if (params.bg_color !== undefined && params.bg_color !== '') body.bg_color = params.bg_color + if (params.footer_links !== undefined && params.footer_links !== '') + body.footer_links = parseJsonArrayParam(params.footer_links, 'footer_links') + if (params.header_bg_color !== undefined && params.header_bg_color !== '') + body.header_bg_color = params.header_bg_color + if (params.landing_page_design !== undefined && params.landing_page_design !== '') + body.landing_page_design = parseJsonObjectParam( + params.landing_page_design, + 'landing_page_design' + ) + if (params.skip_app_launcher_login_page !== undefined) + body.skip_app_launcher_login_page = params.skip_app_launcher_login_page return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyAccessApplication(), - error: cloudflareErrorMessage(data, 'Failed to update Access application'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_APPLICATION_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update access application') } + : {}), } - - return { success: true, output: mapAccessApplication(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Access application identifier' }, - name: { type: 'string', description: 'Application name', optional: true }, - domain: { - type: 'string', - description: 'Primary hostname and path secured by Access', - optional: true, - }, - type: { type: 'string', description: 'Application type', optional: true }, - aud: { type: 'string', description: 'Audience tag used to verify Access JWTs', optional: true }, - session_duration: { - type: 'string', - description: 'How long an Access session stays valid', - optional: true, - }, - allowed_idps: { - type: 'array', - description: 'Identity provider IDs users may authenticate with', - items: { type: 'string', description: 'Identity provider ID' }, - optional: true, - }, - app_launcher_visible: { - type: 'boolean', - description: 'Whether the app appears in the App Launcher', - optional: true, - }, - auto_redirect_to_identity: { - type: 'boolean', - description: 'Whether users skip the identity provider picker', - optional: true, - }, - custom_deny_message: { - type: 'string', - description: 'Message shown when access is denied', - optional: true, - }, - custom_deny_url: { - type: 'string', - description: 'URL users are redirected to when access is denied', - optional: true, - }, - logo_url: { type: 'string', description: 'Logo image URL', optional: true }, - self_hosted_domains: { - type: 'array', - description: - 'Additional hostnames and paths secured by the application. Cloudflare deprecated this field in favour of destinations, which is the one to read on a current application', - items: { type: 'string', description: 'Hostname and path' }, - optional: true, - }, - destinations: { - type: 'json', - description: 'Public and private destinations secured by the application', - optional: true, - }, - tags: { - type: 'array', - description: 'Tags categorizing the application', - items: { type: 'string', description: 'Tag name' }, - optional: true, - }, - policies: { - type: 'json', - description: 'Access policies attached to the application', - optional: true, - }, }, + outputs: ACCESS_APPLICATION_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/update_access_group.ts b/apps/sim/tools/cloudflare/update_access_group.ts new file mode 100644 index 00000000000..9df2f55c15d --- /dev/null +++ b/apps/sim/tools/cloudflare/update_access_group.ts @@ -0,0 +1,102 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateAccessGroupParams, + CloudflareUpdateAccessGroupResponse, +} from '@/tools/cloudflare/operation-types' +import { ACCESS_GROUP_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + parseJsonArrayParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateAccessGroupTool: ToolConfig< + CloudflareUpdateAccessGroupParams, + CloudflareUpdateAccessGroupResponse +> = { + id: 'cloudflare_update_access_group', + name: 'Cloudflare Update Access Group', + description: + 'Updates a configured Access group. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + groupId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Group id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + exclude: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with a NOT logical operator. To match a policy, a user cannot meet any of the Exclude rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + include: { + type: 'json', + required: true, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with an OR logical operator. A user needs to meet only one of the Include rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + is_default: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Whether this is the default group', + }, + name: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'The name of the Access group.', + }, + require: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Rules evaluated with an AND logical operator. To match a policy, a user must meet all of the Require rules. Fields: group, any_valid_service_token, auth_context, auth_method, azureAD, certificate, common_name, geo, device_posture, email_domain, email_list, email, everyone, external_evaluation, github-organization, gsuite, login_method, ip_list, ip, okta, saml, oidc, service_token, linked_app_token, user_risk_score, cloudflare_account_member.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/groups/${safeUrlPathSegment(params.groupId, 'groupId')}`, + method: 'PUT', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + exclude: parseJsonArrayParam(params.exclude, 'exclude'), + include: parseJsonArrayParam(params.include, 'include'), + is_default: params.is_default, + name: params.name, + require: parseJsonArrayParam(params.require, 'require'), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_GROUP_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update access group') } : {}), + } + }, + outputs: ACCESS_GROUP_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_access_policy.ts b/apps/sim/tools/cloudflare/update_access_policy.ts index 529155a1d05..41f7204e032 100644 --- a/apps/sim/tools/cloudflare/update_access_policy.ts +++ b/apps/sim/tools/cloudflare/update_access_policy.ts @@ -1,3 +1,5 @@ +import { isRecordLike } from '@sim/utils/object' +import { ACCESS_POLICY_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareAccessPolicyResponse, CloudflareUpdateAccessPolicyParams, @@ -5,11 +7,13 @@ import type { import { cloudflareErrorMessage, cloudflareHeaders, - emptyAccessPolicy, - mapAccessPolicy, + mapCloudflareFields, parseJsonArrayParam, + parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateAccessPolicyTool: ToolConfig< CloudflareUpdateAccessPolicyParams, @@ -18,10 +22,31 @@ export const updateAccessPolicyTool: ToolConfig< id: 'cloudflare_update_access_policy', name: 'Cloudflare Update Access Policy', description: - 'Updates a Cloudflare Access (Zero Trust) policy on an application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: send every rule the policy should keep, because an omitted exclude or require rule may be dropped and widen who gets in. The change applies to live traffic immediately. Read the current policy with "List Access Policies" first. Requires an API token with Account Access: Apps and Policies Edit.', + 'Updates a Cloudflare Access (Zero Trust) policy on an application. Cloudflare does not document merge behavior for this PUT, so treat it as a replace: resend all settings to retain, including exclude, require, approval_groups, connection_rules, and mfa_config; omitted rules or security settings may be dropped and widen access. The change applies to live traffic immediately. Read the current policy with "List Access Policies" first. Requires an API token with Account Access: Apps and Policies Edit.', version: '1.0.0', params: { + approval_groups: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. Administrators who can approve a temporary authentication request. Fields: approvals_needed, email_addresses, email_list_uuid.', + }, + connection_rules: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. The rules that define how users may connect to the targets secured by your application. Fields: rdp, ssh.', + }, + mfa_config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configures multi-factor authentication (MFA) settings for infrastructure applications. Fields: allowed_authenticators, mfa_disabled, session_duration.', + }, accountId: { type: 'string', required: true, @@ -119,7 +144,7 @@ export const updateAccessPolicyTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/accounts/${params.accountId.trim()}/access/apps/${params.appId.trim()}/policies/${params.policyId.trim()}`, + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/apps/${safeUrlPathSegment(params.appId, 'appId')}/policies/${safeUrlPathSegment(params.policyId, 'policyId')}`, method: 'PUT', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -151,66 +176,26 @@ export const updateAccessPolicyTool: ToolConfig< body.purpose_justification_prompt = params.purposeJustificationPrompt } + if (params.approval_groups !== undefined && params.approval_groups !== '') + body.approval_groups = parseJsonArrayParam(params.approval_groups, 'approval_groups') + if (params.connection_rules !== undefined && params.connection_rules !== '') + body.connection_rules = parseJsonObjectParam(params.connection_rules, 'connection_rules') + if (params.mfa_config !== undefined && params.mfa_config !== '') + body.mfa_config = parseJsonObjectParam(params.mfa_config, 'mfa_config') return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyAccessPolicy(), - error: cloudflareErrorMessage(data, 'Failed to update Access policy'), - } + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ACCESS_POLICY_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update access policy') } + : {}), } - - return { success: true, output: mapAccessPolicy(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Policy identifier' }, - name: { type: 'string', description: 'Policy name', optional: true }, - decision: { - type: 'string', - description: 'Decision the policy applies: allow, deny, non_identity, or bypass', - optional: true, - }, - precedence: { - type: 'number', - description: 'Evaluation order of the policy within the application', - optional: true, - }, - include: { type: 'json', description: 'Rules evaluated with OR logic', optional: true }, - exclude: { type: 'json', description: 'Rules evaluated with NOT logic', optional: true }, - require: { type: 'json', description: 'Rules evaluated with AND logic', optional: true }, - session_duration: { - type: 'string', - description: 'How long a session granted by this policy stays valid', - optional: true, - }, - approval_required: { - type: 'boolean', - description: 'Whether an approver must grant each access request', - optional: true, - }, - isolation_required: { - type: 'boolean', - description: 'Whether the session must run in a remote browser', - optional: true, - }, - purpose_justification_required: { - type: 'boolean', - description: 'Whether users must state a reason for access', - optional: true, - }, - purpose_justification_prompt: { - type: 'string', - description: 'Prompt shown when a justification is required', - optional: true, - }, - created_at: { type: 'string', description: 'Creation timestamp', optional: true }, - updated_at: { type: 'string', description: 'Last update timestamp', optional: true }, }, + outputs: ACCESS_POLICY_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/update_access_service_token.ts b/apps/sim/tools/cloudflare/update_access_service_token.ts new file mode 100644 index 00000000000..6c664846b90 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_access_service_token.ts @@ -0,0 +1,107 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateAccessServiceTokenParams, + CloudflareUpdateAccessServiceTokenResponse, +} from '@/tools/cloudflare/operation-types' +import { SERVICE_TOKEN_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateAccessServiceTokenTool: ToolConfig< + CloudflareUpdateAccessServiceTokenParams, + CloudflareUpdateAccessServiceTokenResponse +> = { + id: 'cloudflare_update_access_service_token', + name: 'Cloudflare Update Access Service Token', + description: + 'Updates a configured service token. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + serviceTokenId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Service token id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + client_secret_version: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'A version number identifying the current `client_secret` associated with the service token. Incrementing it triggers a rotation; the previous secret will still be accepted until the time indicated by `previous_client_secret_expires_at`. If the service token was reported as leaked, `previous_client_secret_expires_at` is not required, may not be in the future, and the previous secret is discarded immediately.', + }, + duration: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The duration for how long the service token will be valid. Must be in the format `300ms` or `2h45m`, or the special value `forever` for non-expiring tokens. Valid time units are: ns, us (or \u00b5s), ms, s, m, h. The default is 1 year in hours (8760h).', + }, + enabled: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether the service token is enabled. A disabled service token cannot be used to authenticate; both its current and previous `client_secret` stop being accepted, but the token itself is preserved and can be re-enabled. A service token reported as leaked is disabled automatically and cannot be re-enabled until its secret is rotated; attempting to do so returns a 409. Defaults to enabled when omitted on create.', + }, + name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'The name of the service token.', + }, + previous_client_secret_expires_at: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'The expiration of the previous `client_secret`. This can be modified at any point after a rotation. For example, you may extend it further into the future if you need more time to update services with the new secret; or move it into the past to immediately invalidate the previous token in case of compromise. Rotating a service token that was reported as leaked discards the previous secret entirely, so no grace period can be set.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/access/service_tokens/${safeUrlPathSegment(params.serviceTokenId, 'serviceTokenId')}`, + method: 'PUT', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + client_secret_version: params.client_secret_version, + duration: params.duration, + enabled: params.enabled, + name: params.name, + previous_client_secret_expires_at: + params.previous_client_secret_expires_at === '' + ? undefined + : params.previous_client_secret_expires_at, + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, SERVICE_TOKEN_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update access service token') } + : {}), + } + }, + outputs: SERVICE_TOKEN_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_dns_record.ts b/apps/sim/tools/cloudflare/update_dns_record.ts index 7f86743d0a0..74f12bec3c7 100644 --- a/apps/sim/tools/cloudflare/update_dns_record.ts +++ b/apps/sim/tools/cloudflare/update_dns_record.ts @@ -1,8 +1,19 @@ +import { isRecordLike } from '@sim/utils/object' +import { DNS_RECORD_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareUpdateDnsRecordParams, CloudflareUpdateDnsRecordResponse, } from '@/tools/cloudflare/types' +import { + appendParam, + cloudflareErrorMessage, + mapCloudflareFields, + parseCsvParam, + parseJsonObjectParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateDnsRecordTool: ToolConfig< CloudflareUpdateDnsRecordParams, @@ -14,6 +25,39 @@ export const updateDnsRecordTool: ToolConfig< version: '1.0.0', params: { + clearComment: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Clear the stored DNS record comment', + }, + settings: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Settings for the DNS record. Fields: ipv4_only, ipv6_only, flatten_cname.', + }, + private_routing: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Enables private network routing to the origin.', + }, + data: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Structured record data. The available fields depend on the DNS record type. Fields: flags, tag, value, algorithm, certificate, key_tag, type, protocol, public_key, digest, digest_type, priority, target, altitude, lat_degrees, lat_direction, lat_minutes, lat_seconds, long_degrees, long_direction, long_minutes, long_seconds, precision_horz, precision_vert, size, order, preference, regex, replacement, service, matching_type, selector, usage, port, weight, fingerprint.', + }, + include_shadow_metadata: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Whether to include shadow metadata in the `meta` field of each record in the response. See [Shadowed records](https://developers.cloudflare.com/dns/manage-dns-records/reference/shadowed-records).', + }, zoneId: { type: 'string', required: true, @@ -61,7 +105,7 @@ export const updateDnsRecordTool: ToolConfig< required: false, visibility: 'user-or-llm', description: - 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; an SRV record carries its priority, weight, port, and target inside the record content instead', + 'Record priority. Cloudflare accepts this top-level field for MX and URI records only; use the data object for structured records such as SRV (priority, weight, port, target)', }, comment: { type: 'string', @@ -84,8 +128,13 @@ export const updateDnsRecordTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/dns_records/${params.recordId.trim()}`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/dns_records/${safeUrlPathSegment(params.recordId, 'recordId')}` + ) + appendParam(url, 'include_shadow_metadata', params.include_shadow_metadata) + return url.toString() + }, method: 'PATCH', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, @@ -107,123 +156,26 @@ export const updateDnsRecordTool: ToolConfig< if (params.proxied !== undefined) body.proxied = params.proxied if (params.priority !== undefined) body.priority = Number(params.priority) if (params.comment !== undefined) body.comment = params.comment - if (params.tags) { - const tagList = String(params.tags) - .split(',') - .map((t) => t.trim()) - .filter(Boolean) - if (tagList.length > 0) body.tags = tagList - } + const tags = parseCsvParam(params.tags) + if (tags) body.tags = tags + if (params.settings !== undefined && params.settings !== '') + body.settings = parseJsonObjectParam(params.settings, 'settings') + if (params.private_routing !== undefined) body.private_routing = params.private_routing + if (params.data !== undefined && params.data !== '') + body.data = parseJsonObjectParam(params.data, 'data') + if (params.clearComment === true) body.comment = '' return body }, }, transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: { - id: '', - zone_id: '', - zone_name: '', - type: '', - name: '', - content: '', - proxiable: false, - proxied: false, - ttl: 0, - locked: false, - priority: undefined, - comment: null, - tags: [], - comment_modified_on: null, - tags_modified_on: null, - meta: null, - created_on: '', - modified_on: '', - }, - error: data.errors?.[0]?.message ?? 'Failed to update DNS record', - } - } - - const record = data.result + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) return { - success: true, - output: { - id: record?.id ?? '', - zone_id: record?.zone_id ?? '', - zone_name: record?.zone_name ?? '', - type: record?.type ?? '', - name: record?.name ?? '', - content: record?.content ?? '', - proxiable: record?.proxiable ?? false, - proxied: record?.proxied ?? false, - ttl: record?.ttl ?? 0, - locked: record?.locked ?? false, - priority: record?.priority ?? null, - comment: record?.comment ?? null, - tags: record?.tags ?? [], - comment_modified_on: record?.comment_modified_on ?? null, - tags_modified_on: record?.tags_modified_on ?? null, - meta: record?.meta ?? null, - created_on: record?.created_on ?? '', - modified_on: record?.modified_on ?? '', - }, + success, + output: mapCloudflareFields(data.result, DNS_RECORD_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update dns record') } : {}), } }, - - outputs: { - id: { type: 'string', description: 'Unique identifier for the updated DNS record' }, - zone_id: { type: 'string', description: 'The ID of the zone the record belongs to' }, - zone_name: { type: 'string', description: 'The name of the zone' }, - type: { type: 'string', description: 'DNS record type (A, AAAA, CNAME, MX, TXT, etc.)' }, - name: { type: 'string', description: 'DNS record hostname' }, - content: { - type: 'string', - description: 'DNS record value (e.g., IP address, target hostname)', - }, - proxiable: { - type: 'boolean', - description: 'Whether the record can be proxied through Cloudflare', - }, - proxied: { type: 'boolean', description: 'Whether Cloudflare proxy is enabled' }, - ttl: { type: 'number', description: 'Time to live in seconds (1 = automatic)' }, - locked: { type: 'boolean', description: 'Whether the record is locked' }, - priority: { - type: 'number', - description: 'Record priority, returned for MX and URI records', - optional: true, - }, - comment: { type: 'string', description: 'Comment associated with the record', optional: true }, - tags: { - type: 'array', - description: 'Tags associated with the record', - items: { type: 'string', description: 'Tag value' }, - }, - comment_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the comment was last modified', - optional: true, - }, - tags_modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when tags were last modified', - optional: true, - }, - meta: { - type: 'object', - description: 'Record metadata', - optional: true, - properties: { - source: { type: 'string', description: 'Source of the DNS record' }, - }, - }, - created_on: { type: 'string', description: 'ISO 8601 timestamp when the record was created' }, - modified_on: { - type: 'string', - description: 'ISO 8601 timestamp when the record was last modified', - }, - }, + outputs: DNS_RECORD_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/update_r2_bucket_cors.ts b/apps/sim/tools/cloudflare/update_r2_bucket_cors.ts new file mode 100644 index 00000000000..d6786750070 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_r2_bucket_cors.ts @@ -0,0 +1,79 @@ +import type { + CloudflareUpdateR2BucketCorsParams, + CloudflareUpdateR2BucketCorsResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + parseJsonArrayParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateR2BucketCorsTool: ToolConfig< + CloudflareUpdateR2BucketCorsParams, + CloudflareUpdateR2BucketCorsResponse +> = { + id: 'cloudflare_update_r2_bucket_cors', + name: 'Cloudflare Update R2 Bucket Cors', + description: + 'Replaces the Cross-Origin Resource Sharing (CORS) rules for an R2 bucket. Rules specify which origins, methods, and headers are allowed for browser requests to objects in the bucket. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + bucketName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Bucket name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + rules: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: 'JSON array. rules Fields: allowed, exposeHeaders, id, maxAgeSeconds.', + }, + jurisdiction: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Jurisdiction where objects in this bucket are guaranteed to be stored.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}/cors`, + method: 'PUT', + headers: (params) => ({ + ...cloudflareHeaders(params.apiKey), + ...(params.jurisdiction ? { 'cf-r2-jurisdiction': params.jurisdiction } : {}), + }), + body: (params) => ({ rules: parseJsonArrayParam(params.rules, 'rules') }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true + return { + success, + output: { success }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update r2 bucket cors') } + : {}), + } + }, + outputs: { + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + }, +} diff --git a/apps/sim/tools/cloudflare/update_r2_bucket_lifecycle.ts b/apps/sim/tools/cloudflare/update_r2_bucket_lifecycle.ts new file mode 100644 index 00000000000..f3edb70d235 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_r2_bucket_lifecycle.ts @@ -0,0 +1,80 @@ +import type { + CloudflareUpdateR2BucketLifecycleParams, + CloudflareUpdateR2BucketLifecycleResponse, +} from '@/tools/cloudflare/operation-types' +import { + cloudflareErrorMessage, + cloudflareHeaders, + parseJsonArrayParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateR2BucketLifecycleTool: ToolConfig< + CloudflareUpdateR2BucketLifecycleParams, + CloudflareUpdateR2BucketLifecycleResponse +> = { + id: 'cloudflare_update_r2_bucket_lifecycle', + name: 'Cloudflare Update R2 Bucket Lifecycle', + description: + 'Replaces the object lifecycle rules for an R2 bucket. Rules match object-key prefixes and can expire objects, abort incomplete multipart uploads, or transition objects to Infrequent Access storage. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + bucketName: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Bucket name', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + rules: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. rules Fields: abortMultipartUploadsTransition, conditions, deleteObjectsTransition, enabled, id, storageClassTransitions.', + }, + jurisdiction: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Jurisdiction where objects in this bucket are guaranteed to be stored.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/r2/buckets/${safeUrlPathSegment(params.bucketName, 'bucketName')}/lifecycle`, + method: 'PUT', + headers: (params) => ({ + ...cloudflareHeaders(params.apiKey), + ...(params.jurisdiction ? { 'cf-r2-jurisdiction': params.jurisdiction } : {}), + }), + body: (params) => ({ rules: parseJsonArrayParam(params.rules, 'rules') }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true + return { + success, + output: { success }, + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update r2 bucket lifecycle') } + : {}), + } + }, + outputs: { + success: { type: 'boolean', description: 'Whether Cloudflare accepted the operation' }, + }, +} diff --git a/apps/sim/tools/cloudflare/update_rate_limit_rule.ts b/apps/sim/tools/cloudflare/update_rate_limit_rule.ts index bedd37d6108..e5726c46848 100644 --- a/apps/sim/tools/cloudflare/update_rate_limit_rule.ts +++ b/apps/sim/tools/cloudflare/update_rate_limit_rule.ts @@ -1,16 +1,20 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareRulesetResponse, CloudflareUpdateRateLimitRuleParams, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, parseCsvParam, parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateRateLimitRuleTool: ToolConfig< CloudflareUpdateRateLimitRuleParams, @@ -23,6 +27,40 @@ export const updateRateLimitRuleTool: ToolConfig< version: '1.0.0', params: { + exposed_credential_check: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + position: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. An object configuring where the rule will be placed. Fields: before, after, index.', + }, + score_per_period: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: + 'The score threshold per period for which the action will be executed the first time.', + }, + score_response_header_name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A response header name provided by the origin, which contains the score to increment rate limit counter with.', + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -136,8 +174,13 @@ export const updateRateLimitRuleTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}/rules/${params.ruleId.trim()}`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}/rules/${safeUrlPathSegment(params.ruleId, 'ruleId')}` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'PATCH', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -181,72 +224,34 @@ export const updateRateLimitRuleTool: ToolConfig< const logging = parseJsonObjectParam(params.logging, 'Logging Configuration') if (logging) body.logging = logging + if (params.exposed_credential_check !== undefined && params.exposed_credential_check !== '') + body.exposed_credential_check = parseJsonObjectParam( + params.exposed_credential_check, + 'exposed_credential_check' + ) + if (params.position !== undefined && params.position !== '') + body.position = parseJsonObjectParam(params.position, 'position') + if (params.score_per_period !== undefined) + ratelimit.score_per_period = params.score_per_period + if (params.score_response_header_name !== undefined) + ratelimit.score_response_header_name = params.score_response_header_name return body }, }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to update rate limiting rule'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update rate limit rule') } + : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset ID of the http_ratelimit entry point' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind' }, - phase: { type: 'string', description: 'Phase the ruleset runs in (http_ratelimit)' }, - version: { type: 'string', description: 'Ruleset version after the change', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rate limiting rules after the change, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { type: 'string', description: 'Action applied once the limit is exceeded' }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters', - optional: true, - }, - expression: { type: 'string', description: 'Filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { - type: 'json', - description: 'Rate limiting configuration applied to the rule', - optional: true, - }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/update_ruleset.ts b/apps/sim/tools/cloudflare/update_ruleset.ts new file mode 100644 index 00000000000..6e8beef1b8a --- /dev/null +++ b/apps/sim/tools/cloudflare/update_ruleset.ts @@ -0,0 +1,95 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateRulesetParams, + CloudflareUpdateRulesetResponse, +} from '@/tools/cloudflare/operation-types' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + appendParam, + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareRuleset, + parseJsonArrayParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateRulesetTool: ToolConfig< + CloudflareUpdateRulesetParams, + CloudflareUpdateRulesetResponse +> = { + id: 'cloudflare_update_ruleset', + name: 'Cloudflare Update Ruleset', + description: + 'Updates the description and rules of a zone ruleset, creating a new version. Read the current rules with "Get Ruleset" before replacing the list. The rules array replaces the complete list: include every existing rule you want to keep; omitted rules are removed. Use "Create Ruleset Rule" to add a single rule without replacing the list.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + rulesetId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Ruleset id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + description: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'An informative description of the ruleset.', + }, + rules: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array replacing the complete rule list. Read "Get Ruleset" first and include every rule to retain; omitted rules are removed, and [] removes all rules. Fields: action, action_parameters, categories, description, enabled, exposed_credential_check, expression, id, last_updated, logging, ratelimit, ref, version.', + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Validates the request without persisting changes when set to `true`. Responses that normally return 200 return `result: null`; endpoints that normally return 204 continue to return 204.', + }, + }, + request: { + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, + method: 'PUT', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + description: params.description, + rules: parseJsonArrayParam(params.rules, 'rules'), + }), + }, + transformResponse: async (response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update ruleset') } : {}), + } + }, + outputs: RULESET_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_ruleset_rule.ts b/apps/sim/tools/cloudflare/update_ruleset_rule.ts index 918dd7e557c..82006f37b67 100644 --- a/apps/sim/tools/cloudflare/update_ruleset_rule.ts +++ b/apps/sim/tools/cloudflare/update_ruleset_rule.ts @@ -1,15 +1,19 @@ +import { isRecordLike } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' import type { CloudflareRulesetResponse, CloudflareUpdateRulesetRuleParams, } from '@/tools/cloudflare/types' import { + appendParam, cloudflareErrorMessage, cloudflareHeaders, - emptyRuleset, - mapRuleset, + mapCloudflareRuleset, parseJsonObjectParam, + readCloudflareResponse, } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateRulesetRuleTool: ToolConfig< CloudflareUpdateRulesetRuleParams, @@ -22,6 +26,26 @@ export const updateRulesetRuleTool: ToolConfig< version: '1.0.0', params: { + exposed_credential_check: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. Configuration for exposed credential checking. Fields: password_expression, username_expression.', + }, + position: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. An object configuring where the rule will be placed. Fields: before, after, index.', + }, + dry_run: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'dry run', + }, zoneId: { type: 'string', required: true, @@ -103,8 +127,13 @@ export const updateRulesetRuleTool: ToolConfig< }, request: { - url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/rulesets/${params.rulesetId.trim()}/rules/${params.ruleId.trim()}`, + url: (params) => { + const url = new URL( + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/rulesets/${safeUrlPathSegment(params.rulesetId, 'rulesetId')}/rules/${safeUrlPathSegment(params.ruleId, 'ruleId')}` + ) + appendParam(url, 'dry_run', params.dry_run) + return url.toString() + }, method: 'PATCH', headers: (params) => cloudflareHeaders(params.apiKey), body: (params) => { @@ -138,68 +167,28 @@ export const updateRulesetRuleTool: ToolConfig< const logging = parseJsonObjectParam(params.logging, 'Logging Configuration') if (logging) body.logging = logging + if (params.exposed_credential_check !== undefined && params.exposed_credential_check !== '') + body.exposed_credential_check = parseJsonObjectParam( + params.exposed_credential_check, + 'exposed_credential_check' + ) + if (params.position !== undefined && params.position !== '') + body.position = parseJsonObjectParam(params.position, 'position') return body }, }, - transformResponse: async (response: Response) => { - const data = await response.json() - - if (!data.success) { - return { - success: false, - output: emptyRuleset(), - error: cloudflareErrorMessage(data, 'Failed to update ruleset rule'), - } + transformResponse: async (response: Response, params) => { + const data = await readCloudflareResponse(response) + const success = + response.ok && + data.success === true && + (isRecordLike(data.result) || (params?.dry_run === true && data.result === null)) + return { + success, + output: mapCloudflareRuleset(data.result), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update ruleset rule') } : {}), } - - return { success: true, output: mapRuleset(data.result) } - }, - - outputs: { - id: { type: 'string', description: 'Ruleset identifier' }, - name: { type: 'string', description: 'Ruleset name' }, - description: { type: 'string', description: 'Ruleset description' }, - kind: { type: 'string', description: 'Ruleset kind (managed, custom, root, or zone)' }, - phase: { type: 'string', description: 'Phase the ruleset runs in' }, - version: { type: 'string', description: 'Ruleset version after the change', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - rules: { - type: 'array', - description: 'Rules in the ruleset after the change, in evaluation order', - items: { - type: 'object', - properties: { - id: { type: 'string', description: 'Rule identifier' }, - version: { type: 'string', description: 'Rule version', optional: true }, - action: { type: 'string', description: 'Action the rule performs' }, - action_parameters: { - type: 'json', - description: 'Action-specific parameters', - optional: true, - }, - expression: { type: 'string', description: 'Filter expression' }, - description: { type: 'string', description: 'Rule description' }, - enabled: { type: 'boolean', description: 'Whether the rule is enabled' }, - ref: { type: 'string', description: 'Rule reference tag', optional: true }, - last_updated: { - type: 'string', - description: 'RFC 3339 timestamp of the last change', - optional: true, - }, - categories: { - type: 'array', - description: 'Managed-rule categories', - items: { type: 'string', description: 'Category tag' }, - }, - logging: { type: 'json', description: 'Logging configuration', optional: true }, - ratelimit: { type: 'json', description: 'Rate limiting configuration', optional: true }, - }, - }, - }, }, + outputs: RULESET_OUTPUTS, } diff --git a/apps/sim/tools/cloudflare/update_tunnel.ts b/apps/sim/tools/cloudflare/update_tunnel.ts new file mode 100644 index 00000000000..a13576c1958 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_tunnel.ts @@ -0,0 +1,74 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateTunnelParams, + CloudflareUpdateTunnelResponse, +} from '@/tools/cloudflare/operation-types' +import { TUNNEL_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateTunnelTool: ToolConfig< + CloudflareUpdateTunnelParams, + CloudflareUpdateTunnelResponse +> = { + id: 'cloudflare_update_tunnel', + name: 'Cloudflare Update Tunnel', + description: 'Updates the name or secret of an existing Cloudflare Tunnel.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + tunnelId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Tunnel id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + name: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'A user-friendly name for a tunnel.', + }, + tunnel_secret: { + type: 'string', + required: false, + visibility: 'user-only', + description: + 'Sets the password required to run a locally-managed tunnel. Must be at least 32 bytes and encoded as a base64 string.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}`, + method: 'PATCH', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ name: params.name, tunnel_secret: params.tunnel_secret }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, TUNNEL_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update tunnel') } : {}), + } + }, + outputs: TUNNEL_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_tunnel_configuration.ts b/apps/sim/tools/cloudflare/update_tunnel_configuration.ts new file mode 100644 index 00000000000..e4b61af9d55 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_tunnel_configuration.ts @@ -0,0 +1,72 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateTunnelConfigurationParams, + CloudflareUpdateTunnelConfigurationResponse, +} from '@/tools/cloudflare/operation-types' +import { TUNNEL_CONFIGURATION_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + parseJsonObjectParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateTunnelConfigurationTool: ToolConfig< + CloudflareUpdateTunnelConfigurationParams, + CloudflareUpdateTunnelConfigurationResponse +> = { + id: 'cloudflare_update_tunnel_configuration', + name: 'Cloudflare Update Tunnel Configuration', + description: + 'Replaces the configuration for a remotely managed Cloudflare Tunnel, including its ingress rules and origin request settings. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + accountId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Account id', + }, + tunnelId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Tunnel id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + config: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON object. The tunnel configuration and ingress rules. Fields: ingress, originRequest, warp-routing.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/accounts/${safeUrlPathSegment(params.accountId, 'accountId')}/cfd_tunnel/${safeUrlPathSegment(params.tunnelId, 'tunnelId')}/configurations`, + method: 'PUT', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ config: parseJsonObjectParam(params.config, 'config') }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, TUNNEL_CONFIGURATION_OUTPUTS), + ...(!success + ? { error: cloudflareErrorMessage(data, 'Failed to update tunnel configuration') } + : {}), + } + }, + outputs: TUNNEL_CONFIGURATION_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_worker_route.ts b/apps/sim/tools/cloudflare/update_worker_route.ts new file mode 100644 index 00000000000..e89a3806425 --- /dev/null +++ b/apps/sim/tools/cloudflare/update_worker_route.ts @@ -0,0 +1,75 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateWorkerRouteParams, + CloudflareUpdateWorkerRouteResponse, +} from '@/tools/cloudflare/operation-types' +import { WORKER_ROUTE_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateWorkerRouteTool: ToolConfig< + CloudflareUpdateWorkerRouteParams, + CloudflareUpdateWorkerRouteResponse +> = { + id: 'cloudflare_update_worker_route', + name: 'Cloudflare Update Worker Route', + description: + 'Replaces the URL pattern or Worker associated with a Worker route. Replaces the configuration; resend all values to retain.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + routeId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Route id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + pattern: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: + 'Pattern to match incoming requests against. [Learn more](https://developers.cloudflare.com/workers/configuration/routing/routes/#matching-behavior).', + }, + script: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Name of the script to run if the route matches.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/workers/routes/${safeUrlPathSegment(params.routeId, 'routeId')}`, + method: 'PUT', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ pattern: params.pattern, script: params.script }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, WORKER_ROUTE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update worker route') } : {}), + } + }, + outputs: WORKER_ROUTE_OUTPUTS, +} diff --git a/apps/sim/tools/cloudflare/update_zone.ts b/apps/sim/tools/cloudflare/update_zone.ts new file mode 100644 index 00000000000..ca1d0e2da4c --- /dev/null +++ b/apps/sim/tools/cloudflare/update_zone.ts @@ -0,0 +1,88 @@ +import { isRecordLike } from '@sim/utils/object' +import type { + CloudflareUpdateZoneParams, + CloudflareUpdateZoneResponse, +} from '@/tools/cloudflare/operation-types' +import { ZONE_OUTPUTS } from '@/tools/cloudflare/outputs' +import { + cloudflareErrorMessage, + cloudflareHeaders, + mapCloudflareFields, + parseJsonArrayParam, + parseJsonObjectParam, + readCloudflareResponse, +} from '@/tools/cloudflare/utils' +import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' + +export const updateZoneTool: ToolConfig = + { + id: 'cloudflare_update_zone', + name: 'Cloudflare Update Zone', + description: 'Edits a zone. Only one zone property can be changed at a time.', + version: '1.0.0', + params: { + zoneId: { + type: 'string', + required: true, + visibility: 'user-or-llm', + description: 'Zone id', + }, + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Cloudflare API token', + }, + paused: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Indicates whether the zone is only using Cloudflare DNS services. A true value means the zone will not receive security or performance benefits.', + }, + plan: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + "JSON object. (Deprecated) Please use the `/zones/{zone_id}/subscription` API to update a zone's plan. Changing this value will create/cancel associated subscriptions. To view available plans for this zone, see Zone Plans. Fields: id.", + }, + type: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'A full zone implies that DNS is hosted with Cloudflare. A partial zone is typically a partner-hosted zone or a CNAME setup. This parameter is only available to Enterprise customers or if it has been explicitly enabled on a zone. Allowed values: full, partial, secondary, internal.', + }, + vanity_name_servers: { + type: 'json', + required: false, + visibility: 'user-or-llm', + description: + 'JSON array. An array of domains used for custom name servers. This is only available for Business and Enterprise plans.', + }, + }, + request: { + url: (params) => + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}`, + method: 'PATCH', + headers: (params) => ({ ...cloudflareHeaders(params.apiKey) }), + body: (params) => ({ + paused: params.paused, + plan: parseJsonObjectParam(params.plan, 'plan'), + type: params.type, + vanity_name_servers: parseJsonArrayParam(params.vanity_name_servers, 'vanity_name_servers'), + }), + }, + transformResponse: async (response) => { + const data = await readCloudflareResponse(response) + const success = response.ok && data.success === true && isRecordLike(data.result) + return { + success, + output: mapCloudflareFields(data.result, ZONE_OUTPUTS), + ...(!success ? { error: cloudflareErrorMessage(data, 'Failed to update zone') } : {}), + } + }, + outputs: ZONE_OUTPUTS, + } diff --git a/apps/sim/tools/cloudflare/update_zone_setting.ts b/apps/sim/tools/cloudflare/update_zone_setting.ts index c7ba09db206..ba96bca3546 100644 --- a/apps/sim/tools/cloudflare/update_zone_setting.ts +++ b/apps/sim/tools/cloudflare/update_zone_setting.ts @@ -1,8 +1,13 @@ +import { isRecordLike } from '@sim/utils/object' +import { mapZoneSetting } from '@/tools/cloudflare/get_zone_settings' import type { + CloudflareRawZoneSetting, CloudflareUpdateZoneSettingParams, CloudflareUpdateZoneSettingResponse, } from '@/tools/cloudflare/types' +import { readCloudflareResponse } from '@/tools/cloudflare/utils' import type { ToolConfig } from '@/tools/types' +import { safeUrlPathSegment } from '@/tools/url-path' export const updateZoneSettingTool: ToolConfig< CloudflareUpdateZoneSettingParams, @@ -15,6 +20,13 @@ export const updateZoneSettingTool: ToolConfig< version: '1.0.0', params: { + enabled: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: + 'Enrollment value for ssl_recommender; this setting uses enabled instead of value', + }, zoneId: { type: 'string', required: true, @@ -30,9 +42,9 @@ export const updateZoneSettingTool: ToolConfig< }, value: { type: 'string', - required: true, + required: false, visibility: 'user-or-llm', - description: `New value for the setting as a string, or a JSON string for complex values (e.g., "full" for SSL, "medium" for security_level, "aggressive" for cache_level, ["ECDHE-RSA-AES128-GCM-SHA256"] for ciphers)`, + description: `Required except for ssl_recommender. New value as a string, or a JSON string for complex values (e.g., "full" for SSL, "medium" for security_level, "aggressive" for cache_level, ["ECDHE-RSA-AES128-GCM-SHA256"] for ciphers)`, }, apiKey: { type: 'string', @@ -44,30 +56,38 @@ export const updateZoneSettingTool: ToolConfig< request: { url: (params) => - `https://api.cloudflare.com/client/v4/zones/${params.zoneId.trim()}/settings/${params.settingId.trim()}`, + `https://api.cloudflare.com/client/v4/zones/${safeUrlPathSegment(params.zoneId, 'zoneId')}/settings/${safeUrlPathSegment(params.settingId, 'settingId')}`, method: 'PATCH', headers: (params) => ({ Authorization: `Bearer ${params.apiKey}`, 'Content-Type': 'application/json', }), body: (params) => { - // A block reference can pass an already-structured array/object straight - // through despite the declared string param type — send it as-is rather - // than stringifying it (String([...]) comma-joins, String({...}) yields - // "[object Object]", neither of which is the JSON shape Cloudflare expects). + if (params.settingId.trim() === 'ssl_recommender') { + if (typeof params.enabled !== 'boolean') + throw new Error('enabled is required for ssl_recommender') + return { enabled: params.enabled } + } + if (params.value === undefined || params.value === null) + throw new Error('value is required for this zone setting') + // Resolved block outputs may already be structured JSON. if (params.value !== null && typeof params.value === 'object') { return { value: params.value } } - // Wand-generated values can also arrive as a non-string primitive - // (e.g. a number, or null/undefined) at runtime despite the declared - // param type — coerce null/undefined to '' rather than the literal - // "null"/"undefined" strings String() would otherwise produce. - const trimmed = (params.value == null ? '' : String(params.value)).trim() + const trimmed = String(params.value).trim() - // browser_cache_ttl is the one setting whose value must be a number. - // Number('') is 0, not NaN, so an empty value must be rejected explicitly. - if (params.settingId === 'browser_cache_ttl') { + // Number('') is zero, so preserve empty numeric input for the provider's validation. + if ( + [ + 'browser_cache_ttl', + 'challenge_ttl', + 'edge_cache_ttl', + 'max_upload', + 'origin_h2_max_streams', + 'proxy_read_timeout', + ].includes(params.settingId.trim()) + ) { const numeric = trimmed === '' ? Number.NaN : Number(trimmed) return { value: Number.isNaN(numeric) ? trimmed : numeric } } @@ -87,9 +107,9 @@ export const updateZoneSettingTool: ToolConfig< }, transformResponse: async (response: Response) => { - const data = await response.json() + const data = await readCloudflareResponse(response) - if (!data.success) { + if (!response.ok || data.success !== true || !isRecordLike(data.result)) { return { success: false, output: { id: '', value: '', editable: false, modified_on: '' }, @@ -100,18 +120,7 @@ export const updateZoneSettingTool: ToolConfig< const setting = data.result return { success: true, - output: { - id: setting?.id ?? '', - value: - typeof setting?.value === 'object' && setting?.value !== null - ? JSON.stringify(setting.value) - : String(setting?.value ?? ''), - editable: setting?.editable ?? false, - modified_on: setting?.modified_on ?? '', - ...(setting?.time_remaining != null - ? { time_remaining: setting.time_remaining as number } - : {}), - }, + output: mapZoneSetting(typeof setting.id === 'string' ? setting.id : '', setting), } }, @@ -123,7 +132,7 @@ export const updateZoneSettingTool: ToolConfig< value: { type: 'string', description: - 'Updated setting value as a string. Simple values returned as-is (e.g., "full", "on"). Complex values are JSON-stringified.', + 'Updated setting value as a string. Simple values returned as-is (e.g., "full", "on"). SSL Recommender returns its enabled flag. Complex values are JSON-stringified.', }, editable: { type: 'boolean', diff --git a/apps/sim/tools/cloudflare/utils.ts b/apps/sim/tools/cloudflare/utils.ts index f92b4bc7a36..3bc5d42412d 100644 --- a/apps/sim/tools/cloudflare/utils.ts +++ b/apps/sim/tools/cloudflare/utils.ts @@ -1,29 +1,30 @@ -/** - * Shared request/response helpers for the Cloudflare API tools. - * - * Every Cloudflare v4 endpoint answers with the same envelope: - * `{ success, errors, messages, result }`. A `200 OK` carrying - * `success: false` is a failure, so callers must always branch on - * `data.success` rather than on the HTTP status. - */ - -import type { - CloudflareEnvelope, - CloudflareRawAccessApplication, - CloudflareRawAccessPolicy, - CloudflareRawRuleset, -} from '@/tools/cloudflare/types' +import { isRecordLike, toRecord } from '@sim/utils/object' +import { RULESET_OUTPUTS } from '@/tools/cloudflare/outputs' +import type { CloudflareEnvelope } from '@/tools/cloudflare/types' +import type { ToolOutputProperty } from '@/tools/types' -/** - * Reads a Cloudflare v4 response body into the shared envelope shape, so the - * caller branches on a typed `success` flag and reads `result` through a checked - * payload type instead of an implicitly-`any` `response.json()`. Used by the - * tools whose `result` has a payload type in `types.ts`. - */ +/** Reads a Cloudflare response envelope; endpoints with no content handle 204 before calling. */ export async function readCloudflareResponse( - response: Response + response: Response, + options?: { allowEmptySuccess: boolean } ): Promise> { - return (await response.json()) as CloudflareEnvelope + let data: unknown + if (options?.allowEmptySuccess) { + const body = await response.text() + if (body.trim() === '') { + return response.ok + ? { success: true } + : { + success: false, + errors: [{ message: `Cloudflare returned HTTP ${response.status} with an empty body` }], + } + } + data = JSON.parse(body) + } else { + data = await response.json() + } + if (!isRecordLike(data)) throw new Error('Cloudflare returned an invalid response envelope') + return data as CloudflareEnvelope } /** Standard bearer-token headers for the Cloudflare v4 API. */ @@ -69,15 +70,23 @@ export function parseJsonObjectParam( ): Record | undefined { const parsed = parseJsonParam(value, fieldName) if (parsed === undefined) return undefined - if (typeof parsed !== 'object' || Array.isArray(parsed)) { + if (!isRecordLike(parsed)) { throw new Error(`${fieldName} must be a JSON object`) } return parsed as Record } -/** Splits a comma-separated string param into a trimmed, non-empty list. */ +/** Reads a comma-separated list or an explicit JSON string array, including [] to clear a list. */ export function parseCsvParam(value: unknown): string[] | undefined { - if (typeof value !== 'string' || value.trim() === '') return undefined + if (value === undefined || value === null || value === '') return undefined + if (Array.isArray(value) || (typeof value === 'string' && value.trim().startsWith('['))) { + const items = parseJsonArrayParam(value, 'List') + if (!items?.every((item) => typeof item === 'string')) + throw new Error('List must contain strings') + return items + } + if (typeof value !== 'string') + throw new Error('List must be comma-separated text or a JSON string array') const items = value .split(',') .map((item) => item.trim()) @@ -85,147 +94,42 @@ export function parseCsvParam(value: unknown): string[] | undefined { return items.length > 0 ? items : undefined } -/** - * Maps a Cloudflare ruleset `result` payload onto the flat ruleset output shape - * shared by the get-ruleset, phase-entrypoint, and rule mutation tools — every - * one of those endpoints answers with the full ruleset object. - */ -export function mapRuleset(ruleset: CloudflareRawRuleset | undefined) { - return { - id: ruleset?.id ?? '', - name: ruleset?.name ?? '', - description: ruleset?.description ?? '', - kind: ruleset?.kind ?? '', - phase: ruleset?.phase ?? '', - version: ruleset?.version ?? null, - last_updated: ruleset?.last_updated ?? null, - rules: Array.isArray(ruleset?.rules) - ? ruleset.rules.map((rule) => ({ - id: rule.id ?? '', - version: rule.version ?? null, - action: rule.action ?? '', - action_parameters: rule.action_parameters ?? null, - expression: rule.expression ?? '', - description: rule.description ?? '', - enabled: rule.enabled ?? false, - ref: rule.ref ?? null, - last_updated: rule.last_updated ?? null, - categories: rule.categories ?? [], - logging: rule.logging ?? null, - ratelimit: rule.ratelimit ?? null, - })) - : [], - } +type CloudflareValue = T extends { type: 'string' } + ? string + : T extends { type: 'number' } + ? number + : T extends { type: 'boolean' } + ? boolean + : T extends { type: 'array'; items: infer I } + ? CloudflareValue[] + : T extends { properties: infer P } + ? { [K in keyof P]?: CloudflareValue | null } + : unknown + +export type CloudflareOutput> = { + [K in keyof T]: T[K] extends { type: 'array' } + ? CloudflareValue + : CloudflareValue | null } -/** The empty ruleset payload returned alongside an error. */ -export function emptyRuleset() { - return { - id: '', - name: '', - description: '', - kind: '', - phase: '', - version: null, - last_updated: null, - rules: [], - } -} - -/** Maps a Cloudflare Access application `result` payload onto the flat output shape. */ -export function mapAccessApplication(app: CloudflareRawAccessApplication | undefined) { - return { - id: app?.id ?? '', - name: app?.name ?? null, - domain: app?.domain ?? null, - type: app?.type ?? null, - aud: app?.aud ?? null, - session_duration: app?.session_duration ?? null, - allowed_idps: app?.allowed_idps ?? null, - app_launcher_visible: app?.app_launcher_visible ?? null, - auto_redirect_to_identity: app?.auto_redirect_to_identity ?? null, - custom_deny_message: app?.custom_deny_message ?? null, - custom_deny_url: app?.custom_deny_url ?? null, - logo_url: app?.logo_url ?? null, - self_hosted_domains: app?.self_hosted_domains ?? null, - destinations: app?.destinations ?? null, - tags: app?.tags ?? null, - policies: app?.policies ?? null, - } -} - -/** The empty Access application payload returned alongside an error. */ -export function emptyAccessApplication() { - return { - id: '', - name: null, - domain: null, - type: null, - aud: null, - session_duration: null, - allowed_idps: null, - app_launcher_visible: null, - auto_redirect_to_identity: null, - custom_deny_message: null, - custom_deny_url: null, - logo_url: null, - self_hosted_domains: null, - destinations: null, - tags: null, - policies: null, - } -} - -/** Maps a Cloudflare Access policy `result` payload onto the flat output shape. */ -export function mapAccessPolicy(policy: CloudflareRawAccessPolicy | undefined) { - return { - id: policy?.id ?? '', - name: policy?.name ?? null, - decision: policy?.decision ?? null, - precedence: policy?.precedence ?? null, - include: policy?.include ?? null, - exclude: policy?.exclude ?? null, - require: policy?.require ?? null, - session_duration: policy?.session_duration ?? null, - approval_required: policy?.approval_required ?? null, - isolation_required: policy?.isolation_required ?? null, - purpose_justification_required: policy?.purpose_justification_required ?? null, - purpose_justification_prompt: policy?.purpose_justification_prompt ?? null, - created_at: policy?.created_at ?? null, - updated_at: policy?.updated_at ?? null, - } -} - -/** The empty Access policy payload returned alongside an error. */ -export function emptyAccessPolicy() { - return { - id: '', - name: null, - decision: null, - precedence: null, - include: null, - exclude: null, - require: null, - session_duration: null, - approval_required: null, - isolation_required: null, - purpose_justification_required: null, - purpose_justification_prompt: null, - created_at: null, - updated_at: null, - } +/** Projects documented provider fields, retaining absent arrays as empty lists and scalars as null. */ +export function mapCloudflareFields>( + value: unknown, + outputs: T +): CloudflareOutput { + const record = toRecord(value) + return Object.fromEntries( + Object.entries(outputs).map(([key, field]) => [ + key, + field.type === 'array' + ? Array.isArray(record[key]) + ? record[key] + : [] + : (record[key] ?? null), + ]) + ) as CloudflareOutput } -/** - * The zone settings "Get Zone Settings" reads when the caller names none. - * - * Cloudflare deprecated the batch `GET /zones/{zone_id}/settings` endpoint, - * which reaches end of life on 2027-03-31, and directs integrations at the - * per-setting `GET /zones/{zone_id}/settings/{setting_id}` endpoint. "Read the - * zone's settings" is therefore a fan-out over an explicit, bounded list rather - * than one request. - * https://developers.cloudflare.com/fundamentals/api/reference/deprecations/ - */ export const DEFAULT_ZONE_SETTING_IDS = [ 'ssl', 'always_use_https', @@ -257,3 +161,23 @@ export function appendParam(url: URL, key: string, value: unknown): void { if (value === undefined || value === null || value === '') return url.searchParams.append(key, String(value)) } + +/** Preserves the existing per-rule defaults while exposing the documented ruleset fields. */ +export function mapCloudflareRuleset(value: unknown) { + const output = mapCloudflareFields(value, RULESET_OUTPUTS) + return { + ...output, + rules: output.rules.map((rule) => { + const fields = mapCloudflareFields(rule, RULESET_OUTPUTS.rules.items.properties) + return { + ...fields, + id: fields.id ?? '', + action: fields.action ?? '', + expression: fields.expression ?? '', + description: fields.description ?? '', + enabled: fields.enabled ?? false, + categories: fields.categories ?? [], + } + }), + } +} diff --git a/apps/sim/tools/generated/tool-ids.ts b/apps/sim/tools/generated/tool-ids.ts index 5f9ed0665ab..84b08a7303d 100644 --- a/apps/sim/tools/generated/tool-ids.ts +++ b/apps/sim/tools/generated/tool-ids.ts @@ -3,7 +3,7 @@ /** Every registered tool id, including versioned variants. */ const toolIds: string[] = JSON.parse( - '["a2a_cancel_task","a2a_get_agent_card","a2a_get_task","a2a_send_message","affinity_batch_update_entity_fields","affinity_batch_update_list_entry_fields","affinity_create_list","affinity_create_list_field_dropdown_option","affinity_create_merge","affinity_create_note","affinity_create_reminder","affinity_delete_list_field_dropdown_option","affinity_delete_note","affinity_get_company","affinity_get_current_user","affinity_get_entity_field_value","affinity_get_list","affinity_get_list_entry","affinity_get_list_entry_field","affinity_get_list_field_dropdown_option","affinity_get_merge","affinity_get_merge_task","affinity_get_note","affinity_get_opportunity","affinity_get_person","affinity_get_saved_view","affinity_get_transcript","affinity_get_user","affinity_list_calls","affinity_list_chat_messages","affinity_list_companies","affinity_list_coworker_connections","affinity_list_emails","affinity_list_entity_field_values","affinity_list_entity_list_entries","affinity_list_entity_lists","affinity_list_entity_notes","affinity_list_entity_relationships","affinity_list_field_dropdown_options","affinity_list_field_metadata","affinity_list_field_value_changes","affinity_list_investor_executive_connections","affinity_list_list_entries","affinity_list_list_entry_field_value_changes","affinity_list_list_entry_fields","affinity_list_list_field_dropdown_options","affinity_list_list_fields","affinity_list_lists","affinity_list_meetings","affinity_list_merge_tasks","affinity_list_merges","affinity_list_note_attached_companies","affinity_list_note_attached_opportunities","affinity_list_note_attached_persons","affinity_list_note_replies","affinity_list_notes","affinity_list_opportunities","affinity_list_persons","affinity_list_reminders","affinity_list_saved_view_entries","affinity_list_saved_views","affinity_list_transcript_fragments","affinity_list_transcripts","affinity_list_users","affinity_search_companies","affinity_search_files","affinity_search_list_entries","affinity_search_notes","affinity_search_persons","affinity_semantic_search","affinity_update_entity_field_value","affinity_update_list_entry_field","affinity_update_list_field_dropdown_option","affinity_update_note","agentmail_create_draft","agentmail_create_inbox","agentmail_delete_draft","agentmail_delete_inbox","agentmail_delete_thread","agentmail_forward_message","agentmail_get_draft","agentmail_get_inbox","agentmail_get_message","agentmail_get_thread","agentmail_list_drafts","agentmail_list_inboxes","agentmail_list_messages","agentmail_list_threads","agentmail_reply_message","agentmail_send_draft","agentmail_send_message","agentmail_update_draft","agentmail_update_inbox","agentmail_update_message","agentmail_update_thread","agentphone_create_call","agentphone_create_contact","agentphone_create_number","agentphone_delete_contact","agentphone_get_call","agentphone_get_call_transcript","agentphone_get_contact","agentphone_get_conversation","agentphone_get_conversation_messages","agentphone_get_number_messages","agentphone_get_usage","agentphone_get_usage_daily","agentphone_get_usage_monthly","agentphone_list_calls","agentphone_list_contacts","agentphone_list_conversations","agentphone_list_numbers","agentphone_react_to_message","agentphone_release_number","agentphone_send_message","agentphone_update_contact","agentphone_update_conversation","agiloft_async_status","agiloft_attach_file","agiloft_attachment_info","agiloft_create_record","agiloft_delete_record","agiloft_get_choice_line_id","agiloft_list_tables","agiloft_lock_record","agiloft_nlp_search","agiloft_read_record","agiloft_remove_attachment","agiloft_retrieve_attachment","agiloft_run_action_button","agiloft_saved_search","agiloft_search_records","agiloft_select_records","agiloft_update_record","agiloft_upsert_record","ahrefs_anchors","ahrefs_backlinks","ahrefs_backlinks_stats","ahrefs_batch_analysis","ahrefs_broken_backlinks","ahrefs_domain_rating","ahrefs_domain_rating_history","ahrefs_keyword_overview","ahrefs_keywords_history","ahrefs_metrics","ahrefs_metrics_history","ahrefs_organic_competitors","ahrefs_organic_keywords","ahrefs_paid_pages","ahrefs_rank_tracker_competitors_overview","ahrefs_rank_tracker_competitors_stats","ahrefs_rank_tracker_overview","ahrefs_rank_tracker_serp_overview","ahrefs_refdomains_history","ahrefs_referring_domains","ahrefs_related_terms","ahrefs_site_audit_page_explorer","ahrefs_top_pages","airtable_create_records","airtable_delete_records","airtable_get_base_schema","airtable_get_record","airtable_list_bases","airtable_list_records","airtable_list_tables","airtable_update_multiple_records","airtable_update_record","airtable_upsert_records","algolia_add_record","algolia_batch_operations","algolia_browse_records","algolia_clear_records","algolia_copy_move_index","algolia_delete_by_filter","algolia_delete_index","algolia_delete_record","algolia_get_record","algolia_get_records","algolia_get_settings","algolia_get_task_status","algolia_list_indices","algolia_partial_update_record","algolia_search","algolia_update_settings","amplitude_event_segmentation","amplitude_funnels","amplitude_get_active_users","amplitude_get_revenue","amplitude_group_identify","amplitude_identify_user","amplitude_list_events","amplitude_realtime_active_users","amplitude_retention","amplitude_send_event","amplitude_user_activity","amplitude_user_profile","amplitude_user_search","apify_get_dataset_items","apify_get_run","apify_run_actor_async","apify_run_actor_sync","apify_run_task","apollo_account_bulk_create","apollo_account_bulk_update","apollo_account_create","apollo_account_search","apollo_account_update","apollo_contact_bulk_create","apollo_contact_bulk_update","apollo_contact_create","apollo_contact_search","apollo_contact_update","apollo_email_accounts","apollo_opportunity_create","apollo_opportunity_get","apollo_opportunity_search","apollo_opportunity_update","apollo_organization_bulk_enrich","apollo_organization_enrich","apollo_organization_search","apollo_people_bulk_enrich","apollo_people_enrich","apollo_people_search","apollo_sequence_add_contacts","apollo_sequence_search","apollo_task_create","apollo_task_search","appconfig_create_application","appconfig_create_configuration_profile","appconfig_create_environment","appconfig_create_hosted_configuration_version","appconfig_delete_application","appconfig_delete_configuration_profile","appconfig_delete_environment","appconfig_delete_hosted_configuration_version","appconfig_get_application","appconfig_get_configuration","appconfig_get_configuration_profile","appconfig_get_deployment","appconfig_get_environment","appconfig_get_hosted_configuration_version","appconfig_list_applications","appconfig_list_configuration_profiles","appconfig_list_deployment_strategies","appconfig_list_deployments","appconfig_list_environments","appconfig_list_hosted_configuration_versions","appconfig_start_deployment","appconfig_stop_deployment","appconfig_update_application","appconfig_update_configuration_profile","appconfig_update_environment","arxiv_get_author_papers","arxiv_get_paper","arxiv_search","asana_add_comment","asana_add_followers","asana_create_project","asana_create_section","asana_create_subtask","asana_create_task","asana_delete_task","asana_get_project","asana_get_projects","asana_get_task","asana_list_sections","asana_list_workspaces","asana_search_tasks","asana_update_task","ashby_add_candidate_tag","ashby_anonymize_candidate","ashby_change_application_source","ashby_change_application_stage","ashby_create_application","ashby_create_candidate","ashby_create_note","ashby_delete_application","ashby_get_application","ashby_get_candidate","ashby_get_job","ashby_get_job_posting","ashby_get_offer","ashby_get_opening","ashby_list_application_feedback","ashby_list_application_history","ashby_list_applications","ashby_list_archive_reasons","ashby_list_candidate_tags","ashby_list_candidates","ashby_list_custom_fields","ashby_list_departments","ashby_list_interview_plans","ashby_list_interview_stages","ashby_list_interviews","ashby_list_job_postings","ashby_list_jobs","ashby_list_locations","ashby_list_notes","ashby_list_offers","ashby_list_openings","ashby_list_sources","ashby_list_users","ashby_remove_candidate_tag","ashby_search_candidates","ashby_search_jobs","ashby_search_openings","ashby_search_users","ashby_set_custom_field_value","ashby_set_custom_field_values","ashby_transfer_application","ashby_update_candidate","ashby_upload_candidate_file","ashby_upload_resume","athena_batch_get_named_query","athena_batch_get_prepared_statement","athena_batch_get_query_execution","athena_create_named_query","athena_create_prepared_statement","athena_delete_named_query","athena_delete_prepared_statement","athena_get_data_catalog","athena_get_database","athena_get_named_query","athena_get_prepared_statement","athena_get_query_execution","athena_get_query_results","athena_get_query_runtime_statistics","athena_get_table_metadata","athena_get_work_group","athena_list_data_catalogs","athena_list_databases","athena_list_named_queries","athena_list_prepared_statements","athena_list_query_executions","athena_list_table_metadata","athena_list_work_groups","athena_start_query","athena_stop_query","athena_update_named_query","athena_update_prepared_statement","attio_assert_record","attio_create_attribute","attio_create_comment","attio_create_list","attio_create_list_entry","attio_create_note","attio_create_object","attio_create_record","attio_create_task","attio_create_webhook","attio_delete_comment","attio_delete_list_entry","attio_delete_note","attio_delete_record","attio_delete_task","attio_delete_webhook","attio_get_attribute","attio_get_comment","attio_get_list","attio_get_list_entry","attio_get_member","attio_get_note","attio_get_object","attio_get_record","attio_get_task","attio_get_thread","attio_get_webhook","attio_list_attributes","attio_list_lists","attio_list_members","attio_list_notes","attio_list_objects","attio_list_records","attio_list_tasks","attio_list_threads","attio_list_webhooks","attio_query_list_entries","attio_search_records","attio_update_attribute","attio_update_list","attio_update_list_entry","attio_update_object","attio_update_record","attio_update_task","attio_update_webhook","azure_data_explorer_create_table","azure_data_explorer_drop_table","azure_data_explorer_ingest_from_query","azure_data_explorer_ingest_inline","azure_data_explorer_list_databases","azure_data_explorer_list_functions","azure_data_explorer_list_tables","azure_data_explorer_management","azure_data_explorer_query","azure_data_explorer_show_database_schema","azure_data_explorer_show_ingestion_failures","azure_data_explorer_show_operations","azure_data_explorer_show_table_details","azure_data_explorer_show_table_schema","azure_devops_add_comment","azure_devops_create_work_item","azure_devops_get_build_log","azure_devops_get_build_timeline","azure_devops_get_comments","azure_devops_get_pipeline","azure_devops_get_pipeline_run","azure_devops_get_work_item","azure_devops_get_work_items_batch","azure_devops_get_work_items_between_builds","azure_devops_list_build_logs","azure_devops_list_builds","azure_devops_list_pipeline_runs","azure_devops_list_pipelines","azure_devops_query_work_items","azure_devops_update_work_item","bitbucket_approve_pull_request","bitbucket_create_branch","bitbucket_create_pull_request","bitbucket_create_pull_request_comment","bitbucket_decline_pull_request","bitbucket_delete_branch","bitbucket_get_commit","bitbucket_get_file","bitbucket_get_file_metadata","bitbucket_get_pipeline","bitbucket_get_pipeline_step_log","bitbucket_get_pull_request","bitbucket_get_pull_request_diff","bitbucket_get_pull_request_diffstat","bitbucket_get_pull_request_merge_task_status","bitbucket_get_repository","bitbucket_list_branches","bitbucket_list_commits","bitbucket_list_directory","bitbucket_list_pipeline_steps","bitbucket_list_pipelines","bitbucket_list_pull_request_comments","bitbucket_list_pull_request_commit_statuses","bitbucket_list_pull_requests","bitbucket_list_repositories","bitbucket_list_workspaces","bitbucket_merge_pull_request","bitbucket_request_pull_request_changes","bitbucket_stop_pipeline","bitbucket_trigger_pipeline","box_copy_file","box_create_folder","box_delete_file","box_delete_folder","box_download_file","box_download_file_v2","box_get_file_info","box_list_folder_items","box_search","box_sign_cancel_request","box_sign_create_request","box_sign_get_request","box_sign_list_requests","box_sign_resend_request","box_update_file","box_upload_file","brandfetch_get_brand","brandfetch_search","brex_archive_budget","brex_create_budget","brex_create_spend_limit","brex_create_transfer","brex_create_vendor","brex_get_budget","brex_get_cash_account","brex_get_company","brex_get_current_user","brex_get_expense","brex_get_spend_limit","brex_get_transfer","brex_get_user","brex_get_vendor","brex_list_budgets","brex_list_card_accounts","brex_list_card_statements","brex_list_card_transactions","brex_list_cards","brex_list_cash_accounts","brex_list_cash_statements","brex_list_cash_transactions","brex_list_departments","brex_list_expenses","brex_list_locations","brex_list_spend_limits","brex_list_titles","brex_list_transfers","brex_list_users","brex_list_vendors","brex_match_receipt","brex_update_expense","brex_update_vendor","brex_upload_receipt","brightdata_cancel_snapshot","brightdata_discover","brightdata_download_snapshot","brightdata_scrape_dataset","brightdata_scrape_url","brightdata_serp_search","brightdata_snapshot_status","brightdata_sync_scrape","browser_use_run_task","buffer_create_idea","buffer_create_post","buffer_delete_post","buffer_edit_post","buffer_get_account","buffer_get_aggregated_post_metrics","buffer_get_channel","buffer_get_channels","buffer_get_daily_posting_limits","buffer_get_idea_groups","buffer_get_ideas","buffer_get_post","buffer_get_posts","calcom_cancel_booking","calcom_confirm_booking","calcom_create_booking","calcom_create_event_type","calcom_create_schedule","calcom_decline_booking","calcom_delete_event_type","calcom_delete_schedule","calcom_get_booking","calcom_get_default_schedule","calcom_get_event_type","calcom_get_schedule","calcom_get_slots","calcom_list_bookings","calcom_list_event_types","calcom_list_schedules","calcom_reschedule_booking","calcom_update_event_type","calcom_update_schedule","calendly_cancel_event","calendly_create_event_invitee","calendly_create_invitee_no_show","calendly_create_scheduling_link","calendly_create_webhook","calendly_delete_invitee_no_show","calendly_delete_webhook","calendly_get_current_user","calendly_get_event_invitee","calendly_get_event_type","calendly_get_scheduled_event","calendly_get_user","calendly_list_event_invitees","calendly_list_event_type_available_times","calendly_list_event_types","calendly_list_organization_memberships","calendly_list_routing_form_submissions","calendly_list_routing_forms","calendly_list_scheduled_events","calendly_list_user_availability_schedules","calendly_list_user_busy_times","calendly_list_webhooks","cbinsights_chat","cbinsights_get_commercial_maturity_history","cbinsights_get_exit_probability_history","cbinsights_get_mosaic_history","cbinsights_get_org_business_relationships","cbinsights_get_org_funding_window","cbinsights_get_org_fundings","cbinsights_get_org_investments","cbinsights_get_org_management_and_board","cbinsights_get_org_outlook","cbinsights_get_org_portfolio_exits","cbinsights_get_org_revenue","cbinsights_get_scouting_report","cbinsights_get_strategy_map","cbinsights_list_business_relationships","cbinsights_list_funding_window","cbinsights_list_fundings","cbinsights_list_investments","cbinsights_list_management_and_board","cbinsights_list_outlook","cbinsights_list_portfolio_exits","cbinsights_list_revenue","cbinsights_lookup_organizations","cbinsights_rag","cbinsights_search_firmographics","checkr_add_report_tag","checkr_apply_report_review_action","checkr_cancel_adverse_action","checkr_cancel_continuous_check","checkr_cancel_invitation","checkr_cancel_subscription","checkr_complete_report","checkr_create_adverse_action","checkr_create_candidate","checkr_create_continuous_check","checkr_create_geo","checkr_create_invitation","checkr_create_report","checkr_create_subscription","checkr_delete_candidate_pii","checkr_delete_geo","checkr_get_account","checkr_get_adverse_action","checkr_get_candidate","checkr_get_continuous_check","checkr_get_document","checkr_get_geo","checkr_get_invitation","checkr_get_node","checkr_get_package","checkr_get_program","checkr_get_report","checkr_get_report_eta","checkr_get_report_progressive_status","checkr_get_report_tags","checkr_get_screening","checkr_get_subscription","checkr_get_verification","checkr_list_adverse_actions","checkr_list_adverse_items","checkr_list_assessments","checkr_list_candidate_documents","checkr_list_candidates","checkr_list_continuous_checks","checkr_list_counties","checkr_list_geos","checkr_list_invitations","checkr_list_nodes","checkr_list_packages","checkr_list_programs","checkr_list_report_addresses","checkr_list_subscriptions","checkr_list_users","checkr_list_verifications","checkr_remove_report_tag","checkr_set_report_tags","checkr_update_candidate","checkr_update_continuous_check","checkr_update_geo","checkr_update_report","checkr_update_subscription","circleback_add_tag_to_meetings","circleback_create_tag","circleback_delete_action_item","circleback_delete_meeting","circleback_delete_tag","circleback_get_company","circleback_get_meeting","circleback_get_person","circleback_get_transcript","circleback_list_action_items","circleback_list_calendar_events","circleback_list_companies","circleback_list_meetings","circleback_list_people","circleback_list_tags","circleback_remove_tag_from_meetings","circleback_search_meetings","circleback_update_action_item","circleback_update_meeting","circleback_update_tag","clay_populate","clerk_add_organization_member","clerk_ban_user","clerk_create_actor_token","clerk_create_allowlist_identifier","clerk_create_blocklist_identifier","clerk_create_organization","clerk_create_organization_invitation","clerk_create_user","clerk_delete_allowlist_identifier","clerk_delete_blocklist_identifier","clerk_delete_organization","clerk_delete_user","clerk_get_jwt_template","clerk_get_organization","clerk_get_session","clerk_get_user","clerk_get_user_oauth_token","clerk_list_allowlist_identifiers","clerk_list_blocklist_identifiers","clerk_list_jwt_templates","clerk_list_organization_invitations","clerk_list_organization_memberships","clerk_list_organizations","clerk_list_sessions","clerk_list_users","clerk_lock_user","clerk_remove_organization_member","clerk_revoke_actor_token","clerk_revoke_session","clerk_unban_user","clerk_unlock_user","clerk_update_organization","clerk_update_organization_membership","clerk_update_user","clickhouse_count_rows","clickhouse_create_database","clickhouse_create_table","clickhouse_delete","clickhouse_describe_table","clickhouse_drop_database","clickhouse_drop_partition","clickhouse_drop_table","clickhouse_execute","clickhouse_insert","clickhouse_insert_rows","clickhouse_introspect","clickhouse_kill_query","clickhouse_list_clusters","clickhouse_list_databases","clickhouse_list_mutations","clickhouse_list_partitions","clickhouse_list_running_queries","clickhouse_list_tables","clickhouse_optimize_table","clickhouse_query","clickhouse_rename_table","clickhouse_show_create_table","clickhouse_table_stats","clickhouse_truncate_table","clickhouse_update","clickup_add_tag_to_task","clickup_create_checklist","clickup_create_checklist_item","clickup_create_comment","clickup_create_folder","clickup_create_list","clickup_create_task","clickup_create_time_entry","clickup_delete_checklist","clickup_delete_checklist_item","clickup_delete_comment","clickup_delete_task","clickup_delete_time_entry","clickup_get_comments","clickup_get_custom_fields","clickup_get_folders","clickup_get_list_members","clickup_get_lists","clickup_get_running_timer","clickup_get_space_tags","clickup_get_spaces","clickup_get_task","clickup_get_task_members","clickup_get_tasks","clickup_get_time_entries","clickup_get_workspaces","clickup_remove_custom_field_value","clickup_remove_tag_from_task","clickup_search_tasks","clickup_set_custom_field_value","clickup_start_timer","clickup_stop_timer","clickup_update_checklist","clickup_update_checklist_item","clickup_update_comment","clickup_update_task","clickup_update_time_entry","clickup_upload_attachment","cloudflare_create_access_application","cloudflare_create_access_policy","cloudflare_create_access_service_token","cloudflare_create_dns_record","cloudflare_create_r2_bucket","cloudflare_create_rate_limit_rule","cloudflare_create_ruleset","cloudflare_create_ruleset_rule","cloudflare_create_zone","cloudflare_delete_access_application","cloudflare_delete_access_policy","cloudflare_delete_dns_record","cloudflare_delete_r2_bucket","cloudflare_delete_ruleset_rule","cloudflare_delete_zone","cloudflare_dns_analytics","cloudflare_get_access_application","cloudflare_get_r2_bucket","cloudflare_get_ruleset","cloudflare_get_ruleset_entrypoint","cloudflare_get_tunnel","cloudflare_get_tunnel_configuration","cloudflare_get_worker_script_settings","cloudflare_get_zone","cloudflare_get_zone_settings","cloudflare_list_access_applications","cloudflare_list_access_groups","cloudflare_list_access_identity_providers","cloudflare_list_access_policies","cloudflare_list_access_service_tokens","cloudflare_list_certificates","cloudflare_list_dns_records","cloudflare_list_managed_ruleset_overrides","cloudflare_list_r2_buckets","cloudflare_list_rate_limit_rules","cloudflare_list_rulesets","cloudflare_list_tunnels","cloudflare_list_worker_routes","cloudflare_list_worker_scripts","cloudflare_list_zones","cloudflare_purge_cache","cloudflare_revoke_access_service_token","cloudflare_update_access_application","cloudflare_update_access_policy","cloudflare_update_dns_record","cloudflare_update_rate_limit_rule","cloudflare_update_ruleset_rule","cloudflare_update_zone_setting","cloudformation_cancel_update_stack","cloudformation_create_change_set","cloudformation_create_stack","cloudformation_delete_stack","cloudformation_describe_change_set","cloudformation_describe_stack_drift_detection_status","cloudformation_describe_stack_events","cloudformation_describe_stacks","cloudformation_detect_stack_drift","cloudformation_execute_change_set","cloudformation_get_template","cloudformation_get_template_summary","cloudformation_list_stack_resources","cloudformation_update_stack","cloudformation_validate_template","cloudtrail_cancel_query","cloudtrail_describe_query","cloudtrail_describe_trails","cloudtrail_get_event_data_store","cloudtrail_get_event_selectors","cloudtrail_get_insight_selectors","cloudtrail_get_query_results","cloudtrail_get_trail","cloudtrail_get_trail_status","cloudtrail_list_event_data_stores","cloudtrail_list_tags","cloudtrail_list_trails","cloudtrail_lookup_events","cloudtrail_start_query","cloudwatch_describe_alarm_history","cloudwatch_describe_alarms","cloudwatch_describe_log_groups","cloudwatch_describe_log_streams","cloudwatch_filter_log_events","cloudwatch_get_log_events","cloudwatch_get_metric_statistics","cloudwatch_list_metrics","cloudwatch_mute_alarm","cloudwatch_put_log_group_retention","cloudwatch_put_metric_data","cloudwatch_query_logs","cloudwatch_unmute_alarm","coda_add_custom_domain","coda_add_permission","coda_change_user_role","coda_create_doc","coda_create_folder","coda_create_page","coda_delete_custom_domain","coda_delete_doc","coda_delete_folder","coda_delete_page","coda_delete_page_content","coda_delete_permission","coda_delete_row","coda_delete_rows","coda_export_page","coda_get_acl_settings","coda_get_analytics_last_updated","coda_get_column","coda_get_control","coda_get_custom_domain_provider","coda_get_doc","coda_get_doc_analytics_summary","coda_get_folder","coda_get_formula","coda_get_mutation_status","coda_get_page","coda_get_page_content","coda_get_page_export_status","coda_get_row","coda_get_sharing_metadata","coda_get_table","coda_list_categories","coda_list_columns","coda_list_controls","coda_list_custom_domains","coda_list_doc_analytics","coda_list_docs","coda_list_folder_children","coda_list_folders","coda_list_formulas","coda_list_page_analytics","coda_list_pages","coda_list_permissions","coda_list_rows","coda_list_tables","coda_list_workspace_members","coda_list_workspace_roles","coda_publish_doc","coda_push_button","coda_resolve_browser_link","coda_search_principals","coda_trigger_automation","coda_unpublish_doc","coda_update_acl_settings","coda_update_doc","coda_update_folder","coda_update_page","coda_update_row","coda_upsert_rows","coda_whoami","codepipeline_disable_stage_transition","codepipeline_enable_stage_transition","codepipeline_get_pipeline","codepipeline_get_pipeline_execution","codepipeline_get_pipeline_state","codepipeline_list_action_executions","codepipeline_list_pipeline_executions","codepipeline_list_pipelines","codepipeline_put_approval_result","codepipeline_retry_stage_execution","codepipeline_start_execution","codepipeline_stop_execution","confluence_add_label","confluence_create_blogpost","confluence_create_comment","confluence_create_page","confluence_create_page_property","confluence_create_space","confluence_create_space_property","confluence_delete_attachment","confluence_delete_blogpost","confluence_delete_comment","confluence_delete_label","confluence_delete_page","confluence_delete_page_property","confluence_delete_space","confluence_delete_space_property","confluence_get_blogpost","confluence_get_page_ancestors","confluence_get_page_children","confluence_get_page_descendants","confluence_get_page_version","confluence_get_pages_by_label","confluence_get_space","confluence_get_task","confluence_get_user","confluence_list_attachments","confluence_list_blogposts","confluence_list_blogposts_in_space","confluence_list_comments","confluence_list_labels","confluence_list_page_properties","confluence_list_page_versions","confluence_list_pages_in_space","confluence_list_space_labels","confluence_list_space_permissions","confluence_list_space_properties","confluence_list_spaces","confluence_list_tasks","confluence_retrieve","confluence_search","confluence_search_in_space","confluence_update","confluence_update_blogpost","confluence_update_comment","confluence_update_space","confluence_update_task","confluence_upload_attachment","context_dev_classify_naics","context_dev_classify_sic","context_dev_crawl","context_dev_extract","context_dev_extract_product","context_dev_extract_products","context_dev_get_brand","context_dev_get_brand_by_email","context_dev_get_brand_by_name","context_dev_get_brand_by_ticker","context_dev_identify_transaction","context_dev_map","context_dev_scrape_fonts","context_dev_scrape_html","context_dev_scrape_images","context_dev_scrape_markdown","context_dev_scrape_styleguide","context_dev_screenshot","context_dev_search","convex_action","convex_document_deltas","convex_list_documents","convex_list_tables","convex_mutation","convex_query","convex_run_function","crowdstrike_create_indicators","crowdstrike_delete_indicators","crowdstrike_delete_rtr_session","crowdstrike_execute_rtr_command","crowdstrike_get_alert_details","crowdstrike_get_case_details","crowdstrike_get_host_group_details","crowdstrike_get_indicator_details","crowdstrike_get_rtr_command_status","crowdstrike_get_sensor_aggregates","crowdstrike_get_sensor_details","crowdstrike_get_vulnerability_details","crowdstrike_init_rtr_session","crowdstrike_perform_host_action","crowdstrike_perform_host_group_action","crowdstrike_query_alerts","crowdstrike_query_cases","crowdstrike_query_host_groups","crowdstrike_query_indicators","crowdstrike_query_sensors","crowdstrike_query_vulnerabilities","crowdstrike_update_alerts","crowdstrike_update_indicators","crunchbase_autocomplete","crunchbase_get_acquisition","crunchbase_get_entity","crunchbase_get_entity_card","crunchbase_get_fields_metadata","crunchbase_get_funding_round","crunchbase_get_organization","crunchbase_get_person","crunchbase_list_deleted_entities","crunchbase_search_acquisitions","crunchbase_search_entities","crunchbase_search_funding_rounds","crunchbase_search_organizations","crunchbase_search_people","cursor_add_followup","cursor_add_followup_v2","cursor_delete_agent","cursor_delete_agent_v2","cursor_download_artifact","cursor_download_artifact_v2","cursor_get_agent","cursor_get_agent_v2","cursor_get_api_key_info","cursor_get_api_key_info_v2","cursor_get_conversation","cursor_get_conversation_v2","cursor_launch_agent","cursor_launch_agent_v2","cursor_list_agents","cursor_list_agents_v2","cursor_list_artifacts","cursor_list_artifacts_v2","cursor_list_models","cursor_list_models_v2","cursor_list_repositories","cursor_list_repositories_v2","cursor_stop_agent","cursor_stop_agent_v2","dagster_delete_run","dagster_get_asset","dagster_get_run","dagster_get_run_logs","dagster_launch_run","dagster_list_assets","dagster_list_jobs","dagster_list_runs","dagster_list_schedules","dagster_list_sensors","dagster_materialize_assets","dagster_reexecute_run","dagster_report_asset_materialization","dagster_start_schedule","dagster_start_sensor","dagster_stop_schedule","dagster_stop_sensor","dagster_terminate_run","dagster_wipe_asset","databricks_cancel_all_runs","databricks_cancel_run","databricks_cancel_statement","databricks_create_cluster","databricks_create_job","databricks_create_warehouse","databricks_delete_cluster","databricks_delete_job","databricks_delete_run","databricks_delete_warehouse","databricks_edit_cluster","databricks_edit_warehouse","databricks_execute_sql","databricks_genie_agent_ask","databricks_genie_agent_cancel","databricks_genie_agent_list_items","databricks_genie_ask","databricks_genie_create_space","databricks_genie_delete_conversation","databricks_genie_delete_message","databricks_genie_delete_space","databricks_genie_download_visualization","databricks_genie_execute_query","databricks_genie_get_message","databricks_genie_get_query_result","databricks_genie_get_space","databricks_genie_list_conversations","databricks_genie_list_messages","databricks_genie_list_spaces","databricks_genie_send_feedback","databricks_genie_update_space","databricks_get_cluster","databricks_get_job","databricks_get_run","databricks_get_run_output","databricks_get_statement","databricks_get_statement_chunk","databricks_get_warehouse","databricks_list_clusters","databricks_list_jobs","databricks_list_runs","databricks_list_warehouses","databricks_repair_run","databricks_reset_job","databricks_resize_cluster","databricks_restart_cluster","databricks_run_job","databricks_start_cluster","databricks_start_warehouse","databricks_stop_warehouse","databricks_submit_run","databricks_terminate_cluster","databricks_update_job","datadog_add_incident_todo","datadog_cancel_downtime","datadog_create_dashboard","datadog_create_downtime","datadog_create_event","datadog_create_incident","datadog_create_monitor","datadog_create_slo","datadog_delete_dashboard","datadog_delete_slo","datadog_get_browser_synthetics_results","datadog_get_dashboard","datadog_get_incident","datadog_get_monitor","datadog_get_security_signal","datadog_get_slo","datadog_get_slo_history","datadog_get_synthetics_results","datadog_get_synthetics_test","datadog_list_dashboards","datadog_list_downtimes","datadog_list_incidents","datadog_list_monitors","datadog_list_security_rules","datadog_list_security_signals","datadog_list_services","datadog_list_slos","datadog_list_synthetics_tests","datadog_mute_monitor","datadog_query_logs","datadog_query_timeseries","datadog_search_spans","datadog_send_logs","datadog_submit_metrics","datadog_trigger_synthetics_tests","datadog_unmute_monitor","datadog_update_incident","datadog_update_security_signal_assignee","datadog_update_security_signal_state","datadog_update_slo","datadog_update_synthetics_status","datagma_enrich_company","datagma_enrich_person","datagma_find_email","datagma_find_phone","datagma_get_credits","daytona_create_sandbox","daytona_delete_sandbox","daytona_download_file","daytona_execute_command","daytona_get_sandbox","daytona_git_clone","daytona_list_files","daytona_list_sandboxes","daytona_run_code","daytona_start_sandbox","daytona_stop_sandbox","daytona_upload_file","deployed_block_executor","deployments_deploy","deployments_get_version","deployments_list_versions","deployments_promote","deployments_undeploy","devin_append_session_tags","devin_archive_session","devin_create_session","devin_get_session","devin_get_session_tags","devin_list_session_attachments","devin_list_session_messages","devin_list_sessions","devin_replace_session_tags","devin_send_message","devin_terminate_session","discord_add_reaction","discord_archive_thread","discord_assign_role","discord_ban_member","discord_bulk_delete_messages","discord_create_channel","discord_create_invite","discord_create_role","discord_create_thread","discord_create_webhook","discord_delete_channel","discord_delete_invite","discord_delete_message","discord_delete_role","discord_delete_webhook","discord_edit_message","discord_execute_webhook","discord_get_channel","discord_get_invite","discord_get_member","discord_get_messages","discord_get_pinned_messages","discord_get_server","discord_get_user","discord_get_webhook","discord_join_thread","discord_kick_member","discord_leave_thread","discord_list_channels","discord_list_roles","discord_pin_message","discord_remove_reaction","discord_remove_role","discord_send_message","discord_unban_member","discord_unpin_message","discord_update_channel","discord_update_member","discord_update_role","docusign_create_from_template","docusign_download_document","docusign_get_envelope","docusign_list_envelopes","docusign_list_recipients","docusign_list_templates","docusign_send_envelope","docusign_void_envelope","downdetector_get_company","downdetector_get_company_attribution","downdetector_get_company_baseline","downdetector_get_company_events","downdetector_get_company_incidents","downdetector_get_company_indicators","downdetector_get_company_last_15","downdetector_get_company_status","downdetector_get_provider","downdetector_get_reports","downdetector_get_site_companies","downdetector_list_categories","downdetector_list_incidents","downdetector_list_sites","downdetector_search_companies","dropbox_copy","dropbox_create_folder","dropbox_create_shared_link","dropbox_delete","dropbox_download","dropbox_download_v2","dropbox_get_metadata","dropbox_list_folder","dropbox_list_revisions","dropbox_list_shared_links","dropbox_move","dropbox_restore","dropbox_search","dropbox_upload","dropcontact_enrich_contact","dspy_chain_of_thought","dspy_predict","dspy_react","dub_bulk_create_links","dub_bulk_delete_links","dub_bulk_update_links","dub_create_link","dub_create_tag","dub_delete_link","dub_get_analytics","dub_get_events","dub_get_link","dub_get_links_count","dub_get_qr_code","dub_get_qr_code_v2","dub_list_domains","dub_list_folders","dub_list_links","dub_list_tags","dub_update_link","dub_upsert_link","duckduckgo_search","dynamodb_delete","dynamodb_get","dynamodb_introspect","dynamodb_put","dynamodb_query","dynamodb_scan","dynamodb_update","dynatrace_add_problem_comment","dynatrace_add_tags","dynatrace_close_problem","dynatrace_create_settings_object","dynatrace_create_slo","dynatrace_delete_problem_comment","dynatrace_delete_settings_object","dynatrace_delete_slo","dynatrace_delete_tag","dynatrace_execute_synthetic_monitors","dynatrace_get_attack","dynatrace_get_audit_logs","dynatrace_get_entity","dynatrace_get_event","dynatrace_get_metric","dynatrace_get_problem","dynatrace_get_problem_comment","dynatrace_get_security_problem","dynatrace_get_settings_object","dynatrace_get_slo","dynatrace_get_synthetic_batch","dynatrace_ingest_event","dynatrace_ingest_logs","dynatrace_ingest_metrics","dynatrace_list_attacks","dynatrace_list_entities","dynatrace_list_entity_types","dynatrace_list_events","dynatrace_list_metrics","dynatrace_list_problem_comments","dynatrace_list_problems","dynatrace_list_remediation_items","dynatrace_list_security_problems","dynatrace_list_settings_objects","dynatrace_list_settings_schemas","dynatrace_list_slos","dynatrace_list_synthetic_monitors","dynatrace_list_tags","dynatrace_mute_security_problem","dynatrace_mute_security_problems","dynatrace_query_metrics","dynatrace_search_logs","dynatrace_unmute_security_problem","dynatrace_unmute_security_problems","dynatrace_update_problem_comment","dynatrace_update_settings_object","dynatrace_update_slo","elasticsearch_bulk","elasticsearch_cluster_health","elasticsearch_cluster_stats","elasticsearch_count","elasticsearch_create_index","elasticsearch_delete_document","elasticsearch_delete_index","elasticsearch_get_document","elasticsearch_get_index","elasticsearch_index_document","elasticsearch_list_indices","elasticsearch_search","elasticsearch_update_document","elevenlabs_audio_isolation","elevenlabs_edit_voice_settings","elevenlabs_get_user","elevenlabs_get_voice","elevenlabs_get_voice_settings","elevenlabs_list_models","elevenlabs_list_voices","elevenlabs_sound_effects","elevenlabs_speech_to_speech","elevenlabs_tts","emailbison_attach_leads_to_campaign","emailbison_attach_tags_to_leads","emailbison_create_campaign","emailbison_create_lead","emailbison_create_tag","emailbison_get_lead","emailbison_list_campaigns","emailbison_list_leads","emailbison_list_replies","emailbison_list_tags","emailbison_update_campaign","emailbison_update_campaign_status","emailbison_update_lead","embeddings_cohere","embeddings_gemini","embeddings_mistral","embeddings_ollama","embeddings_openai","embeddings_openrouter","enrich_check_credits","enrich_company_funding","enrich_company_lookup","enrich_company_revenue","enrich_disposable_email_check","enrich_email_to_ip","enrich_email_to_person_lite","enrich_email_to_phone","enrich_email_to_profile","enrich_find_email","enrich_get_post_details","enrich_ip_to_company","enrich_linkedin_profile","enrich_linkedin_to_personal_email","enrich_linkedin_to_work_email","enrich_phone_finder","enrich_reverse_hash_lookup","enrich_sales_pointer_people","enrich_search_company","enrich_search_company_activities","enrich_search_company_employees","enrich_search_jobs","enrich_search_logo","enrich_search_people","enrich_search_people_activities","enrich_search_post_comments","enrich_search_post_comments_by_url","enrich_search_post_reactions","enrich_search_post_reactions_by_url","enrich_search_posts","enrich_search_similar_companies","enrich_verify_email","enrichment_run","enrow_find_email","enrow_verify_email","exa_agent","exa_answer","exa_find_similar_links","exa_get_contents","exa_search","extend_parser","extend_parser_v2","fathom_get_summary","fathom_get_transcript","fathom_list_meeting_types","fathom_list_meetings","fathom_list_team_members","fathom_list_teams","file_append","file_compress","file_create_folder","file_decompress","file_delete_folder","file_edit","file_fetch","file_get","file_get_content","file_list","file_manage_sharing","file_move","file_parser","file_parser_v2","file_parser_v3","file_read","file_restore_folder","file_search","file_update_folder","file_write","findymail_find_email_from_linkedin","findymail_find_email_from_name","findymail_find_emails_by_domain","findymail_find_employees","findymail_find_phone","findymail_get_company","findymail_get_credits","findymail_lookup_technologies","findymail_reverse_email_lookup","findymail_search_technologies","findymail_verify_email","firecrawl_agent","firecrawl_batch_scrape","firecrawl_batch_scrape_status","firecrawl_cancel_crawl","firecrawl_crawl","firecrawl_crawl_status","firecrawl_credit_usage","firecrawl_extract","firecrawl_extract_status","firecrawl_map","firecrawl_parse","firecrawl_scrape","firecrawl_search","fireflies_add_to_live_meeting","fireflies_create_bite","fireflies_delete_transcript","fireflies_get_transcript","fireflies_get_user","fireflies_list_bites","fireflies_list_contacts","fireflies_list_transcripts","fireflies_list_users","fireflies_upload_audio","fivetran_cancel_transformation","fivetran_create_connect_card","fivetran_create_connection","fivetran_create_destination","fivetran_create_group","fivetran_delete_connection","fivetran_get_account_info","fivetran_get_connection","fivetran_get_connection_schema_config","fivetran_get_connection_warnings","fivetran_get_connector_type","fivetran_get_destination","fivetran_get_group","fivetran_get_sync_history","fivetran_get_transformation","fivetran_list_connections","fivetran_list_connector_types","fivetran_list_destinations","fivetran_list_groups","fivetran_list_transformations","fivetran_list_users","fivetran_reload_connection_schema","fivetran_resync_connection","fivetran_resync_tables","fivetran_run_connection_setup_tests","fivetran_run_destination_setup_tests","fivetran_run_transformation","fivetran_sync_connection","fivetran_update_connection","fivetran_update_connection_schema","fivetran_update_connection_table","fivetran_update_schema_config","flint_create_task","flint_generate_pages","flint_get_task","function_execute","gamma_check_status","gamma_generate","gamma_generate_from_template","gamma_list_folders","gamma_list_themes","github_add_assignees","github_add_assignees_v2","github_add_labels","github_add_labels_v2","github_cancel_workflow_run","github_cancel_workflow_run_v2","github_check_star","github_check_star_v2","github_close_issue","github_close_issue_v2","github_close_pr","github_close_pr_v2","github_comment","github_comment_v2","github_compare_commits","github_compare_commits_v2","github_create_branch","github_create_branch_v2","github_create_comment_reaction","github_create_comment_reaction_v2","github_create_file","github_create_file_v2","github_create_gist","github_create_gist_v2","github_create_issue","github_create_issue_reaction","github_create_issue_reaction_v2","github_create_issue_v2","github_create_milestone","github_create_milestone_v2","github_create_pr","github_create_pr_review","github_create_pr_review_v2","github_create_pr_v2","github_create_project","github_create_project_v2","github_create_release","github_create_release_v2","github_delete_branch","github_delete_branch_v2","github_delete_comment","github_delete_comment_reaction","github_delete_comment_reaction_v2","github_delete_comment_v2","github_delete_file","github_delete_file_v2","github_delete_gist","github_delete_gist_v2","github_delete_issue_reaction","github_delete_issue_reaction_v2","github_delete_milestone","github_delete_milestone_v2","github_delete_project","github_delete_project_v2","github_delete_release","github_delete_release_v2","github_fork_gist","github_fork_gist_v2","github_fork_repo","github_fork_repo_v2","github_get_branch","github_get_branch_protection","github_get_branch_protection_v2","github_get_branch_v2","github_get_commit","github_get_commit_v2","github_get_file_content","github_get_file_content_v2","github_get_gist","github_get_gist_v2","github_get_issue","github_get_issue_v2","github_get_latest_release","github_get_latest_release_v2","github_get_milestone","github_get_milestone_v2","github_get_pr_files","github_get_pr_files_v2","github_get_project","github_get_project_v2","github_get_readme","github_get_readme_v2","github_get_release","github_get_release_v2","github_get_tree","github_get_tree_v2","github_get_workflow","github_get_workflow_run","github_get_workflow_run_v2","github_get_workflow_v2","github_issue_comment","github_issue_comment_v2","github_job_logs","github_latest_commit","github_latest_commit_v2","github_list_branches","github_list_branches_v2","github_list_commits","github_list_commits_v2","github_list_forks","github_list_forks_v2","github_list_gists","github_list_gists_v2","github_list_issue_comments","github_list_issue_comments_v2","github_list_issues","github_list_issues_v2","github_list_milestones","github_list_milestones_v2","github_list_pr_comments","github_list_pr_comments_v2","github_list_projects","github_list_projects_v2","github_list_prs","github_list_prs_v2","github_list_releases","github_list_releases_v2","github_list_review_threads","github_list_stargazers","github_list_stargazers_v2","github_list_tags","github_list_tags_v2","github_list_workflow_runs","github_list_workflow_runs_v2","github_list_workflows","github_list_workflows_v2","github_merge_pr","github_merge_pr_v2","github_pr","github_pr_v2","github_remove_label","github_remove_label_v2","github_reply_review_thread","github_repo_info","github_repo_info_v2","github_request_reviewers","github_request_reviewers_v2","github_rerun_workflow","github_rerun_workflow_v2","github_resolve_review_thread","github_search_code","github_search_code_v2","github_search_commits","github_search_commits_v2","github_search_issues","github_search_issues_v2","github_search_repos","github_search_repos_v2","github_search_users","github_search_users_v2","github_star_gist","github_star_gist_v2","github_star_repo","github_star_repo_v2","github_status_check_rollup","github_trigger_workflow","github_trigger_workflow_v2","github_unstar_gist","github_unstar_gist_v2","github_unstar_repo","github_unstar_repo_v2","github_update_branch_protection","github_update_branch_protection_v2","github_update_comment","github_update_comment_v2","github_update_file","github_update_file_v2","github_update_gist","github_update_gist_v2","github_update_issue","github_update_issue_v2","github_update_milestone","github_update_milestone_v2","github_update_pr","github_update_pr_v2","github_update_project","github_update_project_v2","github_update_release","github_update_release_v2","gitlab_activate_user","gitlab_add_member","gitlab_add_saml_group_link","gitlab_approve_access_request","gitlab_approve_merge_request","gitlab_approve_user","gitlab_ban_user","gitlab_block_user","gitlab_cancel_pipeline","gitlab_compare_branches","gitlab_create_branch","gitlab_create_file","gitlab_create_issue","gitlab_create_issue_note","gitlab_create_merge_request","gitlab_create_merge_request_note","gitlab_create_pipeline","gitlab_create_release","gitlab_create_user","gitlab_deactivate_user","gitlab_delete_branch","gitlab_delete_issue","gitlab_delete_saml_group_link","gitlab_delete_user","gitlab_delete_user_identity","gitlab_deny_access_request","gitlab_get_file","gitlab_get_group","gitlab_get_issue","gitlab_get_job_log","gitlab_get_merge_request","gitlab_get_merge_request_changes","gitlab_get_pipeline","gitlab_get_project","gitlab_invite_member","gitlab_list_access_requests","gitlab_list_branches","gitlab_list_commits","gitlab_list_groups","gitlab_list_invitations","gitlab_list_issues","gitlab_list_members","gitlab_list_merge_requests","gitlab_list_pipeline_jobs","gitlab_list_pipelines","gitlab_list_projects","gitlab_list_releases","gitlab_list_repository_tree","gitlab_list_saml_group_links","gitlab_list_user_memberships","gitlab_merge_merge_request","gitlab_play_job","gitlab_reject_user","gitlab_remove_member","gitlab_retry_pipeline","gitlab_revoke_invitation","gitlab_search_users","gitlab_unban_user","gitlab_unblock_user","gitlab_update_file","gitlab_update_invitation","gitlab_update_issue","gitlab_update_member","gitlab_update_merge_request","gitlab_update_user","gmail_add_label","gmail_add_label_v2","gmail_archive","gmail_archive_v2","gmail_create_label_v2","gmail_delete","gmail_delete_draft_v2","gmail_delete_label_v2","gmail_delete_v2","gmail_draft","gmail_draft_v2","gmail_edit_draft_v2","gmail_get_draft_v2","gmail_get_thread_v2","gmail_list_drafts_v2","gmail_list_labels_v2","gmail_list_threads_v2","gmail_mark_read","gmail_mark_read_v2","gmail_mark_unread","gmail_mark_unread_v2","gmail_move","gmail_move_v2","gmail_read","gmail_read_v2","gmail_remove_label","gmail_remove_label_v2","gmail_search","gmail_search_v2","gmail_send","gmail_send_v2","gmail_trash_thread_v2","gmail_unarchive","gmail_unarchive_v2","gmail_untrash_thread_v2","gmail_update_label_v2","gong_aggregate_activity","gong_aggregate_by_period","gong_answered_scorecards","gong_ask_anything","gong_assign_flow_prospects","gong_create_call","gong_day_by_day_activity","gong_get_brief","gong_get_call","gong_get_call_transcript","gong_get_coaching","gong_get_extensive_calls","gong_get_folder_content","gong_get_logs","gong_get_prospect_flows","gong_get_user","gong_interaction_stats","gong_list_calls","gong_list_flows","gong_list_library_folders","gong_list_scorecards","gong_list_trackers","gong_list_users","gong_list_workspaces","gong_lookup_email","gong_lookup_phone","gong_purge_email_address","gong_purge_phone_number","gong_unassign_flow_prospects","google_ads_ad_performance","google_ads_campaign_performance","google_ads_list_ad_groups","google_ads_list_campaigns","google_ads_list_customers","google_ads_search","google_appsheet_add_rows","google_appsheet_delete_rows","google_appsheet_edit_rows","google_appsheet_find_rows","google_bigquery_create_dataset","google_bigquery_create_table","google_bigquery_delete_dataset","google_bigquery_delete_table","google_bigquery_get_query_results","google_bigquery_get_table","google_bigquery_insert_rows","google_bigquery_list_datasets","google_bigquery_list_table_data","google_bigquery_list_tables","google_bigquery_query","google_books_volume_details","google_books_volume_search","google_calendar_create","google_calendar_create_calendar","google_calendar_create_calendar_v2","google_calendar_create_v2","google_calendar_delete","google_calendar_delete_calendar","google_calendar_delete_calendar_v2","google_calendar_delete_v2","google_calendar_freebusy","google_calendar_freebusy_v2","google_calendar_get","google_calendar_get_v2","google_calendar_instances","google_calendar_instances_v2","google_calendar_invite","google_calendar_invite_v2","google_calendar_list","google_calendar_list_acl","google_calendar_list_acl_v2","google_calendar_list_calendars","google_calendar_list_calendars_v2","google_calendar_list_v2","google_calendar_move","google_calendar_move_v2","google_calendar_quick_add","google_calendar_quick_add_v2","google_calendar_respond","google_calendar_respond_v2","google_calendar_share_calendar","google_calendar_share_calendar_v2","google_calendar_unshare_calendar","google_calendar_unshare_calendar_v2","google_calendar_update","google_calendar_update_acl","google_calendar_update_acl_v2","google_calendar_update_calendar","google_calendar_update_calendar_v2","google_calendar_update_v2","google_contacts_create","google_contacts_delete","google_contacts_get","google_contacts_list","google_contacts_search","google_contacts_update","google_docs_create","google_docs_create_named_range","google_docs_create_paragraph_bullets","google_docs_delete_content_range","google_docs_delete_named_range","google_docs_delete_paragraph_bullets","google_docs_insert_image","google_docs_insert_page_break","google_docs_insert_table","google_docs_insert_text","google_docs_read","google_docs_replace_text","google_docs_update_paragraph_style","google_docs_update_text_style","google_docs_write","google_drive_copy","google_drive_create_comment","google_drive_create_folder","google_drive_delete","google_drive_delete_comment","google_drive_download","google_drive_export","google_drive_get_about","google_drive_get_content","google_drive_get_file","google_drive_get_revision","google_drive_list","google_drive_list_comments","google_drive_list_permissions","google_drive_list_revisions","google_drive_move","google_drive_search","google_drive_share","google_drive_trash","google_drive_unshare","google_drive_untrash","google_drive_update","google_drive_upload","google_forms_batch_update","google_forms_create_form","google_forms_create_watch","google_forms_delete_watch","google_forms_get_form","google_forms_get_responses","google_forms_list_watches","google_forms_renew_watch","google_forms_set_publish_settings","google_groups_add_alias","google_groups_add_member","google_groups_create_group","google_groups_delete_group","google_groups_get_group","google_groups_get_member","google_groups_get_settings","google_groups_has_member","google_groups_list_aliases","google_groups_list_groups","google_groups_list_members","google_groups_remove_alias","google_groups_remove_member","google_groups_update_group","google_groups_update_member","google_groups_update_settings","google_maps_air_quality","google_maps_directions","google_maps_distance_matrix","google_maps_elevation","google_maps_geocode","google_maps_geolocate","google_maps_place_details","google_maps_places_nearby","google_maps_places_search","google_maps_pollen","google_maps_reverse_geocode","google_maps_snap_to_roads","google_maps_solar","google_maps_speed_limits","google_maps_timezone","google_maps_validate_address","google_meet_create_space","google_meet_end_conference","google_meet_get_conference_record","google_meet_get_space","google_meet_list_conference_records","google_meet_list_participants","google_pagespeed_analyze","google_search","google_sheets_append","google_sheets_append_v2","google_sheets_batch_clear_v2","google_sheets_batch_get_v2","google_sheets_batch_update_v2","google_sheets_clear_v2","google_sheets_copy_sheet_v2","google_sheets_create_spreadsheet_v2","google_sheets_delete_rows_v2","google_sheets_delete_sheet_v2","google_sheets_delete_spreadsheet_v2","google_sheets_get_spreadsheet_v2","google_sheets_read","google_sheets_read_v2","google_sheets_update","google_sheets_update_v2","google_sheets_write","google_sheets_write_v2","google_slides_add_image","google_slides_add_slide","google_slides_batch_update","google_slides_copy_presentation","google_slides_create","google_slides_create_line","google_slides_create_paragraph_bullets","google_slides_create_shape","google_slides_create_sheets_chart","google_slides_create_table","google_slides_create_video","google_slides_delete_object","google_slides_delete_paragraph_bullets","google_slides_delete_table_column","google_slides_delete_table_row","google_slides_delete_text","google_slides_duplicate_object","google_slides_export_presentation","google_slides_get_page","google_slides_get_thumbnail","google_slides_group_objects","google_slides_insert_table_columns","google_slides_insert_table_rows","google_slides_insert_text","google_slides_merge_table_cells","google_slides_read","google_slides_refresh_sheets_chart","google_slides_replace_all_shapes_with_image","google_slides_replace_all_shapes_with_sheets_chart","google_slides_replace_all_text","google_slides_replace_image","google_slides_reroute_line","google_slides_ungroup_objects","google_slides_unmerge_table_cells","google_slides_update_image_properties","google_slides_update_line_category","google_slides_update_line_properties","google_slides_update_page_element_alt_text","google_slides_update_page_element_transform","google_slides_update_page_elements_z_order","google_slides_update_page_properties","google_slides_update_paragraph_style","google_slides_update_shape_properties","google_slides_update_slide_properties","google_slides_update_slides_position","google_slides_update_table_border_properties","google_slides_update_table_cell_properties","google_slides_update_table_column_properties","google_slides_update_table_row_properties","google_slides_update_text_style","google_slides_update_video_properties","google_slides_write","google_tasks_create","google_tasks_delete","google_tasks_get","google_tasks_list","google_tasks_list_task_lists","google_tasks_update","google_translate_detect","google_translate_text","google_vault_add_held_accounts","google_vault_add_matters_permissions","google_vault_close_matters","google_vault_create_matters","google_vault_create_matters_export","google_vault_create_matters_holds","google_vault_create_saved_query","google_vault_delete_matters","google_vault_delete_matters_export","google_vault_delete_matters_holds","google_vault_delete_saved_query","google_vault_download_export_file","google_vault_list_matters","google_vault_list_matters_export","google_vault_list_matters_holds","google_vault_list_saved_queries","google_vault_remove_held_accounts","google_vault_remove_matters_permissions","google_vault_reopen_matters","google_vault_undelete_matters","google_vault_update_matters","google_vault_update_matters_holds","grafana_check_data_source_health","grafana_create_alert_rule","grafana_create_annotation","grafana_create_contact_point","grafana_create_dashboard","grafana_create_folder","grafana_delete_alert_rule","grafana_delete_annotation","grafana_delete_contact_point","grafana_delete_dashboard","grafana_delete_folder","grafana_get_alert_rule","grafana_get_alert_rule_group","grafana_get_dashboard","grafana_get_data_source","grafana_get_folder","grafana_get_health","grafana_list_alert_rules","grafana_list_annotations","grafana_list_contact_points","grafana_list_dashboards","grafana_list_data_sources","grafana_list_folders","grafana_move_folder","grafana_query_data_source","grafana_update_alert_rule","grafana_update_annotation","grafana_update_contact_point","grafana_update_dashboard","grafana_update_folder","grain_create_hook","grain_create_hook_v2","grain_delete_hook","grain_delete_hook_v2","grain_get_recording","grain_get_transcript","grain_list_hooks","grain_list_hooks_v2","grain_list_meeting_types","grain_list_recordings","grain_list_teams","grain_list_views","granola_create_webhook_endpoint","granola_delete_webhook_endpoint","granola_get_note","granola_get_transcript","granola_list_audit_events","granola_list_folders","granola_list_notes","granola_list_webhook_endpoints","granola_update_webhook_endpoint","greenhouse_get_application","greenhouse_get_candidate","greenhouse_get_job","greenhouse_get_user","greenhouse_list_applications","greenhouse_list_candidates","greenhouse_list_departments","greenhouse_list_job_stages","greenhouse_list_jobs","greenhouse_list_offices","greenhouse_list_users","greptile_index_repo","greptile_query","greptile_search","greptile_status","guardrails_validate","harmonic_batch_get_people","harmonic_clear_people_saved_search_net_new_results","harmonic_enrich_person","harmonic_get_company_employees","harmonic_get_email_enrichment_job","harmonic_get_email_enrichment_usage","harmonic_get_enrichment_status","harmonic_get_people_saved_search_net_new_results","harmonic_get_people_saved_search_results","harmonic_get_person","harmonic_list_people_saved_searches","harmonic_search_people_scout","harmonic_submit_email_enrichment_job","hex_cancel_run","hex_create_collection","hex_create_group","hex_deactivate_user","hex_delete_group","hex_get_collection","hex_get_data_connection","hex_get_group","hex_get_project","hex_get_project_runs","hex_get_queried_tables","hex_get_run_status","hex_list_collections","hex_list_data_connections","hex_list_groups","hex_list_projects","hex_list_users","hex_run_project","hex_update_collection","hex_update_group","hex_update_project","http_request","hubspot_add_list_memberships","hubspot_create_appointment","hubspot_create_association","hubspot_create_company","hubspot_create_contact","hubspot_create_deal","hubspot_create_email","hubspot_create_line_item","hubspot_create_list","hubspot_create_note","hubspot_create_ticket","hubspot_delete_association","hubspot_delete_company","hubspot_delete_contact","hubspot_delete_deal","hubspot_delete_line_item","hubspot_delete_ticket","hubspot_get_appointment","hubspot_get_association_labels","hubspot_get_cart","hubspot_get_company","hubspot_get_contact","hubspot_get_deal","hubspot_get_email","hubspot_get_line_item","hubspot_get_list","hubspot_get_list_memberships","hubspot_get_marketing_event","hubspot_get_note","hubspot_get_properties","hubspot_get_quote","hubspot_get_ticket","hubspot_get_users","hubspot_list_appointments","hubspot_list_associations","hubspot_list_carts","hubspot_list_companies","hubspot_list_contacts","hubspot_list_deals","hubspot_list_emails","hubspot_list_line_items","hubspot_list_lists","hubspot_list_marketing_events","hubspot_list_notes","hubspot_list_owners","hubspot_list_quotes","hubspot_list_tickets","hubspot_remove_list_memberships","hubspot_search_companies","hubspot_search_contacts","hubspot_search_deals","hubspot_search_emails","hubspot_search_line_items","hubspot_search_notes","hubspot_search_quotes","hubspot_search_tickets","hubspot_update_appointment","hubspot_update_company","hubspot_update_contact","hubspot_update_deal","hubspot_update_line_item","hubspot_update_ticket","huggingface_chat","hunter_companies_find","hunter_discover","hunter_domain_search","hunter_email_count","hunter_email_finder","hunter_email_verifier","iam_add_user_to_group","iam_attach_role_policy","iam_attach_user_policy","iam_create_access_key","iam_create_role","iam_create_user","iam_delete_access_key","iam_delete_role","iam_delete_user","iam_detach_role_policy","iam_detach_user_policy","iam_get_policy","iam_get_role","iam_get_user","iam_list_access_keys","iam_list_attached_role_policies","iam_list_attached_user_policies","iam_list_groups","iam_list_policies","iam_list_roles","iam_list_users","iam_remove_user_from_group","iam_simulate_principal_policy","iam_update_access_key","icypeas_find_email","icypeas_verify_email","identity_center_check_assignment_deletion_status","identity_center_check_assignment_status","identity_center_create_account_assignment","identity_center_delete_account_assignment","identity_center_describe_account","identity_center_describe_group","identity_center_describe_user","identity_center_get_group","identity_center_get_user","identity_center_list_account_assignments","identity_center_list_accounts","identity_center_list_assignments_for_account","identity_center_list_group_memberships","identity_center_list_groups","identity_center_list_instances","identity_center_list_permission_sets","image_generate","incidentio_actions_create","incidentio_actions_list","incidentio_actions_show","incidentio_actions_update","incidentio_alert_events_create","incidentio_alerts_list","incidentio_alerts_resolve","incidentio_alerts_show","incidentio_catalog_entries_list","incidentio_catalog_types_list","incidentio_custom_fields_create","incidentio_custom_fields_delete","incidentio_custom_fields_list","incidentio_custom_fields_show","incidentio_custom_fields_update","incidentio_escalation_paths_create","incidentio_escalation_paths_delete","incidentio_escalation_paths_list","incidentio_escalation_paths_show","incidentio_escalation_paths_update","incidentio_escalations_cancel","incidentio_escalations_create","incidentio_escalations_list","incidentio_escalations_show","incidentio_follow_ups_create","incidentio_follow_ups_list","incidentio_follow_ups_show","incidentio_follow_ups_update","incidentio_incident_alerts_list","incidentio_incident_memberships_create","incidentio_incident_memberships_revoke","incidentio_incident_participants_list","incidentio_incident_roles_create","incidentio_incident_roles_delete","incidentio_incident_roles_list","incidentio_incident_roles_show","incidentio_incident_roles_update","incidentio_incident_statuses_list","incidentio_incident_timestamps_list","incidentio_incident_timestamps_show","incidentio_incident_types_list","incidentio_incident_updates_list","incidentio_incidents_create","incidentio_incidents_list","incidentio_incidents_show","incidentio_incidents_update","incidentio_on_call_now","incidentio_schedule_entries_list","incidentio_schedule_overrides_create","incidentio_schedule_overrides_list","incidentio_schedules_create","incidentio_schedules_delete","incidentio_schedules_list","incidentio_schedules_show","incidentio_schedules_update","incidentio_severities_list","incidentio_teams_list","incidentio_teams_show","incidentio_users_list","incidentio_users_show","incidentio_workflows_create","incidentio_workflows_delete","incidentio_workflows_list","incidentio_workflows_show","incidentio_workflows_update","infisical_create_secret","infisical_delete_secret","infisical_get_secret","infisical_list_secrets","infisical_update_secret","instagram_delete_comment","instagram_download_media","instagram_get_account_insights","instagram_get_container_status","instagram_get_conversation_messages","instagram_get_media","instagram_get_media_insights","instagram_get_message","instagram_get_profile","instagram_get_publishing_limit","instagram_hide_comment","instagram_list_comments","instagram_list_conversations","instagram_list_media","instagram_list_stories","instagram_private_reply","instagram_publish_carousel","instagram_publish_image","instagram_publish_reel","instagram_publish_story","instagram_publish_video","instagram_reply_to_comment","instagram_send_text_message","instagram_set_comments_enabled","instantly_activate_campaign","instantly_create_campaign","instantly_create_lead","instantly_create_lead_list","instantly_delete_campaign","instantly_delete_leads","instantly_get_lead","instantly_list_campaigns","instantly_list_emails","instantly_list_lead_lists","instantly_list_leads","instantly_patch_campaign","instantly_patch_lead","instantly_pause_campaign","instantly_reply_to_email","instantly_update_lead_interest_status","intercom_assign_conversation_v2","intercom_attach_contact_to_company_v2","intercom_close_conversation_v2","intercom_create_company","intercom_create_company_v2","intercom_create_contact","intercom_create_contact_v2","intercom_create_event_v2","intercom_create_message","intercom_create_message_v2","intercom_create_note_v2","intercom_create_tag_v2","intercom_create_ticket","intercom_create_ticket_v2","intercom_delete_contact","intercom_delete_contact_v2","intercom_detach_contact_from_company_v2","intercom_get_company","intercom_get_company_v2","intercom_get_contact","intercom_get_contact_v2","intercom_get_conversation","intercom_get_conversation_v2","intercom_get_ticket","intercom_get_ticket_v2","intercom_list_admins_v2","intercom_list_companies","intercom_list_companies_v2","intercom_list_contacts","intercom_list_contacts_v2","intercom_list_conversations","intercom_list_conversations_v2","intercom_list_tags_v2","intercom_open_conversation_v2","intercom_reply_conversation","intercom_reply_conversation_v2","intercom_search_contacts","intercom_search_contacts_v2","intercom_search_conversations","intercom_search_conversations_v2","intercom_snooze_conversation_v2","intercom_tag_contact_v2","intercom_tag_conversation_v2","intercom_untag_contact_v2","intercom_update_contact","intercom_update_contact_v2","intercom_update_ticket_v2","intune_get_compliance_policy","intune_get_detected_app","intune_get_device","intune_get_device_configuration","intune_list_app_devices","intune_list_compliance_policies","intune_list_compliance_policy_device_statuses","intune_list_detected_apps","intune_list_device_configurations","intune_list_devices","intune_reboot_device","intune_remote_lock_device","intune_retire_device","intune_sync_device","jina_read_url","jina_search","jira_add_attachment","jira_add_comment","jira_add_watcher","jira_add_worklog","jira_assign_issue","jira_bulk_read","jira_create_issue_link","jira_delete_attachment","jira_delete_comment","jira_delete_issue","jira_delete_issue_link","jira_delete_worklog","jira_get_attachments","jira_get_comments","jira_get_fields","jira_get_project","jira_get_transitions","jira_get_users","jira_get_worklogs","jira_list_issue_types","jira_list_projects","jira_remove_watcher","jira_retrieve","jira_search_issues","jira_search_users","jira_transition_issue","jira_update","jira_update_comment","jira_update_worklog","jira_write","jotform_add_label_resources","jotform_clone_form","jotform_create_form","jotform_create_label","jotform_create_question","jotform_create_questions","jotform_create_report","jotform_create_submission","jotform_create_submissions","jotform_create_webhook","jotform_delete_form","jotform_delete_label","jotform_delete_question","jotform_delete_report","jotform_delete_submission","jotform_delete_webhook","jotform_get_form","jotform_get_form_properties","jotform_get_history","jotform_get_label","jotform_get_question","jotform_get_report","jotform_get_settings","jotform_get_submission","jotform_get_usage","jotform_get_user","jotform_list_form_files","jotform_list_form_reports","jotform_list_form_submissions","jotform_list_forms","jotform_list_label_resources","jotform_list_labels","jotform_list_questions","jotform_list_reports","jotform_list_submissions","jotform_list_subusers","jotform_list_webhooks","jotform_remove_label_resources","jotform_update_form_properties","jotform_update_label","jotform_update_question","jotform_update_settings","jotform_update_submission","jsm_add_comment","jsm_add_customer","jsm_add_organization","jsm_add_participants","jsm_answer_approval","jsm_attach_form","jsm_copy_forms","jsm_create_object","jsm_create_organization","jsm_create_request","jsm_delete_form","jsm_delete_object","jsm_externalise_form","jsm_get_approvals","jsm_get_comments","jsm_get_customers","jsm_get_form","jsm_get_form_answers","jsm_get_form_structure","jsm_get_form_templates","jsm_get_issue_forms","jsm_get_object","jsm_get_object_schema","jsm_get_object_type_attributes","jsm_get_organizations","jsm_get_participants","jsm_get_queues","jsm_get_request","jsm_get_request_type_fields","jsm_get_request_types","jsm_get_requests","jsm_get_service_desks","jsm_get_sla","jsm_get_transitions","jsm_internalise_form","jsm_list_object_schemas","jsm_list_object_types","jsm_reopen_form","jsm_save_form_answers","jsm_search_objects_aql","jsm_submit_form","jsm_transition_request","jsm_update_object","jupyter_copy_content","jupyter_create_file","jupyter_create_session","jupyter_delete_content","jupyter_delete_session","jupyter_get_content","jupyter_get_content_v2","jupyter_interrupt_kernel","jupyter_list_contents","jupyter_list_kernels","jupyter_list_kernelspecs","jupyter_list_sessions","jupyter_rename_content","jupyter_restart_kernel","jupyter_start_kernel","jupyter_stop_kernel","jupyter_upload_file","kalshi_amend_order","kalshi_amend_order_v2","kalshi_cancel_order","kalshi_cancel_order_v2","kalshi_create_order","kalshi_create_order_v2","kalshi_get_balance","kalshi_get_balance_v2","kalshi_get_candlesticks","kalshi_get_candlesticks_v2","kalshi_get_event","kalshi_get_event_candlesticks","kalshi_get_event_candlesticks_v2","kalshi_get_event_v2","kalshi_get_events","kalshi_get_events_v2","kalshi_get_exchange_announcements","kalshi_get_exchange_announcements_v2","kalshi_get_exchange_schedule","kalshi_get_exchange_schedule_v2","kalshi_get_exchange_status","kalshi_get_exchange_status_v2","kalshi_get_fills","kalshi_get_fills_v2","kalshi_get_market","kalshi_get_market_v2","kalshi_get_markets","kalshi_get_markets_v2","kalshi_get_order","kalshi_get_order_v2","kalshi_get_orderbook","kalshi_get_orderbook_v2","kalshi_get_orders","kalshi_get_orders_v2","kalshi_get_positions","kalshi_get_positions_v2","kalshi_get_series_by_ticker","kalshi_get_series_by_ticker_v2","kalshi_get_series_list","kalshi_get_series_list_v2","kalshi_get_settlements","kalshi_get_settlements_v2","kalshi_get_trades","kalshi_get_trades_v2","ketch_get_consent","ketch_get_subscriptions","ketch_invoke_right","ketch_set_consent","ketch_set_subscriptions","knowledge_create_document","knowledge_delete_chunk","knowledge_delete_document","knowledge_get_connector","knowledge_get_document","knowledge_list_chunks","knowledge_list_connectors","knowledge_list_documents","knowledge_list_tags","knowledge_search","knowledge_trigger_sync","knowledge_update_chunk","knowledge_upload_chunk","knowledge_upsert_document","lambda_add_permission","lambda_create_alias","lambda_create_event_source_mapping","lambda_create_function","lambda_create_function_url_config","lambda_delete_alias","lambda_delete_event_source_mapping","lambda_delete_function","lambda_delete_function_concurrency","lambda_delete_function_event_invoke_config","lambda_delete_function_url_config","lambda_delete_provisioned_concurrency_config","lambda_get_account_settings","lambda_get_alias","lambda_get_event_source_mapping","lambda_get_function","lambda_get_function_concurrency","lambda_get_function_configuration","lambda_get_function_event_invoke_config","lambda_get_function_recursion_config","lambda_get_function_url_config","lambda_get_layer_version","lambda_get_policy","lambda_get_provisioned_concurrency_config","lambda_get_runtime_management_config","lambda_invoke","lambda_list_aliases","lambda_list_event_source_mappings","lambda_list_function_event_invoke_configs","lambda_list_function_url_configs","lambda_list_functions","lambda_list_layer_versions","lambda_list_layers","lambda_list_provisioned_concurrency_configs","lambda_list_tags","lambda_list_versions_by_function","lambda_publish_version","lambda_put_function_concurrency","lambda_put_function_event_invoke_config","lambda_put_function_recursion_config","lambda_put_provisioned_concurrency_config","lambda_put_runtime_management_config","lambda_remove_permission","lambda_tag_resource","lambda_untag_resource","lambda_update_alias","lambda_update_event_source_mapping","lambda_update_function_code","lambda_update_function_configuration","lambda_update_function_url_config","langsmith_create_feedback","langsmith_create_run","langsmith_create_runs_batch","langsmith_get_run","langsmith_update_run","latex_compile","latex_get_package","latex_list_fonts","latex_search_packages","launchdarkly_create_flag","launchdarkly_delete_flag","launchdarkly_get_audit_log","launchdarkly_get_flag","launchdarkly_get_flag_status","launchdarkly_list_environments","launchdarkly_list_flags","launchdarkly_list_members","launchdarkly_list_projects","launchdarkly_list_segments","launchdarkly_toggle_flag","launchdarkly_update_flag","leadmagic_company_search","leadmagic_email_to_profile","leadmagic_find_email","leadmagic_find_mobile","leadmagic_get_credits","leadmagic_profile_search","leadmagic_profile_to_email","leadmagic_role_finder","leadmagic_validate_email","lemlist_get_activities","lemlist_get_lead","lemlist_send_email","linear_add_label_to_issue","linear_add_label_to_project","linear_archive_issue","linear_archive_label","linear_archive_project","linear_create_attachment","linear_create_comment","linear_create_customer","linear_create_customer_request","linear_create_customer_status","linear_create_customer_tier","linear_create_cycle","linear_create_favorite","linear_create_issue","linear_create_issue_relation","linear_create_label","linear_create_project","linear_create_project_label","linear_create_project_milestone","linear_create_project_status","linear_create_project_update","linear_create_workflow_state","linear_delete_attachment","linear_delete_comment","linear_delete_customer","linear_delete_customer_status","linear_delete_customer_tier","linear_delete_issue","linear_delete_issue_relation","linear_delete_project","linear_delete_project_label","linear_delete_project_milestone","linear_delete_project_status","linear_get_active_cycle","linear_get_customer","linear_get_cycle","linear_get_issue","linear_get_project","linear_get_viewer","linear_list_attachments","linear_list_comments","linear_list_customer_requests","linear_list_customer_statuses","linear_list_customer_tiers","linear_list_customers","linear_list_cycles","linear_list_favorites","linear_list_issue_relations","linear_list_labels","linear_list_notifications","linear_list_project_labels","linear_list_project_milestones","linear_list_project_statuses","linear_list_project_updates","linear_list_projects","linear_list_teams","linear_list_users","linear_list_workflow_states","linear_merge_customers","linear_read_issues","linear_remove_label_from_issue","linear_remove_label_from_project","linear_search_issues","linear_unarchive_issue","linear_update_attachment","linear_update_comment","linear_update_customer","linear_update_customer_request","linear_update_customer_status","linear_update_customer_tier","linear_update_issue","linear_update_label","linear_update_notification","linear_update_project","linear_update_project_label","linear_update_project_milestone","linear_update_project_status","linear_update_workflow_state","linkedin_get_profile","linkedin_share_post","linkup_search","linq_add_participant","linq_check_imessage","linq_check_rcs","linq_create_attachment","linq_create_chat","linq_create_contact_card","linq_create_webhook_subscription","linq_delete_attachment","linq_delete_message","linq_delete_webhook_subscription","linq_edit_message","linq_get_attachment","linq_get_chat","linq_get_contact_card","linq_get_message","linq_get_webhook_subscription","linq_leave_chat","linq_list_chats","linq_list_messages","linq_list_phone_numbers","linq_list_thread","linq_list_webhook_events","linq_list_webhook_subscriptions","linq_mark_chat_read","linq_react_to_message","linq_remove_participant","linq_send_message","linq_send_voice_memo","linq_share_contact_card","linq_start_typing","linq_stop_typing","linq_update_chat","linq_update_contact_card","linq_update_webhook_subscription","llm_chat","logfire_get_token_info","logfire_get_trace","logfire_query","logfire_search_records","logrocket_create_release","logrocket_get_audit_logs","logrocket_get_highlights","logrocket_identify_user","logrocket_list_exported_sessions","logrocket_request_highlights","logs_get","logs_get_execution","logs_get_run_details","logs_query","logs_query_runs","loops_check_contact_suppression","loops_create_contact","loops_create_contact_property","loops_delete_contact","loops_find_contact","loops_get_transactional_email","loops_list_contact_properties","loops_list_mailing_lists","loops_list_transactional_emails","loops_remove_contact_suppression","loops_send_event","loops_send_transactional_email","loops_update_contact","luma_add_guests","luma_cancel_event","luma_create_event","luma_get_event","luma_get_guest","luma_get_guests","luma_list_events","luma_lookup_event","luma_send_invites","luma_update_event","luma_update_guest_status","mailchimp_add_member","mailchimp_add_member_tags","mailchimp_add_or_update_member","mailchimp_add_segment_member","mailchimp_add_subscriber_to_automation","mailchimp_archive_member","mailchimp_create_audience","mailchimp_create_batch_operation","mailchimp_create_campaign","mailchimp_create_interest","mailchimp_create_interest_category","mailchimp_create_landing_page","mailchimp_create_merge_field","mailchimp_create_segment","mailchimp_create_template","mailchimp_delete_audience","mailchimp_delete_batch_operation","mailchimp_delete_campaign","mailchimp_delete_interest","mailchimp_delete_interest_category","mailchimp_delete_landing_page","mailchimp_delete_member","mailchimp_delete_merge_field","mailchimp_delete_segment","mailchimp_delete_template","mailchimp_get_audience","mailchimp_get_audiences","mailchimp_get_automation","mailchimp_get_automations","mailchimp_get_batch_operation","mailchimp_get_batch_operations","mailchimp_get_campaign","mailchimp_get_campaign_content","mailchimp_get_campaign_report","mailchimp_get_campaign_reports","mailchimp_get_campaigns","mailchimp_get_interest","mailchimp_get_interest_categories","mailchimp_get_interest_category","mailchimp_get_interests","mailchimp_get_landing_page","mailchimp_get_landing_pages","mailchimp_get_member","mailchimp_get_member_tags","mailchimp_get_members","mailchimp_get_merge_field","mailchimp_get_merge_fields","mailchimp_get_segment","mailchimp_get_segment_members","mailchimp_get_segments","mailchimp_get_template","mailchimp_get_templates","mailchimp_pause_automation","mailchimp_publish_landing_page","mailchimp_remove_member_tags","mailchimp_remove_segment_member","mailchimp_replicate_campaign","mailchimp_schedule_campaign","mailchimp_send_campaign","mailchimp_set_campaign_content","mailchimp_start_automation","mailchimp_unarchive_member","mailchimp_unpublish_landing_page","mailchimp_unschedule_campaign","mailchimp_update_audience","mailchimp_update_campaign","mailchimp_update_interest","mailchimp_update_interest_category","mailchimp_update_landing_page","mailchimp_update_member","mailchimp_update_merge_field","mailchimp_update_segment","mailchimp_update_template","mailgun_add_list_member","mailgun_create_mailing_list","mailgun_get_domain","mailgun_get_mailing_list","mailgun_get_message","mailgun_list_domains","mailgun_list_messages","mailgun_send_message","managed_agent_archive_session","managed_agent_create_session","managed_agent_delete_session","managed_agent_get_session","managed_agent_interrupt_session","managed_agent_list_events","managed_agent_respond_custom_tool","managed_agent_respond_tool_confirmation","managed_agent_run_session","managed_agent_send_message","managed_agent_update_session","manageengine_sdp_add_change_note","manageengine_sdp_add_problem_note","manageengine_sdp_add_request_note","manageengine_sdp_create_asset","manageengine_sdp_create_change","manageengine_sdp_create_problem","manageengine_sdp_create_request","manageengine_sdp_create_solution","manageengine_sdp_delete_asset","manageengine_sdp_delete_change","manageengine_sdp_delete_problem","manageengine_sdp_delete_request","manageengine_sdp_delete_solution","manageengine_sdp_get_asset","manageengine_sdp_get_change","manageengine_sdp_get_problem","manageengine_sdp_get_request","manageengine_sdp_get_solution","manageengine_sdp_list_assets","manageengine_sdp_list_change_notes","manageengine_sdp_list_changes","manageengine_sdp_list_problem_notes","manageengine_sdp_list_problems","manageengine_sdp_list_request_notes","manageengine_sdp_list_requests","manageengine_sdp_list_solutions","manageengine_sdp_update_asset","manageengine_sdp_update_change","manageengine_sdp_update_problem","manageengine_sdp_update_request","manageengine_sdp_update_solution","mcp_list_operations","mcp_run_operation","mem0_add_memories","mem0_get_memories","mem0_search_memories","memory_add","memory_delete","memory_get","memory_get_all","microsoft_ad_add_directory_role_member","microsoft_ad_add_group_member","microsoft_ad_add_user_app_role_assignment","microsoft_ad_assign_license","microsoft_ad_create_group","microsoft_ad_create_user","microsoft_ad_delete_group","microsoft_ad_delete_user","microsoft_ad_get_conditional_access_policy","microsoft_ad_get_device","microsoft_ad_get_group","microsoft_ad_get_user","microsoft_ad_list_authentication_methods","microsoft_ad_list_conditional_access_policies","microsoft_ad_list_devices","microsoft_ad_list_directory_audits","microsoft_ad_list_directory_role_members","microsoft_ad_list_directory_roles","microsoft_ad_list_group_members","microsoft_ad_list_groups","microsoft_ad_list_service_principal_app_role_assignments","microsoft_ad_list_service_principals","microsoft_ad_list_sign_ins","microsoft_ad_list_subscribed_skus","microsoft_ad_list_user_app_role_assignments","microsoft_ad_list_user_devices","microsoft_ad_list_user_licenses","microsoft_ad_list_users","microsoft_ad_remove_directory_role_member","microsoft_ad_remove_group_member","microsoft_ad_remove_user_app_role_assignment","microsoft_ad_reset_password","microsoft_ad_revoke_sign_in_sessions","microsoft_ad_set_password","microsoft_ad_update_group","microsoft_ad_update_user","microsoft_dataverse_associate","microsoft_dataverse_create_multiple","microsoft_dataverse_create_record","microsoft_dataverse_delete_record","microsoft_dataverse_disassociate","microsoft_dataverse_download_file","microsoft_dataverse_download_file_v2","microsoft_dataverse_execute_action","microsoft_dataverse_execute_function","microsoft_dataverse_fetchxml_query","microsoft_dataverse_get_entity_metadata","microsoft_dataverse_get_record","microsoft_dataverse_list_records","microsoft_dataverse_search","microsoft_dataverse_update_multiple","microsoft_dataverse_update_record","microsoft_dataverse_upload_file","microsoft_dataverse_upsert_record","microsoft_dataverse_whoami","microsoft_dynamics_365_close_case","microsoft_dynamics_365_close_opportunity","microsoft_dynamics_365_create_record","microsoft_dynamics_365_get_record","microsoft_dynamics_365_list_records","microsoft_dynamics_365_qualify_lead","microsoft_dynamics_365_search_records","microsoft_dynamics_365_update_record","microsoft_excel_clear_range","microsoft_excel_create_table","microsoft_excel_delete_worksheet","microsoft_excel_format_range","microsoft_excel_read","microsoft_excel_read_v2","microsoft_excel_sort_range","microsoft_excel_table_add","microsoft_excel_worksheet_add","microsoft_excel_write","microsoft_excel_write_v2","microsoft_planner_create_bucket","microsoft_planner_create_plan","microsoft_planner_create_task","microsoft_planner_delete_bucket","microsoft_planner_delete_plan","microsoft_planner_delete_task","microsoft_planner_get_plan_details","microsoft_planner_get_task_details","microsoft_planner_list_buckets","microsoft_planner_list_plans","microsoft_planner_read_bucket","microsoft_planner_read_plan","microsoft_planner_read_task","microsoft_planner_update_bucket","microsoft_planner_update_plan","microsoft_planner_update_plan_details","microsoft_planner_update_task","microsoft_planner_update_task_details","microsoft_teams_delete_channel_message","microsoft_teams_delete_chat_message","microsoft_teams_get_message","microsoft_teams_list_channel_members","microsoft_teams_list_channels","microsoft_teams_list_chat_members","microsoft_teams_list_chats","microsoft_teams_list_team_members","microsoft_teams_list_teams","microsoft_teams_read_channel","microsoft_teams_read_chat","microsoft_teams_reply_to_message","microsoft_teams_set_reaction","microsoft_teams_unset_reaction","microsoft_teams_update_channel_message","microsoft_teams_update_chat_message","microsoft_teams_write_channel","microsoft_teams_write_chat","microsoft_word_append","microsoft_word_create","microsoft_word_create_from_template","microsoft_word_export_pdf","microsoft_word_list","microsoft_word_read","microsoft_word_replace_text","microsoft_word_update","millionverifier_get_credits","millionverifier_verify_email","mintlify_create_agent_job","mintlify_create_assistant_message","mintlify_detect_ai_prose","mintlify_get_agent_job","mintlify_get_assistant_caller_stats","mintlify_get_assistant_conversations","mintlify_get_feedback","mintlify_get_feedback_by_page","mintlify_get_page_content","mintlify_get_searches","mintlify_get_update_status","mintlify_get_views","mintlify_get_visitors","mintlify_search","mintlify_send_agent_message","mintlify_trigger_automation","mintlify_trigger_preview","mintlify_trigger_update","mistral_parser","mistral_parser_v2","mistral_parser_v3","modal_call_function","modal_chat_completion","modal_list_models","monday_archive_item","monday_change_column_value","monday_create_board","monday_create_column","monday_create_group","monday_create_item","monday_create_subitem","monday_create_update","monday_delete_item","monday_duplicate_item","monday_get_board","monday_get_groups","monday_get_item","monday_get_items","monday_list_boards","monday_move_item_to_group","monday_search_items","monday_update_item","mongodb_delete","mongodb_execute","mongodb_insert","mongodb_introspect","mongodb_query","mongodb_update","mssql_delete","mssql_execute","mssql_insert","mssql_introspect","mssql_query","mssql_update","mysql_delete","mysql_execute","mysql_insert","mysql_introspect","mysql_query","mysql_update","neo4j_create","neo4j_delete","neo4j_execute","neo4j_introspect","neo4j_merge","neo4j_query","neo4j_update","netsuite_attach_record","netsuite_batch_create_records","netsuite_batch_delete_records","netsuite_batch_get_records","netsuite_batch_update_records","netsuite_batch_upsert_records","netsuite_create_record","netsuite_delete_record","netsuite_detach_record","netsuite_execute_action","netsuite_execute_dataset","netsuite_execute_suiteql","netsuite_get_async_result","netsuite_get_async_status","netsuite_get_governance_limits","netsuite_get_record","netsuite_get_record_form","netsuite_get_record_metadata","netsuite_get_select_options","netsuite_get_server_time","netsuite_get_subresource","netsuite_list_datasets","netsuite_list_record_types","netsuite_list_records","netsuite_transform_record","netsuite_update_record","netsuite_upsert_record","neverbounce_get_credits","neverbounce_verify_email","new_relic_create_deployment_event","new_relic_get_entity","new_relic_nrql_query","new_relic_search_entities","notion_add_database_row","notion_add_database_row_v2","notion_append_blocks","notion_append_blocks_v2","notion_create_comment","notion_create_comment_v2","notion_create_database","notion_create_database_v2","notion_create_page","notion_create_page_v2","notion_delete_block","notion_delete_block_v2","notion_list_comments","notion_list_comments_v2","notion_list_users","notion_list_users_v2","notion_query_database","notion_query_database_v2","notion_read","notion_read_database","notion_read_database_v2","notion_read_v2","notion_retrieve_block","notion_retrieve_block_children","notion_retrieve_block_children_v2","notion_retrieve_block_v2","notion_retrieve_user","notion_retrieve_user_v2","notion_search","notion_search_v2","notion_update_block","notion_update_block_v2","notion_update_page","notion_update_page_v2","notion_write","notion_write_v2","obsidian_append_active","obsidian_append_note","obsidian_append_periodic_note","obsidian_create_note","obsidian_delete_note","obsidian_execute_command","obsidian_get_active","obsidian_get_note","obsidian_get_periodic_note","obsidian_list_commands","obsidian_list_files","obsidian_open_file","obsidian_patch_active","obsidian_patch_note","obsidian_search","okta_activate_group_rule","okta_activate_user","okta_add_user_to_group","okta_assign_group_to_app","okta_assign_user_role","okta_assign_user_to_app","okta_clear_user_sessions","okta_create_group","okta_create_group_rule","okta_create_user","okta_deactivate_group_rule","okta_deactivate_user","okta_delete_group","okta_delete_group_rule","okta_delete_user","okta_enroll_factor","okta_get_app","okta_get_factor","okta_get_group","okta_get_group_rule","okta_get_logs","okta_get_session","okta_get_user","okta_list_app_groups","okta_list_app_users","okta_list_apps","okta_list_factors","okta_list_group_members","okta_list_group_rules","okta_list_groups","okta_list_user_roles","okta_list_users","okta_remove_group_from_app","okta_remove_user_from_app","okta_remove_user_from_group","okta_remove_user_role","okta_reset_all_factors","okta_reset_factor","okta_reset_password","okta_revoke_session","okta_suspend_user","okta_unsuspend_user","okta_update_group","okta_update_user","onedrive_copy","onedrive_create_folder","onedrive_create_share_link","onedrive_delete","onedrive_download","onedrive_get_drive_info","onedrive_get_item","onedrive_list","onedrive_move","onedrive_search","onedrive_upload","onepassword_create_item","onepassword_delete_item","onepassword_get_item","onepassword_get_item_file","onepassword_get_vault","onepassword_list_items","onepassword_list_vaults","onepassword_replace_item","onepassword_resolve_secret","onepassword_update_item","openai_embeddings","openai_image","oracle_fusion_financials_apply_receivables_receipt","oracle_fusion_financials_approve_receivables_invoice","oracle_fusion_financials_create_expense_line","oracle_fusion_financials_create_expense_report","oracle_fusion_financials_create_receivables_credit_memo","oracle_fusion_financials_create_receivables_invoice","oracle_fusion_financials_create_receivables_receipt","oracle_fusion_financials_get_expense_line","oracle_fusion_financials_get_expense_report","oracle_fusion_financials_get_gl_journal_batch","oracle_fusion_financials_get_gl_ledger","oracle_fusion_financials_get_payables_invoice","oracle_fusion_financials_get_payables_invoice_line","oracle_fusion_financials_get_payables_payment","oracle_fusion_financials_get_receivables_credit_memo","oracle_fusion_financials_get_receivables_invoice","oracle_fusion_financials_get_receivables_invoice_installment","oracle_fusion_financials_get_receivables_invoice_line","oracle_fusion_financials_get_receivables_receipt","oracle_fusion_financials_list_expense_lines","oracle_fusion_financials_list_expense_reports","oracle_fusion_financials_list_gl_balances","oracle_fusion_financials_list_gl_journal_batches","oracle_fusion_financials_list_gl_ledgers","oracle_fusion_financials_list_payables_invoice_lines","oracle_fusion_financials_list_payables_invoices","oracle_fusion_financials_list_payables_payments","oracle_fusion_financials_list_receivables_credit_memos","oracle_fusion_financials_list_receivables_invoice_installments","oracle_fusion_financials_list_receivables_invoice_lines","oracle_fusion_financials_list_receivables_invoices","oracle_fusion_financials_list_receivables_receipts","oracle_fusion_financials_submit_expense_report","oracle_fusion_financials_update_expense_line","oracle_fusion_financials_update_expense_report","oracle_fusion_financials_update_receivables_invoice","oracledb_delete","oracledb_execute","oracledb_insert","oracledb_introspect","oracledb_query","oracledb_update","otter_create_conversation","otter_get_conversation","otter_get_conversation_audio","otter_get_workspace","otter_list_channel_members","otter_list_channels","otter_list_conversations","otter_list_workspace_conversations","outlook_calendar_create_event","outlook_calendar_delete_event","outlook_calendar_get_event","outlook_calendar_list_events","outlook_calendar_respond","outlook_calendar_update_event","outlook_copy","outlook_create_folder","outlook_delete","outlook_draft","outlook_forward","outlook_get_attachment","outlook_list_attachments","outlook_list_folders","outlook_mark_read","outlook_mark_unread","outlook_move","outlook_read","outlook_reply","outlook_reply_all","outlook_search","outlook_send","outlook_update_message","pagerduty_add_note","pagerduty_create_incident","pagerduty_get_incident","pagerduty_get_service","pagerduty_list_escalation_policies","pagerduty_list_incident_alerts","pagerduty_list_incidents","pagerduty_list_oncalls","pagerduty_list_schedules","pagerduty_list_services","pagerduty_list_users","pagerduty_merge_incidents","pagerduty_send_event","pagerduty_snooze_incident","pagerduty_update_incident","parallel_deep_research","parallel_extract","parallel_search","pdl_autocomplete","pdl_bulk_company_enrich","pdl_bulk_person_enrich","pdl_clean_company","pdl_clean_location","pdl_clean_school","pdl_company_enrich","pdl_company_search","pdl_person_enrich","pdl_person_identify","pdl_person_search","perplexity_chat","perplexity_search","persona_approve_inquiry","persona_create_account","persona_create_inquiry","persona_create_report","persona_decline_inquiry","persona_expire_inquiry","persona_generate_inquiry_link","persona_get_account","persona_get_case","persona_get_document","persona_get_inquiry","persona_get_report","persona_get_verification","persona_import_accounts","persona_list_accounts","persona_list_cases","persona_list_inquiries","persona_list_inquiry_templates","persona_list_reports","persona_mark_inquiry_for_review","persona_print_inquiry_pdf","persona_redact_account","persona_redact_inquiry","persona_resume_inquiry","persona_update_account","persona_update_inquiry","pinecone_delete_vectors","pinecone_describe_index","pinecone_describe_index_stats","pinecone_fetch","pinecone_generate_embeddings","pinecone_list_indexes","pinecone_list_vector_ids","pinecone_search_text","pinecone_search_vector","pinecone_update_vector","pinecone_upsert_text","pipedrive_create_activity","pipedrive_create_deal","pipedrive_create_lead","pipedrive_create_project","pipedrive_delete_lead","pipedrive_get_activities","pipedrive_get_all_deals","pipedrive_get_deal","pipedrive_get_files","pipedrive_get_leads","pipedrive_get_mail_messages","pipedrive_get_mail_thread","pipedrive_get_pipeline_deals","pipedrive_get_pipelines","pipedrive_get_projects","pipedrive_update_activity","pipedrive_update_deal","pipedrive_update_lead","pitchbook_company_active_investors","pitchbook_company_bio","pitchbook_company_deal_service_providers","pitchbook_company_deals","pitchbook_company_financials","pitchbook_company_general_service_providers","pitchbook_company_industries","pitchbook_company_investors","pitchbook_company_most_recent_debt_financing","pitchbook_company_most_recent_financials","pitchbook_company_most_recent_financing","pitchbook_company_search","pitchbook_company_similar_companies","pitchbook_company_social_analytics","pitchbook_company_updates","pitchbook_company_vc_exit_predictions","pitchbook_contracts_history","pitchbook_cost_of_calls","pitchbook_credit_history","pitchbook_credit_news","pitchbook_credit_news_bulk","pitchbook_credit_news_most_recent","pitchbook_credit_news_search","pitchbook_deal_bio","pitchbook_deal_cap_table_history","pitchbook_deal_debt_lenders","pitchbook_deal_detailed","pitchbook_deal_investors","pitchbook_deal_multiples","pitchbook_deal_search","pitchbook_deal_service_providers","pitchbook_deal_stock_info","pitchbook_deal_tranche_info","pitchbook_deal_updates","pitchbook_deal_valuation","pitchbook_entity_affiliates","pitchbook_entity_locations","pitchbook_entity_news","pitchbook_entity_people","pitchbook_entity_updates","pitchbook_fund_active_investments","pitchbook_fund_benchmark","pitchbook_fund_bio","pitchbook_fund_cash_flows","pitchbook_fund_commitments","pitchbook_fund_investment_preferences","pitchbook_fund_investments","pitchbook_fund_performance","pitchbook_fund_search","pitchbook_fund_team","pitchbook_fund_updates","pitchbook_investor_active_investments","pitchbook_investor_bio","pitchbook_investor_board_seats","pitchbook_investor_deal_service_providers","pitchbook_investor_funds","pitchbook_investor_general_service_providers","pitchbook_investor_investments","pitchbook_investor_last_closed_fund","pitchbook_investor_preferences","pitchbook_investor_search","pitchbook_investor_updates","pitchbook_limited_partner_actual_allocations","pitchbook_limited_partner_bio","pitchbook_limited_partner_commitment_aggregates","pitchbook_limited_partner_commitment_preferences","pitchbook_limited_partner_commitments_detailed","pitchbook_limited_partner_search","pitchbook_limited_partner_service_providers","pitchbook_limited_partner_target_allocations","pitchbook_limited_partner_updates","pitchbook_lookup_table_structure","pitchbook_lookup_tables","pitchbook_patent_detailed","pitchbook_patent_search","pitchbook_people_search","pitchbook_person_bio","pitchbook_person_contact","pitchbook_person_education_work","pitchbook_sandbox_entities","pitchbook_search","pitchbook_service_provider_bio","pitchbook_service_provider_search","pitchbook_service_provider_updates","pitchbook_serviced_companies","pitchbook_serviced_deals","pitchbook_serviced_funds","pitchbook_serviced_investors","pitchbook_serviced_limited_partners","pitchbook_shared_search","pitchbook_usage_report","plane_archive_project","plane_archive_work_item","plane_confirm_attachment_upload","plane_create_attachment_upload","plane_create_comment","plane_create_cycle","plane_create_label","plane_create_link","plane_create_module","plane_create_project","plane_create_project_page","plane_create_state","plane_create_webhook","plane_create_work_item","plane_delete_attachment","plane_delete_comment","plane_delete_cycle","plane_delete_label","plane_delete_link","plane_delete_module","plane_delete_project","plane_delete_project_page","plane_delete_state","plane_delete_webhook","plane_delete_work_item","plane_get_attachment","plane_get_comment","plane_get_current_user","plane_get_cycle","plane_get_label","plane_get_link","plane_get_module","plane_get_project","plane_get_project_page","plane_get_project_summary","plane_get_state","plane_get_webhook","plane_get_work_item","plane_get_work_item_by_identifier","plane_list_attachments","plane_list_comments","plane_list_cycles","plane_list_labels","plane_list_links","plane_list_modules","plane_list_project_pages","plane_list_projects","plane_list_states","plane_list_webhooks","plane_list_work_items","plane_list_workspace_work_items","plane_manage_cycle_work_items","plane_manage_module_work_items","plane_regenerate_webhook_secret","plane_transfer_cycle_work_items","plane_unarchive_project","plane_unarchive_work_item","plane_update_comment","plane_update_cycle","plane_update_label","plane_update_link","plane_update_module","plane_update_project","plane_update_project_page","plane_update_state","plane_update_webhook","plane_update_work_item","planetscale_close_deploy_request","planetscale_create_backup","planetscale_create_branch","planetscale_create_deploy_request","planetscale_delete_branch","planetscale_get_backup","planetscale_get_branch","planetscale_get_database","planetscale_get_deploy_request","planetscale_list_backups","planetscale_list_branches","planetscale_list_databases","planetscale_list_deploy_requests","planetscale_queue_deploy_request","planetscale_review_deploy_request","polymarket_get_activity","polymarket_get_event","polymarket_get_events","polymarket_get_holders","polymarket_get_last_trade_price","polymarket_get_leaderboard","polymarket_get_market","polymarket_get_markets","polymarket_get_midpoint","polymarket_get_orderbook","polymarket_get_positions","polymarket_get_price","polymarket_get_price_history","polymarket_get_series","polymarket_get_series_by_id","polymarket_get_spread","polymarket_get_tags","polymarket_get_tick_size","polymarket_get_trades","polymarket_search","postgresql_delete","postgresql_execute","postgresql_insert","postgresql_introspect","postgresql_query","postgresql_update","posthog_batch_events","posthog_capture_event","posthog_create_annotation","posthog_create_cohort","posthog_create_dashboard","posthog_create_experiment","posthog_create_feature_flag","posthog_create_insight","posthog_create_survey","posthog_delete_feature_flag","posthog_delete_person","posthog_delete_survey","posthog_evaluate_flags","posthog_get_cohort","posthog_get_dashboard","posthog_get_event_definition","posthog_get_experiment","posthog_get_feature_flag","posthog_get_insight","posthog_get_organization","posthog_get_person","posthog_get_project","posthog_get_property_definition","posthog_get_session_recording","posthog_get_survey","posthog_list_actions","posthog_list_annotations","posthog_list_cohorts","posthog_list_dashboards","posthog_list_event_definitions","posthog_list_experiments","posthog_list_feature_flags","posthog_list_insights","posthog_list_organizations","posthog_list_persons","posthog_list_projects","posthog_list_property_definitions","posthog_list_recording_playlists","posthog_list_session_recordings","posthog_list_surveys","posthog_query","posthog_update_cohort","posthog_update_event_definition","posthog_update_experiment","posthog_update_feature_flag","posthog_update_insight","posthog_update_property_definition","posthog_update_survey","powerbi_execute_query","powerbi_get_dataset","powerbi_get_refresh_history","powerbi_get_report","powerbi_list_datasets","powerbi_list_reports","powerbi_list_workspaces","powerbi_refresh_dataset","profound_bot_logs","profound_bots_report","profound_category_assets","profound_category_personas","profound_category_prompts","profound_category_tags","profound_category_topics","profound_citation_prompts","profound_citations_report","profound_list_assets","profound_list_categories","profound_list_domains","profound_list_models","profound_list_optimizations","profound_list_personas","profound_list_regions","profound_optimization_analysis","profound_prompt_answers","profound_prompt_volume","profound_query_fanouts","profound_raw_logs","profound_referrals_report","profound_sentiment_report","profound_visibility_report","prospeo_account_information","prospeo_bulk_enrich_company","prospeo_bulk_enrich_person","prospeo_enrich_company","prospeo_enrich_person","prospeo_search_company","prospeo_search_person","prospeo_search_suggestions","pulse_parser","pulse_parser_v2","qdrant_fetch_points","qdrant_search_vector","qdrant_upsert_points","quartr_get_audio","quartr_get_company","quartr_get_event","quartr_get_event_summary","quartr_get_report","quartr_get_slide_deck","quartr_get_transcript","quartr_list_audio","quartr_list_companies","quartr_list_document_types","quartr_list_documents","quartr_list_event_types","quartr_list_events","quartr_list_live_events","quartr_list_reports","quartr_list_slide_decks","quartr_list_transcripts","quickbooks_add_attachment","quickbooks_create_bill","quickbooks_create_bill_payment","quickbooks_create_credit_memo","quickbooks_create_customer","quickbooks_create_customer_payment","quickbooks_create_deposit","quickbooks_create_employee","quickbooks_create_estimate","quickbooks_create_invoice","quickbooks_create_item","quickbooks_create_journal_entry","quickbooks_create_purchase","quickbooks_create_purchase_order","quickbooks_create_refund_receipt","quickbooks_create_sales_receipt","quickbooks_create_vendor","quickbooks_create_vendor_credit","quickbooks_download_attachment","quickbooks_download_transaction_pdf","quickbooks_email_transaction","quickbooks_get_company_info","quickbooks_read_accounting_transactions","quickbooks_read_attachments","quickbooks_read_master_data","quickbooks_read_purchasing_transactions","quickbooks_read_sales_transactions","quickbooks_run_financial_report","quickbooks_update_bill","quickbooks_update_bill_payment","quickbooks_update_credit_memo","quickbooks_update_customer","quickbooks_update_customer_payment","quickbooks_update_deposit","quickbooks_update_employee","quickbooks_update_estimate","quickbooks_update_invoice","quickbooks_update_item","quickbooks_update_journal_entry","quickbooks_update_purchase","quickbooks_update_purchase_order","quickbooks_update_refund_receipt","quickbooks_update_sales_receipt","quickbooks_update_vendor","quickbooks_update_vendor_credit","quickbooks_void_bill_payment","quickbooks_void_customer_payment","quickbooks_void_invoice","quickbooks_void_sales_receipt","quiver_image_to_svg","quiver_image_to_svg_v2","quiver_list_models","quiver_text_to_svg","quiver_text_to_svg_v2","rabbitmq_create_binding","rabbitmq_create_exchange","rabbitmq_create_policy","rabbitmq_create_queue","rabbitmq_delete_binding","rabbitmq_delete_exchange","rabbitmq_delete_policy","rabbitmq_delete_queue","rabbitmq_get_exchange","rabbitmq_get_messages","rabbitmq_get_overview","rabbitmq_get_queue","rabbitmq_health_check","rabbitmq_list_bindings","rabbitmq_list_channels","rabbitmq_list_connections","rabbitmq_list_consumers","rabbitmq_list_exchange_bindings","rabbitmq_list_exchanges","rabbitmq_list_nodes","rabbitmq_list_policies","rabbitmq_list_queues","rabbitmq_list_vhosts","rabbitmq_publish_message","rabbitmq_purge_queue","railway_create_environment","railway_create_project","railway_create_service","railway_delete_environment","railway_delete_project","railway_delete_service","railway_delete_variable","railway_deploy_service","railway_get_deployment","railway_get_deployment_logs","railway_get_project","railway_list_deployments","railway_list_project_members","railway_list_projects","railway_list_variables","railway_restart_deployment","railway_rollback_deployment","railway_transfer_project","railway_update_project","railway_upsert_variable","ramp_create_memo","ramp_get_balance","ramp_get_bill","ramp_get_business","ramp_get_memo","ramp_get_physical_card","ramp_get_reimbursement","ramp_get_transaction","ramp_get_user","ramp_get_vendor","ramp_get_virtual_card","ramp_list_bills","ramp_list_physical_cards","ramp_list_reimbursements","ramp_list_transactions","ramp_list_users","ramp_list_vendors","ramp_list_virtual_cards","rb2b_credit_check","rb2b_email_to_activity","rb2b_hem_to_best_linkedin","rb2b_hem_to_business_profile","rb2b_hem_to_linkedin","rb2b_hem_to_maid","rb2b_ip_to_company","rb2b_ip_to_hem","rb2b_ip_to_maid","rb2b_linkedin_slug_search","rb2b_linkedin_to_best_personal_email","rb2b_linkedin_to_business_profile","rb2b_linkedin_to_hashed_emails","rb2b_linkedin_to_mobile_phone","rb2b_linkedin_to_personal_email","rds_delete","rds_execute","rds_insert","rds_introspect","rds_query","rds_update","reddit_delete","reddit_edit","reddit_get_comments","reddit_get_controversial","reddit_get_info","reddit_get_me","reddit_get_messages","reddit_get_posts","reddit_get_saved","reddit_get_subreddit_info","reddit_get_subreddit_rules","reddit_get_user","reddit_get_user_comments","reddit_get_user_posts","reddit_hide","reddit_hot_posts","reddit_list_my_subreddits","reddit_lock","reddit_mark_all_read","reddit_mark_read","reddit_marknsfw","reddit_mod_approve","reddit_mod_distinguish","reddit_mod_remove","reddit_mod_sticky","reddit_reply","reddit_report","reddit_save","reddit_search","reddit_search_subreddits","reddit_send_message","reddit_submit_post","reddit_subscribe","reddit_unhide","reddit_unlock","reddit_unmarknsfw","reddit_unsave","reddit_vote","redis_command","redis_delete","redis_exists","redis_expire","redis_get","redis_hdel","redis_hget","redis_hgetall","redis_hset","redis_incr","redis_incrby","redis_keys","redis_llen","redis_lpop","redis_lpush","redis_lrange","redis_persist","redis_rpop","redis_rpush","redis_set","redis_setnx","redis_ttl","reducto_parser","reducto_parser_v2","resend_cancel_email","resend_create_audience","resend_create_broadcast","resend_create_contact","resend_delete_audience","resend_delete_contact","resend_get_audience","resend_get_broadcast","resend_get_contact","resend_get_email","resend_list_audiences","resend_list_contacts","resend_list_domains","resend_send","resend_send_broadcast","resend_update_contact","revenuecat_create_purchase","revenuecat_defer_google_subscription","revenuecat_delete_customer","revenuecat_get_customer","revenuecat_grant_entitlement","revenuecat_list_offerings","revenuecat_refund_google_subscription","revenuecat_revoke_entitlement","revenuecat_revoke_google_subscription","revenuecat_update_subscriber_attributes","rippling_bulk_create_custom_object_records","rippling_bulk_delete_custom_object_records","rippling_bulk_update_custom_object_records","rippling_create_business_partner","rippling_create_business_partner_group","rippling_create_custom_app","rippling_create_custom_object","rippling_create_custom_object_field","rippling_create_custom_object_record","rippling_create_custom_page","rippling_create_custom_setting","rippling_create_department","rippling_create_draft_hires","rippling_create_object_category","rippling_create_title","rippling_create_work_location","rippling_delete_business_partner","rippling_delete_business_partner_group","rippling_delete_custom_app","rippling_delete_custom_object","rippling_delete_custom_object_field","rippling_delete_custom_object_record","rippling_delete_custom_page","rippling_delete_custom_setting","rippling_delete_object_category","rippling_delete_title","rippling_delete_work_location","rippling_get_business_partner","rippling_get_business_partner_group","rippling_get_current_user","rippling_get_custom_app","rippling_get_custom_object","rippling_get_custom_object_field","rippling_get_custom_object_record","rippling_get_custom_object_record_by_external_id","rippling_get_custom_page","rippling_get_custom_setting","rippling_get_department","rippling_get_employment_type","rippling_get_job_function","rippling_get_object_category","rippling_get_report_run","rippling_get_supergroup","rippling_get_team","rippling_get_title","rippling_get_user","rippling_get_work_location","rippling_get_worker","rippling_list_business_partner_groups","rippling_list_business_partners","rippling_list_companies","rippling_list_custom_apps","rippling_list_custom_fields","rippling_list_custom_object_fields","rippling_list_custom_object_records","rippling_list_custom_objects","rippling_list_custom_pages","rippling_list_custom_settings","rippling_list_departments","rippling_list_employment_types","rippling_list_entitlements","rippling_list_job_functions","rippling_list_object_categories","rippling_list_supergroup_exclusion_members","rippling_list_supergroup_inclusion_members","rippling_list_supergroup_members","rippling_list_supergroups","rippling_list_teams","rippling_list_titles","rippling_list_users","rippling_list_work_locations","rippling_list_workers","rippling_query_custom_object_records","rippling_trigger_report_run","rippling_update_custom_app","rippling_update_custom_object","rippling_update_custom_object_field","rippling_update_custom_object_record","rippling_update_custom_page","rippling_update_custom_setting","rippling_update_department","rippling_update_object_category","rippling_update_supergroup_exclusion_members","rippling_update_supergroup_inclusion_members","rippling_update_title","rippling_update_work_location","rocketlane_add_field_option","rocketlane_add_project_members","rocketlane_add_task_assignees","rocketlane_add_task_dependencies","rocketlane_add_task_followers","rocketlane_archive_project","rocketlane_assign_placeholders","rocketlane_create_field","rocketlane_create_phase","rocketlane_create_project","rocketlane_create_space","rocketlane_create_space_document","rocketlane_create_task","rocketlane_create_time_entry","rocketlane_create_time_off","rocketlane_delete_field","rocketlane_delete_phase","rocketlane_delete_project","rocketlane_delete_space","rocketlane_delete_space_document","rocketlane_delete_task","rocketlane_delete_time_entry","rocketlane_delete_time_off","rocketlane_get_field","rocketlane_get_invoice","rocketlane_get_invoice_line_items","rocketlane_get_invoice_payments","rocketlane_get_phase","rocketlane_get_project","rocketlane_get_space","rocketlane_get_space_document","rocketlane_get_task","rocketlane_get_time_entry","rocketlane_get_time_off","rocketlane_get_user","rocketlane_import_template","rocketlane_list_fields","rocketlane_list_invoices","rocketlane_list_phases","rocketlane_list_placeholders","rocketlane_list_projects","rocketlane_list_resource_allocations","rocketlane_list_space_documents","rocketlane_list_spaces","rocketlane_list_tasks","rocketlane_list_time_entries","rocketlane_list_time_entry_categories","rocketlane_list_time_offs","rocketlane_list_users","rocketlane_move_task_to_phase","rocketlane_remove_project_members","rocketlane_remove_task_assignees","rocketlane_remove_task_dependencies","rocketlane_remove_task_followers","rocketlane_search_time_entries","rocketlane_unassign_placeholders","rocketlane_update_field","rocketlane_update_field_option","rocketlane_update_phase","rocketlane_update_project","rocketlane_update_space","rocketlane_update_space_document","rocketlane_update_task","rocketlane_update_time_entry","rootly_acknowledge_alert","rootly_add_incident_event","rootly_add_subscribers","rootly_assign_incident_role","rootly_create_action_item","rootly_create_alert","rootly_create_incident","rootly_create_status_page_event","rootly_delete_action_item","rootly_delete_incident","rootly_escalate_alert","rootly_get_alert","rootly_get_incident","rootly_list_action_items","rootly_list_alerts","rootly_list_causes","rootly_list_environments","rootly_list_escalation_policies","rootly_list_functionalities","rootly_list_incident_events","rootly_list_incident_roles","rootly_list_incident_types","rootly_list_incidents","rootly_list_on_calls","rootly_list_playbooks","rootly_list_retrospectives","rootly_list_schedules","rootly_list_services","rootly_list_severities","rootly_list_teams","rootly_list_users","rootly_mitigate_incident","rootly_remove_subscribers","rootly_resolve_alert","rootly_resolve_incident","rootly_run_workflow","rootly_snooze_alert","rootly_unassign_incident_role","rootly_update_action_item","rootly_update_alert","rootly_update_incident","s3_copy_object","s3_create_bucket","s3_delete_bucket","s3_delete_object","s3_delete_objects","s3_get_object","s3_head_object","s3_list_buckets","s3_list_objects","s3_presigned_url","s3_put_object","sailpoint_approve_access_request","sailpoint_cancel_access_request","sailpoint_decide_certification_review_items","sailpoint_get_access_profile","sailpoint_get_access_profile_entitlements","sailpoint_get_access_request_config","sailpoint_get_access_request_status","sailpoint_get_account","sailpoint_get_account_activity","sailpoint_get_account_entitlements","sailpoint_get_account_selections","sailpoint_get_campaign","sailpoint_get_certification","sailpoint_get_entitlement","sailpoint_get_entitlement_request_config","sailpoint_get_identity","sailpoint_get_role","sailpoint_get_role_entitlements","sailpoint_get_source","sailpoint_get_task_status","sailpoint_list_access_profiles","sailpoint_list_account_activities","sailpoint_list_accounts","sailpoint_list_campaigns","sailpoint_list_certification_review_items","sailpoint_list_certifications","sailpoint_list_entitlements","sailpoint_list_identities","sailpoint_list_identity_entitlements","sailpoint_list_pending_access_request_approvals","sailpoint_list_roles","sailpoint_list_sources","sailpoint_load_accounts","sailpoint_load_entitlements","sailpoint_reject_access_request","sailpoint_request_access","sailpoint_search","sailpoint_search_aggregate","sailpoint_search_count","sailpoint_sign_off_certification","salesforce_create_account","salesforce_create_case","salesforce_create_contact","salesforce_create_custom_field","salesforce_create_custom_object","salesforce_create_lead","salesforce_create_opportunity","salesforce_create_task","salesforce_delete_account","salesforce_delete_case","salesforce_delete_contact","salesforce_delete_custom_field","salesforce_delete_lead","salesforce_delete_opportunity","salesforce_delete_task","salesforce_describe_object","salesforce_get_accounts","salesforce_get_cases","salesforce_get_contacts","salesforce_get_dashboard","salesforce_get_leads","salesforce_get_opportunities","salesforce_get_report","salesforce_get_tasks","salesforce_list_dashboards","salesforce_list_objects","salesforce_list_report_types","salesforce_list_reports","salesforce_query","salesforce_query_more","salesforce_refresh_dashboard","salesforce_run_report","salesforce_tooling_query","salesforce_update_account","salesforce_update_case","salesforce_update_contact","salesforce_update_custom_field","salesforce_update_lead","salesforce_update_opportunity","salesforce_update_task","sap_concur_approve_expense_report","sap_concur_associate_attendees","sap_concur_create_cash_advance","sap_concur_create_expected_expense","sap_concur_create_expense_report","sap_concur_create_list_item","sap_concur_create_purchase_request","sap_concur_create_quick_expense","sap_concur_create_quick_expense_with_image","sap_concur_create_report_comment","sap_concur_create_travel_request","sap_concur_create_user","sap_concur_delete_expected_expense","sap_concur_delete_expense","sap_concur_delete_expense_report","sap_concur_delete_list_item","sap_concur_delete_travel_request","sap_concur_delete_user","sap_concur_get_allocation","sap_concur_get_budget","sap_concur_get_cash_advance","sap_concur_get_expected_expense","sap_concur_get_expense","sap_concur_get_expense_report","sap_concur_get_itemizations","sap_concur_get_itinerary","sap_concur_get_list","sap_concur_get_list_item","sap_concur_get_purchase_request","sap_concur_get_receipt","sap_concur_get_receipt_status","sap_concur_get_request_cash_advance","sap_concur_get_travel_profile","sap_concur_get_travel_request","sap_concur_get_user","sap_concur_issue_cash_advance","sap_concur_list_allocations","sap_concur_list_attendee_associations","sap_concur_list_budget_categories","sap_concur_list_budgets","sap_concur_list_exceptions","sap_concur_list_expected_expenses","sap_concur_list_expense_reports","sap_concur_list_expenses","sap_concur_list_itineraries","sap_concur_list_list_items","sap_concur_list_lists","sap_concur_list_receipts","sap_concur_list_report_comments","sap_concur_list_reports_to_approve","sap_concur_list_travel_profiles_summary","sap_concur_list_travel_request_comments","sap_concur_list_travel_requests","sap_concur_list_users","sap_concur_move_travel_request","sap_concur_recall_expense_report","sap_concur_remove_all_attendees","sap_concur_search_locations","sap_concur_search_users","sap_concur_send_back_expense_report","sap_concur_submit_expense_report","sap_concur_update_allocation","sap_concur_update_expected_expense","sap_concur_update_expense","sap_concur_update_expense_report","sap_concur_update_list_item","sap_concur_update_travel_request","sap_concur_update_user","sap_concur_upload_exchange_rates","sap_concur_upload_receipt_image","sap_s4hana_create_business_partner","sap_s4hana_create_purchase_order","sap_s4hana_create_purchase_requisition","sap_s4hana_create_sales_order","sap_s4hana_delete_sales_order","sap_s4hana_get_billing_document","sap_s4hana_get_business_partner","sap_s4hana_get_customer","sap_s4hana_get_inbound_delivery","sap_s4hana_get_material_document","sap_s4hana_get_outbound_delivery","sap_s4hana_get_product","sap_s4hana_get_purchase_order","sap_s4hana_get_purchase_requisition","sap_s4hana_get_sales_order","sap_s4hana_get_supplier","sap_s4hana_get_supplier_invoice","sap_s4hana_list_billing_documents","sap_s4hana_list_business_partners","sap_s4hana_list_customers","sap_s4hana_list_inbound_deliveries","sap_s4hana_list_material_documents","sap_s4hana_list_material_stock","sap_s4hana_list_outbound_deliveries","sap_s4hana_list_products","sap_s4hana_list_purchase_orders","sap_s4hana_list_purchase_requisitions","sap_s4hana_list_sales_orders","sap_s4hana_list_supplier_invoices","sap_s4hana_list_suppliers","sap_s4hana_odata_query","sap_s4hana_update_business_partner","sap_s4hana_update_customer","sap_s4hana_update_product","sap_s4hana_update_purchase_order","sap_s4hana_update_purchase_requisition","sap_s4hana_update_sales_order","sap_s4hana_update_supplier","search_tool","secrets_manager_create_secret","secrets_manager_delete_secret","secrets_manager_describe_secret","secrets_manager_get_secret","secrets_manager_list_secrets","secrets_manager_restore_secret","secrets_manager_rotate_secret","secrets_manager_tag_resource","secrets_manager_untag_resource","secrets_manager_update_secret","semrush_backlinks","semrush_backlinks_anchors","semrush_backlinks_competitors","semrush_backlinks_geo_distribution","semrush_backlinks_indexed_pages","semrush_backlinks_overview","semrush_backlinks_tld_distribution","semrush_batch_keyword_overview","semrush_broad_match_keywords","semrush_domain_ad_copies","semrush_domain_ad_history","semrush_domain_organic_competitors","semrush_domain_organic_keywords","semrush_domain_overview","semrush_domain_overview_all","semrush_domain_overview_history","semrush_domain_paid_competitors","semrush_domain_paid_keywords","semrush_domain_pla_copies","semrush_domain_pla_keywords","semrush_domain_vs_domain","semrush_keyword_ad_history","semrush_keyword_difficulty","semrush_keyword_overview","semrush_keyword_overview_all","semrush_keyword_questions","semrush_organic_results","semrush_paid_results","semrush_referring_domains","semrush_referring_ips","semrush_related_keywords","semrush_subdomain_ad_copies","semrush_subdomain_organic_keywords","semrush_subdomain_overview","semrush_subdomain_overview_all","semrush_subdomain_overview_history","semrush_subdomain_paid_keywords","semrush_top_domains","semrush_url_organic_keywords","semrush_url_overview","semrush_url_overview_all","semrush_url_overview_history","semrush_url_paid_keywords","semrush_winners_and_losers","sendblue_evaluate_service","sendblue_get_message","sendblue_send_group_message","sendblue_send_message","sendblue_send_typing_indicator","sendgrid_add_contact","sendgrid_add_contacts_to_list","sendgrid_create_list","sendgrid_create_template","sendgrid_create_template_version","sendgrid_delete_contacts","sendgrid_delete_list","sendgrid_delete_template","sendgrid_get_contact","sendgrid_get_list","sendgrid_get_template","sendgrid_list_all_lists","sendgrid_list_templates","sendgrid_remove_contacts_from_list","sendgrid_search_contacts","sendgrid_send_mail","sentry_events_get","sentry_events_list","sentry_issues_get","sentry_issues_list","sentry_issues_update","sentry_projects_create","sentry_projects_get","sentry_projects_list","sentry_projects_update","sentry_releases_create","sentry_releases_deploy","sentry_releases_list","sentry_teams_list","serper_search","servicenow_add_incident_comment","servicenow_aggregate","servicenow_close_incident","servicenow_create_change_request","servicenow_create_incident","servicenow_create_record","servicenow_delete_record","servicenow_download_attachment","servicenow_download_attachment_v2","servicenow_find_user","servicenow_get_change_next_states","servicenow_get_change_request","servicenow_get_ci","servicenow_get_incident","servicenow_get_knowledge_article","servicenow_get_requested_item","servicenow_list_approvals","servicenow_list_attachments","servicenow_list_catalog_items","servicenow_list_change_requests","servicenow_list_change_tasks","servicenow_list_ci_relationships","servicenow_list_group_members","servicenow_list_incidents","servicenow_list_requested_items","servicenow_order_catalog_item","servicenow_read_record","servicenow_resolve_incident","servicenow_search_cis","servicenow_search_knowledge","servicenow_update_approval","servicenow_update_change_request","servicenow_update_change_state","servicenow_update_incident","servicenow_update_record","servicenow_upload_attachment","ses_create_configuration_set","ses_create_email_identity","ses_create_template","ses_delete_email_identity","ses_delete_suppressed_destination","ses_delete_template","ses_get_account","ses_get_email_identity","ses_get_suppressed_destination","ses_get_template","ses_list_identities","ses_list_suppressed_destinations","ses_list_templates","ses_put_suppressed_destination","ses_send_bulk_email","ses_send_custom_verification_email","ses_send_email","ses_send_templated_email","ses_update_template","sftp_delete","sftp_download","sftp_download_v2","sftp_list","sftp_mkdir","sftp_upload","sharepoint_add_list_items","sharepoint_create_list","sharepoint_create_page","sharepoint_delete_file","sharepoint_delete_list_item","sharepoint_delete_page","sharepoint_download_file","sharepoint_get_drive_item","sharepoint_get_list","sharepoint_get_list_item","sharepoint_list_sites","sharepoint_publish_page","sharepoint_read_page","sharepoint_update_list","sharepoint_update_page","sharepoint_upload_file","shopify_adjust_inventory","shopify_cancel_order","shopify_create_customer","shopify_create_fulfillment","shopify_create_product","shopify_create_product_variants","shopify_delete_customer","shopify_delete_product","shopify_get_collection","shopify_get_customer","shopify_get_fulfillment","shopify_get_fulfillment_order","shopify_get_inventory_level","shopify_get_job","shopify_get_order","shopify_get_product","shopify_list_collections","shopify_list_customers","shopify_list_fulfillment_orders","shopify_list_inventory_items","shopify_list_locations","shopify_list_orders","shopify_list_products","shopify_update_customer","shopify_update_fulfillment_tracking","shopify_update_order","shopify_update_product","shopify_update_product_variants","similarweb_bounce_rate","similarweb_page_views","similarweb_pages_per_visit","similarweb_traffic_visits","similarweb_visit_duration","similarweb_website_overview","sixtyfour_enrich_company","sixtyfour_enrich_lead","sixtyfour_find_email","sixtyfour_find_phone","slack_add_bookmark","slack_add_reaction","slack_archive_conversation","slack_canvas","slack_close_conversation","slack_create_channel_canvas","slack_create_conversation","slack_create_user_group","slack_delete_canvas","slack_delete_file","slack_delete_message","slack_delete_scheduled_message","slack_disable_user_group","slack_download","slack_edit_bookmark","slack_edit_canvas","slack_enable_user_group","slack_ephemeral_message","slack_get_canvas","slack_get_channel_history","slack_get_channel_info","slack_get_dnd_info","slack_get_file_info","slack_get_message","slack_get_permalink","slack_get_reactions","slack_get_team_dnd_info","slack_get_team_info","slack_get_team_profile","slack_get_thread","slack_get_thread_replies","slack_get_user","slack_get_user_presence","slack_get_user_profile","slack_invite_to_conversation","slack_join_conversation","slack_kick_conversation","slack_leave_conversation","slack_list_bookmarks","slack_list_canvases","slack_list_channels","slack_list_emoji","slack_list_files","slack_list_members","slack_list_pins","slack_list_reactions","slack_list_scheduled_messages","slack_list_user_conversations","slack_list_user_group_members","slack_list_user_groups","slack_list_users","slack_lists_access_delete","slack_lists_access_set","slack_lists_create","slack_lists_download_get","slack_lists_download_start","slack_lists_items_create","slack_lists_items_delete","slack_lists_items_delete_multiple","slack_lists_items_info","slack_lists_items_list","slack_lists_items_update","slack_lists_update","slack_lookup_canvas_sections","slack_lookup_user_by_email","slack_mark_conversation_read","slack_message","slack_message_reader","slack_open_conversation","slack_open_view","slack_pin_message","slack_publish_view","slack_push_view","slack_remove_bookmark","slack_remove_reaction","slack_rename_agent_session_v2","slack_rename_conversation","slack_revoke_canvas_access","slack_schedule_message","slack_set_agent_session_status_v2","slack_set_conversation_purpose","slack_set_conversation_topic","slack_set_status","slack_set_suggested_prompts","slack_set_suggested_prompts_v2","slack_set_title","slack_set_user_presence","slack_share_canvas","slack_unarchive_conversation","slack_unfurl_links","slack_unpin_message","slack_update_message","slack_update_user_group","slack_update_user_group_members","slack_update_view","smartlead_add_email_accounts_to_campaign","smartlead_add_leads_to_campaign","smartlead_create_campaign","smartlead_create_lead_list","smartlead_delete_campaign","smartlead_delete_campaign_webhook","smartlead_delete_lead_from_campaign","smartlead_delete_lead_list","smartlead_duplicate_campaign","smartlead_export_campaign_leads","smartlead_get_campaign","smartlead_get_campaign_analytics","smartlead_get_campaign_analytics_by_date","smartlead_get_campaign_lead_statistics","smartlead_get_campaign_mailbox_statistics","smartlead_get_campaign_sequences","smartlead_get_campaign_statistics","smartlead_get_campaign_top_level_analytics_by_date","smartlead_get_campaign_webhook_summary","smartlead_get_lead_by_email","smartlead_get_lead_by_id","smartlead_get_lead_list","smartlead_get_lead_message_history","smartlead_list_campaign_email_accounts","smartlead_list_campaign_leads","smartlead_list_campaign_webhooks","smartlead_list_campaigns","smartlead_list_clients","smartlead_list_email_accounts","smartlead_list_inbox_replies","smartlead_list_lead_activities","smartlead_list_lead_categories","smartlead_list_lead_lists","smartlead_mark_lead_complete","smartlead_pause_lead","smartlead_remove_email_accounts_from_campaign","smartlead_resume_lead","smartlead_save_campaign_sequences","smartlead_unsubscribe_lead_from_campaign","smartlead_unsubscribe_lead_globally","smartlead_update_campaign_schedule","smartlead_update_campaign_settings","smartlead_update_campaign_status","smartlead_update_lead","smartlead_update_lead_category","smartlead_update_lead_list","smartlead_upsert_campaign_webhook","sms_send","smtp_send_mail","snowflake_alter_warehouse","snowflake_call_procedure","snowflake_cancel_statement","snowflake_cancel_task_run","snowflake_cortex_analyst_ask","snowflake_cortex_analyst_feedback","snowflake_delete_rows","snowflake_execute_sql","snowflake_get_statement","snowflake_get_task","snowflake_get_task_run","snowflake_get_task_run_output","snowflake_get_warehouse","snowflake_insert_rows","snowflake_introspect_schema","snowflake_list_copy_history","snowflake_list_databases","snowflake_list_query_history","snowflake_list_schemas","snowflake_list_tables","snowflake_list_task_runs","snowflake_list_tasks","snowflake_list_warehouses","snowflake_load_data","snowflake_resume_task","snowflake_resume_warehouse","snowflake_run_task","snowflake_suspend_task","snowflake_suspend_warehouse","snowflake_unload_data","snowflake_update_rows","snowflake_upsert_rows","splunk_cancel_search_job","splunk_create_search_job","splunk_dispatch_saved_search","splunk_get_fired_alerts","splunk_get_saved_search","splunk_get_search_job","splunk_get_search_results","splunk_list_apps","splunk_list_fired_alerts","splunk_list_indexes","splunk_list_saved_searches","splunk_run_search","sportmonks_core_get_cities","sportmonks_core_get_city","sportmonks_core_get_continent","sportmonks_core_get_continents","sportmonks_core_get_countries","sportmonks_core_get_country","sportmonks_core_get_entity_filters","sportmonks_core_get_my_usage","sportmonks_core_get_region","sportmonks_core_get_regions","sportmonks_core_get_timezones","sportmonks_core_get_type","sportmonks_core_get_type_by_entity","sportmonks_core_get_types","sportmonks_core_search_cities","sportmonks_core_search_countries","sportmonks_core_search_regions","sportmonks_football_expected_by_player","sportmonks_football_expected_by_team","sportmonks_football_get_all_commentaries","sportmonks_football_get_all_fixtures","sportmonks_football_get_all_players","sportmonks_football_get_all_rivals","sportmonks_football_get_all_teams","sportmonks_football_get_all_transfer_rumours","sportmonks_football_get_all_transfers","sportmonks_football_get_brackets_by_season","sportmonks_football_get_coach","sportmonks_football_get_coaches","sportmonks_football_get_coaches_by_country","sportmonks_football_get_commentaries_by_fixture","sportmonks_football_get_current_leagues_by_team","sportmonks_football_get_expected_lineups_by_player","sportmonks_football_get_expected_lineups_by_team","sportmonks_football_get_extended_team_squad","sportmonks_football_get_fixture","sportmonks_football_get_fixtures_by_date","sportmonks_football_get_fixtures_by_date_range","sportmonks_football_get_fixtures_by_date_range_for_team","sportmonks_football_get_fixtures_by_ids","sportmonks_football_get_grouped_standings_by_round","sportmonks_football_get_head_to_head","sportmonks_football_get_inplay_livescores","sportmonks_football_get_latest_coaches","sportmonks_football_get_latest_fixtures","sportmonks_football_get_latest_livescores","sportmonks_football_get_latest_players","sportmonks_football_get_latest_totw","sportmonks_football_get_latest_transfers","sportmonks_football_get_league","sportmonks_football_get_leagues","sportmonks_football_get_leagues_by_country","sportmonks_football_get_leagues_by_date","sportmonks_football_get_leagues_by_team","sportmonks_football_get_live_leagues","sportmonks_football_get_live_probabilities","sportmonks_football_get_live_probabilities_by_fixture","sportmonks_football_get_live_standings_by_league","sportmonks_football_get_livescores","sportmonks_football_get_match_facts","sportmonks_football_get_match_facts_by_date_range","sportmonks_football_get_match_facts_by_fixture","sportmonks_football_get_match_facts_by_league","sportmonks_football_get_past_fixtures_by_tv_station","sportmonks_football_get_player","sportmonks_football_get_players_by_country","sportmonks_football_get_postmatch_news","sportmonks_football_get_postmatch_news_by_season","sportmonks_football_get_predictability_by_league","sportmonks_football_get_prematch_news","sportmonks_football_get_prematch_news_by_season","sportmonks_football_get_prematch_news_upcoming","sportmonks_football_get_probabilities","sportmonks_football_get_probabilities_by_fixture","sportmonks_football_get_referee","sportmonks_football_get_referees","sportmonks_football_get_referees_by_country","sportmonks_football_get_referees_by_season","sportmonks_football_get_rivals_by_team","sportmonks_football_get_round","sportmonks_football_get_round_statistics","sportmonks_football_get_rounds","sportmonks_football_get_rounds_by_season","sportmonks_football_get_schedules_by_season","sportmonks_football_get_schedules_by_season_and_team","sportmonks_football_get_schedules_by_team","sportmonks_football_get_season","sportmonks_football_get_seasons","sportmonks_football_get_seasons_by_team","sportmonks_football_get_stage","sportmonks_football_get_stage_statistics","sportmonks_football_get_stages","sportmonks_football_get_stages_by_season","sportmonks_football_get_standing_corrections_by_season","sportmonks_football_get_standings","sportmonks_football_get_standings_by_round","sportmonks_football_get_standings_by_season","sportmonks_football_get_state","sportmonks_football_get_states","sportmonks_football_get_team","sportmonks_football_get_team_rankings","sportmonks_football_get_team_rankings_by_date","sportmonks_football_get_team_rankings_by_team","sportmonks_football_get_team_squad","sportmonks_football_get_team_squad_by_season","sportmonks_football_get_teams_by_country","sportmonks_football_get_teams_by_season","sportmonks_football_get_topscorers_by_season","sportmonks_football_get_topscorers_by_stage","sportmonks_football_get_totw","sportmonks_football_get_totw_by_round","sportmonks_football_get_transfer","sportmonks_football_get_transfer_rumour","sportmonks_football_get_transfer_rumours_between_dates","sportmonks_football_get_transfer_rumours_by_player","sportmonks_football_get_transfer_rumours_by_team","sportmonks_football_get_transfers_between_dates","sportmonks_football_get_transfers_by_player","sportmonks_football_get_transfers_by_team","sportmonks_football_get_tv_station","sportmonks_football_get_tv_stations","sportmonks_football_get_tv_stations_by_fixture","sportmonks_football_get_upcoming_fixtures_by_market","sportmonks_football_get_upcoming_fixtures_by_tv_station","sportmonks_football_get_value_bets","sportmonks_football_get_value_bets_by_fixture","sportmonks_football_get_venue","sportmonks_football_get_venues","sportmonks_football_get_venues_by_season","sportmonks_football_search_coaches","sportmonks_football_search_fixtures","sportmonks_football_search_leagues","sportmonks_football_search_players","sportmonks_football_search_referees","sportmonks_football_search_rounds","sportmonks_football_search_seasons","sportmonks_football_search_stages","sportmonks_football_search_teams","sportmonks_football_search_venues","sportmonks_motorsport_get_all_fixtures","sportmonks_motorsport_get_current_leagues_by_team","sportmonks_motorsport_get_driver","sportmonks_motorsport_get_driver_standings","sportmonks_motorsport_get_driver_standings_by_season","sportmonks_motorsport_get_drivers","sportmonks_motorsport_get_drivers_by_country","sportmonks_motorsport_get_drivers_by_season","sportmonks_motorsport_get_fixture","sportmonks_motorsport_get_fixtures_by_date","sportmonks_motorsport_get_fixtures_by_date_range","sportmonks_motorsport_get_fixtures_by_ids","sportmonks_motorsport_get_laps_by_fixture","sportmonks_motorsport_get_laps_by_fixture_and_driver","sportmonks_motorsport_get_laps_by_fixture_and_lap","sportmonks_motorsport_get_latest_laps_by_fixture","sportmonks_motorsport_get_latest_pitstops_by_fixture","sportmonks_motorsport_get_latest_stints_by_fixture","sportmonks_motorsport_get_latest_updated_drivers","sportmonks_motorsport_get_latest_updated_fixtures","sportmonks_motorsport_get_league","sportmonks_motorsport_get_leagues","sportmonks_motorsport_get_leagues_by_country","sportmonks_motorsport_get_leagues_by_date","sportmonks_motorsport_get_leagues_by_live","sportmonks_motorsport_get_leagues_by_team","sportmonks_motorsport_get_livescores","sportmonks_motorsport_get_pitstops_by_fixture","sportmonks_motorsport_get_pitstops_by_fixture_and_driver","sportmonks_motorsport_get_pitstops_by_fixture_and_lap","sportmonks_motorsport_get_race_results_by_season_and_driver","sportmonks_motorsport_get_race_results_by_season_and_team","sportmonks_motorsport_get_schedules_by_season","sportmonks_motorsport_get_season","sportmonks_motorsport_get_seasons","sportmonks_motorsport_get_stage","sportmonks_motorsport_get_stages","sportmonks_motorsport_get_stages_by_season","sportmonks_motorsport_get_state","sportmonks_motorsport_get_states","sportmonks_motorsport_get_stints_by_fixture","sportmonks_motorsport_get_stints_by_fixture_and_driver","sportmonks_motorsport_get_stints_by_fixture_and_stint","sportmonks_motorsport_get_team","sportmonks_motorsport_get_team_standings","sportmonks_motorsport_get_team_standings_by_season","sportmonks_motorsport_get_teams","sportmonks_motorsport_get_teams_by_country","sportmonks_motorsport_get_teams_by_season","sportmonks_motorsport_get_venue","sportmonks_motorsport_get_venues","sportmonks_motorsport_get_venues_by_season","sportmonks_motorsport_search_drivers","sportmonks_motorsport_search_leagues","sportmonks_motorsport_search_stages","sportmonks_motorsport_search_teams","sportmonks_motorsport_search_venues","sportmonks_odds_get_all_historical_odds","sportmonks_odds_get_all_inplay_odds","sportmonks_odds_get_all_pre_match_odds","sportmonks_odds_get_all_premium_odds","sportmonks_odds_get_bookmaker","sportmonks_odds_get_bookmaker_event_ids_by_fixture","sportmonks_odds_get_bookmakers","sportmonks_odds_get_bookmakers_by_fixture","sportmonks_odds_get_inplay_odds_by_fixture","sportmonks_odds_get_inplay_odds_by_fixture_and_bookmaker","sportmonks_odds_get_inplay_odds_by_fixture_and_market","sportmonks_odds_get_last_updated_inplay_odds","sportmonks_odds_get_last_updated_pre_match_odds","sportmonks_odds_get_market","sportmonks_odds_get_markets","sportmonks_odds_get_pre_match_odds_by_fixture","sportmonks_odds_get_pre_match_odds_by_fixture_and_bookmaker","sportmonks_odds_get_pre_match_odds_by_fixture_and_market","sportmonks_odds_get_premium_odds_by_fixture","sportmonks_odds_get_premium_odds_by_fixture_and_bookmaker","sportmonks_odds_get_premium_odds_by_fixture_and_market","sportmonks_odds_get_updated_historical_odds_between","sportmonks_odds_get_updated_premium_odds_between","sportmonks_odds_search_bookmakers","sportmonks_odds_search_markets","spotify_add_playlist_cover","spotify_add_to_queue","spotify_add_tracks_to_playlist","spotify_check_following","spotify_check_playlist_followers","spotify_check_saved_albums","spotify_check_saved_audiobooks","spotify_check_saved_episodes","spotify_check_saved_shows","spotify_check_saved_tracks","spotify_create_playlist","spotify_follow_artists","spotify_follow_playlist","spotify_get_album","spotify_get_album_tracks","spotify_get_albums","spotify_get_artist","spotify_get_artist_albums","spotify_get_artist_top_tracks","spotify_get_artists","spotify_get_audiobook","spotify_get_audiobook_chapters","spotify_get_audiobooks","spotify_get_categories","spotify_get_current_user","spotify_get_currently_playing","spotify_get_devices","spotify_get_episode","spotify_get_episodes","spotify_get_followed_artists","spotify_get_markets","spotify_get_new_releases","spotify_get_playback_state","spotify_get_playlist","spotify_get_playlist_cover","spotify_get_playlist_tracks","spotify_get_queue","spotify_get_recently_played","spotify_get_saved_albums","spotify_get_saved_audiobooks","spotify_get_saved_episodes","spotify_get_saved_shows","spotify_get_saved_tracks","spotify_get_show","spotify_get_show_episodes","spotify_get_shows","spotify_get_top_artists","spotify_get_top_tracks","spotify_get_track","spotify_get_tracks","spotify_get_user_playlists","spotify_get_user_profile","spotify_pause","spotify_play","spotify_remove_saved_albums","spotify_remove_saved_audiobooks","spotify_remove_saved_episodes","spotify_remove_saved_shows","spotify_remove_saved_tracks","spotify_remove_tracks_from_playlist","spotify_reorder_playlist_items","spotify_replace_playlist_items","spotify_save_albums","spotify_save_audiobooks","spotify_save_episodes","spotify_save_shows","spotify_save_tracks","spotify_search","spotify_seek","spotify_set_repeat","spotify_set_shuffle","spotify_set_volume","spotify_skip_next","spotify_skip_previous","spotify_transfer_playback","spotify_unfollow_artists","spotify_unfollow_playlist","spotify_update_playlist","sqs_cancel_message_move_task","sqs_change_message_visibility","sqs_change_message_visibility_batch","sqs_create_queue","sqs_delete_message","sqs_delete_message_batch","sqs_delete_queue","sqs_get_queue_attributes","sqs_get_queue_url","sqs_list_dead_letter_source_queues","sqs_list_message_move_tasks","sqs_list_queue_tags","sqs_list_queues","sqs_purge_queue","sqs_receive_message","sqs_send","sqs_send_message_batch","sqs_set_queue_attributes","sqs_start_message_move_task","sqs_tag_queue","sqs_untag_queue","square_batch_retrieve_inventory_counts","square_cancel_invoice","square_cancel_payment","square_complete_payment","square_create_catalog_image","square_create_customer","square_create_invoice","square_create_order","square_create_payment","square_delete_catalog_object","square_delete_customer","square_delete_invoice","square_get_catalog_object","square_get_customer","square_get_invoice","square_get_location","square_get_order","square_get_payment","square_get_refund","square_list_catalog","square_list_customers","square_list_invoices","square_list_locations","square_list_payments","square_list_refunds","square_pay_order","square_publish_invoice","square_refund_payment","square_search_catalog_objects","square_search_customers","square_search_invoices","square_search_orders","square_update_customer","square_upsert_catalog_object","ssh_check_command_exists","ssh_check_file_exists","ssh_create_directory","ssh_delete_file","ssh_download_file","ssh_download_file_v2","ssh_execute_command","ssh_execute_script","ssh_get_system_info","ssh_list_directory","ssh_move_rename","ssh_read_file_content","ssh_upload_file","ssh_write_file_content","ssm_cancel_command","ssm_delete_parameter","ssm_describe_automation_executions","ssm_describe_instance_information","ssm_describe_instance_patch_states","ssm_describe_instance_patches","ssm_describe_parameters","ssm_get_automation_execution","ssm_get_command_invocation","ssm_get_document","ssm_get_parameter","ssm_get_parameters","ssm_get_parameters_by_path","ssm_list_command_invocations","ssm_list_commands","ssm_list_compliance_items","ssm_list_compliance_summaries","ssm_list_documents","ssm_put_parameter","ssm_send_command","ssm_start_automation_execution","ssm_stop_automation_execution","stagehand_agent","stagehand_extract","stripe_cancel_payment_intent","stripe_cancel_subscription","stripe_capture_charge","stripe_capture_payment_intent","stripe_confirm_payment_intent","stripe_create_charge","stripe_create_customer","stripe_create_invoice","stripe_create_payment_intent","stripe_create_price","stripe_create_product","stripe_create_subscription","stripe_delete_customer","stripe_delete_invoice","stripe_delete_product","stripe_finalize_invoice","stripe_list_charges","stripe_list_customers","stripe_list_events","stripe_list_invoices","stripe_list_payment_intents","stripe_list_prices","stripe_list_products","stripe_list_subscriptions","stripe_pay_invoice","stripe_resume_subscription","stripe_retrieve_charge","stripe_retrieve_customer","stripe_retrieve_event","stripe_retrieve_invoice","stripe_retrieve_payment_intent","stripe_retrieve_price","stripe_retrieve_product","stripe_retrieve_subscription","stripe_search_charges","stripe_search_customers","stripe_search_invoices","stripe_search_payment_intents","stripe_search_prices","stripe_search_products","stripe_search_subscriptions","stripe_send_invoice","stripe_update_charge","stripe_update_customer","stripe_update_invoice","stripe_update_payment_intent","stripe_update_price","stripe_update_product","stripe_update_subscription","stripe_void_invoice","sts_assume_role","sts_assume_role_with_saml","sts_assume_role_with_web_identity","sts_get_access_key_info","sts_get_caller_identity","sts_get_session_token","stt_assemblyai","stt_assemblyai_v2","stt_deepgram","stt_deepgram_v2","stt_elevenlabs","stt_elevenlabs_v2","stt_gemini","stt_gemini_v2","stt_whisper","stt_whisper_v2","supabase_count","supabase_delete","supabase_get_row","supabase_insert","supabase_introspect","supabase_invoke_function","supabase_query","supabase_rpc","supabase_storage_copy","supabase_storage_create_bucket","supabase_storage_create_signed_upload_url","supabase_storage_create_signed_url","supabase_storage_delete","supabase_storage_delete_bucket","supabase_storage_download","supabase_storage_empty_bucket","supabase_storage_get_public_url","supabase_storage_list","supabase_storage_list_buckets","supabase_storage_move","supabase_storage_update_bucket","supabase_storage_upload","supabase_text_search","supabase_update","supabase_upsert","supabase_vector_search","table_batch_insert_rows","table_create","table_delete_row","table_delete_rows_by_filter","table_get_row","table_get_schema","table_insert_row","table_list","table_query_rows","table_query_rows_v2","table_update_row","table_update_rows_by_filter","table_upsert_row","tailscale_authorize_device","tailscale_create_auth_key","tailscale_delete_auth_key","tailscale_delete_device","tailscale_delete_user","tailscale_expire_device_key","tailscale_get_acl","tailscale_get_auth_key","tailscale_get_device","tailscale_get_device_routes","tailscale_get_dns_preferences","tailscale_get_dns_searchpaths","tailscale_list_auth_keys","tailscale_list_devices","tailscale_list_dns_nameservers","tailscale_list_users","tailscale_set_acl","tailscale_set_device_routes","tailscale_set_device_tags","tailscale_set_dns_nameservers","tailscale_set_dns_preferences","tailscale_set_dns_searchpaths","tailscale_suspend_user","tailscale_update_device_key","tavily_crawl","tavily_extract","tavily_map","tavily_search","telegram_copy_message","telegram_delete_message","telegram_edit_message_text","telegram_forward_message","telegram_get_chat","telegram_get_chat_member","telegram_message","telegram_pin_message","telegram_send_animation","telegram_send_audio","telegram_send_chat_action","telegram_send_contact","telegram_send_document","telegram_send_location","telegram_send_photo","telegram_send_poll","telegram_send_video","telegram_set_message_reaction","telegram_unpin_message","temporal_cancel_workflow","temporal_count_workflows","temporal_create_schedule","temporal_delete_schedule","temporal_describe_schedule","temporal_describe_task_queue","temporal_describe_workflow","temporal_get_workflow_history","temporal_list_schedules","temporal_list_workflows","temporal_pause_schedule","temporal_query_workflow","temporal_reset_workflow","temporal_signal_with_start","temporal_signal_workflow","temporal_start_workflow","temporal_terminate_workflow","temporal_trigger_schedule","temporal_unpause_schedule","temporal_update_workflow","textract_analyze_expense","textract_analyze_id","textract_parser","textract_parser_v2","thinking_tool","thrive_add_audience_managers","thrive_add_audience_members","thrive_add_user_tags","thrive_create_assignment","thrive_create_audience","thrive_create_completion","thrive_create_user","thrive_delete_assignment","thrive_delete_audience","thrive_delete_user","thrive_get_activity","thrive_get_assignment","thrive_get_audience","thrive_get_completion","thrive_get_content","thrive_get_cpd_category","thrive_get_cpd_entry","thrive_get_cpd_requirement","thrive_get_enrolment","thrive_get_skill_levels","thrive_get_tag","thrive_get_user_by_id","thrive_get_user_by_ref","thrive_list_assignments","thrive_list_audience_managers","thrive_list_audience_members","thrive_list_audiences","thrive_list_completions","thrive_list_enrolments","thrive_list_tags","thrive_query_activities","thrive_query_content","thrive_query_cpd_categories","thrive_query_cpd_entries","thrive_query_cpd_requirements","thrive_query_cpd_user_summaries","thrive_remove_audience_manager","thrive_remove_audience_member","thrive_remove_user_tags","thrive_replace_audience_managers","thrive_replace_audience_members","thrive_search_users","thrive_suspend_user","thrive_update_assignment","thrive_update_audience","thrive_update_user","thrive_update_user_skills","tiktok_get_post_status","tiktok_get_user","tiktok_list_videos","tiktok_query_videos","tiktok_upload_video_draft","tinybird_append_datasource","tinybird_delete_datasource_rows","tinybird_events","tinybird_get_job","tinybird_query","tinybird_query_pipe","tinybird_truncate_datasource","tinyfish_cancel_run","tinyfish_fetch","tinyfish_get_run","tinyfish_list_profiles","tinyfish_list_runs","tinyfish_list_vault_items","tinyfish_run","tinyfish_run_async","tinyfish_search","trello_add_checklist","trello_add_checklist_item","trello_add_comment","trello_add_label","trello_add_member","trello_create_board","trello_create_card","trello_create_list","trello_delete_card","trello_get_actions","trello_get_board","trello_get_card","trello_list_cards","trello_list_lists","trello_list_members","trello_remove_label","trello_remove_member","trello_search","trello_update_card","trello_update_checklist_item","trello_update_list","trigger_dev_activate_schedule","trigger_dev_add_run_tags","trigger_dev_batch_trigger_task","trigger_dev_cancel_run","trigger_dev_complete_waitpoint_token","trigger_dev_create_env_var","trigger_dev_create_schedule","trigger_dev_create_waitpoint_token","trigger_dev_deactivate_schedule","trigger_dev_delete_env_var","trigger_dev_delete_schedule","trigger_dev_execute_query","trigger_dev_get_batch","trigger_dev_get_batch_results","trigger_dev_get_deployment","trigger_dev_get_env_var","trigger_dev_get_latest_deployment","trigger_dev_get_query_schema","trigger_dev_get_queue","trigger_dev_get_run","trigger_dev_get_run_events","trigger_dev_get_run_result","trigger_dev_get_run_trace","trigger_dev_get_schedule","trigger_dev_get_waitpoint_token","trigger_dev_import_env_vars","trigger_dev_list_deployments","trigger_dev_list_env_vars","trigger_dev_list_queues","trigger_dev_list_runs","trigger_dev_list_schedules","trigger_dev_list_timezones","trigger_dev_list_waitpoint_tokens","trigger_dev_override_queue_concurrency","trigger_dev_pause_queue","trigger_dev_promote_deployment","trigger_dev_replay_run","trigger_dev_reschedule_run","trigger_dev_reset_queue_concurrency","trigger_dev_resume_queue","trigger_dev_trigger_task","trigger_dev_update_env_var","trigger_dev_update_run_metadata","trigger_dev_update_schedule","tts_azure","tts_cartesia","tts_deepgram","tts_elevenlabs","tts_google","tts_openai","tts_playht","twilio_send_sms","twilio_voice_get_recording","twilio_voice_list_calls","twilio_voice_make_call","typeform_create_form","typeform_delete_form","typeform_files","typeform_get_form","typeform_insights","typeform_list_forms","typeform_responses","typeform_update_form","upstash_redis_command","upstash_redis_delete","upstash_redis_exists","upstash_redis_expire","upstash_redis_get","upstash_redis_hget","upstash_redis_hgetall","upstash_redis_hset","upstash_redis_incr","upstash_redis_incrby","upstash_redis_keys","upstash_redis_lpush","upstash_redis_lrange","upstash_redis_set","upstash_redis_setnx","upstash_redis_ttl","uptimerobot_create_alert_contact","uptimerobot_create_maintenance_window","uptimerobot_create_monitor","uptimerobot_create_psp","uptimerobot_delete_alert_contact","uptimerobot_delete_maintenance_window","uptimerobot_delete_monitor","uptimerobot_delete_psp","uptimerobot_get_account","uptimerobot_get_alert_contact","uptimerobot_get_incident","uptimerobot_get_maintenance_window","uptimerobot_get_monitor","uptimerobot_get_psp","uptimerobot_list_alert_contacts","uptimerobot_list_incidents","uptimerobot_list_maintenance_windows","uptimerobot_list_monitors","uptimerobot_list_psps","uptimerobot_pause_monitor","uptimerobot_start_monitor","uptimerobot_update_maintenance_window","uptimerobot_update_monitor","uptimerobot_update_psp","vanta_download_document_file","vanta_get_control","vanta_get_document","vanta_get_framework","vanta_get_person","vanta_get_policy","vanta_get_risk_scenario","vanta_get_test","vanta_get_vendor","vanta_get_vulnerable_asset","vanta_list_control_documents","vanta_list_control_tests","vanta_list_controls","vanta_list_document_uploads","vanta_list_documents","vanta_list_framework_controls","vanta_list_frameworks","vanta_list_monitored_computers","vanta_list_people","vanta_list_policies","vanta_list_risk_scenarios","vanta_list_test_entities","vanta_list_tests","vanta_list_vendors","vanta_list_vulnerabilities","vanta_list_vulnerability_remediations","vanta_list_vulnerable_assets","vanta_submit_document","vanta_upload_document_file","vercel_add_domain","vercel_add_project_domain","vercel_cancel_deployment","vercel_create_alias","vercel_create_check","vercel_create_deployment","vercel_create_dns_record","vercel_create_edge_config","vercel_create_env_var","vercel_create_project","vercel_create_webhook","vercel_delete_alias","vercel_delete_deployment","vercel_delete_dns_record","vercel_delete_domain","vercel_delete_edge_config","vercel_delete_env_var","vercel_delete_project","vercel_delete_webhook","vercel_get_alias","vercel_get_check","vercel_get_deployment","vercel_get_deployment_events","vercel_get_domain","vercel_get_domain_config","vercel_get_edge_config","vercel_get_edge_config_items","vercel_get_env_vars","vercel_get_project","vercel_get_team","vercel_get_user","vercel_get_webhook","vercel_list_aliases","vercel_list_checks","vercel_list_deployment_files","vercel_list_deployments","vercel_list_dns_records","vercel_list_domains","vercel_list_edge_configs","vercel_list_project_domains","vercel_list_projects","vercel_list_team_members","vercel_list_teams","vercel_list_webhooks","vercel_pause_project","vercel_promote_deployment","vercel_remove_project_domain","vercel_rerequest_check","vercel_unpause_project","vercel_update_check","vercel_update_dns_record","vercel_update_edge_config_items","vercel_update_env_var","vercel_update_project","vercel_update_project_domain","vercel_verify_project_domain","video_falai","video_luma","video_minimax","video_runway","video_veo","vision_tool","vision_tool_v2","wealthbox_read_contact","wealthbox_read_note","wealthbox_read_task","wealthbox_write_contact","wealthbox_write_note","wealthbox_write_task","webflow_create_item","webflow_delete_item","webflow_get_item","webflow_list_items","webflow_update_item","webhook_request","whatsapp_get_media","whatsapp_mark_read","whatsapp_send_interactive","whatsapp_send_media","whatsapp_send_message","whatsapp_send_reaction","whatsapp_send_template","whatsapp_upload_media","wikipedia_content","wikipedia_random","wikipedia_search","wikipedia_summary","windchill_check_in_document","windchill_check_in_documents","windchill_check_out_document","windchill_check_out_documents","windchill_create_document","windchill_create_documents","windchill_delete_document","windchill_delete_documents","windchill_download_attachment","windchill_download_primary_content","windchill_get_document","windchill_get_document_structure","windchill_get_primary_content","windchill_get_valid_state_transitions","windchill_list_attachments","windchill_list_documents","windchill_revise_document","windchill_revise_documents","windchill_set_lifecycle_state","windchill_undo_check_out_document","windchill_undo_check_out_documents","windchill_update_common_properties","windchill_update_document","windchill_update_document_security_labels","windchill_update_documents","windchill_upload_attachments","windchill_upload_primary_content","wiza_company_enrichment","wiza_get_credits","wiza_individual_reveal","wiza_prospect_search","wordpress_create_category","wordpress_create_comment","wordpress_create_page","wordpress_create_post","wordpress_create_tag","wordpress_delete_category","wordpress_delete_comment","wordpress_delete_media","wordpress_delete_page","wordpress_delete_post","wordpress_delete_tag","wordpress_get_category","wordpress_get_current_user","wordpress_get_media","wordpress_get_page","wordpress_get_post","wordpress_get_tag","wordpress_get_user","wordpress_list_categories","wordpress_list_comments","wordpress_list_media","wordpress_list_pages","wordpress_list_posts","wordpress_list_tags","wordpress_list_users","wordpress_search_content","wordpress_update_category","wordpress_update_comment","wordpress_update_page","wordpress_update_post","wordpress_update_tag","wordpress_upload_media","workday_assign_onboarding","workday_change_job","workday_create_prehire","workday_get_compensation","workday_get_organizations","workday_get_worker","workday_hire_employee","workday_list_workers","workday_terminate_worker","workday_update_worker","workflow_executor","x_create_bookmark","x_create_tweet","x_delete_bookmark","x_delete_tweet","x_get_blocking","x_get_bookmarks","x_get_followers","x_get_following","x_get_liked_tweets","x_get_liking_users","x_get_me","x_get_personalized_trends","x_get_quote_tweets","x_get_retweeted_by","x_get_trends_by_woeid","x_get_tweets_by_ids","x_get_usage","x_get_user_mentions","x_get_user_timeline","x_get_user_tweets","x_hide_reply","x_manage_block","x_manage_follow","x_manage_like","x_manage_mute","x_manage_retweet","x_read","x_search","x_search_tweets","x_search_users","x_user","x_write","youcom_answer","youcom_finance_research","youcom_get_account_balance","youcom_get_contents","youcom_get_research_task","youcom_research","youcom_search","youcom_search_images","youtube_channel_info","youtube_channel_playlists","youtube_channel_videos","youtube_comments","youtube_playlist_items","youtube_search","youtube_trending","youtube_video_categories","youtube_video_details","zendesk_autocomplete_organizations","zendesk_create_organization","zendesk_create_organizations_bulk","zendesk_create_ticket","zendesk_create_tickets_bulk","zendesk_create_user","zendesk_create_users_bulk","zendesk_delete_organization","zendesk_delete_ticket","zendesk_delete_user","zendesk_get_current_user","zendesk_get_organization","zendesk_get_organizations","zendesk_get_ticket","zendesk_get_tickets","zendesk_get_user","zendesk_get_users","zendesk_merge_tickets","zendesk_search","zendesk_search_count","zendesk_search_users","zendesk_update_organization","zendesk_update_ticket","zendesk_update_tickets_bulk","zendesk_update_user","zendesk_update_users_bulk","zep_add_messages","zep_add_user","zep_create_thread","zep_delete_thread","zep_get_context","zep_get_messages","zep_get_threads","zep_get_user","zep_get_user_threads","zerobounce_get_credits","zerobounce_verify_email","zoho_desk_add_comment","zoho_desk_get_attachment","zoho_desk_get_contact","zoho_desk_get_thread","zoho_desk_get_ticket","zoho_desk_list_comments","zoho_desk_list_organizations","zoho_desk_list_threads","zoho_desk_list_tickets","zoho_desk_update_ticket","zoom_create_meeting","zoom_delete_meeting","zoom_delete_recording","zoom_get_meeting","zoom_get_meeting_invitation","zoom_get_meeting_recordings","zoom_list_meetings","zoom_list_past_participants","zoom_list_recordings","zoom_update_meeting","zoominfo_enrich_companies","zoominfo_enrich_contacts","zoominfo_search_companies","zoominfo_search_contacts","zoominfo_search_intent","zoominfo_search_news"]' + '["a2a_cancel_task","a2a_get_agent_card","a2a_get_task","a2a_send_message","affinity_batch_update_entity_fields","affinity_batch_update_list_entry_fields","affinity_create_list","affinity_create_list_field_dropdown_option","affinity_create_merge","affinity_create_note","affinity_create_reminder","affinity_delete_list_field_dropdown_option","affinity_delete_note","affinity_get_company","affinity_get_current_user","affinity_get_entity_field_value","affinity_get_list","affinity_get_list_entry","affinity_get_list_entry_field","affinity_get_list_field_dropdown_option","affinity_get_merge","affinity_get_merge_task","affinity_get_note","affinity_get_opportunity","affinity_get_person","affinity_get_saved_view","affinity_get_transcript","affinity_get_user","affinity_list_calls","affinity_list_chat_messages","affinity_list_companies","affinity_list_coworker_connections","affinity_list_emails","affinity_list_entity_field_values","affinity_list_entity_list_entries","affinity_list_entity_lists","affinity_list_entity_notes","affinity_list_entity_relationships","affinity_list_field_dropdown_options","affinity_list_field_metadata","affinity_list_field_value_changes","affinity_list_investor_executive_connections","affinity_list_list_entries","affinity_list_list_entry_field_value_changes","affinity_list_list_entry_fields","affinity_list_list_field_dropdown_options","affinity_list_list_fields","affinity_list_lists","affinity_list_meetings","affinity_list_merge_tasks","affinity_list_merges","affinity_list_note_attached_companies","affinity_list_note_attached_opportunities","affinity_list_note_attached_persons","affinity_list_note_replies","affinity_list_notes","affinity_list_opportunities","affinity_list_persons","affinity_list_reminders","affinity_list_saved_view_entries","affinity_list_saved_views","affinity_list_transcript_fragments","affinity_list_transcripts","affinity_list_users","affinity_search_companies","affinity_search_files","affinity_search_list_entries","affinity_search_notes","affinity_search_persons","affinity_semantic_search","affinity_update_entity_field_value","affinity_update_list_entry_field","affinity_update_list_field_dropdown_option","affinity_update_note","agentmail_create_draft","agentmail_create_inbox","agentmail_delete_draft","agentmail_delete_inbox","agentmail_delete_thread","agentmail_forward_message","agentmail_get_draft","agentmail_get_inbox","agentmail_get_message","agentmail_get_thread","agentmail_list_drafts","agentmail_list_inboxes","agentmail_list_messages","agentmail_list_threads","agentmail_reply_message","agentmail_send_draft","agentmail_send_message","agentmail_update_draft","agentmail_update_inbox","agentmail_update_message","agentmail_update_thread","agentphone_create_call","agentphone_create_contact","agentphone_create_number","agentphone_delete_contact","agentphone_get_call","agentphone_get_call_transcript","agentphone_get_contact","agentphone_get_conversation","agentphone_get_conversation_messages","agentphone_get_number_messages","agentphone_get_usage","agentphone_get_usage_daily","agentphone_get_usage_monthly","agentphone_list_calls","agentphone_list_contacts","agentphone_list_conversations","agentphone_list_numbers","agentphone_react_to_message","agentphone_release_number","agentphone_send_message","agentphone_update_contact","agentphone_update_conversation","agiloft_async_status","agiloft_attach_file","agiloft_attachment_info","agiloft_create_record","agiloft_delete_record","agiloft_get_choice_line_id","agiloft_list_tables","agiloft_lock_record","agiloft_nlp_search","agiloft_read_record","agiloft_remove_attachment","agiloft_retrieve_attachment","agiloft_run_action_button","agiloft_saved_search","agiloft_search_records","agiloft_select_records","agiloft_update_record","agiloft_upsert_record","ahrefs_anchors","ahrefs_backlinks","ahrefs_backlinks_stats","ahrefs_batch_analysis","ahrefs_broken_backlinks","ahrefs_domain_rating","ahrefs_domain_rating_history","ahrefs_keyword_overview","ahrefs_keywords_history","ahrefs_metrics","ahrefs_metrics_history","ahrefs_organic_competitors","ahrefs_organic_keywords","ahrefs_paid_pages","ahrefs_rank_tracker_competitors_overview","ahrefs_rank_tracker_competitors_stats","ahrefs_rank_tracker_overview","ahrefs_rank_tracker_serp_overview","ahrefs_refdomains_history","ahrefs_referring_domains","ahrefs_related_terms","ahrefs_site_audit_page_explorer","ahrefs_top_pages","airtable_create_records","airtable_delete_records","airtable_get_base_schema","airtable_get_record","airtable_list_bases","airtable_list_records","airtable_list_tables","airtable_update_multiple_records","airtable_update_record","airtable_upsert_records","algolia_add_record","algolia_batch_operations","algolia_browse_records","algolia_clear_records","algolia_copy_move_index","algolia_delete_by_filter","algolia_delete_index","algolia_delete_record","algolia_get_record","algolia_get_records","algolia_get_settings","algolia_get_task_status","algolia_list_indices","algolia_partial_update_record","algolia_search","algolia_update_settings","amplitude_event_segmentation","amplitude_funnels","amplitude_get_active_users","amplitude_get_revenue","amplitude_group_identify","amplitude_identify_user","amplitude_list_events","amplitude_realtime_active_users","amplitude_retention","amplitude_send_event","amplitude_user_activity","amplitude_user_profile","amplitude_user_search","apify_get_dataset_items","apify_get_run","apify_run_actor_async","apify_run_actor_sync","apify_run_task","apollo_account_bulk_create","apollo_account_bulk_update","apollo_account_create","apollo_account_search","apollo_account_update","apollo_contact_bulk_create","apollo_contact_bulk_update","apollo_contact_create","apollo_contact_search","apollo_contact_update","apollo_email_accounts","apollo_opportunity_create","apollo_opportunity_get","apollo_opportunity_search","apollo_opportunity_update","apollo_organization_bulk_enrich","apollo_organization_enrich","apollo_organization_search","apollo_people_bulk_enrich","apollo_people_enrich","apollo_people_search","apollo_sequence_add_contacts","apollo_sequence_search","apollo_task_create","apollo_task_search","appconfig_create_application","appconfig_create_configuration_profile","appconfig_create_environment","appconfig_create_hosted_configuration_version","appconfig_delete_application","appconfig_delete_configuration_profile","appconfig_delete_environment","appconfig_delete_hosted_configuration_version","appconfig_get_application","appconfig_get_configuration","appconfig_get_configuration_profile","appconfig_get_deployment","appconfig_get_environment","appconfig_get_hosted_configuration_version","appconfig_list_applications","appconfig_list_configuration_profiles","appconfig_list_deployment_strategies","appconfig_list_deployments","appconfig_list_environments","appconfig_list_hosted_configuration_versions","appconfig_start_deployment","appconfig_stop_deployment","appconfig_update_application","appconfig_update_configuration_profile","appconfig_update_environment","arxiv_get_author_papers","arxiv_get_paper","arxiv_search","asana_add_comment","asana_add_followers","asana_create_project","asana_create_section","asana_create_subtask","asana_create_task","asana_delete_task","asana_get_project","asana_get_projects","asana_get_task","asana_list_sections","asana_list_workspaces","asana_search_tasks","asana_update_task","ashby_add_candidate_tag","ashby_anonymize_candidate","ashby_change_application_source","ashby_change_application_stage","ashby_create_application","ashby_create_candidate","ashby_create_note","ashby_delete_application","ashby_get_application","ashby_get_candidate","ashby_get_job","ashby_get_job_posting","ashby_get_offer","ashby_get_opening","ashby_list_application_feedback","ashby_list_application_history","ashby_list_applications","ashby_list_archive_reasons","ashby_list_candidate_tags","ashby_list_candidates","ashby_list_custom_fields","ashby_list_departments","ashby_list_interview_plans","ashby_list_interview_stages","ashby_list_interviews","ashby_list_job_postings","ashby_list_jobs","ashby_list_locations","ashby_list_notes","ashby_list_offers","ashby_list_openings","ashby_list_sources","ashby_list_users","ashby_remove_candidate_tag","ashby_search_candidates","ashby_search_jobs","ashby_search_openings","ashby_search_users","ashby_set_custom_field_value","ashby_set_custom_field_values","ashby_transfer_application","ashby_update_candidate","ashby_upload_candidate_file","ashby_upload_resume","athena_batch_get_named_query","athena_batch_get_prepared_statement","athena_batch_get_query_execution","athena_create_named_query","athena_create_prepared_statement","athena_delete_named_query","athena_delete_prepared_statement","athena_get_data_catalog","athena_get_database","athena_get_named_query","athena_get_prepared_statement","athena_get_query_execution","athena_get_query_results","athena_get_query_runtime_statistics","athena_get_table_metadata","athena_get_work_group","athena_list_data_catalogs","athena_list_databases","athena_list_named_queries","athena_list_prepared_statements","athena_list_query_executions","athena_list_table_metadata","athena_list_work_groups","athena_start_query","athena_stop_query","athena_update_named_query","athena_update_prepared_statement","attio_assert_record","attio_create_attribute","attio_create_comment","attio_create_list","attio_create_list_entry","attio_create_note","attio_create_object","attio_create_record","attio_create_task","attio_create_webhook","attio_delete_comment","attio_delete_list_entry","attio_delete_note","attio_delete_record","attio_delete_task","attio_delete_webhook","attio_get_attribute","attio_get_comment","attio_get_list","attio_get_list_entry","attio_get_member","attio_get_note","attio_get_object","attio_get_record","attio_get_task","attio_get_thread","attio_get_webhook","attio_list_attributes","attio_list_lists","attio_list_members","attio_list_notes","attio_list_objects","attio_list_records","attio_list_tasks","attio_list_threads","attio_list_webhooks","attio_query_list_entries","attio_search_records","attio_update_attribute","attio_update_list","attio_update_list_entry","attio_update_object","attio_update_record","attio_update_task","attio_update_webhook","azure_data_explorer_create_table","azure_data_explorer_drop_table","azure_data_explorer_ingest_from_query","azure_data_explorer_ingest_inline","azure_data_explorer_list_databases","azure_data_explorer_list_functions","azure_data_explorer_list_tables","azure_data_explorer_management","azure_data_explorer_query","azure_data_explorer_show_database_schema","azure_data_explorer_show_ingestion_failures","azure_data_explorer_show_operations","azure_data_explorer_show_table_details","azure_data_explorer_show_table_schema","azure_devops_add_comment","azure_devops_create_work_item","azure_devops_get_build_log","azure_devops_get_build_timeline","azure_devops_get_comments","azure_devops_get_pipeline","azure_devops_get_pipeline_run","azure_devops_get_work_item","azure_devops_get_work_items_batch","azure_devops_get_work_items_between_builds","azure_devops_list_build_logs","azure_devops_list_builds","azure_devops_list_pipeline_runs","azure_devops_list_pipelines","azure_devops_query_work_items","azure_devops_update_work_item","bitbucket_approve_pull_request","bitbucket_create_branch","bitbucket_create_pull_request","bitbucket_create_pull_request_comment","bitbucket_decline_pull_request","bitbucket_delete_branch","bitbucket_get_commit","bitbucket_get_file","bitbucket_get_file_metadata","bitbucket_get_pipeline","bitbucket_get_pipeline_step_log","bitbucket_get_pull_request","bitbucket_get_pull_request_diff","bitbucket_get_pull_request_diffstat","bitbucket_get_pull_request_merge_task_status","bitbucket_get_repository","bitbucket_list_branches","bitbucket_list_commits","bitbucket_list_directory","bitbucket_list_pipeline_steps","bitbucket_list_pipelines","bitbucket_list_pull_request_comments","bitbucket_list_pull_request_commit_statuses","bitbucket_list_pull_requests","bitbucket_list_repositories","bitbucket_list_workspaces","bitbucket_merge_pull_request","bitbucket_request_pull_request_changes","bitbucket_stop_pipeline","bitbucket_trigger_pipeline","box_copy_file","box_create_folder","box_delete_file","box_delete_folder","box_download_file","box_download_file_v2","box_get_file_info","box_list_folder_items","box_search","box_sign_cancel_request","box_sign_create_request","box_sign_get_request","box_sign_list_requests","box_sign_resend_request","box_update_file","box_upload_file","brandfetch_get_brand","brandfetch_search","brex_archive_budget","brex_create_budget","brex_create_spend_limit","brex_create_transfer","brex_create_vendor","brex_get_budget","brex_get_cash_account","brex_get_company","brex_get_current_user","brex_get_expense","brex_get_spend_limit","brex_get_transfer","brex_get_user","brex_get_vendor","brex_list_budgets","brex_list_card_accounts","brex_list_card_statements","brex_list_card_transactions","brex_list_cards","brex_list_cash_accounts","brex_list_cash_statements","brex_list_cash_transactions","brex_list_departments","brex_list_expenses","brex_list_locations","brex_list_spend_limits","brex_list_titles","brex_list_transfers","brex_list_users","brex_list_vendors","brex_match_receipt","brex_update_expense","brex_update_vendor","brex_upload_receipt","brightdata_cancel_snapshot","brightdata_discover","brightdata_download_snapshot","brightdata_scrape_dataset","brightdata_scrape_url","brightdata_serp_search","brightdata_snapshot_status","brightdata_sync_scrape","browser_use_run_task","buffer_create_idea","buffer_create_post","buffer_delete_post","buffer_edit_post","buffer_get_account","buffer_get_aggregated_post_metrics","buffer_get_channel","buffer_get_channels","buffer_get_daily_posting_limits","buffer_get_idea_groups","buffer_get_ideas","buffer_get_post","buffer_get_posts","calcom_cancel_booking","calcom_confirm_booking","calcom_create_booking","calcom_create_event_type","calcom_create_schedule","calcom_decline_booking","calcom_delete_event_type","calcom_delete_schedule","calcom_get_booking","calcom_get_default_schedule","calcom_get_event_type","calcom_get_schedule","calcom_get_slots","calcom_list_bookings","calcom_list_event_types","calcom_list_schedules","calcom_reschedule_booking","calcom_update_event_type","calcom_update_schedule","calendly_cancel_event","calendly_create_event_invitee","calendly_create_invitee_no_show","calendly_create_scheduling_link","calendly_create_webhook","calendly_delete_invitee_no_show","calendly_delete_webhook","calendly_get_current_user","calendly_get_event_invitee","calendly_get_event_type","calendly_get_scheduled_event","calendly_get_user","calendly_list_event_invitees","calendly_list_event_type_available_times","calendly_list_event_types","calendly_list_organization_memberships","calendly_list_routing_form_submissions","calendly_list_routing_forms","calendly_list_scheduled_events","calendly_list_user_availability_schedules","calendly_list_user_busy_times","calendly_list_webhooks","cbinsights_chat","cbinsights_get_commercial_maturity_history","cbinsights_get_exit_probability_history","cbinsights_get_mosaic_history","cbinsights_get_org_business_relationships","cbinsights_get_org_funding_window","cbinsights_get_org_fundings","cbinsights_get_org_investments","cbinsights_get_org_management_and_board","cbinsights_get_org_outlook","cbinsights_get_org_portfolio_exits","cbinsights_get_org_revenue","cbinsights_get_scouting_report","cbinsights_get_strategy_map","cbinsights_list_business_relationships","cbinsights_list_funding_window","cbinsights_list_fundings","cbinsights_list_investments","cbinsights_list_management_and_board","cbinsights_list_outlook","cbinsights_list_portfolio_exits","cbinsights_list_revenue","cbinsights_lookup_organizations","cbinsights_rag","cbinsights_search_firmographics","checkr_add_report_tag","checkr_apply_report_review_action","checkr_cancel_adverse_action","checkr_cancel_continuous_check","checkr_cancel_invitation","checkr_cancel_subscription","checkr_complete_report","checkr_create_adverse_action","checkr_create_candidate","checkr_create_continuous_check","checkr_create_geo","checkr_create_invitation","checkr_create_report","checkr_create_subscription","checkr_delete_candidate_pii","checkr_delete_geo","checkr_get_account","checkr_get_adverse_action","checkr_get_candidate","checkr_get_continuous_check","checkr_get_document","checkr_get_geo","checkr_get_invitation","checkr_get_node","checkr_get_package","checkr_get_program","checkr_get_report","checkr_get_report_eta","checkr_get_report_progressive_status","checkr_get_report_tags","checkr_get_screening","checkr_get_subscription","checkr_get_verification","checkr_list_adverse_actions","checkr_list_adverse_items","checkr_list_assessments","checkr_list_candidate_documents","checkr_list_candidates","checkr_list_continuous_checks","checkr_list_counties","checkr_list_geos","checkr_list_invitations","checkr_list_nodes","checkr_list_packages","checkr_list_programs","checkr_list_report_addresses","checkr_list_subscriptions","checkr_list_users","checkr_list_verifications","checkr_remove_report_tag","checkr_set_report_tags","checkr_update_candidate","checkr_update_continuous_check","checkr_update_geo","checkr_update_report","checkr_update_subscription","circleback_add_tag_to_meetings","circleback_create_tag","circleback_delete_action_item","circleback_delete_meeting","circleback_delete_tag","circleback_get_company","circleback_get_meeting","circleback_get_person","circleback_get_transcript","circleback_list_action_items","circleback_list_calendar_events","circleback_list_companies","circleback_list_meetings","circleback_list_people","circleback_list_tags","circleback_remove_tag_from_meetings","circleback_search_meetings","circleback_update_action_item","circleback_update_meeting","circleback_update_tag","clay_populate","clerk_add_organization_member","clerk_ban_user","clerk_create_actor_token","clerk_create_allowlist_identifier","clerk_create_blocklist_identifier","clerk_create_organization","clerk_create_organization_invitation","clerk_create_user","clerk_delete_allowlist_identifier","clerk_delete_blocklist_identifier","clerk_delete_organization","clerk_delete_user","clerk_get_jwt_template","clerk_get_organization","clerk_get_session","clerk_get_user","clerk_get_user_oauth_token","clerk_list_allowlist_identifiers","clerk_list_blocklist_identifiers","clerk_list_jwt_templates","clerk_list_organization_invitations","clerk_list_organization_memberships","clerk_list_organizations","clerk_list_sessions","clerk_list_users","clerk_lock_user","clerk_remove_organization_member","clerk_revoke_actor_token","clerk_revoke_session","clerk_unban_user","clerk_unlock_user","clerk_update_organization","clerk_update_organization_membership","clerk_update_user","clickhouse_count_rows","clickhouse_create_database","clickhouse_create_table","clickhouse_delete","clickhouse_describe_table","clickhouse_drop_database","clickhouse_drop_partition","clickhouse_drop_table","clickhouse_execute","clickhouse_insert","clickhouse_insert_rows","clickhouse_introspect","clickhouse_kill_query","clickhouse_list_clusters","clickhouse_list_databases","clickhouse_list_mutations","clickhouse_list_partitions","clickhouse_list_running_queries","clickhouse_list_tables","clickhouse_optimize_table","clickhouse_query","clickhouse_rename_table","clickhouse_show_create_table","clickhouse_table_stats","clickhouse_truncate_table","clickhouse_update","clickup_add_tag_to_task","clickup_create_checklist","clickup_create_checklist_item","clickup_create_comment","clickup_create_folder","clickup_create_list","clickup_create_task","clickup_create_time_entry","clickup_delete_checklist","clickup_delete_checklist_item","clickup_delete_comment","clickup_delete_task","clickup_delete_time_entry","clickup_get_comments","clickup_get_custom_fields","clickup_get_folders","clickup_get_list_members","clickup_get_lists","clickup_get_running_timer","clickup_get_space_tags","clickup_get_spaces","clickup_get_task","clickup_get_task_members","clickup_get_tasks","clickup_get_time_entries","clickup_get_workspaces","clickup_remove_custom_field_value","clickup_remove_tag_from_task","clickup_search_tasks","clickup_set_custom_field_value","clickup_start_timer","clickup_stop_timer","clickup_update_checklist","clickup_update_checklist_item","clickup_update_comment","clickup_update_task","clickup_update_time_entry","clickup_upload_attachment","cloudflare_create_access_application","cloudflare_create_access_group","cloudflare_create_access_policy","cloudflare_create_access_service_token","cloudflare_create_dns_record","cloudflare_create_r2_bucket","cloudflare_create_rate_limit_rule","cloudflare_create_ruleset","cloudflare_create_ruleset_rule","cloudflare_create_tunnel","cloudflare_create_worker_route","cloudflare_create_zone","cloudflare_delete_access_application","cloudflare_delete_access_group","cloudflare_delete_access_policy","cloudflare_delete_dns_record","cloudflare_delete_r2_bucket","cloudflare_delete_r2_bucket_cors","cloudflare_delete_ruleset","cloudflare_delete_ruleset_rule","cloudflare_delete_tunnel","cloudflare_delete_worker_route","cloudflare_delete_worker_script","cloudflare_delete_zone","cloudflare_dns_analytics","cloudflare_get_access_application","cloudflare_get_access_group","cloudflare_get_access_policy","cloudflare_get_access_service_token","cloudflare_get_dns_record","cloudflare_get_r2_bucket","cloudflare_get_r2_bucket_cors","cloudflare_get_r2_bucket_lifecycle","cloudflare_get_ruleset","cloudflare_get_ruleset_entrypoint","cloudflare_get_tunnel","cloudflare_get_tunnel_configuration","cloudflare_get_tunnel_token","cloudflare_get_worker_route","cloudflare_get_worker_script_settings","cloudflare_get_zone","cloudflare_get_zone_settings","cloudflare_list_access_applications","cloudflare_list_access_groups","cloudflare_list_access_identity_providers","cloudflare_list_access_policies","cloudflare_list_access_service_tokens","cloudflare_list_certificates","cloudflare_list_dns_records","cloudflare_list_managed_ruleset_overrides","cloudflare_list_r2_buckets","cloudflare_list_rate_limit_rules","cloudflare_list_rulesets","cloudflare_list_tunnels","cloudflare_list_worker_routes","cloudflare_list_worker_scripts","cloudflare_list_zones","cloudflare_purge_cache","cloudflare_refresh_access_service_token","cloudflare_revoke_access_service_token","cloudflare_rotate_access_service_token","cloudflare_update_access_application","cloudflare_update_access_group","cloudflare_update_access_policy","cloudflare_update_access_service_token","cloudflare_update_dns_record","cloudflare_update_r2_bucket_cors","cloudflare_update_r2_bucket_lifecycle","cloudflare_update_rate_limit_rule","cloudflare_update_ruleset","cloudflare_update_ruleset_rule","cloudflare_update_tunnel","cloudflare_update_tunnel_configuration","cloudflare_update_worker_route","cloudflare_update_zone","cloudflare_update_zone_setting","cloudformation_cancel_update_stack","cloudformation_create_change_set","cloudformation_create_stack","cloudformation_delete_stack","cloudformation_describe_change_set","cloudformation_describe_stack_drift_detection_status","cloudformation_describe_stack_events","cloudformation_describe_stacks","cloudformation_detect_stack_drift","cloudformation_execute_change_set","cloudformation_get_template","cloudformation_get_template_summary","cloudformation_list_stack_resources","cloudformation_update_stack","cloudformation_validate_template","cloudtrail_cancel_query","cloudtrail_describe_query","cloudtrail_describe_trails","cloudtrail_get_event_data_store","cloudtrail_get_event_selectors","cloudtrail_get_insight_selectors","cloudtrail_get_query_results","cloudtrail_get_trail","cloudtrail_get_trail_status","cloudtrail_list_event_data_stores","cloudtrail_list_tags","cloudtrail_list_trails","cloudtrail_lookup_events","cloudtrail_start_query","cloudwatch_describe_alarm_history","cloudwatch_describe_alarms","cloudwatch_describe_log_groups","cloudwatch_describe_log_streams","cloudwatch_filter_log_events","cloudwatch_get_log_events","cloudwatch_get_metric_statistics","cloudwatch_list_metrics","cloudwatch_mute_alarm","cloudwatch_put_log_group_retention","cloudwatch_put_metric_data","cloudwatch_query_logs","cloudwatch_unmute_alarm","coda_add_custom_domain","coda_add_permission","coda_change_user_role","coda_create_doc","coda_create_folder","coda_create_page","coda_delete_custom_domain","coda_delete_doc","coda_delete_folder","coda_delete_page","coda_delete_page_content","coda_delete_permission","coda_delete_row","coda_delete_rows","coda_export_page","coda_get_acl_settings","coda_get_analytics_last_updated","coda_get_column","coda_get_control","coda_get_custom_domain_provider","coda_get_doc","coda_get_doc_analytics_summary","coda_get_folder","coda_get_formula","coda_get_mutation_status","coda_get_page","coda_get_page_content","coda_get_page_export_status","coda_get_row","coda_get_sharing_metadata","coda_get_table","coda_list_categories","coda_list_columns","coda_list_controls","coda_list_custom_domains","coda_list_doc_analytics","coda_list_docs","coda_list_folder_children","coda_list_folders","coda_list_formulas","coda_list_page_analytics","coda_list_pages","coda_list_permissions","coda_list_rows","coda_list_tables","coda_list_workspace_members","coda_list_workspace_roles","coda_publish_doc","coda_push_button","coda_resolve_browser_link","coda_search_principals","coda_trigger_automation","coda_unpublish_doc","coda_update_acl_settings","coda_update_doc","coda_update_folder","coda_update_page","coda_update_row","coda_upsert_rows","coda_whoami","codepipeline_disable_stage_transition","codepipeline_enable_stage_transition","codepipeline_get_pipeline","codepipeline_get_pipeline_execution","codepipeline_get_pipeline_state","codepipeline_list_action_executions","codepipeline_list_pipeline_executions","codepipeline_list_pipelines","codepipeline_put_approval_result","codepipeline_retry_stage_execution","codepipeline_start_execution","codepipeline_stop_execution","confluence_add_label","confluence_create_blogpost","confluence_create_comment","confluence_create_page","confluence_create_page_property","confluence_create_space","confluence_create_space_property","confluence_delete_attachment","confluence_delete_blogpost","confluence_delete_comment","confluence_delete_label","confluence_delete_page","confluence_delete_page_property","confluence_delete_space","confluence_delete_space_property","confluence_get_blogpost","confluence_get_page_ancestors","confluence_get_page_children","confluence_get_page_descendants","confluence_get_page_version","confluence_get_pages_by_label","confluence_get_space","confluence_get_task","confluence_get_user","confluence_list_attachments","confluence_list_blogposts","confluence_list_blogposts_in_space","confluence_list_comments","confluence_list_labels","confluence_list_page_properties","confluence_list_page_versions","confluence_list_pages_in_space","confluence_list_space_labels","confluence_list_space_permissions","confluence_list_space_properties","confluence_list_spaces","confluence_list_tasks","confluence_retrieve","confluence_search","confluence_search_in_space","confluence_update","confluence_update_blogpost","confluence_update_comment","confluence_update_space","confluence_update_task","confluence_upload_attachment","context_dev_classify_naics","context_dev_classify_sic","context_dev_crawl","context_dev_extract","context_dev_extract_product","context_dev_extract_products","context_dev_get_brand","context_dev_get_brand_by_email","context_dev_get_brand_by_name","context_dev_get_brand_by_ticker","context_dev_identify_transaction","context_dev_map","context_dev_scrape_fonts","context_dev_scrape_html","context_dev_scrape_images","context_dev_scrape_markdown","context_dev_scrape_styleguide","context_dev_screenshot","context_dev_search","convex_action","convex_document_deltas","convex_list_documents","convex_list_tables","convex_mutation","convex_query","convex_run_function","crowdstrike_create_indicators","crowdstrike_delete_indicators","crowdstrike_delete_rtr_session","crowdstrike_execute_rtr_command","crowdstrike_get_alert_details","crowdstrike_get_case_details","crowdstrike_get_host_group_details","crowdstrike_get_indicator_details","crowdstrike_get_rtr_command_status","crowdstrike_get_sensor_aggregates","crowdstrike_get_sensor_details","crowdstrike_get_vulnerability_details","crowdstrike_init_rtr_session","crowdstrike_perform_host_action","crowdstrike_perform_host_group_action","crowdstrike_query_alerts","crowdstrike_query_cases","crowdstrike_query_host_groups","crowdstrike_query_indicators","crowdstrike_query_sensors","crowdstrike_query_vulnerabilities","crowdstrike_update_alerts","crowdstrike_update_indicators","crunchbase_autocomplete","crunchbase_get_acquisition","crunchbase_get_entity","crunchbase_get_entity_card","crunchbase_get_fields_metadata","crunchbase_get_funding_round","crunchbase_get_organization","crunchbase_get_person","crunchbase_list_deleted_entities","crunchbase_search_acquisitions","crunchbase_search_entities","crunchbase_search_funding_rounds","crunchbase_search_organizations","crunchbase_search_people","cursor_add_followup","cursor_add_followup_v2","cursor_delete_agent","cursor_delete_agent_v2","cursor_download_artifact","cursor_download_artifact_v2","cursor_get_agent","cursor_get_agent_v2","cursor_get_api_key_info","cursor_get_api_key_info_v2","cursor_get_conversation","cursor_get_conversation_v2","cursor_launch_agent","cursor_launch_agent_v2","cursor_list_agents","cursor_list_agents_v2","cursor_list_artifacts","cursor_list_artifacts_v2","cursor_list_models","cursor_list_models_v2","cursor_list_repositories","cursor_list_repositories_v2","cursor_stop_agent","cursor_stop_agent_v2","dagster_delete_run","dagster_get_asset","dagster_get_run","dagster_get_run_logs","dagster_launch_run","dagster_list_assets","dagster_list_jobs","dagster_list_runs","dagster_list_schedules","dagster_list_sensors","dagster_materialize_assets","dagster_reexecute_run","dagster_report_asset_materialization","dagster_start_schedule","dagster_start_sensor","dagster_stop_schedule","dagster_stop_sensor","dagster_terminate_run","dagster_wipe_asset","databricks_cancel_all_runs","databricks_cancel_run","databricks_cancel_statement","databricks_create_cluster","databricks_create_job","databricks_create_warehouse","databricks_delete_cluster","databricks_delete_job","databricks_delete_run","databricks_delete_warehouse","databricks_edit_cluster","databricks_edit_warehouse","databricks_execute_sql","databricks_genie_agent_ask","databricks_genie_agent_cancel","databricks_genie_agent_list_items","databricks_genie_ask","databricks_genie_create_space","databricks_genie_delete_conversation","databricks_genie_delete_message","databricks_genie_delete_space","databricks_genie_download_visualization","databricks_genie_execute_query","databricks_genie_get_message","databricks_genie_get_query_result","databricks_genie_get_space","databricks_genie_list_conversations","databricks_genie_list_messages","databricks_genie_list_spaces","databricks_genie_send_feedback","databricks_genie_update_space","databricks_get_cluster","databricks_get_job","databricks_get_run","databricks_get_run_output","databricks_get_statement","databricks_get_statement_chunk","databricks_get_warehouse","databricks_list_clusters","databricks_list_jobs","databricks_list_runs","databricks_list_warehouses","databricks_repair_run","databricks_reset_job","databricks_resize_cluster","databricks_restart_cluster","databricks_run_job","databricks_start_cluster","databricks_start_warehouse","databricks_stop_warehouse","databricks_submit_run","databricks_terminate_cluster","databricks_update_job","datadog_add_incident_todo","datadog_cancel_downtime","datadog_create_dashboard","datadog_create_downtime","datadog_create_event","datadog_create_incident","datadog_create_monitor","datadog_create_slo","datadog_delete_dashboard","datadog_delete_slo","datadog_get_browser_synthetics_results","datadog_get_dashboard","datadog_get_incident","datadog_get_monitor","datadog_get_security_signal","datadog_get_slo","datadog_get_slo_history","datadog_get_synthetics_results","datadog_get_synthetics_test","datadog_list_dashboards","datadog_list_downtimes","datadog_list_incidents","datadog_list_monitors","datadog_list_security_rules","datadog_list_security_signals","datadog_list_services","datadog_list_slos","datadog_list_synthetics_tests","datadog_mute_monitor","datadog_query_logs","datadog_query_timeseries","datadog_search_spans","datadog_send_logs","datadog_submit_metrics","datadog_trigger_synthetics_tests","datadog_unmute_monitor","datadog_update_incident","datadog_update_security_signal_assignee","datadog_update_security_signal_state","datadog_update_slo","datadog_update_synthetics_status","datagma_enrich_company","datagma_enrich_person","datagma_find_email","datagma_find_phone","datagma_get_credits","daytona_create_sandbox","daytona_delete_sandbox","daytona_download_file","daytona_execute_command","daytona_get_sandbox","daytona_git_clone","daytona_list_files","daytona_list_sandboxes","daytona_run_code","daytona_start_sandbox","daytona_stop_sandbox","daytona_upload_file","deployed_block_executor","deployments_deploy","deployments_get_version","deployments_list_versions","deployments_promote","deployments_undeploy","devin_append_session_tags","devin_archive_session","devin_create_session","devin_get_session","devin_get_session_tags","devin_list_session_attachments","devin_list_session_messages","devin_list_sessions","devin_replace_session_tags","devin_send_message","devin_terminate_session","discord_add_reaction","discord_archive_thread","discord_assign_role","discord_ban_member","discord_bulk_delete_messages","discord_create_channel","discord_create_invite","discord_create_role","discord_create_thread","discord_create_webhook","discord_delete_channel","discord_delete_invite","discord_delete_message","discord_delete_role","discord_delete_webhook","discord_edit_message","discord_execute_webhook","discord_get_channel","discord_get_invite","discord_get_member","discord_get_messages","discord_get_pinned_messages","discord_get_server","discord_get_user","discord_get_webhook","discord_join_thread","discord_kick_member","discord_leave_thread","discord_list_channels","discord_list_roles","discord_pin_message","discord_remove_reaction","discord_remove_role","discord_send_message","discord_unban_member","discord_unpin_message","discord_update_channel","discord_update_member","discord_update_role","docusign_create_from_template","docusign_download_document","docusign_get_envelope","docusign_list_envelopes","docusign_list_recipients","docusign_list_templates","docusign_send_envelope","docusign_void_envelope","downdetector_get_company","downdetector_get_company_attribution","downdetector_get_company_baseline","downdetector_get_company_events","downdetector_get_company_incidents","downdetector_get_company_indicators","downdetector_get_company_last_15","downdetector_get_company_status","downdetector_get_provider","downdetector_get_reports","downdetector_get_site_companies","downdetector_list_categories","downdetector_list_incidents","downdetector_list_sites","downdetector_search_companies","dropbox_copy","dropbox_create_folder","dropbox_create_shared_link","dropbox_delete","dropbox_download","dropbox_download_v2","dropbox_get_metadata","dropbox_list_folder","dropbox_list_revisions","dropbox_list_shared_links","dropbox_move","dropbox_restore","dropbox_search","dropbox_upload","dropcontact_enrich_contact","dspy_chain_of_thought","dspy_predict","dspy_react","dub_bulk_create_links","dub_bulk_delete_links","dub_bulk_update_links","dub_create_link","dub_create_tag","dub_delete_link","dub_get_analytics","dub_get_events","dub_get_link","dub_get_links_count","dub_get_qr_code","dub_get_qr_code_v2","dub_list_domains","dub_list_folders","dub_list_links","dub_list_tags","dub_update_link","dub_upsert_link","duckduckgo_search","dynamodb_delete","dynamodb_get","dynamodb_introspect","dynamodb_put","dynamodb_query","dynamodb_scan","dynamodb_update","dynatrace_add_problem_comment","dynatrace_add_tags","dynatrace_close_problem","dynatrace_create_settings_object","dynatrace_create_slo","dynatrace_delete_problem_comment","dynatrace_delete_settings_object","dynatrace_delete_slo","dynatrace_delete_tag","dynatrace_execute_synthetic_monitors","dynatrace_get_attack","dynatrace_get_audit_logs","dynatrace_get_entity","dynatrace_get_event","dynatrace_get_metric","dynatrace_get_problem","dynatrace_get_problem_comment","dynatrace_get_security_problem","dynatrace_get_settings_object","dynatrace_get_slo","dynatrace_get_synthetic_batch","dynatrace_ingest_event","dynatrace_ingest_logs","dynatrace_ingest_metrics","dynatrace_list_attacks","dynatrace_list_entities","dynatrace_list_entity_types","dynatrace_list_events","dynatrace_list_metrics","dynatrace_list_problem_comments","dynatrace_list_problems","dynatrace_list_remediation_items","dynatrace_list_security_problems","dynatrace_list_settings_objects","dynatrace_list_settings_schemas","dynatrace_list_slos","dynatrace_list_synthetic_monitors","dynatrace_list_tags","dynatrace_mute_security_problem","dynatrace_mute_security_problems","dynatrace_query_metrics","dynatrace_search_logs","dynatrace_unmute_security_problem","dynatrace_unmute_security_problems","dynatrace_update_problem_comment","dynatrace_update_settings_object","dynatrace_update_slo","elasticsearch_bulk","elasticsearch_cluster_health","elasticsearch_cluster_stats","elasticsearch_count","elasticsearch_create_index","elasticsearch_delete_document","elasticsearch_delete_index","elasticsearch_get_document","elasticsearch_get_index","elasticsearch_index_document","elasticsearch_list_indices","elasticsearch_search","elasticsearch_update_document","elevenlabs_audio_isolation","elevenlabs_edit_voice_settings","elevenlabs_get_user","elevenlabs_get_voice","elevenlabs_get_voice_settings","elevenlabs_list_models","elevenlabs_list_voices","elevenlabs_sound_effects","elevenlabs_speech_to_speech","elevenlabs_tts","emailbison_attach_leads_to_campaign","emailbison_attach_tags_to_leads","emailbison_create_campaign","emailbison_create_lead","emailbison_create_tag","emailbison_get_lead","emailbison_list_campaigns","emailbison_list_leads","emailbison_list_replies","emailbison_list_tags","emailbison_update_campaign","emailbison_update_campaign_status","emailbison_update_lead","embeddings_cohere","embeddings_gemini","embeddings_mistral","embeddings_ollama","embeddings_openai","embeddings_openrouter","enrich_check_credits","enrich_company_funding","enrich_company_lookup","enrich_company_revenue","enrich_disposable_email_check","enrich_email_to_ip","enrich_email_to_person_lite","enrich_email_to_phone","enrich_email_to_profile","enrich_find_email","enrich_get_post_details","enrich_ip_to_company","enrich_linkedin_profile","enrich_linkedin_to_personal_email","enrich_linkedin_to_work_email","enrich_phone_finder","enrich_reverse_hash_lookup","enrich_sales_pointer_people","enrich_search_company","enrich_search_company_activities","enrich_search_company_employees","enrich_search_jobs","enrich_search_logo","enrich_search_people","enrich_search_people_activities","enrich_search_post_comments","enrich_search_post_comments_by_url","enrich_search_post_reactions","enrich_search_post_reactions_by_url","enrich_search_posts","enrich_search_similar_companies","enrich_verify_email","enrichment_run","enrow_find_email","enrow_verify_email","exa_agent","exa_answer","exa_find_similar_links","exa_get_contents","exa_search","extend_parser","extend_parser_v2","fathom_get_summary","fathom_get_transcript","fathom_list_meeting_types","fathom_list_meetings","fathom_list_team_members","fathom_list_teams","file_append","file_compress","file_create_folder","file_decompress","file_delete_folder","file_edit","file_fetch","file_get","file_get_content","file_list","file_manage_sharing","file_move","file_parser","file_parser_v2","file_parser_v3","file_read","file_restore_folder","file_search","file_update_folder","file_write","findymail_find_email_from_linkedin","findymail_find_email_from_name","findymail_find_emails_by_domain","findymail_find_employees","findymail_find_phone","findymail_get_company","findymail_get_credits","findymail_lookup_technologies","findymail_reverse_email_lookup","findymail_search_technologies","findymail_verify_email","firecrawl_agent","firecrawl_batch_scrape","firecrawl_batch_scrape_status","firecrawl_cancel_crawl","firecrawl_crawl","firecrawl_crawl_status","firecrawl_credit_usage","firecrawl_extract","firecrawl_extract_status","firecrawl_map","firecrawl_parse","firecrawl_scrape","firecrawl_search","fireflies_add_to_live_meeting","fireflies_create_bite","fireflies_delete_transcript","fireflies_get_transcript","fireflies_get_user","fireflies_list_bites","fireflies_list_contacts","fireflies_list_transcripts","fireflies_list_users","fireflies_upload_audio","fivetran_cancel_transformation","fivetran_create_connect_card","fivetran_create_connection","fivetran_create_destination","fivetran_create_group","fivetran_delete_connection","fivetran_get_account_info","fivetran_get_connection","fivetran_get_connection_schema_config","fivetran_get_connection_warnings","fivetran_get_connector_type","fivetran_get_destination","fivetran_get_group","fivetran_get_sync_history","fivetran_get_transformation","fivetran_list_connections","fivetran_list_connector_types","fivetran_list_destinations","fivetran_list_groups","fivetran_list_transformations","fivetran_list_users","fivetran_reload_connection_schema","fivetran_resync_connection","fivetran_resync_tables","fivetran_run_connection_setup_tests","fivetran_run_destination_setup_tests","fivetran_run_transformation","fivetran_sync_connection","fivetran_update_connection","fivetran_update_connection_schema","fivetran_update_connection_table","fivetran_update_schema_config","flint_create_task","flint_generate_pages","flint_get_task","function_execute","gamma_check_status","gamma_generate","gamma_generate_from_template","gamma_list_folders","gamma_list_themes","github_add_assignees","github_add_assignees_v2","github_add_labels","github_add_labels_v2","github_cancel_workflow_run","github_cancel_workflow_run_v2","github_check_star","github_check_star_v2","github_close_issue","github_close_issue_v2","github_close_pr","github_close_pr_v2","github_comment","github_comment_v2","github_compare_commits","github_compare_commits_v2","github_create_branch","github_create_branch_v2","github_create_comment_reaction","github_create_comment_reaction_v2","github_create_file","github_create_file_v2","github_create_gist","github_create_gist_v2","github_create_issue","github_create_issue_reaction","github_create_issue_reaction_v2","github_create_issue_v2","github_create_milestone","github_create_milestone_v2","github_create_pr","github_create_pr_review","github_create_pr_review_v2","github_create_pr_v2","github_create_project","github_create_project_v2","github_create_release","github_create_release_v2","github_delete_branch","github_delete_branch_v2","github_delete_comment","github_delete_comment_reaction","github_delete_comment_reaction_v2","github_delete_comment_v2","github_delete_file","github_delete_file_v2","github_delete_gist","github_delete_gist_v2","github_delete_issue_reaction","github_delete_issue_reaction_v2","github_delete_milestone","github_delete_milestone_v2","github_delete_project","github_delete_project_v2","github_delete_release","github_delete_release_v2","github_fork_gist","github_fork_gist_v2","github_fork_repo","github_fork_repo_v2","github_get_branch","github_get_branch_protection","github_get_branch_protection_v2","github_get_branch_v2","github_get_commit","github_get_commit_v2","github_get_file_content","github_get_file_content_v2","github_get_gist","github_get_gist_v2","github_get_issue","github_get_issue_v2","github_get_latest_release","github_get_latest_release_v2","github_get_milestone","github_get_milestone_v2","github_get_pr_files","github_get_pr_files_v2","github_get_project","github_get_project_v2","github_get_readme","github_get_readme_v2","github_get_release","github_get_release_v2","github_get_tree","github_get_tree_v2","github_get_workflow","github_get_workflow_run","github_get_workflow_run_v2","github_get_workflow_v2","github_issue_comment","github_issue_comment_v2","github_job_logs","github_latest_commit","github_latest_commit_v2","github_list_branches","github_list_branches_v2","github_list_commits","github_list_commits_v2","github_list_forks","github_list_forks_v2","github_list_gists","github_list_gists_v2","github_list_issue_comments","github_list_issue_comments_v2","github_list_issues","github_list_issues_v2","github_list_milestones","github_list_milestones_v2","github_list_pr_comments","github_list_pr_comments_v2","github_list_projects","github_list_projects_v2","github_list_prs","github_list_prs_v2","github_list_releases","github_list_releases_v2","github_list_review_threads","github_list_stargazers","github_list_stargazers_v2","github_list_tags","github_list_tags_v2","github_list_workflow_runs","github_list_workflow_runs_v2","github_list_workflows","github_list_workflows_v2","github_merge_pr","github_merge_pr_v2","github_pr","github_pr_v2","github_remove_label","github_remove_label_v2","github_reply_review_thread","github_repo_info","github_repo_info_v2","github_request_reviewers","github_request_reviewers_v2","github_rerun_workflow","github_rerun_workflow_v2","github_resolve_review_thread","github_search_code","github_search_code_v2","github_search_commits","github_search_commits_v2","github_search_issues","github_search_issues_v2","github_search_repos","github_search_repos_v2","github_search_users","github_search_users_v2","github_star_gist","github_star_gist_v2","github_star_repo","github_star_repo_v2","github_status_check_rollup","github_trigger_workflow","github_trigger_workflow_v2","github_unstar_gist","github_unstar_gist_v2","github_unstar_repo","github_unstar_repo_v2","github_update_branch_protection","github_update_branch_protection_v2","github_update_comment","github_update_comment_v2","github_update_file","github_update_file_v2","github_update_gist","github_update_gist_v2","github_update_issue","github_update_issue_v2","github_update_milestone","github_update_milestone_v2","github_update_pr","github_update_pr_v2","github_update_project","github_update_project_v2","github_update_release","github_update_release_v2","gitlab_activate_user","gitlab_add_member","gitlab_add_saml_group_link","gitlab_approve_access_request","gitlab_approve_merge_request","gitlab_approve_user","gitlab_ban_user","gitlab_block_user","gitlab_cancel_pipeline","gitlab_compare_branches","gitlab_create_branch","gitlab_create_file","gitlab_create_issue","gitlab_create_issue_note","gitlab_create_merge_request","gitlab_create_merge_request_note","gitlab_create_pipeline","gitlab_create_release","gitlab_create_user","gitlab_deactivate_user","gitlab_delete_branch","gitlab_delete_issue","gitlab_delete_saml_group_link","gitlab_delete_user","gitlab_delete_user_identity","gitlab_deny_access_request","gitlab_get_file","gitlab_get_group","gitlab_get_issue","gitlab_get_job_log","gitlab_get_merge_request","gitlab_get_merge_request_changes","gitlab_get_pipeline","gitlab_get_project","gitlab_invite_member","gitlab_list_access_requests","gitlab_list_branches","gitlab_list_commits","gitlab_list_groups","gitlab_list_invitations","gitlab_list_issues","gitlab_list_members","gitlab_list_merge_requests","gitlab_list_pipeline_jobs","gitlab_list_pipelines","gitlab_list_projects","gitlab_list_releases","gitlab_list_repository_tree","gitlab_list_saml_group_links","gitlab_list_user_memberships","gitlab_merge_merge_request","gitlab_play_job","gitlab_reject_user","gitlab_remove_member","gitlab_retry_pipeline","gitlab_revoke_invitation","gitlab_search_users","gitlab_unban_user","gitlab_unblock_user","gitlab_update_file","gitlab_update_invitation","gitlab_update_issue","gitlab_update_member","gitlab_update_merge_request","gitlab_update_user","gmail_add_label","gmail_add_label_v2","gmail_archive","gmail_archive_v2","gmail_create_label_v2","gmail_delete","gmail_delete_draft_v2","gmail_delete_label_v2","gmail_delete_v2","gmail_draft","gmail_draft_v2","gmail_edit_draft_v2","gmail_get_draft_v2","gmail_get_thread_v2","gmail_list_drafts_v2","gmail_list_labels_v2","gmail_list_threads_v2","gmail_mark_read","gmail_mark_read_v2","gmail_mark_unread","gmail_mark_unread_v2","gmail_move","gmail_move_v2","gmail_read","gmail_read_v2","gmail_remove_label","gmail_remove_label_v2","gmail_search","gmail_search_v2","gmail_send","gmail_send_v2","gmail_trash_thread_v2","gmail_unarchive","gmail_unarchive_v2","gmail_untrash_thread_v2","gmail_update_label_v2","gong_aggregate_activity","gong_aggregate_by_period","gong_answered_scorecards","gong_ask_anything","gong_assign_flow_prospects","gong_create_call","gong_day_by_day_activity","gong_get_brief","gong_get_call","gong_get_call_transcript","gong_get_coaching","gong_get_extensive_calls","gong_get_folder_content","gong_get_logs","gong_get_prospect_flows","gong_get_user","gong_interaction_stats","gong_list_calls","gong_list_flows","gong_list_library_folders","gong_list_scorecards","gong_list_trackers","gong_list_users","gong_list_workspaces","gong_lookup_email","gong_lookup_phone","gong_purge_email_address","gong_purge_phone_number","gong_unassign_flow_prospects","google_ads_ad_performance","google_ads_campaign_performance","google_ads_list_ad_groups","google_ads_list_campaigns","google_ads_list_customers","google_ads_search","google_appsheet_add_rows","google_appsheet_delete_rows","google_appsheet_edit_rows","google_appsheet_find_rows","google_bigquery_create_dataset","google_bigquery_create_table","google_bigquery_delete_dataset","google_bigquery_delete_table","google_bigquery_get_query_results","google_bigquery_get_table","google_bigquery_insert_rows","google_bigquery_list_datasets","google_bigquery_list_table_data","google_bigquery_list_tables","google_bigquery_query","google_books_volume_details","google_books_volume_search","google_calendar_create","google_calendar_create_calendar","google_calendar_create_calendar_v2","google_calendar_create_v2","google_calendar_delete","google_calendar_delete_calendar","google_calendar_delete_calendar_v2","google_calendar_delete_v2","google_calendar_freebusy","google_calendar_freebusy_v2","google_calendar_get","google_calendar_get_v2","google_calendar_instances","google_calendar_instances_v2","google_calendar_invite","google_calendar_invite_v2","google_calendar_list","google_calendar_list_acl","google_calendar_list_acl_v2","google_calendar_list_calendars","google_calendar_list_calendars_v2","google_calendar_list_v2","google_calendar_move","google_calendar_move_v2","google_calendar_quick_add","google_calendar_quick_add_v2","google_calendar_respond","google_calendar_respond_v2","google_calendar_share_calendar","google_calendar_share_calendar_v2","google_calendar_unshare_calendar","google_calendar_unshare_calendar_v2","google_calendar_update","google_calendar_update_acl","google_calendar_update_acl_v2","google_calendar_update_calendar","google_calendar_update_calendar_v2","google_calendar_update_v2","google_contacts_create","google_contacts_delete","google_contacts_get","google_contacts_list","google_contacts_search","google_contacts_update","google_docs_create","google_docs_create_named_range","google_docs_create_paragraph_bullets","google_docs_delete_content_range","google_docs_delete_named_range","google_docs_delete_paragraph_bullets","google_docs_insert_image","google_docs_insert_page_break","google_docs_insert_table","google_docs_insert_text","google_docs_read","google_docs_replace_text","google_docs_update_paragraph_style","google_docs_update_text_style","google_docs_write","google_drive_copy","google_drive_create_comment","google_drive_create_folder","google_drive_delete","google_drive_delete_comment","google_drive_download","google_drive_export","google_drive_get_about","google_drive_get_content","google_drive_get_file","google_drive_get_revision","google_drive_list","google_drive_list_comments","google_drive_list_permissions","google_drive_list_revisions","google_drive_move","google_drive_search","google_drive_share","google_drive_trash","google_drive_unshare","google_drive_untrash","google_drive_update","google_drive_upload","google_forms_batch_update","google_forms_create_form","google_forms_create_watch","google_forms_delete_watch","google_forms_get_form","google_forms_get_responses","google_forms_list_watches","google_forms_renew_watch","google_forms_set_publish_settings","google_groups_add_alias","google_groups_add_member","google_groups_create_group","google_groups_delete_group","google_groups_get_group","google_groups_get_member","google_groups_get_settings","google_groups_has_member","google_groups_list_aliases","google_groups_list_groups","google_groups_list_members","google_groups_remove_alias","google_groups_remove_member","google_groups_update_group","google_groups_update_member","google_groups_update_settings","google_maps_air_quality","google_maps_directions","google_maps_distance_matrix","google_maps_elevation","google_maps_geocode","google_maps_geolocate","google_maps_place_details","google_maps_places_nearby","google_maps_places_search","google_maps_pollen","google_maps_reverse_geocode","google_maps_snap_to_roads","google_maps_solar","google_maps_speed_limits","google_maps_timezone","google_maps_validate_address","google_meet_create_space","google_meet_end_conference","google_meet_get_conference_record","google_meet_get_space","google_meet_list_conference_records","google_meet_list_participants","google_pagespeed_analyze","google_search","google_sheets_append","google_sheets_append_v2","google_sheets_batch_clear_v2","google_sheets_batch_get_v2","google_sheets_batch_update_v2","google_sheets_clear_v2","google_sheets_copy_sheet_v2","google_sheets_create_spreadsheet_v2","google_sheets_delete_rows_v2","google_sheets_delete_sheet_v2","google_sheets_delete_spreadsheet_v2","google_sheets_get_spreadsheet_v2","google_sheets_read","google_sheets_read_v2","google_sheets_update","google_sheets_update_v2","google_sheets_write","google_sheets_write_v2","google_slides_add_image","google_slides_add_slide","google_slides_batch_update","google_slides_copy_presentation","google_slides_create","google_slides_create_line","google_slides_create_paragraph_bullets","google_slides_create_shape","google_slides_create_sheets_chart","google_slides_create_table","google_slides_create_video","google_slides_delete_object","google_slides_delete_paragraph_bullets","google_slides_delete_table_column","google_slides_delete_table_row","google_slides_delete_text","google_slides_duplicate_object","google_slides_export_presentation","google_slides_get_page","google_slides_get_thumbnail","google_slides_group_objects","google_slides_insert_table_columns","google_slides_insert_table_rows","google_slides_insert_text","google_slides_merge_table_cells","google_slides_read","google_slides_refresh_sheets_chart","google_slides_replace_all_shapes_with_image","google_slides_replace_all_shapes_with_sheets_chart","google_slides_replace_all_text","google_slides_replace_image","google_slides_reroute_line","google_slides_ungroup_objects","google_slides_unmerge_table_cells","google_slides_update_image_properties","google_slides_update_line_category","google_slides_update_line_properties","google_slides_update_page_element_alt_text","google_slides_update_page_element_transform","google_slides_update_page_elements_z_order","google_slides_update_page_properties","google_slides_update_paragraph_style","google_slides_update_shape_properties","google_slides_update_slide_properties","google_slides_update_slides_position","google_slides_update_table_border_properties","google_slides_update_table_cell_properties","google_slides_update_table_column_properties","google_slides_update_table_row_properties","google_slides_update_text_style","google_slides_update_video_properties","google_slides_write","google_tasks_create","google_tasks_delete","google_tasks_get","google_tasks_list","google_tasks_list_task_lists","google_tasks_update","google_translate_detect","google_translate_text","google_vault_add_held_accounts","google_vault_add_matters_permissions","google_vault_close_matters","google_vault_create_matters","google_vault_create_matters_export","google_vault_create_matters_holds","google_vault_create_saved_query","google_vault_delete_matters","google_vault_delete_matters_export","google_vault_delete_matters_holds","google_vault_delete_saved_query","google_vault_download_export_file","google_vault_list_matters","google_vault_list_matters_export","google_vault_list_matters_holds","google_vault_list_saved_queries","google_vault_remove_held_accounts","google_vault_remove_matters_permissions","google_vault_reopen_matters","google_vault_undelete_matters","google_vault_update_matters","google_vault_update_matters_holds","grafana_check_data_source_health","grafana_create_alert_rule","grafana_create_annotation","grafana_create_contact_point","grafana_create_dashboard","grafana_create_folder","grafana_delete_alert_rule","grafana_delete_annotation","grafana_delete_contact_point","grafana_delete_dashboard","grafana_delete_folder","grafana_get_alert_rule","grafana_get_alert_rule_group","grafana_get_dashboard","grafana_get_data_source","grafana_get_folder","grafana_get_health","grafana_list_alert_rules","grafana_list_annotations","grafana_list_contact_points","grafana_list_dashboards","grafana_list_data_sources","grafana_list_folders","grafana_move_folder","grafana_query_data_source","grafana_update_alert_rule","grafana_update_annotation","grafana_update_contact_point","grafana_update_dashboard","grafana_update_folder","grain_create_hook","grain_create_hook_v2","grain_delete_hook","grain_delete_hook_v2","grain_get_recording","grain_get_transcript","grain_list_hooks","grain_list_hooks_v2","grain_list_meeting_types","grain_list_recordings","grain_list_teams","grain_list_views","granola_create_webhook_endpoint","granola_delete_webhook_endpoint","granola_get_note","granola_get_transcript","granola_list_audit_events","granola_list_folders","granola_list_notes","granola_list_webhook_endpoints","granola_update_webhook_endpoint","greenhouse_get_application","greenhouse_get_candidate","greenhouse_get_job","greenhouse_get_user","greenhouse_list_applications","greenhouse_list_candidates","greenhouse_list_departments","greenhouse_list_job_stages","greenhouse_list_jobs","greenhouse_list_offices","greenhouse_list_users","greptile_index_repo","greptile_query","greptile_search","greptile_status","guardrails_validate","harmonic_batch_get_people","harmonic_clear_people_saved_search_net_new_results","harmonic_enrich_person","harmonic_get_company_employees","harmonic_get_email_enrichment_job","harmonic_get_email_enrichment_usage","harmonic_get_enrichment_status","harmonic_get_people_saved_search_net_new_results","harmonic_get_people_saved_search_results","harmonic_get_person","harmonic_list_people_saved_searches","harmonic_search_people_scout","harmonic_submit_email_enrichment_job","hex_cancel_run","hex_create_collection","hex_create_group","hex_deactivate_user","hex_delete_group","hex_get_collection","hex_get_data_connection","hex_get_group","hex_get_project","hex_get_project_runs","hex_get_queried_tables","hex_get_run_status","hex_list_collections","hex_list_data_connections","hex_list_groups","hex_list_projects","hex_list_users","hex_run_project","hex_update_collection","hex_update_group","hex_update_project","http_request","hubspot_add_list_memberships","hubspot_create_appointment","hubspot_create_association","hubspot_create_company","hubspot_create_contact","hubspot_create_deal","hubspot_create_email","hubspot_create_line_item","hubspot_create_list","hubspot_create_note","hubspot_create_ticket","hubspot_delete_association","hubspot_delete_company","hubspot_delete_contact","hubspot_delete_deal","hubspot_delete_line_item","hubspot_delete_ticket","hubspot_get_appointment","hubspot_get_association_labels","hubspot_get_cart","hubspot_get_company","hubspot_get_contact","hubspot_get_deal","hubspot_get_email","hubspot_get_line_item","hubspot_get_list","hubspot_get_list_memberships","hubspot_get_marketing_event","hubspot_get_note","hubspot_get_properties","hubspot_get_quote","hubspot_get_ticket","hubspot_get_users","hubspot_list_appointments","hubspot_list_associations","hubspot_list_carts","hubspot_list_companies","hubspot_list_contacts","hubspot_list_deals","hubspot_list_emails","hubspot_list_line_items","hubspot_list_lists","hubspot_list_marketing_events","hubspot_list_notes","hubspot_list_owners","hubspot_list_quotes","hubspot_list_tickets","hubspot_remove_list_memberships","hubspot_search_companies","hubspot_search_contacts","hubspot_search_deals","hubspot_search_emails","hubspot_search_line_items","hubspot_search_notes","hubspot_search_quotes","hubspot_search_tickets","hubspot_update_appointment","hubspot_update_company","hubspot_update_contact","hubspot_update_deal","hubspot_update_line_item","hubspot_update_ticket","huggingface_chat","hunter_companies_find","hunter_discover","hunter_domain_search","hunter_email_count","hunter_email_finder","hunter_email_verifier","iam_add_user_to_group","iam_attach_role_policy","iam_attach_user_policy","iam_create_access_key","iam_create_role","iam_create_user","iam_delete_access_key","iam_delete_role","iam_delete_user","iam_detach_role_policy","iam_detach_user_policy","iam_get_policy","iam_get_role","iam_get_user","iam_list_access_keys","iam_list_attached_role_policies","iam_list_attached_user_policies","iam_list_groups","iam_list_policies","iam_list_roles","iam_list_users","iam_remove_user_from_group","iam_simulate_principal_policy","iam_update_access_key","icypeas_find_email","icypeas_verify_email","identity_center_check_assignment_deletion_status","identity_center_check_assignment_status","identity_center_create_account_assignment","identity_center_delete_account_assignment","identity_center_describe_account","identity_center_describe_group","identity_center_describe_user","identity_center_get_group","identity_center_get_user","identity_center_list_account_assignments","identity_center_list_accounts","identity_center_list_assignments_for_account","identity_center_list_group_memberships","identity_center_list_groups","identity_center_list_instances","identity_center_list_permission_sets","image_generate","incidentio_actions_create","incidentio_actions_list","incidentio_actions_show","incidentio_actions_update","incidentio_alert_events_create","incidentio_alerts_list","incidentio_alerts_resolve","incidentio_alerts_show","incidentio_catalog_entries_list","incidentio_catalog_types_list","incidentio_custom_fields_create","incidentio_custom_fields_delete","incidentio_custom_fields_list","incidentio_custom_fields_show","incidentio_custom_fields_update","incidentio_escalation_paths_create","incidentio_escalation_paths_delete","incidentio_escalation_paths_list","incidentio_escalation_paths_show","incidentio_escalation_paths_update","incidentio_escalations_cancel","incidentio_escalations_create","incidentio_escalations_list","incidentio_escalations_show","incidentio_follow_ups_create","incidentio_follow_ups_list","incidentio_follow_ups_show","incidentio_follow_ups_update","incidentio_incident_alerts_list","incidentio_incident_memberships_create","incidentio_incident_memberships_revoke","incidentio_incident_participants_list","incidentio_incident_roles_create","incidentio_incident_roles_delete","incidentio_incident_roles_list","incidentio_incident_roles_show","incidentio_incident_roles_update","incidentio_incident_statuses_list","incidentio_incident_timestamps_list","incidentio_incident_timestamps_show","incidentio_incident_types_list","incidentio_incident_updates_list","incidentio_incidents_create","incidentio_incidents_list","incidentio_incidents_show","incidentio_incidents_update","incidentio_on_call_now","incidentio_schedule_entries_list","incidentio_schedule_overrides_create","incidentio_schedule_overrides_list","incidentio_schedules_create","incidentio_schedules_delete","incidentio_schedules_list","incidentio_schedules_show","incidentio_schedules_update","incidentio_severities_list","incidentio_teams_list","incidentio_teams_show","incidentio_users_list","incidentio_users_show","incidentio_workflows_create","incidentio_workflows_delete","incidentio_workflows_list","incidentio_workflows_show","incidentio_workflows_update","infisical_create_secret","infisical_delete_secret","infisical_get_secret","infisical_list_secrets","infisical_update_secret","instagram_delete_comment","instagram_download_media","instagram_get_account_insights","instagram_get_container_status","instagram_get_conversation_messages","instagram_get_media","instagram_get_media_insights","instagram_get_message","instagram_get_profile","instagram_get_publishing_limit","instagram_hide_comment","instagram_list_comments","instagram_list_conversations","instagram_list_media","instagram_list_stories","instagram_private_reply","instagram_publish_carousel","instagram_publish_image","instagram_publish_reel","instagram_publish_story","instagram_publish_video","instagram_reply_to_comment","instagram_send_text_message","instagram_set_comments_enabled","instantly_activate_campaign","instantly_create_campaign","instantly_create_lead","instantly_create_lead_list","instantly_delete_campaign","instantly_delete_leads","instantly_get_lead","instantly_list_campaigns","instantly_list_emails","instantly_list_lead_lists","instantly_list_leads","instantly_patch_campaign","instantly_patch_lead","instantly_pause_campaign","instantly_reply_to_email","instantly_update_lead_interest_status","intercom_assign_conversation_v2","intercom_attach_contact_to_company_v2","intercom_close_conversation_v2","intercom_create_company","intercom_create_company_v2","intercom_create_contact","intercom_create_contact_v2","intercom_create_event_v2","intercom_create_message","intercom_create_message_v2","intercom_create_note_v2","intercom_create_tag_v2","intercom_create_ticket","intercom_create_ticket_v2","intercom_delete_contact","intercom_delete_contact_v2","intercom_detach_contact_from_company_v2","intercom_get_company","intercom_get_company_v2","intercom_get_contact","intercom_get_contact_v2","intercom_get_conversation","intercom_get_conversation_v2","intercom_get_ticket","intercom_get_ticket_v2","intercom_list_admins_v2","intercom_list_companies","intercom_list_companies_v2","intercom_list_contacts","intercom_list_contacts_v2","intercom_list_conversations","intercom_list_conversations_v2","intercom_list_tags_v2","intercom_open_conversation_v2","intercom_reply_conversation","intercom_reply_conversation_v2","intercom_search_contacts","intercom_search_contacts_v2","intercom_search_conversations","intercom_search_conversations_v2","intercom_snooze_conversation_v2","intercom_tag_contact_v2","intercom_tag_conversation_v2","intercom_untag_contact_v2","intercom_update_contact","intercom_update_contact_v2","intercom_update_ticket_v2","intune_get_compliance_policy","intune_get_detected_app","intune_get_device","intune_get_device_configuration","intune_list_app_devices","intune_list_compliance_policies","intune_list_compliance_policy_device_statuses","intune_list_detected_apps","intune_list_device_configurations","intune_list_devices","intune_reboot_device","intune_remote_lock_device","intune_retire_device","intune_sync_device","jina_read_url","jina_search","jira_add_attachment","jira_add_comment","jira_add_watcher","jira_add_worklog","jira_assign_issue","jira_bulk_read","jira_create_issue_link","jira_delete_attachment","jira_delete_comment","jira_delete_issue","jira_delete_issue_link","jira_delete_worklog","jira_get_attachments","jira_get_comments","jira_get_fields","jira_get_project","jira_get_transitions","jira_get_users","jira_get_worklogs","jira_list_issue_types","jira_list_projects","jira_remove_watcher","jira_retrieve","jira_search_issues","jira_search_users","jira_transition_issue","jira_update","jira_update_comment","jira_update_worklog","jira_write","jotform_add_label_resources","jotform_clone_form","jotform_create_form","jotform_create_label","jotform_create_question","jotform_create_questions","jotform_create_report","jotform_create_submission","jotform_create_submissions","jotform_create_webhook","jotform_delete_form","jotform_delete_label","jotform_delete_question","jotform_delete_report","jotform_delete_submission","jotform_delete_webhook","jotform_get_form","jotform_get_form_properties","jotform_get_history","jotform_get_label","jotform_get_question","jotform_get_report","jotform_get_settings","jotform_get_submission","jotform_get_usage","jotform_get_user","jotform_list_form_files","jotform_list_form_reports","jotform_list_form_submissions","jotform_list_forms","jotform_list_label_resources","jotform_list_labels","jotform_list_questions","jotform_list_reports","jotform_list_submissions","jotform_list_subusers","jotform_list_webhooks","jotform_remove_label_resources","jotform_update_form_properties","jotform_update_label","jotform_update_question","jotform_update_settings","jotform_update_submission","jsm_add_comment","jsm_add_customer","jsm_add_organization","jsm_add_participants","jsm_answer_approval","jsm_attach_form","jsm_copy_forms","jsm_create_object","jsm_create_organization","jsm_create_request","jsm_delete_form","jsm_delete_object","jsm_externalise_form","jsm_get_approvals","jsm_get_comments","jsm_get_customers","jsm_get_form","jsm_get_form_answers","jsm_get_form_structure","jsm_get_form_templates","jsm_get_issue_forms","jsm_get_object","jsm_get_object_schema","jsm_get_object_type_attributes","jsm_get_organizations","jsm_get_participants","jsm_get_queues","jsm_get_request","jsm_get_request_type_fields","jsm_get_request_types","jsm_get_requests","jsm_get_service_desks","jsm_get_sla","jsm_get_transitions","jsm_internalise_form","jsm_list_object_schemas","jsm_list_object_types","jsm_reopen_form","jsm_save_form_answers","jsm_search_objects_aql","jsm_submit_form","jsm_transition_request","jsm_update_object","jupyter_copy_content","jupyter_create_file","jupyter_create_session","jupyter_delete_content","jupyter_delete_session","jupyter_get_content","jupyter_get_content_v2","jupyter_interrupt_kernel","jupyter_list_contents","jupyter_list_kernels","jupyter_list_kernelspecs","jupyter_list_sessions","jupyter_rename_content","jupyter_restart_kernel","jupyter_start_kernel","jupyter_stop_kernel","jupyter_upload_file","kalshi_amend_order","kalshi_amend_order_v2","kalshi_cancel_order","kalshi_cancel_order_v2","kalshi_create_order","kalshi_create_order_v2","kalshi_get_balance","kalshi_get_balance_v2","kalshi_get_candlesticks","kalshi_get_candlesticks_v2","kalshi_get_event","kalshi_get_event_candlesticks","kalshi_get_event_candlesticks_v2","kalshi_get_event_v2","kalshi_get_events","kalshi_get_events_v2","kalshi_get_exchange_announcements","kalshi_get_exchange_announcements_v2","kalshi_get_exchange_schedule","kalshi_get_exchange_schedule_v2","kalshi_get_exchange_status","kalshi_get_exchange_status_v2","kalshi_get_fills","kalshi_get_fills_v2","kalshi_get_market","kalshi_get_market_v2","kalshi_get_markets","kalshi_get_markets_v2","kalshi_get_order","kalshi_get_order_v2","kalshi_get_orderbook","kalshi_get_orderbook_v2","kalshi_get_orders","kalshi_get_orders_v2","kalshi_get_positions","kalshi_get_positions_v2","kalshi_get_series_by_ticker","kalshi_get_series_by_ticker_v2","kalshi_get_series_list","kalshi_get_series_list_v2","kalshi_get_settlements","kalshi_get_settlements_v2","kalshi_get_trades","kalshi_get_trades_v2","ketch_get_consent","ketch_get_subscriptions","ketch_invoke_right","ketch_set_consent","ketch_set_subscriptions","knowledge_create_document","knowledge_delete_chunk","knowledge_delete_document","knowledge_get_connector","knowledge_get_document","knowledge_list_chunks","knowledge_list_connectors","knowledge_list_documents","knowledge_list_tags","knowledge_search","knowledge_trigger_sync","knowledge_update_chunk","knowledge_upload_chunk","knowledge_upsert_document","lambda_add_permission","lambda_create_alias","lambda_create_event_source_mapping","lambda_create_function","lambda_create_function_url_config","lambda_delete_alias","lambda_delete_event_source_mapping","lambda_delete_function","lambda_delete_function_concurrency","lambda_delete_function_event_invoke_config","lambda_delete_function_url_config","lambda_delete_provisioned_concurrency_config","lambda_get_account_settings","lambda_get_alias","lambda_get_event_source_mapping","lambda_get_function","lambda_get_function_concurrency","lambda_get_function_configuration","lambda_get_function_event_invoke_config","lambda_get_function_recursion_config","lambda_get_function_url_config","lambda_get_layer_version","lambda_get_policy","lambda_get_provisioned_concurrency_config","lambda_get_runtime_management_config","lambda_invoke","lambda_list_aliases","lambda_list_event_source_mappings","lambda_list_function_event_invoke_configs","lambda_list_function_url_configs","lambda_list_functions","lambda_list_layer_versions","lambda_list_layers","lambda_list_provisioned_concurrency_configs","lambda_list_tags","lambda_list_versions_by_function","lambda_publish_version","lambda_put_function_concurrency","lambda_put_function_event_invoke_config","lambda_put_function_recursion_config","lambda_put_provisioned_concurrency_config","lambda_put_runtime_management_config","lambda_remove_permission","lambda_tag_resource","lambda_untag_resource","lambda_update_alias","lambda_update_event_source_mapping","lambda_update_function_code","lambda_update_function_configuration","lambda_update_function_url_config","langsmith_create_feedback","langsmith_create_run","langsmith_create_runs_batch","langsmith_get_run","langsmith_update_run","latex_compile","latex_get_package","latex_list_fonts","latex_search_packages","launchdarkly_create_flag","launchdarkly_delete_flag","launchdarkly_get_audit_log","launchdarkly_get_flag","launchdarkly_get_flag_status","launchdarkly_list_environments","launchdarkly_list_flags","launchdarkly_list_members","launchdarkly_list_projects","launchdarkly_list_segments","launchdarkly_toggle_flag","launchdarkly_update_flag","leadmagic_company_search","leadmagic_email_to_profile","leadmagic_find_email","leadmagic_find_mobile","leadmagic_get_credits","leadmagic_profile_search","leadmagic_profile_to_email","leadmagic_role_finder","leadmagic_validate_email","lemlist_get_activities","lemlist_get_lead","lemlist_send_email","linear_add_label_to_issue","linear_add_label_to_project","linear_archive_issue","linear_archive_label","linear_archive_project","linear_create_attachment","linear_create_comment","linear_create_customer","linear_create_customer_request","linear_create_customer_status","linear_create_customer_tier","linear_create_cycle","linear_create_favorite","linear_create_issue","linear_create_issue_relation","linear_create_label","linear_create_project","linear_create_project_label","linear_create_project_milestone","linear_create_project_status","linear_create_project_update","linear_create_workflow_state","linear_delete_attachment","linear_delete_comment","linear_delete_customer","linear_delete_customer_status","linear_delete_customer_tier","linear_delete_issue","linear_delete_issue_relation","linear_delete_project","linear_delete_project_label","linear_delete_project_milestone","linear_delete_project_status","linear_get_active_cycle","linear_get_customer","linear_get_cycle","linear_get_issue","linear_get_project","linear_get_viewer","linear_list_attachments","linear_list_comments","linear_list_customer_requests","linear_list_customer_statuses","linear_list_customer_tiers","linear_list_customers","linear_list_cycles","linear_list_favorites","linear_list_issue_relations","linear_list_labels","linear_list_notifications","linear_list_project_labels","linear_list_project_milestones","linear_list_project_statuses","linear_list_project_updates","linear_list_projects","linear_list_teams","linear_list_users","linear_list_workflow_states","linear_merge_customers","linear_read_issues","linear_remove_label_from_issue","linear_remove_label_from_project","linear_search_issues","linear_unarchive_issue","linear_update_attachment","linear_update_comment","linear_update_customer","linear_update_customer_request","linear_update_customer_status","linear_update_customer_tier","linear_update_issue","linear_update_label","linear_update_notification","linear_update_project","linear_update_project_label","linear_update_project_milestone","linear_update_project_status","linear_update_workflow_state","linkedin_get_profile","linkedin_share_post","linkup_search","linq_add_participant","linq_check_imessage","linq_check_rcs","linq_create_attachment","linq_create_chat","linq_create_contact_card","linq_create_webhook_subscription","linq_delete_attachment","linq_delete_message","linq_delete_webhook_subscription","linq_edit_message","linq_get_attachment","linq_get_chat","linq_get_contact_card","linq_get_message","linq_get_webhook_subscription","linq_leave_chat","linq_list_chats","linq_list_messages","linq_list_phone_numbers","linq_list_thread","linq_list_webhook_events","linq_list_webhook_subscriptions","linq_mark_chat_read","linq_react_to_message","linq_remove_participant","linq_send_message","linq_send_voice_memo","linq_share_contact_card","linq_start_typing","linq_stop_typing","linq_update_chat","linq_update_contact_card","linq_update_webhook_subscription","llm_chat","logfire_get_token_info","logfire_get_trace","logfire_query","logfire_search_records","logrocket_create_release","logrocket_get_audit_logs","logrocket_get_highlights","logrocket_identify_user","logrocket_list_exported_sessions","logrocket_request_highlights","logs_get","logs_get_execution","logs_get_run_details","logs_query","logs_query_runs","loops_check_contact_suppression","loops_create_contact","loops_create_contact_property","loops_delete_contact","loops_find_contact","loops_get_transactional_email","loops_list_contact_properties","loops_list_mailing_lists","loops_list_transactional_emails","loops_remove_contact_suppression","loops_send_event","loops_send_transactional_email","loops_update_contact","luma_add_guests","luma_cancel_event","luma_create_event","luma_get_event","luma_get_guest","luma_get_guests","luma_list_events","luma_lookup_event","luma_send_invites","luma_update_event","luma_update_guest_status","mailchimp_add_member","mailchimp_add_member_tags","mailchimp_add_or_update_member","mailchimp_add_segment_member","mailchimp_add_subscriber_to_automation","mailchimp_archive_member","mailchimp_create_audience","mailchimp_create_batch_operation","mailchimp_create_campaign","mailchimp_create_interest","mailchimp_create_interest_category","mailchimp_create_landing_page","mailchimp_create_merge_field","mailchimp_create_segment","mailchimp_create_template","mailchimp_delete_audience","mailchimp_delete_batch_operation","mailchimp_delete_campaign","mailchimp_delete_interest","mailchimp_delete_interest_category","mailchimp_delete_landing_page","mailchimp_delete_member","mailchimp_delete_merge_field","mailchimp_delete_segment","mailchimp_delete_template","mailchimp_get_audience","mailchimp_get_audiences","mailchimp_get_automation","mailchimp_get_automations","mailchimp_get_batch_operation","mailchimp_get_batch_operations","mailchimp_get_campaign","mailchimp_get_campaign_content","mailchimp_get_campaign_report","mailchimp_get_campaign_reports","mailchimp_get_campaigns","mailchimp_get_interest","mailchimp_get_interest_categories","mailchimp_get_interest_category","mailchimp_get_interests","mailchimp_get_landing_page","mailchimp_get_landing_pages","mailchimp_get_member","mailchimp_get_member_tags","mailchimp_get_members","mailchimp_get_merge_field","mailchimp_get_merge_fields","mailchimp_get_segment","mailchimp_get_segment_members","mailchimp_get_segments","mailchimp_get_template","mailchimp_get_templates","mailchimp_pause_automation","mailchimp_publish_landing_page","mailchimp_remove_member_tags","mailchimp_remove_segment_member","mailchimp_replicate_campaign","mailchimp_schedule_campaign","mailchimp_send_campaign","mailchimp_set_campaign_content","mailchimp_start_automation","mailchimp_unarchive_member","mailchimp_unpublish_landing_page","mailchimp_unschedule_campaign","mailchimp_update_audience","mailchimp_update_campaign","mailchimp_update_interest","mailchimp_update_interest_category","mailchimp_update_landing_page","mailchimp_update_member","mailchimp_update_merge_field","mailchimp_update_segment","mailchimp_update_template","mailgun_add_list_member","mailgun_create_mailing_list","mailgun_get_domain","mailgun_get_mailing_list","mailgun_get_message","mailgun_list_domains","mailgun_list_messages","mailgun_send_message","managed_agent_archive_session","managed_agent_create_session","managed_agent_delete_session","managed_agent_get_session","managed_agent_interrupt_session","managed_agent_list_events","managed_agent_respond_custom_tool","managed_agent_respond_tool_confirmation","managed_agent_run_session","managed_agent_send_message","managed_agent_update_session","manageengine_sdp_add_change_note","manageengine_sdp_add_problem_note","manageengine_sdp_add_request_note","manageengine_sdp_create_asset","manageengine_sdp_create_change","manageengine_sdp_create_problem","manageengine_sdp_create_request","manageengine_sdp_create_solution","manageengine_sdp_delete_asset","manageengine_sdp_delete_change","manageengine_sdp_delete_problem","manageengine_sdp_delete_request","manageengine_sdp_delete_solution","manageengine_sdp_get_asset","manageengine_sdp_get_change","manageengine_sdp_get_problem","manageengine_sdp_get_request","manageengine_sdp_get_solution","manageengine_sdp_list_assets","manageengine_sdp_list_change_notes","manageengine_sdp_list_changes","manageengine_sdp_list_problem_notes","manageengine_sdp_list_problems","manageengine_sdp_list_request_notes","manageengine_sdp_list_requests","manageengine_sdp_list_solutions","manageengine_sdp_update_asset","manageengine_sdp_update_change","manageengine_sdp_update_problem","manageengine_sdp_update_request","manageengine_sdp_update_solution","mcp_list_operations","mcp_run_operation","mem0_add_memories","mem0_get_memories","mem0_search_memories","memory_add","memory_delete","memory_get","memory_get_all","microsoft_ad_add_directory_role_member","microsoft_ad_add_group_member","microsoft_ad_add_user_app_role_assignment","microsoft_ad_assign_license","microsoft_ad_create_group","microsoft_ad_create_user","microsoft_ad_delete_group","microsoft_ad_delete_user","microsoft_ad_get_conditional_access_policy","microsoft_ad_get_device","microsoft_ad_get_group","microsoft_ad_get_user","microsoft_ad_list_authentication_methods","microsoft_ad_list_conditional_access_policies","microsoft_ad_list_devices","microsoft_ad_list_directory_audits","microsoft_ad_list_directory_role_members","microsoft_ad_list_directory_roles","microsoft_ad_list_group_members","microsoft_ad_list_groups","microsoft_ad_list_service_principal_app_role_assignments","microsoft_ad_list_service_principals","microsoft_ad_list_sign_ins","microsoft_ad_list_subscribed_skus","microsoft_ad_list_user_app_role_assignments","microsoft_ad_list_user_devices","microsoft_ad_list_user_licenses","microsoft_ad_list_users","microsoft_ad_remove_directory_role_member","microsoft_ad_remove_group_member","microsoft_ad_remove_user_app_role_assignment","microsoft_ad_reset_password","microsoft_ad_revoke_sign_in_sessions","microsoft_ad_set_password","microsoft_ad_update_group","microsoft_ad_update_user","microsoft_dataverse_associate","microsoft_dataverse_create_multiple","microsoft_dataverse_create_record","microsoft_dataverse_delete_record","microsoft_dataverse_disassociate","microsoft_dataverse_download_file","microsoft_dataverse_download_file_v2","microsoft_dataverse_execute_action","microsoft_dataverse_execute_function","microsoft_dataverse_fetchxml_query","microsoft_dataverse_get_entity_metadata","microsoft_dataverse_get_record","microsoft_dataverse_list_records","microsoft_dataverse_search","microsoft_dataverse_update_multiple","microsoft_dataverse_update_record","microsoft_dataverse_upload_file","microsoft_dataverse_upsert_record","microsoft_dataverse_whoami","microsoft_dynamics_365_close_case","microsoft_dynamics_365_close_opportunity","microsoft_dynamics_365_create_record","microsoft_dynamics_365_get_record","microsoft_dynamics_365_list_records","microsoft_dynamics_365_qualify_lead","microsoft_dynamics_365_search_records","microsoft_dynamics_365_update_record","microsoft_excel_clear_range","microsoft_excel_create_table","microsoft_excel_delete_worksheet","microsoft_excel_format_range","microsoft_excel_read","microsoft_excel_read_v2","microsoft_excel_sort_range","microsoft_excel_table_add","microsoft_excel_worksheet_add","microsoft_excel_write","microsoft_excel_write_v2","microsoft_planner_create_bucket","microsoft_planner_create_plan","microsoft_planner_create_task","microsoft_planner_delete_bucket","microsoft_planner_delete_plan","microsoft_planner_delete_task","microsoft_planner_get_plan_details","microsoft_planner_get_task_details","microsoft_planner_list_buckets","microsoft_planner_list_plans","microsoft_planner_read_bucket","microsoft_planner_read_plan","microsoft_planner_read_task","microsoft_planner_update_bucket","microsoft_planner_update_plan","microsoft_planner_update_plan_details","microsoft_planner_update_task","microsoft_planner_update_task_details","microsoft_teams_delete_channel_message","microsoft_teams_delete_chat_message","microsoft_teams_get_message","microsoft_teams_list_channel_members","microsoft_teams_list_channels","microsoft_teams_list_chat_members","microsoft_teams_list_chats","microsoft_teams_list_team_members","microsoft_teams_list_teams","microsoft_teams_read_channel","microsoft_teams_read_chat","microsoft_teams_reply_to_message","microsoft_teams_set_reaction","microsoft_teams_unset_reaction","microsoft_teams_update_channel_message","microsoft_teams_update_chat_message","microsoft_teams_write_channel","microsoft_teams_write_chat","microsoft_word_append","microsoft_word_create","microsoft_word_create_from_template","microsoft_word_export_pdf","microsoft_word_list","microsoft_word_read","microsoft_word_replace_text","microsoft_word_update","millionverifier_get_credits","millionverifier_verify_email","mintlify_create_agent_job","mintlify_create_assistant_message","mintlify_detect_ai_prose","mintlify_get_agent_job","mintlify_get_assistant_caller_stats","mintlify_get_assistant_conversations","mintlify_get_feedback","mintlify_get_feedback_by_page","mintlify_get_page_content","mintlify_get_searches","mintlify_get_update_status","mintlify_get_views","mintlify_get_visitors","mintlify_search","mintlify_send_agent_message","mintlify_trigger_automation","mintlify_trigger_preview","mintlify_trigger_update","mistral_parser","mistral_parser_v2","mistral_parser_v3","modal_call_function","modal_chat_completion","modal_list_models","monday_archive_item","monday_change_column_value","monday_create_board","monday_create_column","monday_create_group","monday_create_item","monday_create_subitem","monday_create_update","monday_delete_item","monday_duplicate_item","monday_get_board","monday_get_groups","monday_get_item","monday_get_items","monday_list_boards","monday_move_item_to_group","monday_search_items","monday_update_item","mongodb_delete","mongodb_execute","mongodb_insert","mongodb_introspect","mongodb_query","mongodb_update","mssql_delete","mssql_execute","mssql_insert","mssql_introspect","mssql_query","mssql_update","mysql_delete","mysql_execute","mysql_insert","mysql_introspect","mysql_query","mysql_update","neo4j_create","neo4j_delete","neo4j_execute","neo4j_introspect","neo4j_merge","neo4j_query","neo4j_update","netsuite_attach_record","netsuite_batch_create_records","netsuite_batch_delete_records","netsuite_batch_get_records","netsuite_batch_update_records","netsuite_batch_upsert_records","netsuite_create_record","netsuite_delete_record","netsuite_detach_record","netsuite_execute_action","netsuite_execute_dataset","netsuite_execute_suiteql","netsuite_get_async_result","netsuite_get_async_status","netsuite_get_governance_limits","netsuite_get_record","netsuite_get_record_form","netsuite_get_record_metadata","netsuite_get_select_options","netsuite_get_server_time","netsuite_get_subresource","netsuite_list_datasets","netsuite_list_record_types","netsuite_list_records","netsuite_transform_record","netsuite_update_record","netsuite_upsert_record","neverbounce_get_credits","neverbounce_verify_email","new_relic_create_deployment_event","new_relic_get_entity","new_relic_nrql_query","new_relic_search_entities","notion_add_database_row","notion_add_database_row_v2","notion_append_blocks","notion_append_blocks_v2","notion_create_comment","notion_create_comment_v2","notion_create_database","notion_create_database_v2","notion_create_page","notion_create_page_v2","notion_delete_block","notion_delete_block_v2","notion_list_comments","notion_list_comments_v2","notion_list_users","notion_list_users_v2","notion_query_database","notion_query_database_v2","notion_read","notion_read_database","notion_read_database_v2","notion_read_v2","notion_retrieve_block","notion_retrieve_block_children","notion_retrieve_block_children_v2","notion_retrieve_block_v2","notion_retrieve_user","notion_retrieve_user_v2","notion_search","notion_search_v2","notion_update_block","notion_update_block_v2","notion_update_page","notion_update_page_v2","notion_write","notion_write_v2","obsidian_append_active","obsidian_append_note","obsidian_append_periodic_note","obsidian_create_note","obsidian_delete_note","obsidian_execute_command","obsidian_get_active","obsidian_get_note","obsidian_get_periodic_note","obsidian_list_commands","obsidian_list_files","obsidian_open_file","obsidian_patch_active","obsidian_patch_note","obsidian_search","okta_activate_group_rule","okta_activate_user","okta_add_user_to_group","okta_assign_group_to_app","okta_assign_user_role","okta_assign_user_to_app","okta_clear_user_sessions","okta_create_group","okta_create_group_rule","okta_create_user","okta_deactivate_group_rule","okta_deactivate_user","okta_delete_group","okta_delete_group_rule","okta_delete_user","okta_enroll_factor","okta_get_app","okta_get_factor","okta_get_group","okta_get_group_rule","okta_get_logs","okta_get_session","okta_get_user","okta_list_app_groups","okta_list_app_users","okta_list_apps","okta_list_factors","okta_list_group_members","okta_list_group_rules","okta_list_groups","okta_list_user_roles","okta_list_users","okta_remove_group_from_app","okta_remove_user_from_app","okta_remove_user_from_group","okta_remove_user_role","okta_reset_all_factors","okta_reset_factor","okta_reset_password","okta_revoke_session","okta_suspend_user","okta_unsuspend_user","okta_update_group","okta_update_user","onedrive_copy","onedrive_create_folder","onedrive_create_share_link","onedrive_delete","onedrive_download","onedrive_get_drive_info","onedrive_get_item","onedrive_list","onedrive_move","onedrive_search","onedrive_upload","onepassword_create_item","onepassword_delete_item","onepassword_get_item","onepassword_get_item_file","onepassword_get_vault","onepassword_list_items","onepassword_list_vaults","onepassword_replace_item","onepassword_resolve_secret","onepassword_update_item","openai_embeddings","openai_image","oracle_fusion_financials_apply_receivables_receipt","oracle_fusion_financials_approve_receivables_invoice","oracle_fusion_financials_create_expense_line","oracle_fusion_financials_create_expense_report","oracle_fusion_financials_create_receivables_credit_memo","oracle_fusion_financials_create_receivables_invoice","oracle_fusion_financials_create_receivables_receipt","oracle_fusion_financials_get_expense_line","oracle_fusion_financials_get_expense_report","oracle_fusion_financials_get_gl_journal_batch","oracle_fusion_financials_get_gl_ledger","oracle_fusion_financials_get_payables_invoice","oracle_fusion_financials_get_payables_invoice_line","oracle_fusion_financials_get_payables_payment","oracle_fusion_financials_get_receivables_credit_memo","oracle_fusion_financials_get_receivables_invoice","oracle_fusion_financials_get_receivables_invoice_installment","oracle_fusion_financials_get_receivables_invoice_line","oracle_fusion_financials_get_receivables_receipt","oracle_fusion_financials_list_expense_lines","oracle_fusion_financials_list_expense_reports","oracle_fusion_financials_list_gl_balances","oracle_fusion_financials_list_gl_journal_batches","oracle_fusion_financials_list_gl_ledgers","oracle_fusion_financials_list_payables_invoice_lines","oracle_fusion_financials_list_payables_invoices","oracle_fusion_financials_list_payables_payments","oracle_fusion_financials_list_receivables_credit_memos","oracle_fusion_financials_list_receivables_invoice_installments","oracle_fusion_financials_list_receivables_invoice_lines","oracle_fusion_financials_list_receivables_invoices","oracle_fusion_financials_list_receivables_receipts","oracle_fusion_financials_submit_expense_report","oracle_fusion_financials_update_expense_line","oracle_fusion_financials_update_expense_report","oracle_fusion_financials_update_receivables_invoice","oracledb_delete","oracledb_execute","oracledb_insert","oracledb_introspect","oracledb_query","oracledb_update","otter_create_conversation","otter_get_conversation","otter_get_conversation_audio","otter_get_workspace","otter_list_channel_members","otter_list_channels","otter_list_conversations","otter_list_workspace_conversations","outlook_calendar_create_event","outlook_calendar_delete_event","outlook_calendar_get_event","outlook_calendar_list_events","outlook_calendar_respond","outlook_calendar_update_event","outlook_copy","outlook_create_folder","outlook_delete","outlook_draft","outlook_forward","outlook_get_attachment","outlook_list_attachments","outlook_list_folders","outlook_mark_read","outlook_mark_unread","outlook_move","outlook_read","outlook_reply","outlook_reply_all","outlook_search","outlook_send","outlook_update_message","pagerduty_add_note","pagerduty_create_incident","pagerduty_get_incident","pagerduty_get_service","pagerduty_list_escalation_policies","pagerduty_list_incident_alerts","pagerduty_list_incidents","pagerduty_list_oncalls","pagerduty_list_schedules","pagerduty_list_services","pagerduty_list_users","pagerduty_merge_incidents","pagerduty_send_event","pagerduty_snooze_incident","pagerduty_update_incident","parallel_deep_research","parallel_extract","parallel_search","pdl_autocomplete","pdl_bulk_company_enrich","pdl_bulk_person_enrich","pdl_clean_company","pdl_clean_location","pdl_clean_school","pdl_company_enrich","pdl_company_search","pdl_person_enrich","pdl_person_identify","pdl_person_search","perplexity_chat","perplexity_search","persona_approve_inquiry","persona_create_account","persona_create_inquiry","persona_create_report","persona_decline_inquiry","persona_expire_inquiry","persona_generate_inquiry_link","persona_get_account","persona_get_case","persona_get_document","persona_get_inquiry","persona_get_report","persona_get_verification","persona_import_accounts","persona_list_accounts","persona_list_cases","persona_list_inquiries","persona_list_inquiry_templates","persona_list_reports","persona_mark_inquiry_for_review","persona_print_inquiry_pdf","persona_redact_account","persona_redact_inquiry","persona_resume_inquiry","persona_update_account","persona_update_inquiry","pinecone_delete_vectors","pinecone_describe_index","pinecone_describe_index_stats","pinecone_fetch","pinecone_generate_embeddings","pinecone_list_indexes","pinecone_list_vector_ids","pinecone_search_text","pinecone_search_vector","pinecone_update_vector","pinecone_upsert_text","pipedrive_create_activity","pipedrive_create_deal","pipedrive_create_lead","pipedrive_create_project","pipedrive_delete_lead","pipedrive_get_activities","pipedrive_get_all_deals","pipedrive_get_deal","pipedrive_get_files","pipedrive_get_leads","pipedrive_get_mail_messages","pipedrive_get_mail_thread","pipedrive_get_pipeline_deals","pipedrive_get_pipelines","pipedrive_get_projects","pipedrive_update_activity","pipedrive_update_deal","pipedrive_update_lead","pitchbook_company_active_investors","pitchbook_company_bio","pitchbook_company_deal_service_providers","pitchbook_company_deals","pitchbook_company_financials","pitchbook_company_general_service_providers","pitchbook_company_industries","pitchbook_company_investors","pitchbook_company_most_recent_debt_financing","pitchbook_company_most_recent_financials","pitchbook_company_most_recent_financing","pitchbook_company_search","pitchbook_company_similar_companies","pitchbook_company_social_analytics","pitchbook_company_updates","pitchbook_company_vc_exit_predictions","pitchbook_contracts_history","pitchbook_cost_of_calls","pitchbook_credit_history","pitchbook_credit_news","pitchbook_credit_news_bulk","pitchbook_credit_news_most_recent","pitchbook_credit_news_search","pitchbook_deal_bio","pitchbook_deal_cap_table_history","pitchbook_deal_debt_lenders","pitchbook_deal_detailed","pitchbook_deal_investors","pitchbook_deal_multiples","pitchbook_deal_search","pitchbook_deal_service_providers","pitchbook_deal_stock_info","pitchbook_deal_tranche_info","pitchbook_deal_updates","pitchbook_deal_valuation","pitchbook_entity_affiliates","pitchbook_entity_locations","pitchbook_entity_news","pitchbook_entity_people","pitchbook_entity_updates","pitchbook_fund_active_investments","pitchbook_fund_benchmark","pitchbook_fund_bio","pitchbook_fund_cash_flows","pitchbook_fund_commitments","pitchbook_fund_investment_preferences","pitchbook_fund_investments","pitchbook_fund_performance","pitchbook_fund_search","pitchbook_fund_team","pitchbook_fund_updates","pitchbook_investor_active_investments","pitchbook_investor_bio","pitchbook_investor_board_seats","pitchbook_investor_deal_service_providers","pitchbook_investor_funds","pitchbook_investor_general_service_providers","pitchbook_investor_investments","pitchbook_investor_last_closed_fund","pitchbook_investor_preferences","pitchbook_investor_search","pitchbook_investor_updates","pitchbook_limited_partner_actual_allocations","pitchbook_limited_partner_bio","pitchbook_limited_partner_commitment_aggregates","pitchbook_limited_partner_commitment_preferences","pitchbook_limited_partner_commitments_detailed","pitchbook_limited_partner_search","pitchbook_limited_partner_service_providers","pitchbook_limited_partner_target_allocations","pitchbook_limited_partner_updates","pitchbook_lookup_table_structure","pitchbook_lookup_tables","pitchbook_patent_detailed","pitchbook_patent_search","pitchbook_people_search","pitchbook_person_bio","pitchbook_person_contact","pitchbook_person_education_work","pitchbook_sandbox_entities","pitchbook_search","pitchbook_service_provider_bio","pitchbook_service_provider_search","pitchbook_service_provider_updates","pitchbook_serviced_companies","pitchbook_serviced_deals","pitchbook_serviced_funds","pitchbook_serviced_investors","pitchbook_serviced_limited_partners","pitchbook_shared_search","pitchbook_usage_report","plane_archive_project","plane_archive_work_item","plane_confirm_attachment_upload","plane_create_attachment_upload","plane_create_comment","plane_create_cycle","plane_create_label","plane_create_link","plane_create_module","plane_create_project","plane_create_project_page","plane_create_state","plane_create_webhook","plane_create_work_item","plane_delete_attachment","plane_delete_comment","plane_delete_cycle","plane_delete_label","plane_delete_link","plane_delete_module","plane_delete_project","plane_delete_project_page","plane_delete_state","plane_delete_webhook","plane_delete_work_item","plane_get_attachment","plane_get_comment","plane_get_current_user","plane_get_cycle","plane_get_label","plane_get_link","plane_get_module","plane_get_project","plane_get_project_page","plane_get_project_summary","plane_get_state","plane_get_webhook","plane_get_work_item","plane_get_work_item_by_identifier","plane_list_attachments","plane_list_comments","plane_list_cycles","plane_list_labels","plane_list_links","plane_list_modules","plane_list_project_pages","plane_list_projects","plane_list_states","plane_list_webhooks","plane_list_work_items","plane_list_workspace_work_items","plane_manage_cycle_work_items","plane_manage_module_work_items","plane_regenerate_webhook_secret","plane_transfer_cycle_work_items","plane_unarchive_project","plane_unarchive_work_item","plane_update_comment","plane_update_cycle","plane_update_label","plane_update_link","plane_update_module","plane_update_project","plane_update_project_page","plane_update_state","plane_update_webhook","plane_update_work_item","planetscale_close_deploy_request","planetscale_create_backup","planetscale_create_branch","planetscale_create_deploy_request","planetscale_delete_branch","planetscale_get_backup","planetscale_get_branch","planetscale_get_database","planetscale_get_deploy_request","planetscale_list_backups","planetscale_list_branches","planetscale_list_databases","planetscale_list_deploy_requests","planetscale_queue_deploy_request","planetscale_review_deploy_request","polymarket_get_activity","polymarket_get_event","polymarket_get_events","polymarket_get_holders","polymarket_get_last_trade_price","polymarket_get_leaderboard","polymarket_get_market","polymarket_get_markets","polymarket_get_midpoint","polymarket_get_orderbook","polymarket_get_positions","polymarket_get_price","polymarket_get_price_history","polymarket_get_series","polymarket_get_series_by_id","polymarket_get_spread","polymarket_get_tags","polymarket_get_tick_size","polymarket_get_trades","polymarket_search","postgresql_delete","postgresql_execute","postgresql_insert","postgresql_introspect","postgresql_query","postgresql_update","posthog_batch_events","posthog_capture_event","posthog_create_annotation","posthog_create_cohort","posthog_create_dashboard","posthog_create_experiment","posthog_create_feature_flag","posthog_create_insight","posthog_create_survey","posthog_delete_feature_flag","posthog_delete_person","posthog_delete_survey","posthog_evaluate_flags","posthog_get_cohort","posthog_get_dashboard","posthog_get_event_definition","posthog_get_experiment","posthog_get_feature_flag","posthog_get_insight","posthog_get_organization","posthog_get_person","posthog_get_project","posthog_get_property_definition","posthog_get_session_recording","posthog_get_survey","posthog_list_actions","posthog_list_annotations","posthog_list_cohorts","posthog_list_dashboards","posthog_list_event_definitions","posthog_list_experiments","posthog_list_feature_flags","posthog_list_insights","posthog_list_organizations","posthog_list_persons","posthog_list_projects","posthog_list_property_definitions","posthog_list_recording_playlists","posthog_list_session_recordings","posthog_list_surveys","posthog_query","posthog_update_cohort","posthog_update_event_definition","posthog_update_experiment","posthog_update_feature_flag","posthog_update_insight","posthog_update_property_definition","posthog_update_survey","powerbi_execute_query","powerbi_get_dataset","powerbi_get_refresh_history","powerbi_get_report","powerbi_list_datasets","powerbi_list_reports","powerbi_list_workspaces","powerbi_refresh_dataset","profound_bot_logs","profound_bots_report","profound_category_assets","profound_category_personas","profound_category_prompts","profound_category_tags","profound_category_topics","profound_citation_prompts","profound_citations_report","profound_list_assets","profound_list_categories","profound_list_domains","profound_list_models","profound_list_optimizations","profound_list_personas","profound_list_regions","profound_optimization_analysis","profound_prompt_answers","profound_prompt_volume","profound_query_fanouts","profound_raw_logs","profound_referrals_report","profound_sentiment_report","profound_visibility_report","prospeo_account_information","prospeo_bulk_enrich_company","prospeo_bulk_enrich_person","prospeo_enrich_company","prospeo_enrich_person","prospeo_search_company","prospeo_search_person","prospeo_search_suggestions","pulse_parser","pulse_parser_v2","qdrant_fetch_points","qdrant_search_vector","qdrant_upsert_points","quartr_get_audio","quartr_get_company","quartr_get_event","quartr_get_event_summary","quartr_get_report","quartr_get_slide_deck","quartr_get_transcript","quartr_list_audio","quartr_list_companies","quartr_list_document_types","quartr_list_documents","quartr_list_event_types","quartr_list_events","quartr_list_live_events","quartr_list_reports","quartr_list_slide_decks","quartr_list_transcripts","quickbooks_add_attachment","quickbooks_create_bill","quickbooks_create_bill_payment","quickbooks_create_credit_memo","quickbooks_create_customer","quickbooks_create_customer_payment","quickbooks_create_deposit","quickbooks_create_employee","quickbooks_create_estimate","quickbooks_create_invoice","quickbooks_create_item","quickbooks_create_journal_entry","quickbooks_create_purchase","quickbooks_create_purchase_order","quickbooks_create_refund_receipt","quickbooks_create_sales_receipt","quickbooks_create_vendor","quickbooks_create_vendor_credit","quickbooks_download_attachment","quickbooks_download_transaction_pdf","quickbooks_email_transaction","quickbooks_get_company_info","quickbooks_read_accounting_transactions","quickbooks_read_attachments","quickbooks_read_master_data","quickbooks_read_purchasing_transactions","quickbooks_read_sales_transactions","quickbooks_run_financial_report","quickbooks_update_bill","quickbooks_update_bill_payment","quickbooks_update_credit_memo","quickbooks_update_customer","quickbooks_update_customer_payment","quickbooks_update_deposit","quickbooks_update_employee","quickbooks_update_estimate","quickbooks_update_invoice","quickbooks_update_item","quickbooks_update_journal_entry","quickbooks_update_purchase","quickbooks_update_purchase_order","quickbooks_update_refund_receipt","quickbooks_update_sales_receipt","quickbooks_update_vendor","quickbooks_update_vendor_credit","quickbooks_void_bill_payment","quickbooks_void_customer_payment","quickbooks_void_invoice","quickbooks_void_sales_receipt","quiver_image_to_svg","quiver_image_to_svg_v2","quiver_list_models","quiver_text_to_svg","quiver_text_to_svg_v2","rabbitmq_create_binding","rabbitmq_create_exchange","rabbitmq_create_policy","rabbitmq_create_queue","rabbitmq_delete_binding","rabbitmq_delete_exchange","rabbitmq_delete_policy","rabbitmq_delete_queue","rabbitmq_get_exchange","rabbitmq_get_messages","rabbitmq_get_overview","rabbitmq_get_queue","rabbitmq_health_check","rabbitmq_list_bindings","rabbitmq_list_channels","rabbitmq_list_connections","rabbitmq_list_consumers","rabbitmq_list_exchange_bindings","rabbitmq_list_exchanges","rabbitmq_list_nodes","rabbitmq_list_policies","rabbitmq_list_queues","rabbitmq_list_vhosts","rabbitmq_publish_message","rabbitmq_purge_queue","railway_create_environment","railway_create_project","railway_create_service","railway_delete_environment","railway_delete_project","railway_delete_service","railway_delete_variable","railway_deploy_service","railway_get_deployment","railway_get_deployment_logs","railway_get_project","railway_list_deployments","railway_list_project_members","railway_list_projects","railway_list_variables","railway_restart_deployment","railway_rollback_deployment","railway_transfer_project","railway_update_project","railway_upsert_variable","ramp_create_memo","ramp_get_balance","ramp_get_bill","ramp_get_business","ramp_get_memo","ramp_get_physical_card","ramp_get_reimbursement","ramp_get_transaction","ramp_get_user","ramp_get_vendor","ramp_get_virtual_card","ramp_list_bills","ramp_list_physical_cards","ramp_list_reimbursements","ramp_list_transactions","ramp_list_users","ramp_list_vendors","ramp_list_virtual_cards","rb2b_credit_check","rb2b_email_to_activity","rb2b_hem_to_best_linkedin","rb2b_hem_to_business_profile","rb2b_hem_to_linkedin","rb2b_hem_to_maid","rb2b_ip_to_company","rb2b_ip_to_hem","rb2b_ip_to_maid","rb2b_linkedin_slug_search","rb2b_linkedin_to_best_personal_email","rb2b_linkedin_to_business_profile","rb2b_linkedin_to_hashed_emails","rb2b_linkedin_to_mobile_phone","rb2b_linkedin_to_personal_email","rds_delete","rds_execute","rds_insert","rds_introspect","rds_query","rds_update","reddit_delete","reddit_edit","reddit_get_comments","reddit_get_controversial","reddit_get_info","reddit_get_me","reddit_get_messages","reddit_get_posts","reddit_get_saved","reddit_get_subreddit_info","reddit_get_subreddit_rules","reddit_get_user","reddit_get_user_comments","reddit_get_user_posts","reddit_hide","reddit_hot_posts","reddit_list_my_subreddits","reddit_lock","reddit_mark_all_read","reddit_mark_read","reddit_marknsfw","reddit_mod_approve","reddit_mod_distinguish","reddit_mod_remove","reddit_mod_sticky","reddit_reply","reddit_report","reddit_save","reddit_search","reddit_search_subreddits","reddit_send_message","reddit_submit_post","reddit_subscribe","reddit_unhide","reddit_unlock","reddit_unmarknsfw","reddit_unsave","reddit_vote","redis_command","redis_delete","redis_exists","redis_expire","redis_get","redis_hdel","redis_hget","redis_hgetall","redis_hset","redis_incr","redis_incrby","redis_keys","redis_llen","redis_lpop","redis_lpush","redis_lrange","redis_persist","redis_rpop","redis_rpush","redis_set","redis_setnx","redis_ttl","reducto_parser","reducto_parser_v2","resend_cancel_email","resend_create_audience","resend_create_broadcast","resend_create_contact","resend_delete_audience","resend_delete_contact","resend_get_audience","resend_get_broadcast","resend_get_contact","resend_get_email","resend_list_audiences","resend_list_contacts","resend_list_domains","resend_send","resend_send_broadcast","resend_update_contact","revenuecat_create_purchase","revenuecat_defer_google_subscription","revenuecat_delete_customer","revenuecat_get_customer","revenuecat_grant_entitlement","revenuecat_list_offerings","revenuecat_refund_google_subscription","revenuecat_revoke_entitlement","revenuecat_revoke_google_subscription","revenuecat_update_subscriber_attributes","rippling_bulk_create_custom_object_records","rippling_bulk_delete_custom_object_records","rippling_bulk_update_custom_object_records","rippling_create_business_partner","rippling_create_business_partner_group","rippling_create_custom_app","rippling_create_custom_object","rippling_create_custom_object_field","rippling_create_custom_object_record","rippling_create_custom_page","rippling_create_custom_setting","rippling_create_department","rippling_create_draft_hires","rippling_create_object_category","rippling_create_title","rippling_create_work_location","rippling_delete_business_partner","rippling_delete_business_partner_group","rippling_delete_custom_app","rippling_delete_custom_object","rippling_delete_custom_object_field","rippling_delete_custom_object_record","rippling_delete_custom_page","rippling_delete_custom_setting","rippling_delete_object_category","rippling_delete_title","rippling_delete_work_location","rippling_get_business_partner","rippling_get_business_partner_group","rippling_get_current_user","rippling_get_custom_app","rippling_get_custom_object","rippling_get_custom_object_field","rippling_get_custom_object_record","rippling_get_custom_object_record_by_external_id","rippling_get_custom_page","rippling_get_custom_setting","rippling_get_department","rippling_get_employment_type","rippling_get_job_function","rippling_get_object_category","rippling_get_report_run","rippling_get_supergroup","rippling_get_team","rippling_get_title","rippling_get_user","rippling_get_work_location","rippling_get_worker","rippling_list_business_partner_groups","rippling_list_business_partners","rippling_list_companies","rippling_list_custom_apps","rippling_list_custom_fields","rippling_list_custom_object_fields","rippling_list_custom_object_records","rippling_list_custom_objects","rippling_list_custom_pages","rippling_list_custom_settings","rippling_list_departments","rippling_list_employment_types","rippling_list_entitlements","rippling_list_job_functions","rippling_list_object_categories","rippling_list_supergroup_exclusion_members","rippling_list_supergroup_inclusion_members","rippling_list_supergroup_members","rippling_list_supergroups","rippling_list_teams","rippling_list_titles","rippling_list_users","rippling_list_work_locations","rippling_list_workers","rippling_query_custom_object_records","rippling_trigger_report_run","rippling_update_custom_app","rippling_update_custom_object","rippling_update_custom_object_field","rippling_update_custom_object_record","rippling_update_custom_page","rippling_update_custom_setting","rippling_update_department","rippling_update_object_category","rippling_update_supergroup_exclusion_members","rippling_update_supergroup_inclusion_members","rippling_update_title","rippling_update_work_location","rocketlane_add_field_option","rocketlane_add_project_members","rocketlane_add_task_assignees","rocketlane_add_task_dependencies","rocketlane_add_task_followers","rocketlane_archive_project","rocketlane_assign_placeholders","rocketlane_create_field","rocketlane_create_phase","rocketlane_create_project","rocketlane_create_space","rocketlane_create_space_document","rocketlane_create_task","rocketlane_create_time_entry","rocketlane_create_time_off","rocketlane_delete_field","rocketlane_delete_phase","rocketlane_delete_project","rocketlane_delete_space","rocketlane_delete_space_document","rocketlane_delete_task","rocketlane_delete_time_entry","rocketlane_delete_time_off","rocketlane_get_field","rocketlane_get_invoice","rocketlane_get_invoice_line_items","rocketlane_get_invoice_payments","rocketlane_get_phase","rocketlane_get_project","rocketlane_get_space","rocketlane_get_space_document","rocketlane_get_task","rocketlane_get_time_entry","rocketlane_get_time_off","rocketlane_get_user","rocketlane_import_template","rocketlane_list_fields","rocketlane_list_invoices","rocketlane_list_phases","rocketlane_list_placeholders","rocketlane_list_projects","rocketlane_list_resource_allocations","rocketlane_list_space_documents","rocketlane_list_spaces","rocketlane_list_tasks","rocketlane_list_time_entries","rocketlane_list_time_entry_categories","rocketlane_list_time_offs","rocketlane_list_users","rocketlane_move_task_to_phase","rocketlane_remove_project_members","rocketlane_remove_task_assignees","rocketlane_remove_task_dependencies","rocketlane_remove_task_followers","rocketlane_search_time_entries","rocketlane_unassign_placeholders","rocketlane_update_field","rocketlane_update_field_option","rocketlane_update_phase","rocketlane_update_project","rocketlane_update_space","rocketlane_update_space_document","rocketlane_update_task","rocketlane_update_time_entry","rootly_acknowledge_alert","rootly_add_incident_event","rootly_add_subscribers","rootly_assign_incident_role","rootly_create_action_item","rootly_create_alert","rootly_create_incident","rootly_create_status_page_event","rootly_delete_action_item","rootly_delete_incident","rootly_escalate_alert","rootly_get_alert","rootly_get_incident","rootly_list_action_items","rootly_list_alerts","rootly_list_causes","rootly_list_environments","rootly_list_escalation_policies","rootly_list_functionalities","rootly_list_incident_events","rootly_list_incident_roles","rootly_list_incident_types","rootly_list_incidents","rootly_list_on_calls","rootly_list_playbooks","rootly_list_retrospectives","rootly_list_schedules","rootly_list_services","rootly_list_severities","rootly_list_teams","rootly_list_users","rootly_mitigate_incident","rootly_remove_subscribers","rootly_resolve_alert","rootly_resolve_incident","rootly_run_workflow","rootly_snooze_alert","rootly_unassign_incident_role","rootly_update_action_item","rootly_update_alert","rootly_update_incident","s3_copy_object","s3_create_bucket","s3_delete_bucket","s3_delete_object","s3_delete_objects","s3_get_object","s3_head_object","s3_list_buckets","s3_list_objects","s3_presigned_url","s3_put_object","sailpoint_approve_access_request","sailpoint_cancel_access_request","sailpoint_decide_certification_review_items","sailpoint_get_access_profile","sailpoint_get_access_profile_entitlements","sailpoint_get_access_request_config","sailpoint_get_access_request_status","sailpoint_get_account","sailpoint_get_account_activity","sailpoint_get_account_entitlements","sailpoint_get_account_selections","sailpoint_get_campaign","sailpoint_get_certification","sailpoint_get_entitlement","sailpoint_get_entitlement_request_config","sailpoint_get_identity","sailpoint_get_role","sailpoint_get_role_entitlements","sailpoint_get_source","sailpoint_get_task_status","sailpoint_list_access_profiles","sailpoint_list_account_activities","sailpoint_list_accounts","sailpoint_list_campaigns","sailpoint_list_certification_review_items","sailpoint_list_certifications","sailpoint_list_entitlements","sailpoint_list_identities","sailpoint_list_identity_entitlements","sailpoint_list_pending_access_request_approvals","sailpoint_list_roles","sailpoint_list_sources","sailpoint_load_accounts","sailpoint_load_entitlements","sailpoint_reject_access_request","sailpoint_request_access","sailpoint_search","sailpoint_search_aggregate","sailpoint_search_count","sailpoint_sign_off_certification","salesforce_create_account","salesforce_create_case","salesforce_create_contact","salesforce_create_custom_field","salesforce_create_custom_object","salesforce_create_lead","salesforce_create_opportunity","salesforce_create_task","salesforce_delete_account","salesforce_delete_case","salesforce_delete_contact","salesforce_delete_custom_field","salesforce_delete_lead","salesforce_delete_opportunity","salesforce_delete_task","salesforce_describe_object","salesforce_get_accounts","salesforce_get_cases","salesforce_get_contacts","salesforce_get_dashboard","salesforce_get_leads","salesforce_get_opportunities","salesforce_get_report","salesforce_get_tasks","salesforce_list_dashboards","salesforce_list_objects","salesforce_list_report_types","salesforce_list_reports","salesforce_query","salesforce_query_more","salesforce_refresh_dashboard","salesforce_run_report","salesforce_tooling_query","salesforce_update_account","salesforce_update_case","salesforce_update_contact","salesforce_update_custom_field","salesforce_update_lead","salesforce_update_opportunity","salesforce_update_task","sap_concur_approve_expense_report","sap_concur_associate_attendees","sap_concur_create_cash_advance","sap_concur_create_expected_expense","sap_concur_create_expense_report","sap_concur_create_list_item","sap_concur_create_purchase_request","sap_concur_create_quick_expense","sap_concur_create_quick_expense_with_image","sap_concur_create_report_comment","sap_concur_create_travel_request","sap_concur_create_user","sap_concur_delete_expected_expense","sap_concur_delete_expense","sap_concur_delete_expense_report","sap_concur_delete_list_item","sap_concur_delete_travel_request","sap_concur_delete_user","sap_concur_get_allocation","sap_concur_get_budget","sap_concur_get_cash_advance","sap_concur_get_expected_expense","sap_concur_get_expense","sap_concur_get_expense_report","sap_concur_get_itemizations","sap_concur_get_itinerary","sap_concur_get_list","sap_concur_get_list_item","sap_concur_get_purchase_request","sap_concur_get_receipt","sap_concur_get_receipt_status","sap_concur_get_request_cash_advance","sap_concur_get_travel_profile","sap_concur_get_travel_request","sap_concur_get_user","sap_concur_issue_cash_advance","sap_concur_list_allocations","sap_concur_list_attendee_associations","sap_concur_list_budget_categories","sap_concur_list_budgets","sap_concur_list_exceptions","sap_concur_list_expected_expenses","sap_concur_list_expense_reports","sap_concur_list_expenses","sap_concur_list_itineraries","sap_concur_list_list_items","sap_concur_list_lists","sap_concur_list_receipts","sap_concur_list_report_comments","sap_concur_list_reports_to_approve","sap_concur_list_travel_profiles_summary","sap_concur_list_travel_request_comments","sap_concur_list_travel_requests","sap_concur_list_users","sap_concur_move_travel_request","sap_concur_recall_expense_report","sap_concur_remove_all_attendees","sap_concur_search_locations","sap_concur_search_users","sap_concur_send_back_expense_report","sap_concur_submit_expense_report","sap_concur_update_allocation","sap_concur_update_expected_expense","sap_concur_update_expense","sap_concur_update_expense_report","sap_concur_update_list_item","sap_concur_update_travel_request","sap_concur_update_user","sap_concur_upload_exchange_rates","sap_concur_upload_receipt_image","sap_s4hana_create_business_partner","sap_s4hana_create_purchase_order","sap_s4hana_create_purchase_requisition","sap_s4hana_create_sales_order","sap_s4hana_delete_sales_order","sap_s4hana_get_billing_document","sap_s4hana_get_business_partner","sap_s4hana_get_customer","sap_s4hana_get_inbound_delivery","sap_s4hana_get_material_document","sap_s4hana_get_outbound_delivery","sap_s4hana_get_product","sap_s4hana_get_purchase_order","sap_s4hana_get_purchase_requisition","sap_s4hana_get_sales_order","sap_s4hana_get_supplier","sap_s4hana_get_supplier_invoice","sap_s4hana_list_billing_documents","sap_s4hana_list_business_partners","sap_s4hana_list_customers","sap_s4hana_list_inbound_deliveries","sap_s4hana_list_material_documents","sap_s4hana_list_material_stock","sap_s4hana_list_outbound_deliveries","sap_s4hana_list_products","sap_s4hana_list_purchase_orders","sap_s4hana_list_purchase_requisitions","sap_s4hana_list_sales_orders","sap_s4hana_list_supplier_invoices","sap_s4hana_list_suppliers","sap_s4hana_odata_query","sap_s4hana_update_business_partner","sap_s4hana_update_customer","sap_s4hana_update_product","sap_s4hana_update_purchase_order","sap_s4hana_update_purchase_requisition","sap_s4hana_update_sales_order","sap_s4hana_update_supplier","search_tool","secrets_manager_create_secret","secrets_manager_delete_secret","secrets_manager_describe_secret","secrets_manager_get_secret","secrets_manager_list_secrets","secrets_manager_restore_secret","secrets_manager_rotate_secret","secrets_manager_tag_resource","secrets_manager_untag_resource","secrets_manager_update_secret","semrush_backlinks","semrush_backlinks_anchors","semrush_backlinks_competitors","semrush_backlinks_geo_distribution","semrush_backlinks_indexed_pages","semrush_backlinks_overview","semrush_backlinks_tld_distribution","semrush_batch_keyword_overview","semrush_broad_match_keywords","semrush_domain_ad_copies","semrush_domain_ad_history","semrush_domain_organic_competitors","semrush_domain_organic_keywords","semrush_domain_overview","semrush_domain_overview_all","semrush_domain_overview_history","semrush_domain_paid_competitors","semrush_domain_paid_keywords","semrush_domain_pla_copies","semrush_domain_pla_keywords","semrush_domain_vs_domain","semrush_keyword_ad_history","semrush_keyword_difficulty","semrush_keyword_overview","semrush_keyword_overview_all","semrush_keyword_questions","semrush_organic_results","semrush_paid_results","semrush_referring_domains","semrush_referring_ips","semrush_related_keywords","semrush_subdomain_ad_copies","semrush_subdomain_organic_keywords","semrush_subdomain_overview","semrush_subdomain_overview_all","semrush_subdomain_overview_history","semrush_subdomain_paid_keywords","semrush_top_domains","semrush_url_organic_keywords","semrush_url_overview","semrush_url_overview_all","semrush_url_overview_history","semrush_url_paid_keywords","semrush_winners_and_losers","sendblue_evaluate_service","sendblue_get_message","sendblue_send_group_message","sendblue_send_message","sendblue_send_typing_indicator","sendgrid_add_contact","sendgrid_add_contacts_to_list","sendgrid_create_list","sendgrid_create_template","sendgrid_create_template_version","sendgrid_delete_contacts","sendgrid_delete_list","sendgrid_delete_template","sendgrid_get_contact","sendgrid_get_list","sendgrid_get_template","sendgrid_list_all_lists","sendgrid_list_templates","sendgrid_remove_contacts_from_list","sendgrid_search_contacts","sendgrid_send_mail","sentry_events_get","sentry_events_list","sentry_issues_get","sentry_issues_list","sentry_issues_update","sentry_projects_create","sentry_projects_get","sentry_projects_list","sentry_projects_update","sentry_releases_create","sentry_releases_deploy","sentry_releases_list","sentry_teams_list","serper_search","servicenow_add_incident_comment","servicenow_aggregate","servicenow_close_incident","servicenow_create_change_request","servicenow_create_incident","servicenow_create_record","servicenow_delete_record","servicenow_download_attachment","servicenow_download_attachment_v2","servicenow_find_user","servicenow_get_change_next_states","servicenow_get_change_request","servicenow_get_ci","servicenow_get_incident","servicenow_get_knowledge_article","servicenow_get_requested_item","servicenow_list_approvals","servicenow_list_attachments","servicenow_list_catalog_items","servicenow_list_change_requests","servicenow_list_change_tasks","servicenow_list_ci_relationships","servicenow_list_group_members","servicenow_list_incidents","servicenow_list_requested_items","servicenow_order_catalog_item","servicenow_read_record","servicenow_resolve_incident","servicenow_search_cis","servicenow_search_knowledge","servicenow_update_approval","servicenow_update_change_request","servicenow_update_change_state","servicenow_update_incident","servicenow_update_record","servicenow_upload_attachment","ses_create_configuration_set","ses_create_email_identity","ses_create_template","ses_delete_email_identity","ses_delete_suppressed_destination","ses_delete_template","ses_get_account","ses_get_email_identity","ses_get_suppressed_destination","ses_get_template","ses_list_identities","ses_list_suppressed_destinations","ses_list_templates","ses_put_suppressed_destination","ses_send_bulk_email","ses_send_custom_verification_email","ses_send_email","ses_send_templated_email","ses_update_template","sftp_delete","sftp_download","sftp_download_v2","sftp_list","sftp_mkdir","sftp_upload","sharepoint_add_list_items","sharepoint_create_list","sharepoint_create_page","sharepoint_delete_file","sharepoint_delete_list_item","sharepoint_delete_page","sharepoint_download_file","sharepoint_get_drive_item","sharepoint_get_list","sharepoint_get_list_item","sharepoint_list_sites","sharepoint_publish_page","sharepoint_read_page","sharepoint_update_list","sharepoint_update_page","sharepoint_upload_file","shopify_adjust_inventory","shopify_cancel_order","shopify_create_customer","shopify_create_fulfillment","shopify_create_product","shopify_create_product_variants","shopify_delete_customer","shopify_delete_product","shopify_get_collection","shopify_get_customer","shopify_get_fulfillment","shopify_get_fulfillment_order","shopify_get_inventory_level","shopify_get_job","shopify_get_order","shopify_get_product","shopify_list_collections","shopify_list_customers","shopify_list_fulfillment_orders","shopify_list_inventory_items","shopify_list_locations","shopify_list_orders","shopify_list_products","shopify_update_customer","shopify_update_fulfillment_tracking","shopify_update_order","shopify_update_product","shopify_update_product_variants","similarweb_bounce_rate","similarweb_page_views","similarweb_pages_per_visit","similarweb_traffic_visits","similarweb_visit_duration","similarweb_website_overview","sixtyfour_enrich_company","sixtyfour_enrich_lead","sixtyfour_find_email","sixtyfour_find_phone","slack_add_bookmark","slack_add_reaction","slack_archive_conversation","slack_canvas","slack_close_conversation","slack_create_channel_canvas","slack_create_conversation","slack_create_user_group","slack_delete_canvas","slack_delete_file","slack_delete_message","slack_delete_scheduled_message","slack_disable_user_group","slack_download","slack_edit_bookmark","slack_edit_canvas","slack_enable_user_group","slack_ephemeral_message","slack_get_canvas","slack_get_channel_history","slack_get_channel_info","slack_get_dnd_info","slack_get_file_info","slack_get_message","slack_get_permalink","slack_get_reactions","slack_get_team_dnd_info","slack_get_team_info","slack_get_team_profile","slack_get_thread","slack_get_thread_replies","slack_get_user","slack_get_user_presence","slack_get_user_profile","slack_invite_to_conversation","slack_join_conversation","slack_kick_conversation","slack_leave_conversation","slack_list_bookmarks","slack_list_canvases","slack_list_channels","slack_list_emoji","slack_list_files","slack_list_members","slack_list_pins","slack_list_reactions","slack_list_scheduled_messages","slack_list_user_conversations","slack_list_user_group_members","slack_list_user_groups","slack_list_users","slack_lists_access_delete","slack_lists_access_set","slack_lists_create","slack_lists_download_get","slack_lists_download_start","slack_lists_items_create","slack_lists_items_delete","slack_lists_items_delete_multiple","slack_lists_items_info","slack_lists_items_list","slack_lists_items_update","slack_lists_update","slack_lookup_canvas_sections","slack_lookup_user_by_email","slack_mark_conversation_read","slack_message","slack_message_reader","slack_open_conversation","slack_open_view","slack_pin_message","slack_publish_view","slack_push_view","slack_remove_bookmark","slack_remove_reaction","slack_rename_agent_session_v2","slack_rename_conversation","slack_revoke_canvas_access","slack_schedule_message","slack_set_agent_session_status_v2","slack_set_conversation_purpose","slack_set_conversation_topic","slack_set_status","slack_set_suggested_prompts","slack_set_suggested_prompts_v2","slack_set_title","slack_set_user_presence","slack_share_canvas","slack_unarchive_conversation","slack_unfurl_links","slack_unpin_message","slack_update_message","slack_update_user_group","slack_update_user_group_members","slack_update_view","smartlead_add_email_accounts_to_campaign","smartlead_add_leads_to_campaign","smartlead_create_campaign","smartlead_create_lead_list","smartlead_delete_campaign","smartlead_delete_campaign_webhook","smartlead_delete_lead_from_campaign","smartlead_delete_lead_list","smartlead_duplicate_campaign","smartlead_export_campaign_leads","smartlead_get_campaign","smartlead_get_campaign_analytics","smartlead_get_campaign_analytics_by_date","smartlead_get_campaign_lead_statistics","smartlead_get_campaign_mailbox_statistics","smartlead_get_campaign_sequences","smartlead_get_campaign_statistics","smartlead_get_campaign_top_level_analytics_by_date","smartlead_get_campaign_webhook_summary","smartlead_get_lead_by_email","smartlead_get_lead_by_id","smartlead_get_lead_list","smartlead_get_lead_message_history","smartlead_list_campaign_email_accounts","smartlead_list_campaign_leads","smartlead_list_campaign_webhooks","smartlead_list_campaigns","smartlead_list_clients","smartlead_list_email_accounts","smartlead_list_inbox_replies","smartlead_list_lead_activities","smartlead_list_lead_categories","smartlead_list_lead_lists","smartlead_mark_lead_complete","smartlead_pause_lead","smartlead_remove_email_accounts_from_campaign","smartlead_resume_lead","smartlead_save_campaign_sequences","smartlead_unsubscribe_lead_from_campaign","smartlead_unsubscribe_lead_globally","smartlead_update_campaign_schedule","smartlead_update_campaign_settings","smartlead_update_campaign_status","smartlead_update_lead","smartlead_update_lead_category","smartlead_update_lead_list","smartlead_upsert_campaign_webhook","sms_send","smtp_send_mail","snowflake_alter_warehouse","snowflake_call_procedure","snowflake_cancel_statement","snowflake_cancel_task_run","snowflake_cortex_analyst_ask","snowflake_cortex_analyst_feedback","snowflake_delete_rows","snowflake_execute_sql","snowflake_get_statement","snowflake_get_task","snowflake_get_task_run","snowflake_get_task_run_output","snowflake_get_warehouse","snowflake_insert_rows","snowflake_introspect_schema","snowflake_list_copy_history","snowflake_list_databases","snowflake_list_query_history","snowflake_list_schemas","snowflake_list_tables","snowflake_list_task_runs","snowflake_list_tasks","snowflake_list_warehouses","snowflake_load_data","snowflake_resume_task","snowflake_resume_warehouse","snowflake_run_task","snowflake_suspend_task","snowflake_suspend_warehouse","snowflake_unload_data","snowflake_update_rows","snowflake_upsert_rows","splunk_cancel_search_job","splunk_create_search_job","splunk_dispatch_saved_search","splunk_get_fired_alerts","splunk_get_saved_search","splunk_get_search_job","splunk_get_search_results","splunk_list_apps","splunk_list_fired_alerts","splunk_list_indexes","splunk_list_saved_searches","splunk_run_search","sportmonks_core_get_cities","sportmonks_core_get_city","sportmonks_core_get_continent","sportmonks_core_get_continents","sportmonks_core_get_countries","sportmonks_core_get_country","sportmonks_core_get_entity_filters","sportmonks_core_get_my_usage","sportmonks_core_get_region","sportmonks_core_get_regions","sportmonks_core_get_timezones","sportmonks_core_get_type","sportmonks_core_get_type_by_entity","sportmonks_core_get_types","sportmonks_core_search_cities","sportmonks_core_search_countries","sportmonks_core_search_regions","sportmonks_football_expected_by_player","sportmonks_football_expected_by_team","sportmonks_football_get_all_commentaries","sportmonks_football_get_all_fixtures","sportmonks_football_get_all_players","sportmonks_football_get_all_rivals","sportmonks_football_get_all_teams","sportmonks_football_get_all_transfer_rumours","sportmonks_football_get_all_transfers","sportmonks_football_get_brackets_by_season","sportmonks_football_get_coach","sportmonks_football_get_coaches","sportmonks_football_get_coaches_by_country","sportmonks_football_get_commentaries_by_fixture","sportmonks_football_get_current_leagues_by_team","sportmonks_football_get_expected_lineups_by_player","sportmonks_football_get_expected_lineups_by_team","sportmonks_football_get_extended_team_squad","sportmonks_football_get_fixture","sportmonks_football_get_fixtures_by_date","sportmonks_football_get_fixtures_by_date_range","sportmonks_football_get_fixtures_by_date_range_for_team","sportmonks_football_get_fixtures_by_ids","sportmonks_football_get_grouped_standings_by_round","sportmonks_football_get_head_to_head","sportmonks_football_get_inplay_livescores","sportmonks_football_get_latest_coaches","sportmonks_football_get_latest_fixtures","sportmonks_football_get_latest_livescores","sportmonks_football_get_latest_players","sportmonks_football_get_latest_totw","sportmonks_football_get_latest_transfers","sportmonks_football_get_league","sportmonks_football_get_leagues","sportmonks_football_get_leagues_by_country","sportmonks_football_get_leagues_by_date","sportmonks_football_get_leagues_by_team","sportmonks_football_get_live_leagues","sportmonks_football_get_live_probabilities","sportmonks_football_get_live_probabilities_by_fixture","sportmonks_football_get_live_standings_by_league","sportmonks_football_get_livescores","sportmonks_football_get_match_facts","sportmonks_football_get_match_facts_by_date_range","sportmonks_football_get_match_facts_by_fixture","sportmonks_football_get_match_facts_by_league","sportmonks_football_get_past_fixtures_by_tv_station","sportmonks_football_get_player","sportmonks_football_get_players_by_country","sportmonks_football_get_postmatch_news","sportmonks_football_get_postmatch_news_by_season","sportmonks_football_get_predictability_by_league","sportmonks_football_get_prematch_news","sportmonks_football_get_prematch_news_by_season","sportmonks_football_get_prematch_news_upcoming","sportmonks_football_get_probabilities","sportmonks_football_get_probabilities_by_fixture","sportmonks_football_get_referee","sportmonks_football_get_referees","sportmonks_football_get_referees_by_country","sportmonks_football_get_referees_by_season","sportmonks_football_get_rivals_by_team","sportmonks_football_get_round","sportmonks_football_get_round_statistics","sportmonks_football_get_rounds","sportmonks_football_get_rounds_by_season","sportmonks_football_get_schedules_by_season","sportmonks_football_get_schedules_by_season_and_team","sportmonks_football_get_schedules_by_team","sportmonks_football_get_season","sportmonks_football_get_seasons","sportmonks_football_get_seasons_by_team","sportmonks_football_get_stage","sportmonks_football_get_stage_statistics","sportmonks_football_get_stages","sportmonks_football_get_stages_by_season","sportmonks_football_get_standing_corrections_by_season","sportmonks_football_get_standings","sportmonks_football_get_standings_by_round","sportmonks_football_get_standings_by_season","sportmonks_football_get_state","sportmonks_football_get_states","sportmonks_football_get_team","sportmonks_football_get_team_rankings","sportmonks_football_get_team_rankings_by_date","sportmonks_football_get_team_rankings_by_team","sportmonks_football_get_team_squad","sportmonks_football_get_team_squad_by_season","sportmonks_football_get_teams_by_country","sportmonks_football_get_teams_by_season","sportmonks_football_get_topscorers_by_season","sportmonks_football_get_topscorers_by_stage","sportmonks_football_get_totw","sportmonks_football_get_totw_by_round","sportmonks_football_get_transfer","sportmonks_football_get_transfer_rumour","sportmonks_football_get_transfer_rumours_between_dates","sportmonks_football_get_transfer_rumours_by_player","sportmonks_football_get_transfer_rumours_by_team","sportmonks_football_get_transfers_between_dates","sportmonks_football_get_transfers_by_player","sportmonks_football_get_transfers_by_team","sportmonks_football_get_tv_station","sportmonks_football_get_tv_stations","sportmonks_football_get_tv_stations_by_fixture","sportmonks_football_get_upcoming_fixtures_by_market","sportmonks_football_get_upcoming_fixtures_by_tv_station","sportmonks_football_get_value_bets","sportmonks_football_get_value_bets_by_fixture","sportmonks_football_get_venue","sportmonks_football_get_venues","sportmonks_football_get_venues_by_season","sportmonks_football_search_coaches","sportmonks_football_search_fixtures","sportmonks_football_search_leagues","sportmonks_football_search_players","sportmonks_football_search_referees","sportmonks_football_search_rounds","sportmonks_football_search_seasons","sportmonks_football_search_stages","sportmonks_football_search_teams","sportmonks_football_search_venues","sportmonks_motorsport_get_all_fixtures","sportmonks_motorsport_get_current_leagues_by_team","sportmonks_motorsport_get_driver","sportmonks_motorsport_get_driver_standings","sportmonks_motorsport_get_driver_standings_by_season","sportmonks_motorsport_get_drivers","sportmonks_motorsport_get_drivers_by_country","sportmonks_motorsport_get_drivers_by_season","sportmonks_motorsport_get_fixture","sportmonks_motorsport_get_fixtures_by_date","sportmonks_motorsport_get_fixtures_by_date_range","sportmonks_motorsport_get_fixtures_by_ids","sportmonks_motorsport_get_laps_by_fixture","sportmonks_motorsport_get_laps_by_fixture_and_driver","sportmonks_motorsport_get_laps_by_fixture_and_lap","sportmonks_motorsport_get_latest_laps_by_fixture","sportmonks_motorsport_get_latest_pitstops_by_fixture","sportmonks_motorsport_get_latest_stints_by_fixture","sportmonks_motorsport_get_latest_updated_drivers","sportmonks_motorsport_get_latest_updated_fixtures","sportmonks_motorsport_get_league","sportmonks_motorsport_get_leagues","sportmonks_motorsport_get_leagues_by_country","sportmonks_motorsport_get_leagues_by_date","sportmonks_motorsport_get_leagues_by_live","sportmonks_motorsport_get_leagues_by_team","sportmonks_motorsport_get_livescores","sportmonks_motorsport_get_pitstops_by_fixture","sportmonks_motorsport_get_pitstops_by_fixture_and_driver","sportmonks_motorsport_get_pitstops_by_fixture_and_lap","sportmonks_motorsport_get_race_results_by_season_and_driver","sportmonks_motorsport_get_race_results_by_season_and_team","sportmonks_motorsport_get_schedules_by_season","sportmonks_motorsport_get_season","sportmonks_motorsport_get_seasons","sportmonks_motorsport_get_stage","sportmonks_motorsport_get_stages","sportmonks_motorsport_get_stages_by_season","sportmonks_motorsport_get_state","sportmonks_motorsport_get_states","sportmonks_motorsport_get_stints_by_fixture","sportmonks_motorsport_get_stints_by_fixture_and_driver","sportmonks_motorsport_get_stints_by_fixture_and_stint","sportmonks_motorsport_get_team","sportmonks_motorsport_get_team_standings","sportmonks_motorsport_get_team_standings_by_season","sportmonks_motorsport_get_teams","sportmonks_motorsport_get_teams_by_country","sportmonks_motorsport_get_teams_by_season","sportmonks_motorsport_get_venue","sportmonks_motorsport_get_venues","sportmonks_motorsport_get_venues_by_season","sportmonks_motorsport_search_drivers","sportmonks_motorsport_search_leagues","sportmonks_motorsport_search_stages","sportmonks_motorsport_search_teams","sportmonks_motorsport_search_venues","sportmonks_odds_get_all_historical_odds","sportmonks_odds_get_all_inplay_odds","sportmonks_odds_get_all_pre_match_odds","sportmonks_odds_get_all_premium_odds","sportmonks_odds_get_bookmaker","sportmonks_odds_get_bookmaker_event_ids_by_fixture","sportmonks_odds_get_bookmakers","sportmonks_odds_get_bookmakers_by_fixture","sportmonks_odds_get_inplay_odds_by_fixture","sportmonks_odds_get_inplay_odds_by_fixture_and_bookmaker","sportmonks_odds_get_inplay_odds_by_fixture_and_market","sportmonks_odds_get_last_updated_inplay_odds","sportmonks_odds_get_last_updated_pre_match_odds","sportmonks_odds_get_market","sportmonks_odds_get_markets","sportmonks_odds_get_pre_match_odds_by_fixture","sportmonks_odds_get_pre_match_odds_by_fixture_and_bookmaker","sportmonks_odds_get_pre_match_odds_by_fixture_and_market","sportmonks_odds_get_premium_odds_by_fixture","sportmonks_odds_get_premium_odds_by_fixture_and_bookmaker","sportmonks_odds_get_premium_odds_by_fixture_and_market","sportmonks_odds_get_updated_historical_odds_between","sportmonks_odds_get_updated_premium_odds_between","sportmonks_odds_search_bookmakers","sportmonks_odds_search_markets","spotify_add_playlist_cover","spotify_add_to_queue","spotify_add_tracks_to_playlist","spotify_check_following","spotify_check_playlist_followers","spotify_check_saved_albums","spotify_check_saved_audiobooks","spotify_check_saved_episodes","spotify_check_saved_shows","spotify_check_saved_tracks","spotify_create_playlist","spotify_follow_artists","spotify_follow_playlist","spotify_get_album","spotify_get_album_tracks","spotify_get_albums","spotify_get_artist","spotify_get_artist_albums","spotify_get_artist_top_tracks","spotify_get_artists","spotify_get_audiobook","spotify_get_audiobook_chapters","spotify_get_audiobooks","spotify_get_categories","spotify_get_current_user","spotify_get_currently_playing","spotify_get_devices","spotify_get_episode","spotify_get_episodes","spotify_get_followed_artists","spotify_get_markets","spotify_get_new_releases","spotify_get_playback_state","spotify_get_playlist","spotify_get_playlist_cover","spotify_get_playlist_tracks","spotify_get_queue","spotify_get_recently_played","spotify_get_saved_albums","spotify_get_saved_audiobooks","spotify_get_saved_episodes","spotify_get_saved_shows","spotify_get_saved_tracks","spotify_get_show","spotify_get_show_episodes","spotify_get_shows","spotify_get_top_artists","spotify_get_top_tracks","spotify_get_track","spotify_get_tracks","spotify_get_user_playlists","spotify_get_user_profile","spotify_pause","spotify_play","spotify_remove_saved_albums","spotify_remove_saved_audiobooks","spotify_remove_saved_episodes","spotify_remove_saved_shows","spotify_remove_saved_tracks","spotify_remove_tracks_from_playlist","spotify_reorder_playlist_items","spotify_replace_playlist_items","spotify_save_albums","spotify_save_audiobooks","spotify_save_episodes","spotify_save_shows","spotify_save_tracks","spotify_search","spotify_seek","spotify_set_repeat","spotify_set_shuffle","spotify_set_volume","spotify_skip_next","spotify_skip_previous","spotify_transfer_playback","spotify_unfollow_artists","spotify_unfollow_playlist","spotify_update_playlist","sqs_cancel_message_move_task","sqs_change_message_visibility","sqs_change_message_visibility_batch","sqs_create_queue","sqs_delete_message","sqs_delete_message_batch","sqs_delete_queue","sqs_get_queue_attributes","sqs_get_queue_url","sqs_list_dead_letter_source_queues","sqs_list_message_move_tasks","sqs_list_queue_tags","sqs_list_queues","sqs_purge_queue","sqs_receive_message","sqs_send","sqs_send_message_batch","sqs_set_queue_attributes","sqs_start_message_move_task","sqs_tag_queue","sqs_untag_queue","square_batch_retrieve_inventory_counts","square_cancel_invoice","square_cancel_payment","square_complete_payment","square_create_catalog_image","square_create_customer","square_create_invoice","square_create_order","square_create_payment","square_delete_catalog_object","square_delete_customer","square_delete_invoice","square_get_catalog_object","square_get_customer","square_get_invoice","square_get_location","square_get_order","square_get_payment","square_get_refund","square_list_catalog","square_list_customers","square_list_invoices","square_list_locations","square_list_payments","square_list_refunds","square_pay_order","square_publish_invoice","square_refund_payment","square_search_catalog_objects","square_search_customers","square_search_invoices","square_search_orders","square_update_customer","square_upsert_catalog_object","ssh_check_command_exists","ssh_check_file_exists","ssh_create_directory","ssh_delete_file","ssh_download_file","ssh_download_file_v2","ssh_execute_command","ssh_execute_script","ssh_get_system_info","ssh_list_directory","ssh_move_rename","ssh_read_file_content","ssh_upload_file","ssh_write_file_content","ssm_cancel_command","ssm_delete_parameter","ssm_describe_automation_executions","ssm_describe_instance_information","ssm_describe_instance_patch_states","ssm_describe_instance_patches","ssm_describe_parameters","ssm_get_automation_execution","ssm_get_command_invocation","ssm_get_document","ssm_get_parameter","ssm_get_parameters","ssm_get_parameters_by_path","ssm_list_command_invocations","ssm_list_commands","ssm_list_compliance_items","ssm_list_compliance_summaries","ssm_list_documents","ssm_put_parameter","ssm_send_command","ssm_start_automation_execution","ssm_stop_automation_execution","stagehand_agent","stagehand_extract","stripe_cancel_payment_intent","stripe_cancel_subscription","stripe_capture_charge","stripe_capture_payment_intent","stripe_confirm_payment_intent","stripe_create_charge","stripe_create_customer","stripe_create_invoice","stripe_create_payment_intent","stripe_create_price","stripe_create_product","stripe_create_subscription","stripe_delete_customer","stripe_delete_invoice","stripe_delete_product","stripe_finalize_invoice","stripe_list_charges","stripe_list_customers","stripe_list_events","stripe_list_invoices","stripe_list_payment_intents","stripe_list_prices","stripe_list_products","stripe_list_subscriptions","stripe_pay_invoice","stripe_resume_subscription","stripe_retrieve_charge","stripe_retrieve_customer","stripe_retrieve_event","stripe_retrieve_invoice","stripe_retrieve_payment_intent","stripe_retrieve_price","stripe_retrieve_product","stripe_retrieve_subscription","stripe_search_charges","stripe_search_customers","stripe_search_invoices","stripe_search_payment_intents","stripe_search_prices","stripe_search_products","stripe_search_subscriptions","stripe_send_invoice","stripe_update_charge","stripe_update_customer","stripe_update_invoice","stripe_update_payment_intent","stripe_update_price","stripe_update_product","stripe_update_subscription","stripe_void_invoice","sts_assume_role","sts_assume_role_with_saml","sts_assume_role_with_web_identity","sts_get_access_key_info","sts_get_caller_identity","sts_get_session_token","stt_assemblyai","stt_assemblyai_v2","stt_deepgram","stt_deepgram_v2","stt_elevenlabs","stt_elevenlabs_v2","stt_gemini","stt_gemini_v2","stt_whisper","stt_whisper_v2","supabase_count","supabase_delete","supabase_get_row","supabase_insert","supabase_introspect","supabase_invoke_function","supabase_query","supabase_rpc","supabase_storage_copy","supabase_storage_create_bucket","supabase_storage_create_signed_upload_url","supabase_storage_create_signed_url","supabase_storage_delete","supabase_storage_delete_bucket","supabase_storage_download","supabase_storage_empty_bucket","supabase_storage_get_public_url","supabase_storage_list","supabase_storage_list_buckets","supabase_storage_move","supabase_storage_update_bucket","supabase_storage_upload","supabase_text_search","supabase_update","supabase_upsert","supabase_vector_search","table_batch_insert_rows","table_create","table_delete_row","table_delete_rows_by_filter","table_get_row","table_get_schema","table_insert_row","table_list","table_query_rows","table_query_rows_v2","table_update_row","table_update_rows_by_filter","table_upsert_row","tailscale_authorize_device","tailscale_create_auth_key","tailscale_delete_auth_key","tailscale_delete_device","tailscale_delete_user","tailscale_expire_device_key","tailscale_get_acl","tailscale_get_auth_key","tailscale_get_device","tailscale_get_device_routes","tailscale_get_dns_preferences","tailscale_get_dns_searchpaths","tailscale_list_auth_keys","tailscale_list_devices","tailscale_list_dns_nameservers","tailscale_list_users","tailscale_set_acl","tailscale_set_device_routes","tailscale_set_device_tags","tailscale_set_dns_nameservers","tailscale_set_dns_preferences","tailscale_set_dns_searchpaths","tailscale_suspend_user","tailscale_update_device_key","tavily_crawl","tavily_extract","tavily_map","tavily_search","telegram_copy_message","telegram_delete_message","telegram_edit_message_text","telegram_forward_message","telegram_get_chat","telegram_get_chat_member","telegram_message","telegram_pin_message","telegram_send_animation","telegram_send_audio","telegram_send_chat_action","telegram_send_contact","telegram_send_document","telegram_send_location","telegram_send_photo","telegram_send_poll","telegram_send_video","telegram_set_message_reaction","telegram_unpin_message","temporal_cancel_workflow","temporal_count_workflows","temporal_create_schedule","temporal_delete_schedule","temporal_describe_schedule","temporal_describe_task_queue","temporal_describe_workflow","temporal_get_workflow_history","temporal_list_schedules","temporal_list_workflows","temporal_pause_schedule","temporal_query_workflow","temporal_reset_workflow","temporal_signal_with_start","temporal_signal_workflow","temporal_start_workflow","temporal_terminate_workflow","temporal_trigger_schedule","temporal_unpause_schedule","temporal_update_workflow","textract_analyze_expense","textract_analyze_id","textract_parser","textract_parser_v2","thinking_tool","thrive_add_audience_managers","thrive_add_audience_members","thrive_add_user_tags","thrive_create_assignment","thrive_create_audience","thrive_create_completion","thrive_create_user","thrive_delete_assignment","thrive_delete_audience","thrive_delete_user","thrive_get_activity","thrive_get_assignment","thrive_get_audience","thrive_get_completion","thrive_get_content","thrive_get_cpd_category","thrive_get_cpd_entry","thrive_get_cpd_requirement","thrive_get_enrolment","thrive_get_skill_levels","thrive_get_tag","thrive_get_user_by_id","thrive_get_user_by_ref","thrive_list_assignments","thrive_list_audience_managers","thrive_list_audience_members","thrive_list_audiences","thrive_list_completions","thrive_list_enrolments","thrive_list_tags","thrive_query_activities","thrive_query_content","thrive_query_cpd_categories","thrive_query_cpd_entries","thrive_query_cpd_requirements","thrive_query_cpd_user_summaries","thrive_remove_audience_manager","thrive_remove_audience_member","thrive_remove_user_tags","thrive_replace_audience_managers","thrive_replace_audience_members","thrive_search_users","thrive_suspend_user","thrive_update_assignment","thrive_update_audience","thrive_update_user","thrive_update_user_skills","tiktok_get_post_status","tiktok_get_user","tiktok_list_videos","tiktok_query_videos","tiktok_upload_video_draft","tinybird_append_datasource","tinybird_delete_datasource_rows","tinybird_events","tinybird_get_job","tinybird_query","tinybird_query_pipe","tinybird_truncate_datasource","tinyfish_cancel_run","tinyfish_fetch","tinyfish_get_run","tinyfish_list_profiles","tinyfish_list_runs","tinyfish_list_vault_items","tinyfish_run","tinyfish_run_async","tinyfish_search","trello_add_checklist","trello_add_checklist_item","trello_add_comment","trello_add_label","trello_add_member","trello_create_board","trello_create_card","trello_create_list","trello_delete_card","trello_get_actions","trello_get_board","trello_get_card","trello_list_cards","trello_list_lists","trello_list_members","trello_remove_label","trello_remove_member","trello_search","trello_update_card","trello_update_checklist_item","trello_update_list","trigger_dev_activate_schedule","trigger_dev_add_run_tags","trigger_dev_batch_trigger_task","trigger_dev_cancel_run","trigger_dev_complete_waitpoint_token","trigger_dev_create_env_var","trigger_dev_create_schedule","trigger_dev_create_waitpoint_token","trigger_dev_deactivate_schedule","trigger_dev_delete_env_var","trigger_dev_delete_schedule","trigger_dev_execute_query","trigger_dev_get_batch","trigger_dev_get_batch_results","trigger_dev_get_deployment","trigger_dev_get_env_var","trigger_dev_get_latest_deployment","trigger_dev_get_query_schema","trigger_dev_get_queue","trigger_dev_get_run","trigger_dev_get_run_events","trigger_dev_get_run_result","trigger_dev_get_run_trace","trigger_dev_get_schedule","trigger_dev_get_waitpoint_token","trigger_dev_import_env_vars","trigger_dev_list_deployments","trigger_dev_list_env_vars","trigger_dev_list_queues","trigger_dev_list_runs","trigger_dev_list_schedules","trigger_dev_list_timezones","trigger_dev_list_waitpoint_tokens","trigger_dev_override_queue_concurrency","trigger_dev_pause_queue","trigger_dev_promote_deployment","trigger_dev_replay_run","trigger_dev_reschedule_run","trigger_dev_reset_queue_concurrency","trigger_dev_resume_queue","trigger_dev_trigger_task","trigger_dev_update_env_var","trigger_dev_update_run_metadata","trigger_dev_update_schedule","tts_azure","tts_cartesia","tts_deepgram","tts_elevenlabs","tts_google","tts_openai","tts_playht","twilio_send_sms","twilio_voice_get_recording","twilio_voice_list_calls","twilio_voice_make_call","typeform_create_form","typeform_delete_form","typeform_files","typeform_get_form","typeform_insights","typeform_list_forms","typeform_responses","typeform_update_form","upstash_redis_command","upstash_redis_delete","upstash_redis_exists","upstash_redis_expire","upstash_redis_get","upstash_redis_hget","upstash_redis_hgetall","upstash_redis_hset","upstash_redis_incr","upstash_redis_incrby","upstash_redis_keys","upstash_redis_lpush","upstash_redis_lrange","upstash_redis_set","upstash_redis_setnx","upstash_redis_ttl","uptimerobot_create_alert_contact","uptimerobot_create_maintenance_window","uptimerobot_create_monitor","uptimerobot_create_psp","uptimerobot_delete_alert_contact","uptimerobot_delete_maintenance_window","uptimerobot_delete_monitor","uptimerobot_delete_psp","uptimerobot_get_account","uptimerobot_get_alert_contact","uptimerobot_get_incident","uptimerobot_get_maintenance_window","uptimerobot_get_monitor","uptimerobot_get_psp","uptimerobot_list_alert_contacts","uptimerobot_list_incidents","uptimerobot_list_maintenance_windows","uptimerobot_list_monitors","uptimerobot_list_psps","uptimerobot_pause_monitor","uptimerobot_start_monitor","uptimerobot_update_maintenance_window","uptimerobot_update_monitor","uptimerobot_update_psp","vanta_download_document_file","vanta_get_control","vanta_get_document","vanta_get_framework","vanta_get_person","vanta_get_policy","vanta_get_risk_scenario","vanta_get_test","vanta_get_vendor","vanta_get_vulnerable_asset","vanta_list_control_documents","vanta_list_control_tests","vanta_list_controls","vanta_list_document_uploads","vanta_list_documents","vanta_list_framework_controls","vanta_list_frameworks","vanta_list_monitored_computers","vanta_list_people","vanta_list_policies","vanta_list_risk_scenarios","vanta_list_test_entities","vanta_list_tests","vanta_list_vendors","vanta_list_vulnerabilities","vanta_list_vulnerability_remediations","vanta_list_vulnerable_assets","vanta_submit_document","vanta_upload_document_file","vercel_add_domain","vercel_add_project_domain","vercel_cancel_deployment","vercel_create_alias","vercel_create_check","vercel_create_deployment","vercel_create_dns_record","vercel_create_edge_config","vercel_create_env_var","vercel_create_project","vercel_create_webhook","vercel_delete_alias","vercel_delete_deployment","vercel_delete_dns_record","vercel_delete_domain","vercel_delete_edge_config","vercel_delete_env_var","vercel_delete_project","vercel_delete_webhook","vercel_get_alias","vercel_get_check","vercel_get_deployment","vercel_get_deployment_events","vercel_get_domain","vercel_get_domain_config","vercel_get_edge_config","vercel_get_edge_config_items","vercel_get_env_vars","vercel_get_project","vercel_get_team","vercel_get_user","vercel_get_webhook","vercel_list_aliases","vercel_list_checks","vercel_list_deployment_files","vercel_list_deployments","vercel_list_dns_records","vercel_list_domains","vercel_list_edge_configs","vercel_list_project_domains","vercel_list_projects","vercel_list_team_members","vercel_list_teams","vercel_list_webhooks","vercel_pause_project","vercel_promote_deployment","vercel_remove_project_domain","vercel_rerequest_check","vercel_unpause_project","vercel_update_check","vercel_update_dns_record","vercel_update_edge_config_items","vercel_update_env_var","vercel_update_project","vercel_update_project_domain","vercel_verify_project_domain","video_falai","video_luma","video_minimax","video_runway","video_veo","vision_tool","vision_tool_v2","wealthbox_read_contact","wealthbox_read_note","wealthbox_read_task","wealthbox_write_contact","wealthbox_write_note","wealthbox_write_task","webflow_create_item","webflow_delete_item","webflow_get_item","webflow_list_items","webflow_update_item","webhook_request","whatsapp_get_media","whatsapp_mark_read","whatsapp_send_interactive","whatsapp_send_media","whatsapp_send_message","whatsapp_send_reaction","whatsapp_send_template","whatsapp_upload_media","wikipedia_content","wikipedia_random","wikipedia_search","wikipedia_summary","windchill_check_in_document","windchill_check_in_documents","windchill_check_out_document","windchill_check_out_documents","windchill_create_document","windchill_create_documents","windchill_delete_document","windchill_delete_documents","windchill_download_attachment","windchill_download_primary_content","windchill_get_document","windchill_get_document_structure","windchill_get_primary_content","windchill_get_valid_state_transitions","windchill_list_attachments","windchill_list_documents","windchill_revise_document","windchill_revise_documents","windchill_set_lifecycle_state","windchill_undo_check_out_document","windchill_undo_check_out_documents","windchill_update_common_properties","windchill_update_document","windchill_update_document_security_labels","windchill_update_documents","windchill_upload_attachments","windchill_upload_primary_content","wiza_company_enrichment","wiza_get_credits","wiza_individual_reveal","wiza_prospect_search","wordpress_create_category","wordpress_create_comment","wordpress_create_page","wordpress_create_post","wordpress_create_tag","wordpress_delete_category","wordpress_delete_comment","wordpress_delete_media","wordpress_delete_page","wordpress_delete_post","wordpress_delete_tag","wordpress_get_category","wordpress_get_current_user","wordpress_get_media","wordpress_get_page","wordpress_get_post","wordpress_get_tag","wordpress_get_user","wordpress_list_categories","wordpress_list_comments","wordpress_list_media","wordpress_list_pages","wordpress_list_posts","wordpress_list_tags","wordpress_list_users","wordpress_search_content","wordpress_update_category","wordpress_update_comment","wordpress_update_page","wordpress_update_post","wordpress_update_tag","wordpress_upload_media","workday_assign_onboarding","workday_change_job","workday_create_prehire","workday_get_compensation","workday_get_organizations","workday_get_worker","workday_hire_employee","workday_list_workers","workday_terminate_worker","workday_update_worker","workflow_executor","x_create_bookmark","x_create_tweet","x_delete_bookmark","x_delete_tweet","x_get_blocking","x_get_bookmarks","x_get_followers","x_get_following","x_get_liked_tweets","x_get_liking_users","x_get_me","x_get_personalized_trends","x_get_quote_tweets","x_get_retweeted_by","x_get_trends_by_woeid","x_get_tweets_by_ids","x_get_usage","x_get_user_mentions","x_get_user_timeline","x_get_user_tweets","x_hide_reply","x_manage_block","x_manage_follow","x_manage_like","x_manage_mute","x_manage_retweet","x_read","x_search","x_search_tweets","x_search_users","x_user","x_write","youcom_answer","youcom_finance_research","youcom_get_account_balance","youcom_get_contents","youcom_get_research_task","youcom_research","youcom_search","youcom_search_images","youtube_channel_info","youtube_channel_playlists","youtube_channel_videos","youtube_comments","youtube_playlist_items","youtube_search","youtube_trending","youtube_video_categories","youtube_video_details","zendesk_autocomplete_organizations","zendesk_create_organization","zendesk_create_organizations_bulk","zendesk_create_ticket","zendesk_create_tickets_bulk","zendesk_create_user","zendesk_create_users_bulk","zendesk_delete_organization","zendesk_delete_ticket","zendesk_delete_user","zendesk_get_current_user","zendesk_get_organization","zendesk_get_organizations","zendesk_get_ticket","zendesk_get_tickets","zendesk_get_user","zendesk_get_users","zendesk_merge_tickets","zendesk_search","zendesk_search_count","zendesk_search_users","zendesk_update_organization","zendesk_update_ticket","zendesk_update_tickets_bulk","zendesk_update_user","zendesk_update_users_bulk","zep_add_messages","zep_add_user","zep_create_thread","zep_delete_thread","zep_get_context","zep_get_messages","zep_get_threads","zep_get_user","zep_get_user_threads","zerobounce_get_credits","zerobounce_verify_email","zoho_desk_add_comment","zoho_desk_get_attachment","zoho_desk_get_contact","zoho_desk_get_thread","zoho_desk_get_ticket","zoho_desk_list_comments","zoho_desk_list_organizations","zoho_desk_list_threads","zoho_desk_list_tickets","zoho_desk_update_ticket","zoom_create_meeting","zoom_delete_meeting","zoom_delete_recording","zoom_get_meeting","zoom_get_meeting_invitation","zoom_get_meeting_recordings","zoom_list_meetings","zoom_list_past_participants","zoom_list_recordings","zoom_update_meeting","zoominfo_enrich_companies","zoominfo_enrich_contacts","zoominfo_search_companies","zoominfo_search_contacts","zoominfo_search_intent","zoominfo_search_news"]' ) export default toolIds diff --git a/apps/sim/tools/generated/tool-metadata.ts b/apps/sim/tools/generated/tool-metadata.ts index 588e941b74b..61e3f033d3d 100644 --- a/apps/sim/tools/generated/tool-metadata.ts +++ b/apps/sim/tools/generated/tool-metadata.ts @@ -3,7 +3,7 @@ /** Serializable metadata for every built-in tool, keyed by tool id. */ const toolMetadata: Record = JSON.parse( - '{"a2a_cancel_task":{"id":"a2a_cancel_task","name":"A2A Cancel Task","description":"Request cancellation of an in-progress A2A task.","version":"1.0.0","params":{"agentUrl":{"type":"string","required":true,"visibility":"user-only","description":"The A2A agent endpoint URL"},"taskId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The task ID to cancel"},"apiKey":{"type":"string","required":false,"visibility":"user-only","description":"API key for authentication (if required)"}},"hostedApiKey":"none"},"a2a_get_agent_card":{"id":"a2a_get_agent_card","name":"A2A Get Agent Card","description":"Fetch the Agent Card (discovery document) for an external A2A agent.","version":"1.0.0","params":{"agentUrl":{"type":"string","required":true,"visibility":"user-only","description":"The A2A agent endpoint URL"},"apiKey":{"type":"string","required":false,"visibility":"user-only","description":"API key for authentication (if required)"}},"hostedApiKey":"none"},"a2a_get_task":{"id":"a2a_get_task","name":"A2A Get Task","description":"Retrieve the current state and result of an A2A task.","version":"1.0.0","params":{"agentUrl":{"type":"string","required":true,"visibility":"user-only","description":"The A2A agent endpoint URL"},"taskId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The task ID to retrieve"},"historyLength":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of history messages to include"},"apiKey":{"type":"string","required":false,"visibility":"user-only","description":"API key for authentication (if required)"}},"hostedApiKey":"none"},"a2a_send_message":{"id":"a2a_send_message","name":"A2A Send Message","description":"Send a message to an external A2A agent and return its response.","version":"1.0.0","params":{"agentUrl":{"type":"string","required":true,"visibility":"user-only","description":"The A2A agent endpoint URL"},"message":{"type":"string","required":true,"visibility":"user-or-llm","description":"The message text to send"},"data":{"type":"json","required":false,"visibility":"user-or-llm","description":"Optional structured JSON data to attach"},"files":{"type":"json","required":false,"visibility":"user-or-llm","description":"Optional files to attach"},"taskId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Existing task ID to continue"},"contextId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Conversation context ID to continue"},"apiKey":{"type":"string","required":false,"visibility":"user-only","description":"API key for authentication (if required)"}},"hostedApiKey":"none"},"affinity_batch_update_entity_fields":{"id":"affinity_batch_update_entity_fields","name":"Affinity Batch Update Entity Fields","description":"Write up to 100 non-list field values on one company or person in a single request.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to write the fields on: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"updates":{"type":"json","required":true,"visibility":"user-or-llm","description":"Up to 100 field updates as [{\\"id\\":\\"\\",\\"value\\":{\\"type\\":\\"…\\",\\"data\\":…}}], using the same value shapes as a single field update"}},"hostedApiKey":"none"},"affinity_batch_update_list_entry_fields":{"id":"affinity_batch_update_list_entry_fields","name":"Affinity Batch Update List Entry Fields","description":"Write up to 100 field values on one list row in a single request. Requires the \\"Export data from Lists\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"updates":{"type":"json","required":true,"visibility":"user-or-llm","description":"Up to 100 field updates as [{\\"id\\":\\"\\",\\"value\\":{\\"type\\":\\"…\\",\\"data\\":…}}], using the same value shapes as a single field update"}},"hostedApiKey":"none"},"affinity_create_list":{"id":"affinity_create_list","name":"Affinity Create List","description":"Create a list. Its type fixes which entities it can hold, and the API key holder becomes its creator and owner.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the new list"},"type":{"type":"string","required":true,"visibility":"user-or-llm","description":"Entity kind the list holds: company, opportunity, or person"},"isPublic":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Whether everyone in the organization can see the list"}},"hostedApiKey":"none"},"affinity_create_list_field_dropdown_option":{"id":"affinity_create_list_field_dropdown_option","name":"Affinity Create List Field Dropdown Option","description":"Add a selectable option to a dropdown field on a list. A ranked or status option also needs a rank and a color.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown field ID on that list"},"type":{"type":"string","required":true,"visibility":"user-or-llm","description":"Kind of option to create, matching the field. dropdown takes only a label; ranked-dropdown also requires rank and color; status-dropdown additionally requires a status category. Sending a field the kind does not accept is rejected"},"text":{"type":"string","required":true,"visibility":"user-or-llm","description":"The option label"},"rank":{"type":"number","required":false,"visibility":"user-or-llm","description":"Sort order. Required on a ranked-dropdown or status-dropdown option"},"color":{"type":"string","required":false,"visibility":"user-or-llm","description":"Option color: white, gray, blue, green, purple, orange, or red. Required on a ranked-dropdown or status-dropdown option"},"statusCategory":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pipeline meaning of the option: open, won, lost, or on-hold. Status-dropdown options only"},"winRate":{"type":"number","required":false,"visibility":"user-or-llm","description":"Expected win rate of the status. Status-dropdown options only"}},"hostedApiKey":"none"},"affinity_create_merge":{"id":"affinity_create_merge","name":"Affinity Create Merge","description":"Fold a duplicate company or person into the record you are keeping. The merge runs asynchronously — poll the returned task to see it finish. Requires the \\"Manage duplicates\\" permission and an admin role.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"What to merge: companies or persons"},"primaryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to keep"},"duplicateId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the duplicate record to fold in"}},"hostedApiKey":"none"},"affinity_create_note":{"id":"affinity_create_note","name":"Affinity Create Note","description":"Write a note — attached to companies, persons, and opportunities, anchored to a meeting, call, or chat message, or posted as a reply to an existing note.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"type":{"type":"string","required":true,"visibility":"user-or-llm","description":"Note shape: entities to attach it to records, interaction to anchor it to a meeting, call, or chat message, or user-reply to reply to a note"},"html":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note body as HTML"},"companyIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Companies to attach the note to, e.g. [1, 2]. Not used on a reply"},"personIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Persons to attach the note to, e.g. [1, 2]. Not used on a reply"},"opportunityIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Opportunities to attach the note to, e.g. [1, 2]. Not used on a reply"},"interactionId":{"type":"string","required":false,"visibility":"user-or-llm","description":"The interaction to anchor the note to. Required for an interaction note"},"interactionType":{"type":"string","required":false,"visibility":"user-or-llm","description":"Kind of the anchoring interaction: meeting, call, or chat-message. Required for an interaction note"},"parentId":{"type":"string","required":false,"visibility":"user-or-llm","description":"The note being replied to. Required for a user-reply note"},"creatorId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Attribute the note to another internal person. Defaults to the API key holder"},"createdAt":{"type":"string","required":false,"visibility":"user-or-llm","description":"Backdate the note to this ISO 8601 timestamp"}},"hostedApiKey":"none"},"affinity_create_reminder":{"id":"affinity_create_reminder","name":"Affinity Create Reminder","description":"Create a reminder on one company, person, or opportunity. A recurring reminder resets whenever the chosen signal happens instead of firing once.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"type":{"type":"string","required":true,"visibility":"user-or-llm","description":"one-time to fire once, or recurring to reset on a signal"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"What the reminder is about: company, person, or opportunity"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company, person, or opportunity"},"dueDate":{"type":"string","required":false,"visibility":"user-or-llm","description":"When the reminder is due, as an ISO 8601 timestamp. Required for a one-time reminder; on a recurring one Affinity computes it from the period when omitted"},"content":{"type":"string","required":false,"visibility":"user-or-llm","description":"What the reminder says"},"ownerId":{"type":"string","required":true,"visibility":"user-or-llm","description":"User the reminder is assigned to. Must be an internal user. The API key holder is recorded as the creator, which is a separate field"},"resetTrigger":{"type":"string","required":false,"visibility":"user-or-llm","description":"What restarts a recurring reminder: interaction, email, or event. Required when the type is recurring"},"periodDays":{"type":"number","required":false,"visibility":"user-or-llm","description":"Days between firings of a recurring reminder. Required when the type is recurring"}},"hostedApiKey":"none"},"affinity_delete_list_field_dropdown_option":{"id":"affinity_delete_list_field_dropdown_option","name":"Affinity Delete List Field Dropdown Option","description":"Permanently delete a dropdown option on a list field. Every list entry currently set to it is cleared, and those values cannot be recovered.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown field ID on that list"},"dropdownOptionId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown option ID to delete"}},"hostedApiKey":"none"},"affinity_delete_note":{"id":"affinity_delete_note","name":"Affinity Delete Note","description":"Delete a note you created. Deleting a root note also deletes its replies; deleting a reply removes only that reply.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID to delete"}},"hostedApiKey":"none"},"affinity_get_company":{"id":"affinity_get_company","name":"Affinity Get Company","description":"Look up one company by ID. Field data is returned only for the Field IDs or Field Types asked for.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"companyId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The company ID"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"}},"hostedApiKey":"none"},"affinity_get_current_user":{"id":"affinity_get_current_user","name":"Affinity Get Current User","description":"Verify an Affinity API key and return the tenant, the user behind the key, and the scopes the grant carries.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"}},"hostedApiKey":"none"},"affinity_get_entity_field_value":{"id":"affinity_get_entity_field_value","name":"Affinity Get Entity Field Value","description":"Read one non-list field value from a company or person.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to read the field from: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The field ID to read"}},"hostedApiKey":"none"},"affinity_get_list":{"id":"affinity_get_list","name":"Affinity Get List","description":"Read one list — its name, type, owner, and privacy setting.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"}},"hostedApiKey":"none"},"affinity_get_list_entry":{"id":"affinity_get_list_entry","name":"Affinity Get List Entry","description":"Read one row of a list with its entity. Field data is returned only for the Field IDs or Field Types asked for.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, list, or relationship-intelligence. Mutually exclusive with Field IDs"}},"hostedApiKey":"none"},"affinity_get_list_entry_field":{"id":"affinity_get_list_entry_field","name":"Affinity Get List Entry Field","description":"Read one field value on a list row.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The field ID to read"}},"hostedApiKey":"none"},"affinity_get_list_field_dropdown_option":{"id":"affinity_get_list_field_dropdown_option","name":"Affinity Get List Field Dropdown Option","description":"Read one dropdown option on a list field.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown field ID on that list"},"dropdownOptionId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown option ID"}},"hostedApiKey":"none"},"affinity_get_merge":{"id":"affinity_get_merge","name":"Affinity Get Merge","description":"Read the status of one company or person merge, including why it failed if it did.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which merge to read: companies or persons"},"mergeId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The merge ID"}},"hostedApiKey":"none"},"affinity_get_merge_task":{"id":"affinity_get_merge_task","name":"Affinity Get Merge Task","description":"Read one merge task and how its merges are progressing. Poll this after starting a merge.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which merge task to read: companies or persons"},"taskId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The merge task ID"}},"hostedApiKey":"none"},"affinity_get_note":{"id":"affinity_get_note","name":"Affinity Get Note","description":"Read one note with its body, author, mentions, and attached records.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID"},"includes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Extra properties to return, e.g. [\\"repliesCount\\",\\"personsPreview\\",\\"companiesPreview\\",\\"opportunitiesPreview\\"]. Those four fields are omitted unless requested here"}},"hostedApiKey":"none"},"affinity_get_opportunity":{"id":"affinity_get_opportunity","name":"Affinity Get Opportunity","description":"Read one opportunity and the list it belongs to. Its field data lives on the list entry.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"opportunityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The opportunity ID"}},"hostedApiKey":"none"},"affinity_get_person":{"id":"affinity_get_person","name":"Affinity Get Person","description":"Look up one person by ID. Field data is returned only for the Field IDs or Field Types asked for.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"personId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The person ID"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"}},"hostedApiKey":"none"},"affinity_get_saved_view":{"id":"affinity_get_saved_view","name":"Affinity Get Saved View","description":"Read one saved view — its name, kind, and creation date.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"viewId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The saved view ID"}},"hostedApiKey":"none"},"affinity_get_transcript":{"id":"affinity_get_transcript","name":"Affinity Get Transcript","description":"Read one transcript with its first 100 fragments. Page the fragments endpoint for a longer meeting.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"transcriptId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The transcript ID"}},"hostedApiKey":"none"},"affinity_get_user":{"id":"affinity_get_user","name":"Affinity Get User","description":"Read one internal user. A user and their person record share the same numeric ID, so a person ID works here.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"userId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The user ID, which is also their person ID"}},"hostedApiKey":"none"},"affinity_list_calls":{"id":"affinity_list_calls","name":"Affinity List Calls","description":"Page through logged calls and their participants. Only calls the API key holder can see are returned.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_chat_messages":{"id":"affinity_list_chat_messages","name":"Affinity List Chat Messages","description":"Page through logged chat messages and their participants. Only messages the API key holder can see are returned.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_companies":{"id":"affinity_list_companies","name":"Affinity List Companies","description":"Page through companies. Companies come back without field data unless Field IDs or Field Types asks for it.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the page to these company IDs, e.g. [1, 2, 3]"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_coworker_connections":{"id":"affinity_list_coworker_connections","name":"Affinity List Coworker Connections","description":"Find warm paths into a company through shared work history: who in your Affinity data once worked alongside the people you want to reach. Grouped by target, strongest first.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":true,"visibility":"user-or-llm","description":"Required scope. The only supported filter is target.currentCompany.id, e.g. \\"target.currentCompany.id=123\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of targets to return per page, 1-50. Defaults to 20"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_emails":{"id":"affinity_list_emails","name":"Affinity List Emails","description":"Page through email metadata — subject, participants, and timestamps. Affinity never exposes email bodies through the API.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_entity_field_values":{"id":"affinity_list_entity_field_values","name":"Affinity List Entity Field Values","description":"Page through a company\'s or person\'s non-list field values. List fields are not returned here — read those through the list entry.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to read field values from: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict to these field IDs. Mutually exclusive with Field Types"},"types":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict to these field categories: enriched, global, relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 20"}},"hostedApiKey":"none"},"affinity_list_entity_list_entries":{"id":"affinity_list_entity_list_entries","name":"Affinity List Entity List Entries","description":"Page through a company\'s or person\'s rows across every list, each carrying that list\'s field values and when the entity was added.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to look up the rows of: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_entity_lists":{"id":"affinity_list_entity_lists","name":"Affinity List Entity Lists","description":"List every list a company or person appears on that the caller can view.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to look up the lists of: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_entity_notes":{"id":"affinity_list_entity_notes","name":"Affinity List Entity Notes","description":"List the notes relevant to one company, person, or opportunity — directly attached notes plus notes reaching it through its people and meetings.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity the notes hang off: companies, persons, or opportunities"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company, person, or opportunity"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_entity_relationships":{"id":"affinity_list_entity_relationships","name":"Affinity List Entity Relationships","description":"List who knows a company or person, scored 0.0 to 1.0 by how much the two actually interact. Strongest first by default.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to look up relationships for: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression. This endpoint filters on interactionScore only, e.g. \\"interactionScore>=0.5\\""},"orderBy":{"type":"json","required":false,"visibility":"user-or-llm","description":"Sort order: [\\"interactionScore\\"] for weakest first, [\\"-interactionScore\\"] for strongest first (the default)"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_field_dropdown_options":{"id":"affinity_list_field_dropdown_options","name":"Affinity List Field Dropdown Options","description":"List the selectable options on a dropdown or ranked-dropdown company or person field. Writing such a field needs the option ID, not its text.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which field family the field belongs to: companies or persons"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown or ranked-dropdown field ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_field_metadata":{"id":"affinity_list_field_metadata","name":"Affinity List Field Metadata","description":"List the non-list company or person fields, with the value type, filter operators, and sort support of each. Start here to find the Field IDs the read and write tools take.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which fields to describe: companies or persons"},"includes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Extra properties to return: [\\"filterability\\",\\"sortability\\"]. Both are omitted unless requested here"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression. This endpoint filters on name only, e.g. \\"name=~Status\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_field_value_changes":{"id":"affinity_list_field_value_changes","name":"Affinity List Field Value Changes","description":"Page through field value changes across the whole workspace. Built for delta sync: follow nextCursor to the end of a run, then resume from the last cursor next time.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression over field.id, listEntry.id, changer.id, changedAt, or actionType. Resume a sync with e.g. \\"changedAt>2026-06-01T12:00:00Z\\""},"orderBy":{"type":"json","required":false,"visibility":"user-or-llm","description":"Sort order: [\\"changedAt\\"] for oldest first (the default), [\\"-changedAt\\"] for newest first"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_investor_executive_connections":{"id":"affinity_list_investor_executive_connections","name":"Affinity List Investor Executive Connections","description":"Find warm paths into a company through investment history: which investors in your Affinity data backed a company the people you want to reach once led. Grouped by target, strongest first.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":true,"visibility":"user-or-llm","description":"Required scope. The only supported filter is target.currentCompany.id, e.g. \\"target.currentCompany.id=123\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of targets to return per page, 1-50. Defaults to 20"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_list_entries":{"id":"affinity_list_list_entries","name":"Affinity List List Entries","description":"Page through the rows of a list. Rows come back without field data unless Field IDs or Field Types asks for it.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, list, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_list_entry_field_value_changes":{"id":"affinity_list_list_entry_field_value_changes","name":"Affinity List List Entry Field Value Changes","description":"Page through the history of one list row — who changed which field, when, and to what.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression over field.id, changer.id, changedAt, or actionType, e.g. \\"field.id=field-1234\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_list_entry_fields":{"id":"affinity_list_list_entry_fields","name":"Affinity List List Entry Fields","description":"Page through every field value on one list row, including the list-specific columns. All fields are returned unless narrowed.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict to these field IDs. Mutually exclusive with Field Types"},"types":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict to these field categories: enriched, global, list, relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 20"}},"hostedApiKey":"none"},"affinity_list_list_field_dropdown_options":{"id":"affinity_list_list_field_dropdown_options","name":"Affinity List List Field Dropdown Options","description":"List the selectable options on a dropdown, ranked-dropdown, or status-dropdown field of a list.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown field ID on that list"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_list_fields":{"id":"affinity_list_list_fields","name":"Affinity List List Fields","description":"List the fields available on one list, including its list-specific columns. Use these Field IDs when reading or writing list entries.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"includes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Extra properties to return: [\\"filterability\\",\\"sortability\\"]. Both are omitted unless requested here"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression. This endpoint filters on name only, e.g. \\"name=~Stage\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_lists":{"id":"affinity_list_lists","name":"Affinity List Lists","description":"Page through the lists in the organization that the caller can view.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"term":{"type":"string","required":false,"visibility":"user-or-llm","description":"Case-insensitive substring match on the list name"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_meetings":{"id":"affinity_list_meetings","name":"Affinity List Meetings","description":"Page through past and upcoming meetings with their organizer and attendees.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_merge_tasks":{"id":"affinity_list_merge_tasks","name":"Affinity List Merge Tasks","description":"Page through merge tasks, each summarizing how many of its merges are in progress, succeeded, or failed.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which merge tasks to list: companies or persons"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression. This endpoint filters on status only, e.g. \\"status=in-progress\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_merges":{"id":"affinity_list_merges","name":"Affinity List Merges","description":"Page through the company or person merges the organization has run, with the status and the records involved in each.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which merges to list: companies or persons"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression over status or taskId, e.g. \\"status=failed\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_note_attached_companies":{"id":"affinity_list_note_attached_companies","name":"Affinity List Note Attached Companies","description":"List the companies directly attached to one note.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_note_attached_opportunities":{"id":"affinity_list_note_attached_opportunities","name":"Affinity List Note Attached Opportunities","description":"List the opportunities directly attached to one note.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_note_attached_persons":{"id":"affinity_list_note_attached_persons","name":"Affinity List Note Attached Persons","description":"List the persons directly attached to one note.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_note_replies":{"id":"affinity_list_note_replies","name":"Affinity List Note Replies","description":"Page through the replies on one note, including AI Notetaker replies.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID whose replies to read"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_notes":{"id":"affinity_list_notes","name":"Affinity List Notes","description":"Page through every note the caller can see. Replies are excluded.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"includes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Extra properties to return, e.g. [\\"repliesCount\\",\\"personsPreview\\",\\"companiesPreview\\",\\"opportunitiesPreview\\"]. Those four fields are omitted unless requested here"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_opportunities":{"id":"affinity_list_opportunities","name":"Affinity List Opportunities","description":"Page through opportunities. Field data lives on the list entry, not here — read it through the list or saved view the opportunity belongs to.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the page to these opportunity IDs, e.g. [1, 2, 3]"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_persons":{"id":"affinity_list_persons","name":"Affinity List Persons","description":"Page through persons. Persons come back without field data unless Field IDs or Field Types asks for it.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the page to these person IDs, e.g. [1, 2, 3]"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_reminders":{"id":"affinity_list_reminders","name":"Affinity List Reminders","description":"Page through the reminders the caller can see. Filter by status to surface what is overdue.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_saved_view_entries":{"id":"affinity_list_saved_view_entries","name":"Affinity List Saved View Entries","description":"Page through the rows of a saved view. The view\'s own filters and columns decide which rows and which field data come back.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"viewId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The saved view ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_saved_views":{"id":"affinity_list_saved_views","name":"Affinity List Saved Views","description":"List the saved views on a list that the caller can view.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_list_transcript_fragments":{"id":"affinity_list_transcript_fragments","name":"Affinity List Transcript Fragments","description":"Page through everything said in a meeting, segment by segment with the speaker.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"transcriptId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The transcript ID"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_transcripts":{"id":"affinity_list_transcripts","name":"Affinity List Transcripts","description":"Page through meeting transcript metadata. Read one transcript to get what was actually said.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression, e.g. \\"createdAt>=2026-01-01\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_list_users":{"id":"affinity_list_users","name":"Affinity List Users","description":"Page through the internal users in the organization. Email addresses and roles are returned only to callers with the \\"Manage Users\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"term":{"type":"string","required":false,"visibility":"user-or-llm","description":"Case-insensitive match across first name, last name, and primary email"},"filter":{"type":"string","required":false,"visibility":"user-or-llm","description":"Affinity Filtering Language expression over id or status, e.g. \\"status=active\\""},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_search_companies":{"id":"affinity_search_companies","name":"Affinity Search Companies","description":"Search companies by filters, sorts, and a free-text term. Requires the \\"Export All Organizations directory\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Filter group as {operator: \\"and\\"|\\"or\\", filters: [...]}, at most 50 leaves. Each leaf is {valueType, fieldId, operator, value}, and a leaf may itself be a nested group"},"searchTerm":{"type":"string","required":false,"visibility":"user-or-llm","description":"Free-text term matched against the searchable fields. At least 3 characters"},"searchFieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs the search term is matched against. Defaults to the searchable fields"},"sorts":{"type":"json","required":false,"visibility":"user-or-llm","description":"Sort order as [{fieldId, direction: \\"asc\\"|\\"desc\\", attributeId?}], up to 5, applied in order"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_search_files":{"id":"affinity_search_files","name":"Affinity Search Files","description":"Search files by keyword, ordered by relevance. Narrow to specific files or to one company, or leave both unset to search the whole account.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"prompt":{"type":"string","required":true,"visibility":"user-or-llm","description":"What to search for. Between 3 and 500 characters"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the search to these file IDs. Cannot be combined with Company ID"},"companyId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Restrict the search to one company\'s files. Cannot be combined with file IDs"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of files to return, 1-100. Defaults to 20"}},"hostedApiKey":"none"},"affinity_search_list_entries":{"id":"affinity_search_list_entries","name":"Affinity Search List Entries","description":"Search the rows of one list by filters, sorts, and a free-text term. Requires the \\"Export data from Lists\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID to search"},"filters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Filter group as {operator: \\"and\\"|\\"or\\", filters: [...]}, at most 50 leaves. Each leaf is {valueType, fieldId, operator, value}, and a leaf may itself be a nested group"},"searchTerm":{"type":"string","required":false,"visibility":"user-or-llm","description":"Free-text term matched against the searchable fields. At least 3 characters"},"searchFieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs the search term is matched against. Defaults to the searchable fields"},"sorts":{"type":"json","required":false,"visibility":"user-or-llm","description":"Sort order as [{fieldId, direction: \\"asc\\"|\\"desc\\", attributeId?}], up to 5, applied in order"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, list, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_search_notes":{"id":"affinity_search_notes","name":"Affinity Search Notes","description":"Search notes by keyword, ordered by relevance. Narrow to specific notes or to one company, or leave both unset to search the whole account.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"prompt":{"type":"string","required":true,"visibility":"user-or-llm","description":"What to search for. Between 3 and 500 characters"},"ids":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the search to these note IDs. Cannot be combined with Company ID"},"companyId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Restrict the search to one company\'s notes. Cannot be combined with note IDs"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of notes to return, 1-100. Defaults to 20"}},"hostedApiKey":"none"},"affinity_search_persons":{"id":"affinity_search_persons","name":"Affinity Search Persons","description":"Search persons by filters, sorts, and a free-text term. Requires the \\"Export All People directory\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"filters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Filter group as {operator: \\"and\\"|\\"or\\", filters: [...]}, at most 50 leaves. Each leaf is {valueType, fieldId, operator, value}, and a leaf may itself be a nested group"},"searchTerm":{"type":"string","required":false,"visibility":"user-or-llm","description":"Free-text term matched against the searchable fields. At least 3 characters"},"searchFieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs the search term is matched against. Defaults to the searchable fields"},"sorts":{"type":"json","required":false,"visibility":"user-or-llm","description":"Sort order as [{fieldId, direction: \\"asc\\"|\\"desc\\", attributeId?}], up to 5, applied in order"},"fieldIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field IDs to return values for, e.g. [\\"affinity-data-location\\"]. Mutually exclusive with Field Types"},"fieldTypes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Field categories to return values for: enriched, global, or relationship-intelligence. Mutually exclusive with Field IDs"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous page, returned as nextCursor or prevCursor"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to return per page, 1-100. Defaults to 100"},"totalCount":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the total size of the collection. Costs an extra query"}},"hostedApiKey":"none"},"affinity_semantic_search":{"id":"affinity_semantic_search","name":"Affinity Semantic Search","description":"Find companies from a description in plain language — industry, technology, stage, or business model. Currently searches companies only.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"prompt":{"type":"string","required":true,"visibility":"user-or-llm","description":"What to look for, in plain language, e.g. \\"climate tech companies in our pipeline\\". Up to 500 characters"},"listIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Restrict the search to companies on these lists, e.g. [1, 2]"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of companies to return, 1-100. Defaults to 100"}},"hostedApiKey":"none"},"affinity_update_entity_field_value":{"id":"affinity_update_entity_field_value","name":"Affinity Update Entity Field Value","description":"Write one non-list field value on a company or person. The value type must match how the field is defined.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"entityType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Which entity to write the field on: companies or persons"},"entityId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of that company or person"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The field ID to write"},"value":{"type":"json","required":true,"visibility":"user-or-llm","description":"The new value as {type, data}, where type matches the field\'s value type. Examples: {\\"type\\":\\"text\\",\\"data\\":\\"Series B\\"}, {\\"type\\":\\"number\\",\\"data\\":42}, {\\"type\\":\\"dropdown\\",\\"data\\":{\\"dropdownOptionId\\":7}}, {\\"type\\":\\"person\\",\\"data\\":{\\"id\\":123}}, {\\"type\\":\\"person-multi\\",\\"data\\":[{\\"id\\":123}]}. Pass data as null to clear the field"}},"hostedApiKey":"none"},"affinity_update_list_entry_field":{"id":"affinity_update_list_entry_field","name":"Affinity Update List Entry Field","description":"Write one field value on a list row. Requires the \\"Export data from Lists\\" permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"listEntryId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list entry ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The field ID to write"},"value":{"type":"json","required":true,"visibility":"user-or-llm","description":"The new value as {type, data}, where type matches the field\'s value type. Examples: {\\"type\\":\\"text\\",\\"data\\":\\"Series B\\"}, {\\"type\\":\\"number\\",\\"data\\":42}, {\\"type\\":\\"dropdown\\",\\"data\\":{\\"dropdownOptionId\\":7}}, {\\"type\\":\\"person\\",\\"data\\":{\\"id\\":123}}, {\\"type\\":\\"person-multi\\",\\"data\\":[{\\"id\\":123}]}. Pass data as null to clear the field"}},"hostedApiKey":"none"},"affinity_update_list_field_dropdown_option":{"id":"affinity_update_list_field_dropdown_option","name":"Affinity Update List Field Dropdown Option","description":"Change a dropdown option on a list field. Every field is optional — supply only what should change, and only fields the option\'s kind actually has.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"listId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The list ID"},"fieldId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown field ID on that list"},"dropdownOptionId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The dropdown option ID to update"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Replacement option label. Supply at least one field to change"},"rank":{"type":"number","required":false,"visibility":"user-or-llm","description":"Sort order. Required on a ranked-dropdown or status-dropdown option"},"color":{"type":"string","required":false,"visibility":"user-or-llm","description":"Option color: white, gray, blue, green, purple, orange, or red. Required on a ranked-dropdown or status-dropdown option"},"statusCategory":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pipeline meaning of the option: open, won, lost, or on-hold. Status-dropdown options only"},"winRate":{"type":"number","required":false,"visibility":"user-or-llm","description":"Expected win rate of the status. Status-dropdown options only"}},"hostedApiKey":"none"},"affinity_update_note":{"id":"affinity_update_note","name":"Affinity Update Note","description":"Rewrite a note\'s body or replace which records it is attached to. Each list of IDs replaces that association wholesale, an empty list clears it, and omitting one leaves it untouched. A note\'s type cannot be changed.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Affinity API key, sent as a bearer token"},"noteId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note ID to update"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"Replacement note body as HTML"},"companyIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Replacement set of attached companies, e.g. [1, 2]. Send [] to detach every company; omit to leave them unchanged"},"personIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Replacement set of attached persons, e.g. [1, 2]. Send [] to detach every person; omit to leave them unchanged"},"opportunityIds":{"type":"json","required":false,"visibility":"user-or-llm","description":"Replacement set of attached opportunities, e.g. [1, 2]. Send [] to detach every opportunity; omit to leave them unchanged"}},"hostedApiKey":"none"},"agentmail_create_draft":{"id":"agentmail_create_draft","name":"Create Draft","description":"Create a new email draft in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to create the draft in"},"to":{"type":"string","required":false,"visibility":"user-or-llm","description":"Recipient email addresses (comma-separated)"},"subject":{"type":"string","required":false,"visibility":"user-or-llm","description":"Draft subject line"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Plain text draft body"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"HTML draft body"},"cc":{"type":"string","required":false,"visibility":"user-or-llm","description":"CC recipient email addresses (comma-separated)"},"bcc":{"type":"string","required":false,"visibility":"user-or-llm","description":"BCC recipient email addresses (comma-separated)"},"inReplyTo":{"type":"string","required":false,"visibility":"user-or-llm","description":"ID of message being replied to"},"sendAt":{"type":"string","required":false,"visibility":"user-or-llm","description":"ISO 8601 timestamp to schedule sending"}},"hostedApiKey":"none"},"agentmail_create_inbox":{"id":"agentmail_create_inbox","name":"Create Inbox","description":"Create a new email inbox with AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"username":{"type":"string","required":false,"visibility":"user-or-llm","description":"Username for the inbox email address"},"domain":{"type":"string","required":false,"visibility":"user-or-llm","description":"Domain for the inbox email address"},"displayName":{"type":"string","required":false,"visibility":"user-or-llm","description":"Display name for the inbox"}},"hostedApiKey":"none"},"agentmail_delete_draft":{"id":"agentmail_delete_draft","name":"Delete Draft","description":"Delete an email draft in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the draft"},"draftId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the draft to delete"}},"hostedApiKey":"none"},"agentmail_delete_inbox":{"id":"agentmail_delete_inbox","name":"Delete Inbox","description":"Delete an email inbox in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to delete"}},"hostedApiKey":"none"},"agentmail_delete_thread":{"id":"agentmail_delete_thread","name":"Delete Thread","description":"Delete an email thread in AgentMail (moves to trash, or permanently deletes if already in trash)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the thread"},"threadId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the thread to delete"},"permanent":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Force permanent deletion instead of moving to trash"}},"hostedApiKey":"none"},"agentmail_forward_message":{"id":"agentmail_forward_message","name":"Forward Message","description":"Forward an email message to new recipients in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the message"},"messageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the message to forward"},"to":{"type":"string","required":true,"visibility":"user-or-llm","description":"Recipient email addresses (comma-separated)"},"subject":{"type":"string","required":false,"visibility":"user-or-llm","description":"Override subject line"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Additional plain text to prepend"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"Additional HTML to prepend"},"cc":{"type":"string","required":false,"visibility":"user-or-llm","description":"CC recipient email addresses (comma-separated)"},"bcc":{"type":"string","required":false,"visibility":"user-or-llm","description":"BCC recipient email addresses (comma-separated)"}},"hostedApiKey":"none"},"agentmail_get_draft":{"id":"agentmail_get_draft","name":"Get Draft","description":"Get details of a specific email draft in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox the draft belongs to"},"draftId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the draft to retrieve"}},"hostedApiKey":"none"},"agentmail_get_inbox":{"id":"agentmail_get_inbox","name":"Get Inbox","description":"Get details of a specific email inbox in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to retrieve"}},"hostedApiKey":"none"},"agentmail_get_message":{"id":"agentmail_get_message","name":"Get Message","description":"Get details of a specific email message in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the message"},"messageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the message to retrieve"}},"hostedApiKey":"none"},"agentmail_get_thread":{"id":"agentmail_get_thread","name":"Get Thread","description":"Get details of a specific email thread including messages in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the thread"},"threadId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the thread to retrieve"}},"hostedApiKey":"none"},"agentmail_list_drafts":{"id":"agentmail_list_drafts","name":"List Drafts","description":"List email drafts in an inbox in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to list drafts from"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of drafts to return"},"pageToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token for next page of results"}},"hostedApiKey":"none"},"agentmail_list_inboxes":{"id":"agentmail_list_inboxes","name":"List Inboxes","description":"List all email inboxes in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of inboxes to return"},"pageToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token for next page of results"}},"hostedApiKey":"none"},"agentmail_list_messages":{"id":"agentmail_list_messages","name":"List Messages","description":"List messages in an inbox in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to list messages from"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of messages to return"},"pageToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token for next page of results"}},"hostedApiKey":"none"},"agentmail_list_threads":{"id":"agentmail_list_threads","name":"List Threads","description":"List email threads in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to list threads from"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of threads to return"},"pageToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token for next page of results"},"labels":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated labels to filter threads by"},"before":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter threads before this ISO 8601 timestamp"},"after":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter threads after this ISO 8601 timestamp"}},"hostedApiKey":"none"},"agentmail_reply_message":{"id":"agentmail_reply_message","name":"Reply to Message","description":"Reply to an existing email message in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to reply from"},"messageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the message to reply to"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Plain text reply body"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"HTML reply body"},"to":{"type":"string","required":false,"visibility":"user-or-llm","description":"Override recipient email addresses (comma-separated)"},"cc":{"type":"string","required":false,"visibility":"user-or-llm","description":"CC email addresses (comma-separated)"},"bcc":{"type":"string","required":false,"visibility":"user-or-llm","description":"BCC email addresses (comma-separated)"},"replyAll":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Reply to all recipients of the original message"}},"hostedApiKey":"none"},"agentmail_send_draft":{"id":"agentmail_send_draft","name":"Send Draft","description":"Send an existing email draft in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the draft"},"draftId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the draft to send"}},"hostedApiKey":"none"},"agentmail_send_message":{"id":"agentmail_send_message","name":"Send Message","description":"Send an email message from an AgentMail inbox","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to send from"},"to":{"type":"string","required":true,"visibility":"user-or-llm","description":"Recipient email address (comma-separated for multiple)"},"subject":{"type":"string","required":true,"visibility":"user-or-llm","description":"Email subject line"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Plain text email body"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"HTML email body"},"cc":{"type":"string","required":false,"visibility":"user-or-llm","description":"CC recipient email addresses (comma-separated)"},"bcc":{"type":"string","required":false,"visibility":"user-or-llm","description":"BCC recipient email addresses (comma-separated)"}},"hostedApiKey":"none"},"agentmail_update_draft":{"id":"agentmail_update_draft","name":"Update Draft","description":"Update an existing email draft in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the draft"},"draftId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the draft to update"},"to":{"type":"string","required":false,"visibility":"user-or-llm","description":"Recipient email addresses (comma-separated)"},"subject":{"type":"string","required":false,"visibility":"user-or-llm","description":"Draft subject line"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Plain text draft body"},"html":{"type":"string","required":false,"visibility":"user-or-llm","description":"HTML draft body"},"cc":{"type":"string","required":false,"visibility":"user-or-llm","description":"CC recipient email addresses (comma-separated)"},"bcc":{"type":"string","required":false,"visibility":"user-or-llm","description":"BCC recipient email addresses (comma-separated)"},"sendAt":{"type":"string","required":false,"visibility":"user-or-llm","description":"ISO 8601 timestamp to schedule sending"}},"hostedApiKey":"none"},"agentmail_update_inbox":{"id":"agentmail_update_inbox","name":"Update Inbox","description":"Update the display name of an email inbox in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox to update"},"displayName":{"type":"string","required":true,"visibility":"user-or-llm","description":"New display name for the inbox"}},"hostedApiKey":"none"},"agentmail_update_message":{"id":"agentmail_update_message","name":"Update Message","description":"Add or remove labels on an email message in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the message"},"messageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the message to update"},"addLabels":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated labels to add to the message"},"removeLabels":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated labels to remove from the message"}},"hostedApiKey":"none"},"agentmail_update_thread":{"id":"agentmail_update_thread","name":"Update Thread Labels","description":"Add or remove labels on an email thread in AgentMail","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentMail API key"},"inboxId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the inbox containing the thread"},"threadId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the thread to update"},"addLabels":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated labels to add to the thread"},"removeLabels":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated labels to remove from the thread"}},"hostedApiKey":"none"},"agentphone_create_call":{"id":"agentphone_create_call","name":"Create Outbound Call","description":"Initiate an outbound voice call from an AgentPhone agent","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"agentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Agent that will handle the call"},"toNumber":{"type":"string","required":true,"visibility":"user-or-llm","description":"Phone number to call in E.164 format (e.g. +14155551234)"},"fromNumberId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Phone number ID to use as caller ID. Must belong to the agent. If omitted, the agent\'s first assigned number is used."},"initialGreeting":{"type":"string","required":false,"visibility":"user-or-llm","description":"Optional greeting spoken when the recipient answers"},"voice":{"type":"string","required":false,"visibility":"user-or-llm","description":"Voice ID override for this call (defaults to the agent\'s configured voice)"},"systemPrompt":{"type":"string","required":false,"visibility":"user-or-llm","description":"When provided, uses a built-in LLM for the conversation instead of forwarding to your webhook"}},"hostedApiKey":"none"},"agentphone_create_contact":{"id":"agentphone_create_contact","name":"Create Contact","description":"Create a new contact in AgentPhone","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"phoneNumber":{"type":"string","required":true,"visibility":"user-or-llm","description":"Phone number in E.164 format (e.g. +14155551234)"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Contact\'s full name"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"Contact\'s email address"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"Freeform notes stored on the contact"}},"hostedApiKey":"none"},"agentphone_create_number":{"id":"agentphone_create_number","name":"Create Phone Number","description":"Provision a new SMS- and voice-enabled phone number","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Two-letter country code (e.g. US, CA). Defaults to US."},"areaCode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Preferred area code (US/CA only, e.g. \\"415\\"). Best-effort — may be ignored if unavailable."},"agentId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Optionally attach the number to an agent immediately"}},"hostedApiKey":"none"},"agentphone_delete_contact":{"id":"agentphone_delete_contact","name":"Delete Contact","description":"Delete a contact by ID","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"contactId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Contact ID"}},"hostedApiKey":"none"},"agentphone_get_call":{"id":"agentphone_get_call","name":"Get Call","description":"Fetch a call and its full transcript","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"callId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the call to retrieve"}},"hostedApiKey":"none"},"agentphone_get_call_transcript":{"id":"agentphone_get_call_transcript","name":"Get Call Transcript","description":"Get the full ordered transcript for a call","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"callId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the call to retrieve the transcript for"}},"hostedApiKey":"none"},"agentphone_get_contact":{"id":"agentphone_get_contact","name":"Get Contact","description":"Fetch a single contact by ID","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"contactId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Contact ID"}},"hostedApiKey":"none"},"agentphone_get_conversation":{"id":"agentphone_get_conversation","name":"Get Conversation","description":"Get a conversation along with its recent messages","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"conversationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Conversation ID"},"messageLimit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of recent messages to include (default 50, max 100)"}},"hostedApiKey":"none"},"agentphone_get_conversation_messages":{"id":"agentphone_get_conversation_messages","name":"Get Conversation Messages","description":"Get paginated messages for a conversation","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"conversationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Conversation ID"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of messages to return (default 50, max 200)"},"before":{"type":"string","required":false,"visibility":"user-or-llm","description":"Return messages received before this ISO 8601 timestamp"},"after":{"type":"string","required":false,"visibility":"user-or-llm","description":"Return messages received after this ISO 8601 timestamp"}},"hostedApiKey":"none"},"agentphone_get_number_messages":{"id":"agentphone_get_number_messages","name":"Get Phone Number Messages","description":"Fetch messages received on a specific phone number","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"numberId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the phone number"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of messages to return (default 50, max 200)"},"before":{"type":"string","required":false,"visibility":"user-or-llm","description":"Return messages received before this ISO 8601 timestamp"},"after":{"type":"string","required":false,"visibility":"user-or-llm","description":"Return messages received after this ISO 8601 timestamp"}},"hostedApiKey":"none"},"agentphone_get_usage":{"id":"agentphone_get_usage","name":"Get Usage","description":"Retrieve current usage statistics for the AgentPhone account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"}},"hostedApiKey":"none"},"agentphone_get_usage_daily":{"id":"agentphone_get_usage_daily","name":"Get Daily Usage","description":"Get a daily breakdown of usage (messages, calls, webhooks) for the last N days","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"days":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of days to return (1-365, default 30)"}},"hostedApiKey":"none"},"agentphone_get_usage_monthly":{"id":"agentphone_get_usage_monthly","name":"Get Monthly Usage","description":"Get monthly usage aggregation (messages, calls, webhooks) for the last N months","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"months":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of months to return (1-24, default 6)"}},"hostedApiKey":"none"},"agentphone_list_calls":{"id":"agentphone_list_calls","name":"List Calls","description":"List voice calls for this AgentPhone account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to return (default 20, max 100)"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to skip (min 0)"},"status":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter by status (completed, in-progress, failed)"},"direction":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter by direction (inbound, outbound)"},"type":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter by call type (pstn, web)"},"search":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search by phone number (matches fromNumber or toNumber)"}},"hostedApiKey":"none"},"agentphone_list_contacts":{"id":"agentphone_list_contacts","name":"List Contacts","description":"List contacts for this AgentPhone account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"search":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter by name or phone number (case-insensitive contains)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to return (default 50, max 200)"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to skip (min 0)"}},"hostedApiKey":"none"},"agentphone_list_conversations":{"id":"agentphone_list_conversations","name":"List Conversations","description":"List conversations (message threads) for this AgentPhone account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to return (default 20, max 100)"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to skip (min 0)"}},"hostedApiKey":"none"},"agentphone_list_numbers":{"id":"agentphone_list_numbers","name":"List Phone Numbers","description":"List all phone numbers provisioned for this AgentPhone account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to return (default 20, max 100)"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to skip (min 0)"}},"hostedApiKey":"none"},"agentphone_react_to_message":{"id":"agentphone_react_to_message","name":"React to Message","description":"Send an iMessage tapback reaction to a message (iMessage only)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"messageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the message to react to"},"reaction":{"type":"string","required":true,"visibility":"user-or-llm","description":"Reaction type: love, like, dislike, laugh, emphasize, or question"}},"hostedApiKey":"none"},"agentphone_release_number":{"id":"agentphone_release_number","name":"Release Phone Number","description":"Release (delete) a phone number. This action is irreversible.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"numberId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the phone number to release"}},"hostedApiKey":"none"},"agentphone_send_message":{"id":"agentphone_send_message","name":"Send Message","description":"Send an outbound SMS or iMessage from an AgentPhone agent","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"agentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Agent sending the message"},"toNumber":{"type":"string","required":true,"visibility":"user-or-llm","description":"Recipient phone number in E.164 format (e.g. +14155551234)"},"body":{"type":"string","required":true,"visibility":"user-or-llm","description":"Message text to send"},"mediaUrl":{"type":"string","required":false,"visibility":"user-or-llm","description":"Optional URL of an image, video, or file to attach"},"numberId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Phone number ID to send from. If omitted, the agent\'s first assigned number is used."}},"hostedApiKey":"none"},"agentphone_update_contact":{"id":"agentphone_update_contact","name":"Update Contact","description":"Update a contact\'s fields","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"contactId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Contact ID"},"phoneNumber":{"type":"string","required":false,"visibility":"user-or-llm","description":"New phone number in E.164 format"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"New contact name"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"New email address"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"New freeform notes"}},"hostedApiKey":"none"},"agentphone_update_conversation":{"id":"agentphone_update_conversation","name":"Update Conversation","description":"Update conversation metadata (stored state). Pass null to clear existing metadata.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"AgentPhone API key"},"conversationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Conversation ID"},"metadata":{"type":"json","required":false,"visibility":"user-or-llm","description":"Custom key-value metadata to store on the conversation. Pass null to clear existing metadata."}},"hostedApiKey":"none"},"agiloft_async_status":{"id":"agiloft_async_status","name":"Agiloft Async Status","description":"Check whether an asynchronous Agiloft call, such as a run action button, has completed.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table the asynchronous call was made against"},"callbackId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Callback ID returned by the asynchronous call, e.g. from Run Action Button"}},"hostedApiKey":"none"},"agiloft_attach_file":{"id":"agiloft_attach_file","name":"Agiloft Attach File","description":"Attach a file to a field in an Agiloft record.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to attach the file to"},"fieldName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the attachment field"},"file":{"type":"file","required":true,"visibility":"user-or-llm","description":"File to attach"},"fileName":{"type":"string","required":false,"visibility":"user-or-llm","description":"Name to assign to the file (defaults to original file name)"},"overwrite":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Replace the contents of the field instead of adding another file to it"}},"hostedApiKey":"none"},"agiloft_attachment_info":{"id":"agiloft_attachment_info","name":"Agiloft Attachment Info","description":"Get information about file attachments on a record field.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to check attachments on"},"fieldName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the attachment field to inspect"}},"hostedApiKey":"none"},"agiloft_create_record":{"id":"agiloft_create_record","name":"Agiloft Create Record","description":"Create a new record in an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"data":{"type":"string","required":true,"visibility":"user-or-llm","description":"Record field values as a JSON object (e.g., {\\"first_name\\": \\"John\\", \\"status\\": \\"Active\\"})"}},"hostedApiKey":"none"},"agiloft_delete_record":{"id":"agiloft_delete_record","name":"Agiloft Delete Record","description":"Delete a record from an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to delete"},"substituteIds":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated IDs of records that adopt the dependants of the deleted record. Read only when the delete rule is REPLACE_WITH_ANOTHER."},"deleteRule":{"type":"string","required":false,"visibility":"user-or-llm","description":"How to treat records that depend on this one: ERROR_IF_DEPENDANTS (default — fails rather than cascading), APPLY_DELETE_WHERE_POSSIBLE, DELETE_WHERE_POSSIBLE_OTHERWISE_UNLINK, APPLY_UNLINK, UNLINK_WHERE_POSSIBLE_OTHERWISE_DELETE, or REPLACE_WITH_ANOTHER"}},"hostedApiKey":"none"},"agiloft_get_choice_line_id":{"id":"agiloft_get_choice_line_id","name":"Agiloft Get Choice Line ID","description":"Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"case\\", \\"contracts\\")"},"fieldName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Choice field name (e.g., \\"priority\\", \\"status\\")"},"value":{"type":"string","required":true,"visibility":"user-or-llm","description":"Choice display value to resolve (e.g., \\"High\\", \\"Active\\")"}},"hostedApiKey":"none"},"agiloft_list_tables":{"id":"agiloft_list_tables","name":"Agiloft List Tables","description":"List the tables and fields in an Agiloft knowledge base, to discover the logical names other operations need.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":false,"visibility":"user-or-llm","description":"Logical name of a single table to describe (e.g., \\"contacts\\"). Leave empty to list every table in the knowledge base."},"includeLinkedInfo":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Include the source table and column behind each linked field"},"skipColumnsInfo":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Return table names only, omitting field details, for a much smaller response"}},"hostedApiKey":"none"},"agiloft_lock_record":{"id":"agiloft_lock_record","name":"Agiloft Lock Record","description":"Lock, unlock, or check the lock status of an Agiloft record.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to lock, unlock, or check"},"lockAction":{"type":"string","required":true,"visibility":"user-or-llm","description":"Action to perform: \\"lock\\", \\"unlock\\", or \\"check\\""},"force":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Unlock only: release a lock held by another user."}},"hostedApiKey":"none"},"agiloft_nlp_search":{"id":"agiloft_nlp_search","name":"Agiloft Natural Language Search","description":"Search Agiloft records by describing what you want in plain language, such as \\"active NDAs submitted last month\\".","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"nlpQuery":{"type":"string","required":true,"visibility":"user-or-llm","description":"The request in plain language, e.g. \\"Show me open, high-priority contracts\\". Structured field filters are not accepted — use Search Records for those."},"fields":{"type":"string","required":true,"visibility":"user-or-llm","description":"Comma-separated field names to return, e.g. \\"id, contract_title1, company_name\\""},"page":{"type":"string","required":false,"visibility":"user-or-llm","description":"Page number, starting from 0"},"limit":{"type":"string","required":false,"visibility":"user-or-llm","description":"Records per page"}},"hostedApiKey":"none"},"agiloft_read_record":{"id":"agiloft_read_record","name":"Agiloft Read Record","description":"Read a record by ID from an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to read"},"fields":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of field names to include in the response"}},"hostedApiKey":"none"},"agiloft_remove_attachment":{"id":"agiloft_remove_attachment","name":"Agiloft Remove Attachment","description":"Remove an attached file from a field in an Agiloft record.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record containing the attachment"},"fieldName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the attachment field"},"position":{"type":"string","required":true,"visibility":"user-or-llm","description":"Position index of the file to remove (starting from 0)"}},"hostedApiKey":"none"},"agiloft_retrieve_attachment":{"id":"agiloft_retrieve_attachment","name":"Agiloft Retrieve Attachment","description":"Download an attached file from an Agiloft record field.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record containing the attachment"},"fieldName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the attachment field"},"position":{"type":"string","required":true,"visibility":"user-or-llm","description":"Position index of the file in the field (starting from 0)"}},"hostedApiKey":"none"},"agiloft_run_action_button":{"id":"agiloft_run_action_button","name":"Agiloft Run Action Button","description":"Run an action button on an Agiloft record, such as an approval or send-for-signature step.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"case\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to run the action button on"},"actionButtonField":{"type":"string","required":true,"visibility":"user-or-llm","description":"Logical name of the field holding the action button (e.g., \\"ab_field\\")"}},"hostedApiKey":"none"},"agiloft_saved_search":{"id":"agiloft_saved_search","name":"Agiloft Saved Search","description":"List the saved searches defined for an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Logical table name to list saved searches for (e.g., \\"contract\\")"}},"hostedApiKey":"none"},"agiloft_search_records":{"id":"agiloft_search_records","name":"Agiloft Search Records","description":"Search for records in an Agiloft table using a query.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name to search in (e.g., \\"contracts\\", \\"contacts.employees\\")"},"query":{"type":"string","required":false,"visibility":"user-or-llm","description":"Ad hoc EWSearch query. Combine conditions with && (and) or || (or) and quote every value — e.g. \\"summary~=\'test\'&&priority=\'High\'\\". Required unless a saved search is given."},"search":{"type":"string","required":false,"visibility":"user-or-llm","description":"Label of a saved search defined on the table (e.g., \\"C: Status is Closed\\"). Can be combined with a query to narrow it further."},"fields":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of field names to include in the results"},"page":{"type":"string","required":false,"visibility":"user-or-llm","description":"Page number for paginated results (starting from 0)"},"limit":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum number of records to return per page. Agiloft treats 0 as \\"all records\\", so leave it unset or use a positive value to keep result sizes bounded."}},"hostedApiKey":"none"},"agiloft_select_records":{"id":"agiloft_select_records","name":"Agiloft Select Records","description":"Select record IDs matching a SQL WHERE clause from an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"where":{"type":"string","required":true,"visibility":"user-or-llm","description":"SQL WHERE clause using database column names (e.g., \\"summary like \'%new%\'\\" or \\"assigned_person=\'John Doe\'\\"). EWSelect has no page size and returns every matching ID, so append a database limit such as \\"limit 0,200\\" to bound the result."}},"hostedApiKey":"none"},"agiloft_update_record":{"id":"agiloft_update_record","name":"Agiloft Update Record","description":"Update an existing record in an Agiloft table.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the record to update"},"data":{"type":"string","required":true,"visibility":"user-or-llm","description":"Updated field values as a JSON object (e.g., {\\"status\\": \\"Active\\", \\"priority\\": \\"High\\"})"}},"hostedApiKey":"none"},"agiloft_upsert_record":{"id":"agiloft_upsert_record","name":"Agiloft Upsert Record","description":"Create an Agiloft record, or update it when a record already matches the given fields.","version":"1.0.0","params":{"instanceUrl":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft instance URL (e.g., https://mycompany.agiloft.com)"},"knowledgeBase":{"type":"string","required":true,"visibility":"user-only","description":"Knowledge base name"},"login":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft username"},"password":{"type":"string","required":true,"visibility":"user-only","description":"Agiloft password"},"table":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table name (e.g., \\"contracts\\", \\"contacts.employees\\")"},"match":{"type":"string","required":true,"visibility":"user-or-llm","description":"Field used to find an existing record (e.g., \\"ext_id\\"). Pick something that identifies a record uniquely — if more than one record matches, Agiloft writes nothing and returns a conflict."},"async":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Queue the write instead of waiting for it. Returns a callback ID instead of a record ID; pass that to Async Status to poll the result."},"data":{"type":"string","required":true,"visibility":"user-or-llm","description":"Field values as a JSON object. On create these populate the new record; on update only the supplied fields change."}},"hostedApiKey":"none"},"ahrefs_anchors":{"id":"ahrefs_anchors","name":"Ahrefs Anchors","description":"Get the anchor text distribution for a target domain or URL\'s backlinks, showing how many links and referring domains use each anchor text.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"history":{"type":"string","required":false,"visibility":"user-or-llm","description":"Historical scope: \\"live\\" (currently live), \\"all_time\\" (default, includes lost backlinks), or \\"since:YYYY-MM-DD\\" (backlinks found since a date)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_backlinks":{"id":"ahrefs_backlinks","name":"Ahrefs Backlinks","description":"Get a list of backlinks pointing to a target domain or URL. Returns details about each backlink including source URL, anchor text, and domain rating.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"history":{"type":"string","required":false,"visibility":"user-or-llm","description":"Historical scope: \\"live\\" (currently live backlinks), \\"all_time\\" (default, includes lost backlinks), or \\"since:YYYY-MM-DD\\" (backlinks found since a date)."},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_backlinks_stats":{"id":"ahrefs_backlinks_stats","name":"Ahrefs Backlinks Stats","description":"Get backlink and referring domain totals for a target domain or URL, both currently live and across all time.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_batch_analysis":{"id":"ahrefs_batch_analysis","name":"Ahrefs Batch Analysis","description":"Get bulk SEO metrics (Domain Rating, backlinks, referring domains, organic traffic, and more) for multiple domains or URLs in a single request. Useful for comparing many competitors at once.","version":"1.0.0","params":{"targets":{"type":"string","required":true,"visibility":"user-or-llm","description":"Comma-separated list of domains or URLs to analyze. Example: \\"example.com,competitor.com\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode applied to every target: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"protocol":{"type":"string","required":false,"visibility":"user-or-llm","description":"Protocol applied to every target: \\"both\\" (default), \\"http\\", or \\"https\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for traffic data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"volumeMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search volume calculation: \\"monthly\\" or \\"average\\" (default: \\"monthly\\")"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_broken_backlinks":{"id":"ahrefs_broken_backlinks","name":"Ahrefs Broken Backlinks","description":"Get a list of broken backlinks pointing to a target domain or URL. Useful for identifying link reclamation opportunities.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_domain_rating":{"id":"ahrefs_domain_rating","name":"Ahrefs Domain Rating","description":"Get the Domain Rating (DR) and Ahrefs Rank for a target domain. Domain Rating shows the strength of a website\'s backlink profile on a scale from 0 to 100.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain to analyze (e.g., example.com)"},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date for historical data in YYYY-MM-DD format (defaults to today)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_domain_rating_history":{"id":"ahrefs_domain_rating_history","name":"Ahrefs Domain Rating History","description":"Get the historical Domain Rating (DR) trend for a target domain or URL over a date range, grouped daily, weekly, or monthly.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"dateFrom":{"type":"string","required":true,"visibility":"user-only","description":"Start date of the historical period, in YYYY-MM-DD format"},"dateTo":{"type":"string","required":false,"visibility":"user-only","description":"End date of the historical period, in YYYY-MM-DD format (defaults to today)"},"historyGrouping":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval for grouping data points: \\"daily\\", \\"weekly\\", or \\"monthly\\" (default: \\"monthly\\")"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_keyword_overview":{"id":"ahrefs_keyword_overview","name":"Ahrefs Keyword Overview","description":"Get detailed metrics for a keyword including search volume, keyword difficulty, CPC, clicks, and traffic potential.","version":"1.0.0","params":{"keyword":{"type":"string","required":true,"visibility":"user-or-llm","description":"The keyword to analyze"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for keyword data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_keywords_history":{"id":"ahrefs_keywords_history","name":"Ahrefs Keywords History","description":"Get the historical organic keyword ranking distribution for a target domain or URL over a date range: how many keywords rank in each position bucket at each point in time.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"dateFrom":{"type":"string","required":true,"visibility":"user-only","description":"Start date of the historical period, in YYYY-MM-DD format"},"dateTo":{"type":"string","required":false,"visibility":"user-only","description":"End date of the historical period, in YYYY-MM-DD format (defaults to today)"},"historyGrouping":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval for grouping data points: \\"daily\\", \\"weekly\\", or \\"monthly\\" (default: \\"monthly\\")"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for search results. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_metrics":{"id":"ahrefs_metrics","name":"Ahrefs Metrics","description":"Get a one-call organic and paid search overview for a target domain or URL: organic traffic, organic keywords, paid traffic, paid keywords, and estimated traffic cost.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for traffic data. Example: \\"us\\", \\"gb\\", \\"de\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_metrics_history":{"id":"ahrefs_metrics_history","name":"Ahrefs Metrics History","description":"Get the historical organic and paid traffic trend for a target domain or URL over a date range: organic traffic/cost and paid traffic/cost at each point in time.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"dateFrom":{"type":"string","required":true,"visibility":"user-only","description":"Start date of the historical period, in YYYY-MM-DD format"},"dateTo":{"type":"string","required":false,"visibility":"user-only","description":"End date of the historical period, in YYYY-MM-DD format (defaults to today)"},"volumeMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search volume calculation: \\"monthly\\" or \\"average\\" (default: \\"monthly\\")"},"historyGrouping":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval for grouping data points: \\"daily\\", \\"weekly\\", or \\"monthly\\" (default: \\"monthly\\")"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for traffic data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_organic_competitors":{"id":"ahrefs_organic_competitors","name":"Ahrefs Organic Competitors","description":"Get domains that compete with a target domain or URL for the same organic keywords, ranked by keyword overlap.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for search results. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_organic_keywords":{"id":"ahrefs_organic_keywords","name":"Ahrefs Organic Keywords","description":"Get organic keywords that a target domain or URL ranks for in Google search results. Returns keyword details including search volume, ranking position, and estimated traffic.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for search results. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_paid_pages":{"id":"ahrefs_paid_pages","name":"Ahrefs Paid Pages","description":"Get a target domain\'s pages that receive paid search traffic, sorted by estimated paid traffic. Returns page URLs with their paid traffic, keyword counts, and estimated spend.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for traffic data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_rank_tracker_competitors_overview":{"id":"ahrefs_rank_tracker_competitors_overview","name":"Ahrefs Rank Tracker Competitors Overview","description":"Get competitor rankings for the keywords tracked in an Ahrefs Rank Tracker project: each tracked keyword\'s volume and difficulty alongside every competitor\'s position, traffic, and traffic value. This endpoint is free and does not consume API units.","version":"1.0.0","params":{"projectId":{"type":"number","required":true,"visibility":"user-or-llm","description":"The Rank Tracker project ID (found in the project URL in Ahrefs)"},"date":{"type":"string","required":true,"visibility":"user-only","description":"Date to report rankings for, in YYYY-MM-DD format"},"device":{"type":"string","required":true,"visibility":"user-or-llm","description":"Rankings device type: \\"desktop\\" or \\"mobile\\""},"dateCompared":{"type":"string","required":false,"visibility":"user-only","description":"Comparison date in YYYY-MM-DD format, to compute position/traffic deltas"},"volumeMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search volume calculation: \\"monthly\\" or \\"average\\" (default: \\"monthly\\")"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_rank_tracker_competitors_stats":{"id":"ahrefs_rank_tracker_competitors_stats","name":"Ahrefs Rank Tracker Competitors Stats","description":"Get aggregate competitor stats for an Ahrefs Rank Tracker project: each competitor\'s traffic, traffic value, average position, and share of voice across all tracked keywords. This endpoint is free and does not consume API units.","version":"1.0.0","params":{"projectId":{"type":"number","required":true,"visibility":"user-or-llm","description":"The Rank Tracker project ID (found in the project URL in Ahrefs)"},"date":{"type":"string","required":true,"visibility":"user-only","description":"Date to report metrics for, in YYYY-MM-DD format"},"device":{"type":"string","required":true,"visibility":"user-or-llm","description":"Rankings device type: \\"desktop\\" or \\"mobile\\""},"volumeMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search volume calculation: \\"monthly\\" or \\"average\\" (default: \\"monthly\\")"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_rank_tracker_overview":{"id":"ahrefs_rank_tracker_overview","name":"Ahrefs Rank Tracker Overview","description":"Get ranking overview metrics for the keywords tracked in an Ahrefs Rank Tracker project: position, search volume, keyword difficulty, and estimated traffic. This endpoint is free and does not consume API units.","version":"1.0.0","params":{"projectId":{"type":"number","required":true,"visibility":"user-or-llm","description":"The Rank Tracker project ID (found in the project URL in Ahrefs)"},"date":{"type":"string","required":true,"visibility":"user-only","description":"Date to report rankings for, in YYYY-MM-DD format"},"device":{"type":"string","required":true,"visibility":"user-or-llm","description":"Rankings device type: \\"desktop\\" or \\"mobile\\""},"dateCompared":{"type":"string","required":false,"visibility":"user-only","description":"Comparison date in YYYY-MM-DD format, to compute position/traffic deltas"},"volumeMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search volume calculation: \\"monthly\\" or \\"average\\" (default: \\"monthly\\")"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_rank_tracker_serp_overview":{"id":"ahrefs_rank_tracker_serp_overview","name":"Ahrefs Rank Tracker SERP Overview","description":"Get the full SERP (search engine results page) for a keyword tracked in an Ahrefs Rank Tracker project, including every ranking URL with its position, title, and authority metrics. This endpoint is free and does not consume API units.","version":"1.0.0","params":{"projectId":{"type":"number","required":true,"visibility":"user-or-llm","description":"The Rank Tracker project ID (found in the project URL in Ahrefs)"},"keyword":{"type":"string","required":true,"visibility":"user-or-llm","description":"The tracked keyword to retrieve SERP data for"},"country":{"type":"string","required":true,"visibility":"user-or-llm","description":"Country code for the tracked keyword. Example: \\"us\\", \\"gb\\", \\"de\\""},"device":{"type":"string","required":true,"visibility":"user-or-llm","description":"Rankings device type: \\"desktop\\" or \\"mobile\\""},"topPositions":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of top organic positions to return (defaults to all available)"},"date":{"type":"string","required":false,"visibility":"user-only","description":"Timestamp to return the last available SERP Overview at, in YYYY-MM-DDThh:mm:ss format"},"locationId":{"type":"number","required":false,"visibility":"user-or-llm","description":"Location ID of the tracked keyword, if tracked at a specific location"},"languageCode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Language code of the tracked keyword"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_refdomains_history":{"id":"ahrefs_refdomains_history","name":"Ahrefs Referring Domains History","description":"Get the historical referring domains trend for a target domain or URL over a date range, grouped daily, weekly, or monthly.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\""},"dateFrom":{"type":"string","required":true,"visibility":"user-only","description":"Start date of the historical period, in YYYY-MM-DD format"},"dateTo":{"type":"string","required":false,"visibility":"user-only","description":"End date of the historical period, in YYYY-MM-DD format (defaults to today)"},"historyGrouping":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval for grouping data points: \\"daily\\", \\"weekly\\", or \\"monthly\\" (default: \\"monthly\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_referring_domains":{"id":"ahrefs_referring_domains","name":"Ahrefs Referring Domains","description":"Get a list of domains that link to a target domain or URL. Returns unique referring domains with their domain rating, backlink counts, and discovery dates.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain or URL to analyze. Example: \\"example.com\\" or \\"https://example.com/page\\""},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"history":{"type":"string","required":false,"visibility":"user-or-llm","description":"Historical scope: \\"live\\" (currently live), \\"all_time\\" (default, includes lost domains), or \\"since:YYYY-MM-DD\\" (domains found since a date)."},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_related_terms":{"id":"ahrefs_related_terms","name":"Ahrefs Related Terms","description":"Get keyword ideas related to a seed keyword: terms the same top-ranking pages also rank for (\\"also rank for\\") or also discuss (\\"also talk about\\"), with volume, difficulty, and CPC.","version":"1.0.0","params":{"keyword":{"type":"string","required":true,"visibility":"user-or-llm","description":"The seed keyword to find related terms for"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for keyword data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"terms":{"type":"string","required":false,"visibility":"user-or-llm","description":"Type of related keywords to return: \\"also_rank_for\\", \\"also_talk_about\\", or \\"all\\" (default: \\"all\\")"},"viewFor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Whether to derive related terms from the top 10 or top 100 ranking pages (default: \\"top_10\\")"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_site_audit_page_explorer":{"id":"ahrefs_site_audit_page_explorer","name":"Ahrefs Site Audit Page Explorer","description":"Get crawled pages from an Ahrefs Site Audit project with health and SEO metrics: HTTP status, title, link counts, backlinks, indexability, and traffic. Optionally filter to pages affected by a specific issue.","version":"1.0.0","params":{"projectId":{"type":"number","required":true,"visibility":"user-or-llm","description":"The Site Audit project ID (found in the project URL in Ahrefs)"},"date":{"type":"string","required":false,"visibility":"user-only","description":"Crawl date in YYYY-MM-DDThh:mm:ss format (defaults to the most recent crawl)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of results to skip, for pagination"},"issueId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Only return pages affected by this issue ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"ahrefs_top_pages":{"id":"ahrefs_top_pages","name":"Ahrefs Top Pages","description":"Get the top pages of a target domain sorted by organic traffic. Returns page URLs with their traffic, keyword counts, and estimated traffic value.","version":"1.0.0","params":{"target":{"type":"string","required":true,"visibility":"user-or-llm","description":"The target domain to analyze. Example: \\"example.com\\""},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Country code for traffic data. Example: \\"us\\", \\"gb\\", \\"de\\" (default: \\"us\\")"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Analysis mode: domain (entire domain), prefix (URL prefix), subdomains (include all subdomains, default), exact (exact URL match). Example: \\"domain\\""},"date":{"type":"string","required":false,"visibility":"user-only","description":"Date to report metrics on, in YYYY-MM-DD format (defaults to today)"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of results to return. Example: 50 (default: 1000)"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ahrefs API Key"}},"hostedApiKey":"none"},"airtable_create_records":{"id":"airtable_create_records","name":"Airtable Create Records","description":"Write new records to an Airtable table","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"records":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of records to create, each with a `fields` object"},"typecast":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"When true, Airtable automatically converts string values to the field type"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_delete_records":{"id":"airtable_delete_records","name":"Airtable Delete Records","description":"Delete one or more records from an Airtable table by ID","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"recordIds":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of record IDs to delete (each starts with \\"rec\\", e.g., [\\"recXXXXXXXXXXXXXX\\"]). Pass a single-element array to delete one record."}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_get_base_schema":{"id":"airtable_get_base_schema","name":"Airtable Get Base Schema","description":"Get the schema of all tables, fields, and views in an Airtable base","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_get_record":{"id":"airtable_get_record","name":"Airtable Get Record","description":"Retrieve a single record from an Airtable table by its ID","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Record ID to retrieve (starts with \\"rec\\", e.g., \\"recXXXXXXXXXXXXXX\\")"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_list_bases":{"id":"airtable_list_bases","name":"Airtable List Bases","description":"List all bases the authenticated user has access to","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"offset":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination offset for retrieving additional bases"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_list_records":{"id":"airtable_list_records","name":"Airtable List Records","description":"Read records from an Airtable table","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"maxRecords":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of records to return (default: all records)"},"filterFormula":{"type":"string","required":false,"visibility":"user-or-llm","description":"Formula to filter records (e.g., \\"({Field Name} = \'Value\')\\")"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_list_tables":{"id":"airtable_list_tables","name":"Airtable List Tables","description":"List all tables and their schema in an Airtable base","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_update_multiple_records":{"id":"airtable_update_multiple_records","name":"Airtable Update Multiple Records","description":"Update multiple existing records in an Airtable table","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"records":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of records to update, each with an `id` and a `fields` object"},"typecast":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"When true, Airtable automatically converts string values to the field type"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_update_record":{"id":"airtable_update_record","name":"Airtable Update Record","description":"Update an existing record in an Airtable table by ID","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"recordId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Record ID to update (starts with \\"rec\\", e.g., \\"recXXXXXXXXXXXXXX\\")"},"fields":{"type":"json","required":true,"visibility":"user-or-llm","description":"An object containing the field names and their new values"},"typecast":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"When true, Airtable automatically converts string values to the field type"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"airtable_upsert_records":{"id":"airtable_upsert_records","name":"Airtable Upsert Records","description":"Update existing records or create new ones in an Airtable table, matching on the specified merge fields","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token"},"baseId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Airtable base ID (starts with \\"app\\", e.g., \\"appXXXXXXXXXXXXXX\\")"},"tableId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Table ID (starts with \\"tbl\\") or table name"},"records":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of records to upsert, each with a `fields` object"},"fieldsToMergeOn":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of field names used to match existing records (max 3). A record is updated when all merge fields match, otherwise it is created. Example: [\\"Name\\"]"},"typecast":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"When true, Airtable automatically converts string values to the field type"}},"oauth":{"required":true,"provider":"airtable"},"hostedApiKey":"none"},"algolia_add_record":{"id":"algolia_add_record","name":"Algolia Add Record","description":"Add or replace a record in an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"objectID":{"type":"string","required":false,"visibility":"user-or-llm","description":"Object ID for the record (auto-generated if not provided)"},"record":{"type":"json","required":true,"visibility":"user-or-llm","description":"JSON object representing the record to add"}},"hostedApiKey":"none"},"algolia_batch_operations":{"id":"algolia_batch_operations","name":"Algolia Batch Operations","description":"Perform batch add, update, partial update, or delete operations on records in an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"requests":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of batch operations. Each item has \\"action\\" (addObject, updateObject, partialUpdateObject, partialUpdateObjectNoCreate, deleteObject, delete, clear) and \\"body\\" (the record data; must include objectID for update/delete; use an empty object {} for the index-level delete/clear actions)"}},"hostedApiKey":"none"},"algolia_browse_records":{"id":"algolia_browse_records","name":"Algolia Browse Records","description":"Browse and iterate over all records in an Algolia index using cursor pagination","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key (must have browse ACL)"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index to browse"},"query":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search query to filter browsed records"},"filters":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter string to narrow down results"},"attributesToRetrieve":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of attributes to retrieve"},"hitsPerPage":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of hits per page (default: 1000, max: 1000)"},"cursor":{"type":"string","required":false,"visibility":"user-or-llm","description":"Cursor from a previous browse response for pagination"},"aroundLatLng":{"type":"string","required":false,"visibility":"user-or-llm","description":"Coordinates for geo-search (e.g., \\"40.71,-74.01\\")"},"aroundRadius":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum radius in meters for geo-search, or \\"all\\" for unlimited"},"insideBoundingBox":{"type":"json","required":false,"visibility":"user-or-llm","description":"Bounding box coordinates as [[lat1, lng1, lat2, lng2]] for geo-search"},"insidePolygon":{"type":"json","required":false,"visibility":"user-or-llm","description":"Polygon coordinates as [[lat1, lng1, lat2, lng2, lat3, lng3, ...]] for geo-search"}},"hostedApiKey":"none"},"algolia_clear_records":{"id":"algolia_clear_records","name":"Algolia Clear Records","description":"Clear all records from an Algolia index while keeping settings, synonyms, and rules","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key (must have deleteIndex ACL)"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index to clear"}},"hostedApiKey":"none"},"algolia_copy_move_index":{"id":"algolia_copy_move_index","name":"Algolia Copy/Move Index","description":"Copy or move an Algolia index to a new destination","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the source index"},"operation":{"type":"string","required":true,"visibility":"user-or-llm","description":"Operation to perform: \\"copy\\" or \\"move\\""},"destination":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the destination index"},"scope":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of scopes to copy (only for \\"copy\\" operation): [\\"settings\\", \\"synonyms\\", \\"rules\\"]. Omit to copy everything including records."}},"hostedApiKey":"none"},"algolia_delete_by_filter":{"id":"algolia_delete_by_filter","name":"Algolia Delete By Filter","description":"Delete all records matching a filter from an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key (must have deleteIndex ACL)"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"filters":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter expression to match records for deletion (e.g., \\"category:outdated\\")"},"facetFilters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of facet filters (e.g., [\\"brand:Acme\\"])"},"numericFilters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of numeric filters (e.g., [\\"price > 100\\"])"},"tagFilters":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of tag filters using the _tags attribute (e.g., [\\"published\\"])"},"aroundLatLng":{"type":"string","required":false,"visibility":"user-or-llm","description":"Coordinates for geo-search filter (e.g., \\"40.71,-74.01\\")"},"aroundRadius":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum radius in meters for geo-search, or \\"all\\" for unlimited"},"insideBoundingBox":{"type":"json","required":false,"visibility":"user-or-llm","description":"Bounding box coordinates as [[lat1, lng1, lat2, lng2]] for geo-search filter"},"insidePolygon":{"type":"json","required":false,"visibility":"user-or-llm","description":"Polygon coordinates as [[lat1, lng1, lat2, lng2, lat3, lng3, ...]] for geo-search filter"}},"hostedApiKey":"none"},"algolia_delete_index":{"id":"algolia_delete_index","name":"Algolia Delete Index","description":"Delete an entire Algolia index and all its records","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key (must have deleteIndex ACL)"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index to delete"}},"hostedApiKey":"none"},"algolia_delete_record":{"id":"algolia_delete_record","name":"Algolia Delete Record","description":"Delete a record by objectID from an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"objectID":{"type":"string","required":true,"visibility":"user-or-llm","description":"The objectID of the record to delete"}},"hostedApiKey":"none"},"algolia_get_record":{"id":"algolia_get_record","name":"Algolia Get Record","description":"Get a record by objectID from an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"objectID":{"type":"string","required":true,"visibility":"user-or-llm","description":"The objectID of the record to retrieve"},"attributesToRetrieve":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of attributes to retrieve"}},"hostedApiKey":"none"},"algolia_get_records":{"id":"algolia_get_records","name":"Algolia Get Records","description":"Retrieve multiple records by objectID from one or more Algolia indices","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Default index name for all requests"},"requests":{"type":"json","required":true,"visibility":"user-or-llm","description":"Array of objects specifying records to retrieve. Each must have \\"objectID\\" and optionally \\"indexName\\" and \\"attributesToRetrieve\\"."}},"hostedApiKey":"none"},"algolia_get_settings":{"id":"algolia_get_settings","name":"Algolia Get Settings","description":"Retrieve the settings of an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"}},"hostedApiKey":"none"},"algolia_get_task_status":{"id":"algolia_get_task_status","name":"Algolia Get Task Status","description":"Check whether an Algolia indexing task has finished publishing","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index the task ran against"},"taskID":{"type":"number","required":true,"visibility":"user-or-llm","description":"The taskID returned by a previous write operation"}},"hostedApiKey":"none"},"algolia_list_indices":{"id":"algolia_list_indices","name":"Algolia List Indices","description":"List all indices in an Algolia application","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for paginating indices (default: not paginated)"},"hitsPerPage":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of indices per page (default: 100)"}},"hostedApiKey":"none"},"algolia_partial_update_record":{"id":"algolia_partial_update_record","name":"Algolia Partial Update Record","description":"Partially update a record in an Algolia index without replacing it entirely","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"objectID":{"type":"string","required":true,"visibility":"user-or-llm","description":"The objectID of the record to update"},"attributes":{"type":"json","required":true,"visibility":"user-or-llm","description":"JSON object with attributes to update. Supports built-in operations like {\\"stock\\": {\\"_operation\\": \\"Decrement\\", \\"value\\": 1}}"},"createIfNotExists":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Whether to create the record if it does not exist (default: true)"}},"hostedApiKey":"none"},"algolia_search":{"id":"algolia_search","name":"Algolia Search","description":"Search an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia API Key"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index to search"},"query":{"type":"string","required":true,"visibility":"user-or-llm","description":"Search query text"},"hitsPerPage":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of hits per page (default: 20)"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number to retrieve (default: 0)"},"filters":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter string (e.g., \\"category:electronics AND price < 100\\")"},"attributesToRetrieve":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of attributes to retrieve"},"facets":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of facet attribute names to retrieve counts for (use \\"*\\" for all)"},"getRankingInfo":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Whether to include detailed ranking information in each hit"},"aroundLatLng":{"type":"string","required":false,"visibility":"user-or-llm","description":"Coordinates for geo-search (e.g., \\"40.71,-74.01\\")"},"aroundRadius":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum radius in meters for geo-search, or \\"all\\" for unlimited"},"insideBoundingBox":{"type":"json","required":false,"visibility":"user-or-llm","description":"Bounding box coordinates as [[lat1, lng1, lat2, lng2]] for geo-search"},"insidePolygon":{"type":"json","required":false,"visibility":"user-or-llm","description":"Polygon coordinates as [[lat1, lng1, lat2, lng2, lat3, lng3, ...]] for geo-search"}},"hostedApiKey":"none"},"algolia_update_settings":{"id":"algolia_update_settings","name":"Algolia Update Settings","description":"Update the settings of an Algolia index","version":"1.0","params":{"applicationId":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Application ID"},"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Algolia Admin API Key (must have editSettings ACL)"},"indexName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the Algolia index"},"settings":{"type":"json","required":true,"visibility":"user-or-llm","description":"JSON object with settings to update (e.g., {\\"searchableAttributes\\": [\\"name\\", \\"description\\"], \\"customRanking\\": [\\"desc(popularity)\\"]})"},"forwardToReplicas":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Whether to apply changes to replica indices (default: false)"}},"hostedApiKey":"none"},"amplitude_event_segmentation":{"id":"amplitude_event_segmentation","name":"Amplitude Event Segmentation","description":"Query event analytics data with segmentation. Get event counts, uniques, averages, and more.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"eventType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Event type name to analyze"},"start":{"type":"string","required":true,"visibility":"user-or-llm","description":"Start date in YYYYMMDD format"},"end":{"type":"string","required":true,"visibility":"user-or-llm","description":"End date in YYYYMMDD format"},"metric":{"type":"string","required":false,"visibility":"user-or-llm","description":"Metric type: uniques, totals, pct_dau, average, histogram, sums, value_avg, or formula (default: uniques)"},"interval":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval: 1 (daily), 7 (weekly), or 30 (monthly)"},"groupBy":{"type":"string","required":false,"visibility":"user-or-llm","description":"Property name to group by (prefix custom user properties with \\"gp:\\")"},"groupBy2":{"type":"string","required":false,"visibility":"user-or-llm","description":"Second property name to group by (prefix custom user properties with \\"gp:\\")"},"limit":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum number of group-by values (max 1000)"},"filters":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON array of filter objects applied to the event, e.g. [{\\"subprop_type\\":\\"event\\",\\"subprop_key\\":\\"city\\",\\"subprop_op\\":\\"is\\",\\"subprop_value\\":[\\"San Francisco\\"]}]"},"formula":{"type":"string","required":false,"visibility":"user-or-llm","description":"Required when metric is \\"formula\\", e.g. \\"UNIQUES(A)/UNIQUES(B)\\""},"segment":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON segment definition(s) applied to the query"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_funnels":{"id":"amplitude_funnels","name":"Amplitude Funnels","description":"Analyze conversion rates and drop-off between a sequence of events.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"events":{"type":"string","required":true,"visibility":"user-or-llm","description":"JSON array of event objects, one per funnel step in order, e.g. [{\\"event_type\\":\\"signup\\"},{\\"event_type\\":\\"purchase\\"}]"},"start":{"type":"string","required":true,"visibility":"user-or-llm","description":"Start date in YYYYMMDD format"},"end":{"type":"string","required":true,"visibility":"user-or-llm","description":"End date in YYYYMMDD format"},"mode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Funnel ordering: \\"ordered\\", \\"unordered\\", or \\"sequential\\" (default: ordered)"},"userType":{"type":"string","required":false,"visibility":"user-or-llm","description":"User type: \\"new\\" or \\"active\\" (default: active)"},"interval":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval: -300000 (real-time), -3600000 (hourly), 1 (daily), 7 (weekly), or 30 (monthly)"},"conversionWindowSeconds":{"type":"string","required":false,"visibility":"user-or-llm","description":"Conversion window in seconds (default: 2592000, i.e. 30 days)"},"groupBy":{"type":"string","required":false,"visibility":"user-or-llm","description":"Property to group by (limit: one; prefix custom properties with \\"gp:\\")"},"limit":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum number of group-by values (default: 100, max: 1000)"},"segment":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON segment definition(s) applied to the query"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_get_active_users":{"id":"amplitude_get_active_users","name":"Amplitude Get Active Users","description":"Get active or new user counts over a date range from the Dashboard REST API.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"start":{"type":"string","required":true,"visibility":"user-or-llm","description":"Start date in YYYYMMDD format"},"end":{"type":"string","required":true,"visibility":"user-or-llm","description":"End date in YYYYMMDD format"},"metric":{"type":"string","required":false,"visibility":"user-or-llm","description":"Metric type: \\"active\\" or \\"new\\" (default: active)"},"interval":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval: 1 (daily), 7 (weekly), or 30 (monthly)"},"groupBy":{"type":"string","required":false,"visibility":"user-or-llm","description":"Property name to group by"},"segment":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON segment definition(s) applied to the query"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_get_revenue":{"id":"amplitude_get_revenue","name":"Amplitude Get Revenue","description":"Get revenue LTV data including ARPU, ARPPU, total revenue, and paying user counts.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"start":{"type":"string","required":true,"visibility":"user-or-llm","description":"Start date in YYYYMMDD format"},"end":{"type":"string","required":true,"visibility":"user-or-llm","description":"End date in YYYYMMDD format"},"metric":{"type":"string","required":false,"visibility":"user-or-llm","description":"Metric: 0 (ARPU), 1 (ARPPU), 2 (Total Revenue), 3 (Paying Users)"},"interval":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval: 1 (daily), 7 (weekly), or 30 (monthly)"},"groupBy":{"type":"string","required":false,"visibility":"user-or-llm","description":"Property name to group by (limit: one)"},"segment":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON segment definition(s) applied to the query"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_group_identify":{"id":"amplitude_group_identify","name":"Amplitude Group Identify","description":"Set group-level properties in Amplitude. Supports $set, $setOnce, $add, $append, $unset operations.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"groupType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Group classification (e.g., \\"company\\", \\"org_id\\")"},"groupValue":{"type":"string","required":true,"visibility":"user-or-llm","description":"Specific group identifier (e.g., \\"Acme Corp\\")"},"groupProperties":{"type":"string","required":true,"visibility":"user-or-llm","description":"JSON object of group properties. Use operations like $set, $setOnce, $add, $append, $unset."},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_identify_user":{"id":"amplitude_identify_user","name":"Amplitude Identify User","description":"Set user properties in Amplitude using the Identify API. Supports $set, $setOnce, $add, $append, $unset operations.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"userId":{"type":"string","required":false,"visibility":"user-or-llm","description":"User ID (required if no device_id)"},"deviceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Device ID (required if no user_id)"},"userProperties":{"type":"string","required":true,"visibility":"user-or-llm","description":"JSON object of user properties. Use operations like $set, $setOnce, $add, $append, $unset."},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_list_events":{"id":"amplitude_list_events","name":"Amplitude List Events","description":"List all event types in the Amplitude project with their weekly totals and unique counts.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_realtime_active_users":{"id":"amplitude_realtime_active_users","name":"Amplitude Real-time Active Users","description":"Get real-time active user counts at 5-minute granularity for the last 2 days.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_retention":{"id":"amplitude_retention","name":"Amplitude Retention","description":"Measure how many users return to perform an action after a starting action.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"startEvent":{"type":"string","required":true,"visibility":"user-or-llm","description":"JSON starting event object, e.g. {\\"event_type\\":\\"_new\\"} or {\\"event_type\\":\\"_active\\"}"},"returnEvent":{"type":"string","required":true,"visibility":"user-or-llm","description":"JSON returning event object, e.g. {\\"event_type\\":\\"_all\\"} or {\\"event_type\\":\\"_active\\"}"},"start":{"type":"string","required":true,"visibility":"user-or-llm","description":"Start date in YYYYMMDD format"},"end":{"type":"string","required":true,"visibility":"user-or-llm","description":"End date in YYYYMMDD format"},"retentionMode":{"type":"string","required":false,"visibility":"user-or-llm","description":"Retention type: \\"bracket\\", \\"rolling\\", or \\"n-day\\" (default: n-day)"},"retentionBrackets":{"type":"string","required":false,"visibility":"user-or-llm","description":"Required when Retention Mode is \\"bracket\\". Day ranges, e.g. [[0,4]]"},"interval":{"type":"string","required":false,"visibility":"user-or-llm","description":"Time interval: 1 (daily), 7 (weekly), or 30 (monthly)"},"groupBy":{"type":"string","required":false,"visibility":"user-or-llm","description":"Property to group by (limit: one; prefix custom properties with \\"gp:\\")"},"segment":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON segment definition(s) applied to the query"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_send_event":{"id":"amplitude_send_event","name":"Amplitude Send Event","description":"Track an event in Amplitude using the HTTP V2 API.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"userId":{"type":"string","required":false,"visibility":"user-or-llm","description":"User ID (required if no device_id)"},"deviceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Device ID (required if no user_id)"},"eventType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the event (e.g., \\"page_view\\", \\"purchase\\")"},"eventProperties":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON object of custom event properties"},"userProperties":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON object of user properties to set (supports $set, $setOnce, $add, $append, $unset)"},"time":{"type":"string","required":false,"visibility":"user-or-llm","description":"Event timestamp in milliseconds since epoch"},"sessionId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Session start time in milliseconds since epoch"},"insertId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Unique ID for deduplication (within 7-day window)"},"appVersion":{"type":"string","required":false,"visibility":"user-or-llm","description":"Application version string"},"platform":{"type":"string","required":false,"visibility":"user-or-llm","description":"Platform (e.g., \\"Web\\", \\"iOS\\", \\"Android\\")"},"country":{"type":"string","required":false,"visibility":"user-or-llm","description":"Two-letter country code"},"language":{"type":"string","required":false,"visibility":"user-or-llm","description":"Language code (e.g., \\"en\\")"},"ip":{"type":"string","required":false,"visibility":"user-or-llm","description":"IP address for geo-location"},"price":{"type":"string","required":false,"visibility":"user-or-llm","description":"Price of the item purchased"},"quantity":{"type":"string","required":false,"visibility":"user-or-llm","description":"Quantity of items purchased"},"revenue":{"type":"string","required":false,"visibility":"user-or-llm","description":"Revenue amount"},"productId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Product identifier"},"revenueType":{"type":"string","required":false,"visibility":"user-or-llm","description":"Revenue type (e.g., \\"purchase\\", \\"refund\\")"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_user_activity":{"id":"amplitude_user_activity","name":"Amplitude User Activity","description":"Get the event stream for a specific user by their Amplitude ID.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"amplitudeId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Amplitude internal user ID"},"offset":{"type":"string","required":false,"visibility":"user-or-llm","description":"Offset for pagination (default 0)"},"limit":{"type":"string","required":false,"visibility":"user-or-llm","description":"Maximum number of events to return (default 1000, max 1000)"},"direction":{"type":"string","required":false,"visibility":"user-or-llm","description":"Sort direction: \\"latest\\" or \\"earliest\\" (default: latest)"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"amplitude_user_profile":{"id":"amplitude_user_profile","name":"Amplitude User Profile","description":"Get a user profile including properties, cohort memberships, and computed properties. Not available for EU data-residency projects.","version":"1.0.0","params":{"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"userId":{"type":"string","required":false,"visibility":"user-or-llm","description":"External user ID (required if no device_id)"},"deviceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Device ID (required if no user_id)"},"getAmpProps":{"type":"string","required":false,"visibility":"user-or-llm","description":"Include Amplitude user properties (true/false, default: false)"},"getCohortIds":{"type":"string","required":false,"visibility":"user-or-llm","description":"Include cohort IDs the user belongs to (true/false, default: false)"},"getComputations":{"type":"string","required":false,"visibility":"user-or-llm","description":"Include computed user properties (true/false, default: false)"}},"hostedApiKey":"none"},"amplitude_user_search":{"id":"amplitude_user_search","name":"Amplitude User Search","description":"Search for a user by User ID, Device ID, or Amplitude ID using the Dashboard REST API.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude API Key"},"secretKey":{"type":"string","required":true,"visibility":"user-only","description":"Amplitude Secret Key"},"user":{"type":"string","required":true,"visibility":"user-or-llm","description":"User ID, Device ID, or Amplitude ID to search for"},"dataResidency":{"type":"string","required":false,"visibility":"user-or-llm","description":"Data residency region: \\"us\\" (default) or \\"eu\\""}},"hostedApiKey":"none"},"apify_get_dataset_items":{"id":"apify_get_dataset_items","name":"APIFY Get Dataset Items","description":"Retrieve items stored in an APIFY dataset","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"APIFY API token from console.apify.com/account#/integrations"},"datasetId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Dataset ID to read items from. Example: \\"9RnD3Pql2vGZkc5H5\\""},"itemLimit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Max items to return (1-250000). Default: all items. Example: 500"},"offset":{"type":"number","required":false,"visibility":"user-or-llm","description":"Number of items to skip at the start. Default: 0"},"fields":{"type":"string","required":false,"visibility":"user-or-llm","description":"Comma-separated list of fields to include. Example: \\"title,url,price\\""}},"hostedApiKey":"none"},"apify_get_run":{"id":"apify_get_run","name":"APIFY Get Run","description":"Get the status and details of an APIFY actor run","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"APIFY API token from console.apify.com/account#/integrations"},"runId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Actor run ID to fetch. Example: \\"HG7ML7M8z78YcAPEB\\""}},"hostedApiKey":"none"},"apify_run_actor_async":{"id":"apify_run_actor_async","name":"APIFY Run Actor (Async)","description":"Start an APIFY Actor run and poll it within the same workflow step until completion or the polling deadline","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"APIFY API token from console.apify.com/account#/integrations"},"actorId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Actor ID or username/actor-name. Examples: \\"apify/web-scraper\\", \\"janedoe/my-actor\\", \\"moJRLRc85AitArpNN\\""},"input":{"type":"string","required":false,"visibility":"user-or-llm","description":"Actor input as JSON string. Example: { \\"startUrls\\": [ { \\"url\\": \\"https://example.com\\" } ], \\"maxPages\\": 10 }"},"waitForFinish":{"type":"number","required":false,"visibility":"user-or-llm","description":"Initial wait time in seconds (0-60) before polling starts. Example: 30"},"itemLimit":{"type":"number","required":false,"default":100,"visibility":"user-or-llm","description":"Max dataset items to fetch (1-250000). Default: 100. Example: 500"},"memory":{"type":"number","required":false,"visibility":"user-or-llm","description":"Memory in megabytes allocated for the actor run (128-32768). Example: 1024 for 1GB, 2048 for 2GB"},"timeout":{"type":"number","required":false,"visibility":"user-or-llm","description":"Timeout in seconds for the actor run. Example: 300 for 5 minutes, 3600 for 1 hour"},"build":{"type":"string","required":false,"visibility":"user-or-llm","description":"Actor build to run. Examples: \\"latest\\", \\"beta\\", \\"1.2.3\\", \\"build-tag-name\\""}},"hostedApiKey":"none"},"apify_run_actor_sync":{"id":"apify_run_actor_sync","name":"APIFY Run Actor (Sync)","description":"Run an APIFY actor synchronously and get results (max 5 minutes)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"APIFY API token from console.apify.com/account#/integrations"},"actorId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Actor ID or username/actor-name. Examples: \\"apify/web-scraper\\", \\"janedoe/my-actor\\", \\"moJRLRc85AitArpNN\\""},"input":{"type":"string","required":false,"visibility":"user-or-llm","description":"Actor input as JSON string. Example: { \\"startUrls\\": [ { \\"url\\": \\"https://example.com\\" } ], \\"maxPages\\": 10 }"},"memory":{"type":"number","required":false,"visibility":"user-or-llm","description":"Memory in megabytes allocated for the actor run (128-32768). Example: 1024 for 1GB, 2048 for 2GB"},"timeout":{"type":"number","required":false,"visibility":"user-or-llm","description":"Timeout in seconds for the actor run. Example: 300 for 5 minutes, 3600 for 1 hour"},"build":{"type":"string","required":false,"visibility":"user-or-llm","description":"Actor build to run. Examples: \\"latest\\", \\"beta\\", \\"1.2.3\\", \\"build-tag-name\\""}},"hostedApiKey":"none"},"apify_run_task":{"id":"apify_run_task","name":"APIFY Run Task","description":"Run a saved APIFY actor task synchronously and get dataset items (max 5 minutes)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"APIFY API token from console.apify.com/account#/integrations"},"taskId":{"type":"string","required":true,"visibility":"user-or-llm","description":"Task ID or username/task-name. Examples: \\"janedoe/my-task\\", \\"moJRLRc85AitArpNN\\""},"input":{"type":"string","required":false,"visibility":"user-or-llm","description":"JSON string that overrides the task\'s saved input. Example: { \\"startUrls\\": [ { \\"url\\": \\"https://example.com\\" } ] }"},"itemLimit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Max dataset items to return (1-250000). Example: 500"},"memory":{"type":"number","required":false,"visibility":"user-or-llm","description":"Memory in megabytes allocated for the run (128-32768). Example: 1024 for 1GB"},"timeout":{"type":"number","required":false,"visibility":"user-or-llm","description":"Timeout in seconds for the run. Example: 300 for 5 minutes"},"build":{"type":"string","required":false,"visibility":"user-or-llm","description":"Actor build to run. Examples: \\"latest\\", \\"beta\\", \\"1.2.3\\""}},"hostedApiKey":"none"},"apollo_account_bulk_create":{"id":"apollo_account_bulk_create","name":"Apollo Bulk Create Accounts","description":"Create up to 100 accounts at once in your Apollo database. Set run_dedupe=true to deduplicate by domain, organization_id, and name. Master key required.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"accounts":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of accounts to create (max 100). Each account should include a name, and may optionally include domain, phone, phone_status_cd, raw_address, owner_id, linkedin_url, facebook_url, twitter_url, salesforce_id, and hubspot_id."},"append_label_names":{"type":"array","required":false,"visibility":"user-only","description":"Array of label names to add to ALL accounts in this request"},"run_dedupe":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"When true, performs aggressive deduplication by domain, organization_id, and name (defaults to false)"}},"hostedApiKey":"none"},"apollo_account_bulk_update":{"id":"apollo_account_bulk_update","name":"Apollo Bulk Update Accounts","description":"Update up to 1000 existing accounts at once in your Apollo database (higher limit than contacts!). Each account must include an id field. Master key required.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"account_ids":{"type":"array","required":false,"visibility":"user-or-llm","description":"Array of account IDs to update with the same values (max 1000). Use with name/owner_id for uniform updates. Use either this OR account_attributes."},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"When using account_ids, apply this name to all accounts"},"owner_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"When using account_ids, apply this owner to all accounts"},"account_stage_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"When using account_ids, apply this account stage to all accounts"},"account_attributes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of account objects with individual updates (each must include id). Example: [{\\"id\\": \\"acc1\\", \\"name\\": \\"Acme\\", \\"owner_id\\": \\"u1\\", \\"account_stage_id\\": \\"s1\\", \\"typed_custom_fields\\": {\\"field_id\\": \\"value\\"}}]"},"async":{"type":"boolean","required":false,"visibility":"user-only","description":"When true, processes the update asynchronously. Only supported when using account_ids; returns 422 if used with account_attributes."}},"hostedApiKey":"none"},"apollo_account_create":{"id":"apollo_account_create","name":"Apollo Create Account","description":"Create a new account (company) in your Apollo database","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Company name (e.g., \\"Acme Corporation\\")"},"domain":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company domain without www. prefix (e.g., \\"acme.com\\")"},"phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Primary phone number for the account"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"Apollo user ID of the account owner"},"account_stage_id":{"type":"string","required":false,"visibility":"user-only","description":"Apollo ID for the account stage to assign this account to"},"raw_address":{"type":"string","required":false,"visibility":"user-or-llm","description":"Corporate location (e.g., \\"San Francisco, CA, USA\\")"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-only","description":"Custom field values as { custom_field_id: value } map"}},"hostedApiKey":"none"},"apollo_account_search":{"id":"apollo_account_search","name":"Apollo Search Accounts","description":"Search your team\'s accounts in Apollo. Display limit: 50,000 records (100 records per page, 500 pages max). Use filters to narrow results. Master key required.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"q_organization_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter accounts by organization name (partial-match search)"},"account_stage_ids":{"type":"array","required":false,"visibility":"user-only","description":"Filter by account stage IDs"},"account_label_ids":{"type":"array","required":false,"visibility":"user-only","description":"Filter by account label IDs"},"sort_by_field":{"type":"string","required":false,"visibility":"user-or-llm","description":"Sort field: \\"account_last_activity_date\\", \\"account_created_at\\", or \\"account_updated_at\\""},"sort_ascending":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Sort ascending when true. Defaults to descending."},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_account_update":{"id":"apollo_account_update","name":"Apollo Update Account","description":"Update an existing account in your Apollo database","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"account_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the account to update (e.g., \\"acc_abc123\\")"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company name (e.g., \\"Acme Corporation\\")"},"domain":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company domain (e.g., \\"acme.com\\")"},"phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company phone number"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"Apollo user ID of the account owner"},"account_stage_id":{"type":"string","required":false,"visibility":"user-only","description":"Apollo ID for the account stage to assign this account to"},"raw_address":{"type":"string","required":false,"visibility":"user-or-llm","description":"Corporate location (e.g., \\"San Francisco, CA, USA\\")"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-only","description":"Custom field values as { custom_field_id: value } map"}},"hostedApiKey":"none"},"apollo_contact_bulk_create":{"id":"apollo_contact_bulk_create","name":"Apollo Bulk Create Contacts","description":"Create up to 100 contacts at once in your Apollo database. Supports deduplication to prevent creating duplicate contacts. Master key required.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"contacts":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of contacts to create (max 100). Each contact may include first_name, last_name, email, title, organization_name, account_id, owner_id, contact_stage_id, linkedin_url, phone (single string) or phone_numbers (array of {raw_number, position}), contact_emails, typed_custom_fields, and CRM IDs (salesforce_contact_id, hubspot_id, team_id) for cross-system matching"},"append_label_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Label names to add to all contacts in this request (e.g., [\\"Hot Lead\\"])"},"run_dedupe":{"type":"boolean","required":false,"visibility":"user-only","description":"Enable deduplication to prevent creating duplicate contacts. When true, existing contacts are returned without modification"}},"hostedApiKey":"none"},"apollo_contact_bulk_update":{"id":"apollo_contact_bulk_update","name":"Apollo Bulk Update Contacts","description":"Update up to 100 existing contacts at once in your Apollo database. Each contact must include an id field. Master key required.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"contact_ids":{"type":"array","required":false,"visibility":"user-or-llm","description":"Array of contact IDs to update. Must be paired with an object-form contact_attributes specifying the fields to apply uniformly to all listed contacts."},"contact_attributes":{"type":"json","required":false,"visibility":"user-or-llm","description":"Required. Either an array of per-contact updates (each with id) — used standalone — or a single object of attributes to apply to all contact_ids. Supported fields: owner_id, email, organization_name, title, first_name, last_name, account_id, present_raw_address, linkedin_url, typed_custom_fields"},"async":{"type":"boolean","required":false,"visibility":"user-only","description":"Force asynchronous processing. Automatically enabled for >100 contacts"}},"hostedApiKey":"none"},"apollo_contact_create":{"id":"apollo_contact_create","name":"Apollo Create Contact","description":"Create a new contact in your Apollo database","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"first_name":{"type":"string","required":true,"visibility":"user-or-llm","description":"First name of the contact"},"last_name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Last name of the contact"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"Email address of the contact"},"title":{"type":"string","required":false,"visibility":"user-or-llm","description":"Job title (e.g., \\"VP of Sales\\", \\"Software Engineer\\")"},"account_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"Apollo account ID to associate with (e.g., \\"acc_abc123\\")"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"User ID of the contact owner (accepted by Apollo but not officially documented for POST /contacts)"},"organization_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Name of the contact\'s employer (e.g., \\"Apollo\\")"},"website_url":{"type":"string","required":false,"visibility":"user-or-llm","description":"Corporate website URL (e.g., \\"https://www.apollo.io/\\")"},"label_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Lists/labels to add the contact to (e.g., [\\"Prospects\\"])"},"contact_stage_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"Apollo ID for the contact stage"},"present_raw_address":{"type":"string","required":false,"visibility":"user-or-llm","description":"Personal location for the contact (e.g., \\"Atlanta, United States\\")"},"direct_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Primary phone number"},"corporate_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Work/office phone number"},"mobile_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Mobile phone number"},"home_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Home phone number"},"other_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Alternative phone number"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-or-llm","description":"Custom field values keyed by custom field ID"},"run_dedupe":{"type":"boolean","required":false,"visibility":"user-only","description":"When true, Apollo deduplicates against existing contacts"}},"hostedApiKey":"none"},"apollo_contact_search":{"id":"apollo_contact_search","name":"Apollo Search Contacts","description":"Search your team\'s contacts in Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"q_keywords":{"type":"string","required":false,"visibility":"user-or-llm","description":"Keywords to search for"},"contact_stage_ids":{"type":"array","required":false,"visibility":"user-only","description":"Filter by contact stage IDs"},"contact_label_ids":{"type":"array","required":false,"visibility":"user-only","description":"Filter by Apollo label IDs (lists)"},"sort_by_field":{"type":"string","required":false,"visibility":"user-only","description":"Sort field: contact_last_activity_date, contact_email_last_opened_at, contact_email_last_clicked_at, contact_created_at, or contact_updated_at"},"sort_ascending":{"type":"boolean","required":false,"visibility":"user-only","description":"When true, sort ascending. Must be used together with sort_by_field"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_contact_update":{"id":"apollo_contact_update","name":"Apollo Update Contact","description":"Update an existing contact in your Apollo database","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"contact_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the contact to update (e.g., \\"con_abc123\\")"},"first_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"First name of the contact"},"last_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Last name of the contact"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"Email address"},"title":{"type":"string","required":false,"visibility":"user-or-llm","description":"Job title (e.g., \\"VP of Sales\\", \\"Software Engineer\\")"},"account_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"Apollo account ID (e.g., \\"acc_abc123\\")"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"User ID of the contact owner (accepted by Apollo but not officially documented for PATCH /contacts/{id})"},"organization_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Name of the contact\'s employer (e.g., \\"Apollo\\")"},"website_url":{"type":"string","required":false,"visibility":"user-or-llm","description":"Corporate website URL (e.g., \\"https://www.apollo.io/\\")"},"label_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Lists/labels to add the contact to (e.g., [\\"Prospects\\"])"},"contact_stage_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"Apollo ID for the contact stage"},"present_raw_address":{"type":"string","required":false,"visibility":"user-or-llm","description":"Personal location for the contact (e.g., \\"Atlanta, United States\\")"},"direct_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Primary phone number"},"corporate_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Work/office phone number"},"mobile_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Mobile phone number"},"home_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Home phone number"},"other_phone":{"type":"string","required":false,"visibility":"user-or-llm","description":"Alternative phone number"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-or-llm","description":"Custom field values keyed by custom field ID"}},"hostedApiKey":"none"},"apollo_email_accounts":{"id":"apollo_email_accounts","name":"Apollo Get Email Accounts","description":"Get list of team\'s linked email accounts in Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"}},"hostedApiKey":"none"},"apollo_opportunity_create":{"id":"apollo_opportunity_create","name":"Apollo Create Opportunity","description":"Create a new deal for an account in your Apollo database (master key required)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the opportunity/deal (e.g., \\"Enterprise License - Q1\\")"},"account_id":{"type":"string","required":false,"visibility":"user-or-llm","description":"ID of the account this opportunity belongs to (e.g., \\"acc_abc123\\")"},"amount":{"type":"string","required":false,"visibility":"user-or-llm","description":"Monetary value as a plain number string with no commas or currency symbols"},"opportunity_stage_id":{"type":"string","required":false,"visibility":"user-only","description":"ID of the opportunity stage"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"User ID of the opportunity owner"},"closed_date":{"type":"string","required":false,"visibility":"user-or-llm","description":"Expected close date in YYYY-MM-DD format"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-only","description":"Custom field values as { custom_field_id: value } map"}},"hostedApiKey":"none"},"apollo_opportunity_get":{"id":"apollo_opportunity_get","name":"Apollo Get Opportunity","description":"Retrieve complete details of a specific deal/opportunity by ID","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"opportunity_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the opportunity to retrieve (e.g., \\"opp_abc123\\")"}},"hostedApiKey":"none"},"apollo_opportunity_search":{"id":"apollo_opportunity_search","name":"Apollo Search Opportunities","description":"Search and list all deals/opportunities in your team\'s Apollo account","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"sort_by_field":{"type":"string","required":false,"visibility":"user-or-llm","description":"Sort field: \\"amount\\", \\"is_closed\\", or \\"is_won\\""},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_opportunity_update":{"id":"apollo_opportunity_update","name":"Apollo Update Opportunity","description":"Update an existing deal/opportunity in your Apollo database","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"opportunity_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the opportunity to update (e.g., \\"opp_abc123\\")"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Name of the opportunity/deal (e.g., \\"Enterprise License - Q1\\")"},"amount":{"type":"string","required":false,"visibility":"user-or-llm","description":"Monetary value as a plain number string with no commas or currency symbols"},"opportunity_stage_id":{"type":"string","required":false,"visibility":"user-only","description":"ID of the opportunity stage"},"owner_id":{"type":"string","required":false,"visibility":"user-only","description":"User ID of the opportunity owner"},"closed_date":{"type":"string","required":false,"visibility":"user-or-llm","description":"Expected close date in YYYY-MM-DD format"},"typed_custom_fields":{"type":"json","required":false,"visibility":"user-only","description":"Custom field values as { custom_field_id: value } map"}},"hostedApiKey":"none"},"apollo_organization_bulk_enrich":{"id":"apollo_organization_bulk_enrich","name":"Apollo Bulk Organization Enrichment","description":"Enrich data for up to 10 organizations at once using Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"domains":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of company domains to enrich (max 10, no www. or @, e.g., [\\"apollo.io\\", \\"stripe.com\\"])"}},"hostedApiKey":"none"},"apollo_organization_enrich":{"id":"apollo_organization_enrich","name":"Apollo Organization Enrichment","description":"Enrich data for a single organization using Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"domain":{"type":"string","required":true,"visibility":"user-or-llm","description":"Company domain (e.g., \\"apollo.io\\", \\"acme.com\\")"}},"hostedApiKey":"none"},"apollo_organization_search":{"id":"apollo_organization_search","name":"Apollo Organization Search","description":"Search Apollo\'s database for companies using filters","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"organization_locations":{"type":"array","required":false,"visibility":"user-or-llm","description":"Company HQ locations (cities, US states, or countries)"},"organization_not_locations":{"type":"array","required":false,"visibility":"user-or-llm","description":"Exclude companies whose HQ is in these locations"},"organization_num_employees_ranges":{"type":"array","required":false,"visibility":"user-or-llm","description":"Employee count ranges as \\"min,max\\" strings (e.g., [\\"1,10\\", \\"250,500\\", \\"10000,20000\\"])"},"q_organization_keyword_tags":{"type":"array","required":false,"visibility":"user-or-llm","description":"Industry or keyword tags"},"q_organization_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Organization name to search for (e.g., \\"Acme\\", \\"TechCorp\\")"},"organization_ids":{"type":"array","required":false,"visibility":"user-or-llm","description":"Apollo organization IDs to include (e.g., [\\"5e66b6381e05b4008c8331b8\\"])"},"q_organization_domains_list":{"type":"array","required":false,"visibility":"user-or-llm","description":"Domain names to filter by (no www. or @, up to 1,000)"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_people_bulk_enrich":{"id":"apollo_people_bulk_enrich","name":"Apollo Bulk People Enrichment","description":"Enrich data for up to 10 people at once using Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"people":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of people to enrich (max 10)"},"reveal_personal_emails":{"type":"boolean","required":false,"visibility":"user-only","description":"Reveal personal email addresses (uses credits)"},"reveal_phone_number":{"type":"boolean","required":false,"visibility":"user-only","description":"Reveal phone numbers (uses credits, requires webhook_url)"},"webhook_url":{"type":"string","required":false,"visibility":"user-only","description":"Webhook URL for async phone number delivery (required when reveal_phone_number is true)"}},"hostedApiKey":"none"},"apollo_people_enrich":{"id":"apollo_people_enrich","name":"Apollo People Enrichment","description":"Enrich data for a single person using Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"first_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"First name of the person"},"last_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Last name of the person"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Full name of the person (alternative to first_name/last_name)"},"id":{"type":"string","required":false,"visibility":"user-or-llm","description":"Apollo ID for the person"},"hashed_email":{"type":"string","required":false,"visibility":"user-or-llm","description":"MD5 or SHA-256 hashed email"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"Email address of the person"},"organization_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company name where the person works"},"domain":{"type":"string","required":false,"visibility":"user-or-llm","description":"Company domain (e.g., \\"apollo.io\\", \\"acme.com\\")"},"linkedin_url":{"type":"string","required":false,"visibility":"user-or-llm","description":"LinkedIn profile URL"},"reveal_personal_emails":{"type":"boolean","required":false,"visibility":"user-only","description":"Reveal personal email addresses (uses credits)"},"reveal_phone_number":{"type":"boolean","required":false,"visibility":"user-only","description":"Reveal phone numbers (uses credits, requires webhook_url)"},"webhook_url":{"type":"string","required":false,"visibility":"user-only","description":"Webhook URL for async phone number delivery (required when reveal_phone_number is true)"}},"hostedApiKey":"none"},"apollo_people_search":{"id":"apollo_people_search","name":"Apollo People Search","description":"Search Apollo\'s database for people using demographic filters","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key"},"person_titles":{"type":"array","required":false,"visibility":"user-or-llm","description":"Job titles to search for (e.g., [\\"CEO\\", \\"VP of Sales\\"])"},"include_similar_titles":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Whether to return people with job titles similar to person_titles"},"person_locations":{"type":"array","required":false,"visibility":"user-or-llm","description":"Locations to search in (e.g., [\\"San Francisco, CA\\", \\"New York, NY\\"])"},"person_seniorities":{"type":"array","required":false,"visibility":"user-or-llm","description":"Seniority levels (one of: owner, founder, c_suite, partner, vp, head, director, manager, senior, entry, intern)"},"organization_ids":{"type":"array","required":false,"visibility":"user-or-llm","description":"Apollo organization IDs to filter by (e.g., [\\"5e66b6381e05b4008c8331b8\\"])"},"organization_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Company names to search within (legacy filter)"},"organization_locations":{"type":"array","required":false,"visibility":"user-or-llm","description":"Headquarters locations of the people\'s current employer (e.g., [\'texas\', \'tokyo\', \'spain\'])"},"q_organization_domains_list":{"type":"array","required":false,"visibility":"user-or-llm","description":"Employer domain names (e.g., [\\"apollo.io\\", \\"microsoft.com\\"]) — up to 1,000, no www. or @"},"organization_num_employees_ranges":{"type":"array","required":false,"visibility":"user-or-llm","description":"Employee count ranges for the person\'s current employer. Each entry is \\"min,max\\" (e.g., [\\"1,10\\", \\"250,500\\", \\"10000,20000\\"])"},"contact_email_status":{"type":"array","required":false,"visibility":"user-or-llm","description":"Email statuses to filter by: \\"verified\\", \\"unverified\\", \\"likely to engage\\", \\"unavailable\\""},"q_keywords":{"type":"string","required":false,"visibility":"user-or-llm","description":"Keywords to search for"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination, default 1 (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, default 25, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_sequence_add_contacts":{"id":"apollo_sequence_add_contacts","name":"Apollo Add Contacts to Sequence","description":"Add contacts to an Apollo sequence","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"sequence_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the sequence to add contacts to (e.g., \\"seq_abc123\\")"},"contact_ids":{"type":"array","required":false,"visibility":"user-or-llm","description":"Array of contact IDs to add to the sequence (e.g., [\\"con_abc123\\", \\"con_def456\\"]). Either contact_ids or label_names must be provided."},"label_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Array of label names to identify contacts to add to the sequence. Either contact_ids or label_names must be provided."},"send_email_from_email_account_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the email account to send from. Use the Get Email Accounts operation to look this up."},"send_email_from_email_address":{"type":"string","required":false,"visibility":"user-only","description":"Specific email address to send from within the email account."},"sequence_no_email":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts even if they have no email address"},"sequence_unverified_email":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts with unverified email addresses"},"sequence_job_change":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts who recently changed jobs"},"sequence_active_in_other_campaigns":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts active in other campaigns"},"sequence_finished_in_other_campaigns":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts who finished other campaigns"},"sequence_same_company_in_same_campaign":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts even if others from the same company are in the sequence"},"contacts_without_ownership_permission":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts without ownership permission"},"add_if_in_queue":{"type":"boolean","required":false,"visibility":"user-only","description":"Add contacts even if they are in the queue"},"contact_verification_skipped":{"type":"boolean","required":false,"visibility":"user-only","description":"Skip contact verification when adding"},"user_id":{"type":"string","required":false,"visibility":"user-only","description":"ID of the user performing the action"},"status":{"type":"string","required":false,"visibility":"user-only","description":"Initial status for added contacts: \\"active\\" or \\"paused\\""},"auto_unpause_at":{"type":"string","required":false,"visibility":"user-only","description":"ISO 8601 datetime to automatically unpause contacts"}},"hostedApiKey":"none"},"apollo_sequence_search":{"id":"apollo_sequence_search","name":"Apollo Search Sequences","description":"Search for sequences/campaigns in your team\'s Apollo account (master key required)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"q_name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Search sequences by name (e.g., \\"Outbound Q1\\", \\"Follow-up\\")"},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"apollo_task_create":{"id":"apollo_task_create","name":"Apollo Create Task","description":"Create one or more tasks in Apollo (one task per contact_id, master key required)","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"user_id":{"type":"string","required":true,"visibility":"user-or-llm","description":"ID of the Apollo user the task is assigned to"},"contact_ids":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of contact IDs. One task is created per contact."},"priority":{"type":"string","required":false,"visibility":"user-or-llm","description":"Task priority: \\"high\\", \\"medium\\", or \\"low\\" (defaults to \\"medium\\")"},"due_at":{"type":"string","required":true,"visibility":"user-or-llm","description":"Due date/time in ISO 8601 format (e.g., \\"2024-12-31T23:59:59Z\\")"},"type":{"type":"string","required":true,"visibility":"user-or-llm","description":"Task type: \\"call\\", \\"outreach_manual_email\\", \\"linkedin_step_connect\\", \\"linkedin_step_message\\", \\"linkedin_step_view_profile\\", \\"linkedin_step_interact_post\\", or \\"action_item\\""},"status":{"type":"string","required":true,"visibility":"user-or-llm","description":"Task status: \\"scheduled\\", \\"completed\\", or \\"skipped\\""},"note":{"type":"string","required":false,"visibility":"user-or-llm","description":"Free-form note providing context for the task"}},"hostedApiKey":"none"},"apollo_task_search":{"id":"apollo_task_search","name":"Apollo Search Tasks","description":"Search for tasks in Apollo","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Apollo API key (master key required)"},"sort_by_field":{"type":"string","required":false,"visibility":"user-or-llm","description":"Sort field: \\"task_due_at\\" or \\"task_priority\\""},"open_factor_names":{"type":"array","required":false,"visibility":"user-or-llm","description":"Filter by status. Common values: [\\"task_types\\"] for open tasks, [\\"task_completed_at\\"] for completed tasks."},"page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Page number for pagination (e.g., 1, 2, 3)"},"per_page":{"type":"number","required":false,"visibility":"user-or-llm","description":"Results per page, max 100 (e.g., 25, 50, 100)"}},"hostedApiKey":"none"},"appconfig_create_application":{"id":"appconfig_create_application","name":"AppConfig Create Application","description":"Create an application in AWS AppConfig","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the application to create"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"Description of the application"}},"hostedApiKey":"none"},"appconfig_create_configuration_profile":{"id":"appconfig_create_configuration_profile","name":"AppConfig Create Configuration Profile","description":"Create a configuration profile in an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to create the configuration profile in"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the configuration profile"},"locationUri":{"type":"string","required":true,"visibility":"user-or-llm","description":"Where the configuration is stored. Use \\"hosted\\" for AppConfig-hosted configurations, or an SSM/S3 URI"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"Description of the configuration profile"},"retrievalRoleArn":{"type":"string","required":false,"visibility":"user-or-llm","description":"ARN of an IAM role to retrieve the configuration (required for non-hosted URIs)"},"type":{"type":"string","required":false,"visibility":"user-or-llm","description":"Profile type: AWS.Freeform (default) or AWS.AppConfig.FeatureFlags"}},"hostedApiKey":"none"},"appconfig_create_environment":{"id":"appconfig_create_environment","name":"AppConfig Create Environment","description":"Create an environment for an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to create the environment in"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the environment to create"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"Description of the environment"}},"hostedApiKey":"none"},"appconfig_create_hosted_configuration_version":{"id":"appconfig_create_hosted_configuration_version","name":"AppConfig Create Hosted Configuration Version","description":"Create a new hosted configuration version for an AppConfig configuration profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to add the version to"},"content":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration content (e.g., a JSON or YAML document)"},"contentType":{"type":"string","required":true,"visibility":"user-or-llm","description":"Content type of the configuration (e.g., application/json, text/plain)"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"Description of the configuration version"},"latestVersionNumber":{"type":"number","required":false,"visibility":"user-or-llm","description":"The version number of the latest version, used for optimistic concurrency"},"versionLabel":{"type":"string","required":false,"visibility":"user-or-llm","description":"A user-defined label for the configuration version"}},"hostedApiKey":"none"},"appconfig_delete_application":{"id":"appconfig_delete_application","name":"AppConfig Delete Application","description":"Delete an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to delete"}},"hostedApiKey":"none"},"appconfig_delete_configuration_profile":{"id":"appconfig_delete_configuration_profile","name":"AppConfig Delete Configuration Profile","description":"Delete an AWS AppConfig configuration profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to delete"}},"hostedApiKey":"none"},"appconfig_delete_environment":{"id":"appconfig_delete_environment","name":"AppConfig Delete Environment","description":"Delete an AWS AppConfig environment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the environment"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID to delete"}},"hostedApiKey":"none"},"appconfig_delete_hosted_configuration_version":{"id":"appconfig_delete_hosted_configuration_version","name":"AppConfig Delete Hosted Configuration Version","description":"Delete a specific hosted configuration version from an AppConfig profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID that owns the version"},"versionNumber":{"type":"number","required":true,"visibility":"user-or-llm","description":"The version number to delete"}},"hostedApiKey":"none"},"appconfig_get_application":{"id":"appconfig_get_application","name":"AppConfig Get Application","description":"Get details about a single AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to retrieve"}},"hostedApiKey":"none"},"appconfig_get_configuration":{"id":"appconfig_get_configuration","name":"AppConfig Get Configuration","description":"Retrieve the latest deployed configuration for an AppConfig application, environment, and profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID or name to retrieve configuration for"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID or name to retrieve configuration for"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID or name to retrieve"}},"hostedApiKey":"none"},"appconfig_get_configuration_profile":{"id":"appconfig_get_configuration_profile","name":"AppConfig Get Configuration Profile","description":"Get details about a single AWS AppConfig configuration profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to retrieve"}},"hostedApiKey":"none"},"appconfig_get_deployment":{"id":"appconfig_get_deployment","name":"AppConfig Get Deployment","description":"Get details about a specific AWS AppConfig deployment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID of the deployment"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID of the deployment"},"deploymentNumber":{"type":"number","required":true,"visibility":"user-or-llm","description":"The sequence number of the deployment"}},"hostedApiKey":"none"},"appconfig_get_environment":{"id":"appconfig_get_environment","name":"AppConfig Get Environment","description":"Get details about a single AWS AppConfig environment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the environment"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID to retrieve"}},"hostedApiKey":"none"},"appconfig_get_hosted_configuration_version":{"id":"appconfig_get_hosted_configuration_version","name":"AppConfig Get Hosted Configuration Version","description":"Retrieve a specific hosted configuration version from an AppConfig profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to read the version from"},"versionNumber":{"type":"number","required":true,"visibility":"user-or-llm","description":"The version number to retrieve"}},"hostedApiKey":"none"},"appconfig_list_applications":{"id":"appconfig_list_applications","name":"AppConfig List Applications","description":"List applications in AWS AppConfig","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of applications to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_list_configuration_profiles":{"id":"appconfig_list_configuration_profiles","name":"AppConfig List Configuration Profiles","description":"List configuration profiles for an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profiles"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of configuration profiles to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_list_deployment_strategies":{"id":"appconfig_list_deployment_strategies","name":"AppConfig List Deployment Strategies","description":"List deployment strategies available in AWS AppConfig","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of deployment strategies to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_list_deployments":{"id":"appconfig_list_deployments","name":"AppConfig List Deployments","description":"List deployments for an AWS AppConfig environment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID of the deployments"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID of the deployments"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of deployments to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_list_environments":{"id":"appconfig_list_environments","name":"AppConfig List Environments","description":"List environments for an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the environments"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of environments to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_list_hosted_configuration_versions":{"id":"appconfig_list_hosted_configuration_versions","name":"AppConfig List Hosted Configuration Versions","description":"List hosted configuration versions for an AWS AppConfig configuration profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to list versions for"},"maxResults":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of versions to return (1-50)"},"nextToken":{"type":"string","required":false,"visibility":"user-or-llm","description":"Pagination token from a previous response"}},"hostedApiKey":"none"},"appconfig_start_deployment":{"id":"appconfig_start_deployment","name":"AppConfig Start Deployment","description":"Start deploying a configuration version to an AWS AppConfig environment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to deploy in"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID to deploy to"},"deploymentStrategyId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The deployment strategy ID to use"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to deploy"},"configurationVersion":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration version to deploy"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"Description of the deployment"}},"hostedApiKey":"none"},"appconfig_stop_deployment":{"id":"appconfig_stop_deployment","name":"AppConfig Stop Deployment","description":"Stop an in-progress AWS AppConfig deployment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID of the deployment"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID of the deployment"},"deploymentNumber":{"type":"number","required":true,"visibility":"user-or-llm","description":"The sequence number of the deployment to stop"}},"hostedApiKey":"none"},"appconfig_update_application":{"id":"appconfig_update_application","name":"AppConfig Update Application","description":"Update the name or description of an AWS AppConfig application","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID to update"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"New name for the application"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"New description for the application"}},"hostedApiKey":"none"},"appconfig_update_configuration_profile":{"id":"appconfig_update_configuration_profile","name":"AppConfig Update Configuration Profile","description":"Update the name, description, or retrieval role of an AppConfig configuration profile","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the configuration profile"},"configurationProfileId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The configuration profile ID to update"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"New name for the configuration profile"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"New description for the configuration profile"},"retrievalRoleArn":{"type":"string","required":false,"visibility":"user-or-llm","description":"New ARN of the IAM role used to retrieve the configuration"}},"hostedApiKey":"none"},"appconfig_update_environment":{"id":"appconfig_update_environment","name":"AppConfig Update Environment","description":"Update the name or description of an AWS AppConfig environment","version":"1.0","params":{"region":{"type":"string","required":true,"visibility":"user-only","description":"AWS region (e.g., us-east-1)"},"accessKeyId":{"type":"string","required":true,"visibility":"user-only","description":"AWS access key ID"},"secretAccessKey":{"type":"string","required":true,"visibility":"user-only","description":"AWS secret access key"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The application ID that owns the environment"},"environmentId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The environment ID to update"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"New name for the environment"},"description":{"type":"string","required":false,"visibility":"user-or-llm","description":"New description for the environment"}},"hostedApiKey":"none"},"arxiv_get_author_papers":{"id":"arxiv_get_author_papers","name":"ArXiv Get Author Papers","description":"Search for papers by a specific author on ArXiv.","version":"1.0.0","params":{"authorName":{"type":"string","required":true,"visibility":"user-or-llm","description":"Author name to search for"},"maxResults":{"type":"number","required":false,"visibility":"user-only","description":"Maximum number of results to return (default: 10, max: 2000)"}},"hostedApiKey":"none"},"arxiv_get_paper":{"id":"arxiv_get_paper","name":"ArXiv Get Paper","description":"Get detailed information about a specific ArXiv paper by its ID.","version":"1.0.0","params":{"paperId":{"type":"string","required":true,"visibility":"user-or-llm","description":"ArXiv paper ID (e.g., \\"1706.03762\\")"}},"hostedApiKey":"none"},"arxiv_search":{"id":"arxiv_search","name":"ArXiv Search","description":"Search for academic papers on ArXiv by keywords, authors, titles, or other fields.","version":"1.0.0","params":{"searchQuery":{"type":"string","required":true,"visibility":"user-or-llm","description":"The search query to execute"},"searchField":{"type":"string","required":false,"visibility":"user-only","description":"Field to search in: all, ti (title), au (author), abs (abstract), co (comment), jr (journal), cat (category), rn (report number)"},"maxResults":{"type":"number","required":false,"visibility":"user-only","description":"Maximum number of results to return (default: 10, max: 2000)"},"sortBy":{"type":"string","required":false,"visibility":"user-only","description":"Sort by: relevance, lastUpdatedDate, submittedDate (default: relevance)"},"sortOrder":{"type":"string","required":false,"visibility":"user-only","description":"Sort order: ascending, descending (default: descending)"}},"hostedApiKey":"none"},"asana_add_comment":{"id":"asana_add_comment","name":"Asana Add Comment","description":"Add a comment (story) to an Asana task","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana task GID (numeric string)"},"text":{"type":"string","required":true,"visibility":"user-or-llm","description":"The text content of the comment"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_add_followers":{"id":"asana_add_followers","name":"Asana Add Followers","description":"Add one or more followers to an Asana task","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"GID of the Asana task (numeric string)"},"followers":{"type":"array","required":true,"visibility":"user-or-llm","description":"Array of user GIDs to add as followers to the task"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_create_project":{"id":"asana_create_project","name":"Asana Create Project","description":"Create a new project in an Asana workspace","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"workspace":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana workspace GID (numeric string) where the project will be created"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the project"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"Notes or description for the project"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_create_section":{"id":"asana_create_section","name":"Asana Create Section","description":"Create a new section in an Asana project","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"projectGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"GID of the Asana project (numeric string) to add the section to"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the section"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_create_subtask":{"id":"asana_create_subtask","name":"Asana Create Subtask","description":"Create a subtask under an existing Asana task","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"GID of the parent Asana task (numeric string)"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the subtask"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"Notes or description for the subtask"},"assignee":{"type":"string","required":false,"visibility":"user-or-llm","description":"User GID to assign the subtask to"},"due_on":{"type":"string","required":false,"visibility":"user-or-llm","description":"Due date in YYYY-MM-DD format"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_create_task":{"id":"asana_create_task","name":"Asana Create Task","description":"Create a new task in Asana","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"workspace":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana workspace GID (numeric string) where the task will be created"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"Name of the task"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"Notes or description for the task"},"assignee":{"type":"string","required":false,"visibility":"user-or-llm","description":"User GID to assign the task to"},"due_on":{"type":"string","required":false,"visibility":"user-or-llm","description":"Due date in YYYY-MM-DD format"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_delete_task":{"id":"asana_delete_task","name":"Asana Delete Task","description":"Delete an Asana task by its GID (moves it to the trash)","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"GID of the Asana task to delete (numeric string)"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_get_project":{"id":"asana_get_project","name":"Asana Get Project","description":"Retrieve a single Asana project by its GID","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"projectGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana project GID (numeric string) to retrieve"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_get_projects":{"id":"asana_get_projects","name":"Asana Get Projects","description":"Retrieve all projects from an Asana workspace","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"workspace":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana workspace GID (numeric string) to retrieve projects from"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_get_task":{"id":"asana_get_task","name":"Asana Get Task","description":"Retrieve a single task by GID or get multiple tasks with filters","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":false,"visibility":"user-or-llm","description":"The globally unique identifier (GID) of the task. If not provided, will get multiple tasks."},"workspace":{"type":"string","required":false,"visibility":"user-or-llm","description":"Asana workspace GID (numeric string) to filter tasks (required when not using taskGid)"},"project":{"type":"string","required":false,"visibility":"user-or-llm","description":"Asana project GID (numeric string) to filter tasks"},"limit":{"type":"number","required":false,"visibility":"user-or-llm","description":"Maximum number of tasks to return (default: 50)"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_list_sections":{"id":"asana_list_sections","name":"Asana List Sections","description":"List all sections in an Asana project","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"projectGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"GID of the Asana project (numeric string) to list sections from"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_list_workspaces":{"id":"asana_list_workspaces","name":"Asana List Workspaces","description":"List all Asana workspaces and organizations the authenticated user belongs to","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_search_tasks":{"id":"asana_search_tasks","name":"Asana Search Tasks","description":"Search for tasks in an Asana workspace","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"workspace":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana workspace GID (numeric string) to search tasks in"},"text":{"type":"string","required":false,"visibility":"user-or-llm","description":"Text to search for in task names"},"assignee":{"type":"string","required":false,"visibility":"user-or-llm","description":"Filter tasks by assignee user GID"},"projects":{"type":"array","required":false,"visibility":"user-or-llm","description":"Array of Asana project GIDs (numeric strings) to filter tasks by"},"completed":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Filter by completion status"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"asana_update_task":{"id":"asana_update_task","name":"Asana Update Task","description":"Update an existing task in Asana","version":"1.0.0","params":{"accessToken":{"type":"string","required":true,"visibility":"hidden","description":"OAuth access token for Asana"},"taskGid":{"type":"string","required":true,"visibility":"user-or-llm","description":"Asana task GID (numeric string) of the task to update"},"name":{"type":"string","required":false,"visibility":"user-or-llm","description":"Updated name for the task"},"notes":{"type":"string","required":false,"visibility":"user-or-llm","description":"Updated notes or description for the task"},"assignee":{"type":"string","required":false,"visibility":"user-or-llm","description":"Updated assignee user GID"},"completed":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Mark task as completed or not completed"},"due_on":{"type":"string","required":false,"visibility":"user-or-llm","description":"Updated due date in YYYY-MM-DD format"}},"oauth":{"required":true,"provider":"asana"},"hostedApiKey":"none"},"ashby_add_candidate_tag":{"id":"ashby_add_candidate_tag","name":"Ashby Add Candidate Tag","description":"Adds a tag to a candidate in Ashby and returns the updated candidate.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"candidateId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the candidate to add the tag to"},"tagId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the tag to add"}},"hostedApiKey":"none"},"ashby_anonymize_candidate":{"id":"ashby_anonymize_candidate","name":"Ashby Anonymize Candidate","description":"Remove personally identifiable information from an Ashby candidate while retaining the candidate record and its applications. This operation does not delete the candidate. Requires the candidatesWrite permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"candidateId":{"type":"string","required":true,"visibility":"user-or-llm","description":"UUID of the candidate to anonymize"}},"hostedApiKey":"none"},"ashby_change_application_source":{"id":"ashby_change_application_source","name":"Ashby Change Application Source","description":"Changes the source attributed to an existing application, so programmatically created applications report correctly on the recruiting side. Requires the candidatesWrite permission.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"UUID of the application whose source should change"},"sourceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the source to attribute the application to, as returned by List Sources. Omit only when unsetSource is true."},"unsetSource":{"type":"boolean","required":false,"visibility":"user-or-llm","description":"Set true to deliberately clear the application source. Required to unset, so that a missing or empty sourceId cannot wipe attribution by accident."}},"hostedApiKey":"none"},"ashby_change_application_stage":{"id":"ashby_change_application_stage","name":"Ashby Change Application Stage","description":"Moves an application to a different interview stage. Requires an archive reason when moving to an Archived stage.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"applicationId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the application to update the stage of"},"interviewStageId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the interview stage to move the application to"},"archiveReasonId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Archive reason UUID. Required when moving to an Archived stage, ignored otherwise"},"archiveEmail":{"type":"json","required":false,"visibility":"user-or-llm","description":"Archive email configuration with communicationTemplateId and optional sendAt ISO 8601 timestamp. Pass null or omit to send no archive email."}},"hostedApiKey":"none"},"ashby_create_application":{"id":"ashby_create_application","name":"Ashby Create Application","description":"Creates a new application for a candidate on a job. Optionally specify interview plan, stage, source, and credited user.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"candidateId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the candidate to consider for the job"},"jobId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the job to consider the candidate for"},"interviewPlanId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the interview plan to use (defaults to the job default plan)"},"interviewStageId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the interview stage to place the application in, or FirstPreInterviewScreen (defaults to the first Lead stage)"},"sourceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the source to set on the application"},"creditedToUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the user the application is credited to"},"createdAt":{"type":"string","required":false,"visibility":"user-or-llm","description":"ISO 8601 timestamp to set as the application creation date (defaults to now)"},"applicationHistory":{"type":"json","required":false,"visibility":"user-or-llm","description":"Optional documented application history entries to create with the application"}},"hostedApiKey":"none"},"ashby_create_candidate":{"id":"ashby_create_candidate","name":"Ashby Create Candidate","description":"Creates a new candidate record in Ashby.","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"name":{"type":"string","required":true,"visibility":"user-or-llm","description":"The candidate full name"},"email":{"type":"string","required":false,"visibility":"user-or-llm","description":"Primary email address for the candidate"},"phoneNumber":{"type":"string","required":false,"visibility":"user-or-llm","description":"Primary phone number for the candidate"},"linkedInUrl":{"type":"string","required":false,"visibility":"user-or-llm","description":"LinkedIn profile URL"},"githubUrl":{"type":"string","required":false,"visibility":"user-or-llm","description":"GitHub profile URL"},"website":{"type":"string","required":false,"visibility":"user-or-llm","description":"Personal website URL"},"sourceId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the source to attribute the candidate to"},"creditedToUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"UUID of the Ashby user to credit with sourcing this candidate"},"createdAt":{"type":"string","required":false,"visibility":"user-or-llm","description":"Backdated creation timestamp in ISO 8601 (e.g. 2024-01-01T00:00:00Z). Defaults to now."},"alternateEmailAddresses":{"type":"json","required":false,"visibility":"user-or-llm","description":"Array of additional email address strings to add to the candidate, e.g. [\\"a@x.com\\",\\"b@y.com\\"]"},"location":{"type":"json","required":false,"visibility":"user-or-llm","description":"Candidate location object with optional city, region, and country"}},"hostedApiKey":"none"},"ashby_create_note":{"id":"ashby_create_note","name":"Ashby Create Note","description":"Creates a note on a candidate in Ashby. Supports plain text and HTML content (bold, italic, underline, links, lists, code).","version":"1.0.0","params":{"apiKey":{"type":"string","required":true,"visibility":"user-only","description":"Ashby API Key"},"onBehalfOfUserId":{"type":"string","required":false,"visibility":"user-or-llm","description":"Active Ashby user UUID to attribute this mutation to; the API key must permit on-behalf-of calls"},"candidateId":{"type":"string","required":true,"visibility":"user-or-llm","description":"The UUID of the candidate to add the note to"},"note":{"type":"string","required":true,"visibility":"user-or-llm","description":"The note content. If noteType is text/html, supports: , , , ,