The MCP server accepts two kinds of credential, and both are organization tokens with a role: an OAuth connection, created when you grant access from the client, and an API token that you create yourself. Either way the assistant can never do more than you can.
Connecting with OAuth
The server implements MCP authorization (external link) (OAuth 2.1). mcp.openwaf.dev is the protected resource and dash.openwaf.dev, where you sign in, the authorization server. From your side:
- You give the client only the URL
https://mcp.openwaf.dev/mcp. - The client registers itself and opens
dash.openwaf.devin the browser. If you are not signed in, you sign in and come back to the same request. - The consent screen shows the client's name (declared by the client itself, so it is marked as unverified) and the host it will return to, and asks you to choose: - Organization: one of yours. Suspended organizations and those pending approval cannot be chosen. - Role: read only (
readonly), technician (tech) or administrator (admin), never above your own role. A member limited to one client can choosereadonlyortech. - Expiry: 7, 30 or 90 days. - You allow or deny. Denying returns
access_deniedto the client.
If the client's return address is not one it registered, the dashboard shows the error and does not redirect anywhere. Other errors are shown with a «Return to the application» button and the destination host, never an automatic redirect.
Where the connection shows up
The connection is a token of the organization: it appears in API tokens as «MCP · <client>», with the «OAuth app» badge, the role and the expiry you chose. Like any token, its role never exceeds the member's current role, and it dies if the member leaves the organization.
To revoke access, revoke it in API tokens: its access and refresh tokens stop working at once. The client can also revoke it itself.
Behind the scenes the client holds a 1-hour access token (owfa_…) and a single-use refresh token (owfr_…); only the SHA-256 of each secret is stored. An OAuth access token only opens the MCP endpoint: the rest of the REST API answers 401.
In the audit log you will find oauth.authorize (access granted, with client, return host, role and expiry), token.create and token.revoke.
API tokens
For clients without OAuth, or for automation, create a token of its own for the assistant in the dashboard (API tokens) or with POST /v1/orgs/{org}/tokens, with the narrowest role and an expiry:
| Choice | Effect |
|---|---|
readonly | The assistant only sees the read tools; the write tools do not even appear in tools/list |
tech | Read and write zones, records, edge settings and rules |
admin | Everything, including the egress write tools and audit_log |
Limited to a client (client_id) | The assistant only sees that client's zones |
Limited to a zone (zone_id) | The assistant only sees that zone |
audit_log needs admin, or tech limited to a client. Zones outside the token's scope answer not_found, as if they did not exist. Tokens owf_… work the same on every URL of the server.
Lite profile
The full tool list takes about 54 KB of tools/list (around 12,500 tokens), loaded into every conversation. The lite profile lists only discovery, a code mode and the everyday reads (about 1,300 tokens):
| Tool | Purpose |
|---|---|
search_tools | Searches tools and API operations by keywords (English or Spanish) |
describe_tool | The full input schema of a tool or API operation, an example and, for writes, the simulate → confirm protocol |
call_tool | Calls any tool by name, for clients that only call listed tools |
execute | Code mode: a read-only JavaScript script run on the server, with the token's permissions; it can simulate writes but never apply them |
list_zones, get_zone, list_records | The everyday reads |
Every other tool still exists and can be called by name or through call_tool, with the same permissions. Choose it with the profile URL parameter or the X-OpenWAF-MCP-Profile: lite header; an unknown value answers 400. Without the parameter the profile is full, so clients already configured do not change.
claude mcp add --transport http openwaf-lite 'https://mcp.openwaf.dev/mcp?profile=lite' \
--header "Authorization: Bearer $OPENWAF_TOKEN"{ "mcpServers": { "openwaf": { "type": "http", "url": "https://mcp.openwaf.dev/mcp?profile=lite",
"headers": { "Authorization": "Bearer owf_…" } } } }