There are two ways to authenticate. OAuth 2.1 is the default: give the client the URL, sign in to the dashboard when it asks and choose what the assistant may do. An API token is the fallback for clients that cannot do OAuth, or for automation.
Before you start
- An OpenWAF Cloud account with access to an organization. For OAuth, you sign in with it in the browser.
- For the token variant, a token of its own for the assistant, created in the dashboard (API tokens) or with
POST /v1/orgs/{org}/tokens, with the narrowest role and an expiry. See OAuth and tokens.
Claude Code
claude mcp add --transport http openwaf https://mcp.openwaf.dev/mcpWithout a header, Claude Code uses OAuth: run /mcp, pick openwaf and Authenticate opens the browser.
claude mcp add --transport http openwaf https://mcp.openwaf.dev/mcp \
--header "Authorization: Bearer $OPENWAF_TOKEN"claude mcp list should show it connected, and /mcp inside Claude Code lists its tools.
Claude Desktop and claude.ai
Settings → Connectors → Add custom connector → URL https://mcp.openwaf.dev/mcp → Connect. The dashboard opens so you sign in and grant access. You do not need mcp-remote or Node.js.
To use an API token instead of OAuth in Claude Desktop, the mcp-remote (external link) bridge still works in claude_desktop_config.json (Settings → Developer → Edit config):
{
"mcpServers": {
"openwaf": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.openwaf.dev/mcp", "--header", "Authorization:${OPENWAF_AUTH}"],
"env": { "OPENWAF_AUTH": "Bearer owf_…" }
}
}
}The header goes in a variable so the arguments contain no spaces. Restart Claude Desktop afterwards.
Cursor
In ~/.cursor/mcp.json (or the project's .cursor/mcp.json, kept out of the repository):
{
"mcpServers": {
"openwaf": {
"url": "https://mcp.openwaf.dev/mcp"
}
}
}Without headers, Cursor uses OAuth and only needs the url.
{
"mcpServers": {
"openwaf": {
"url": "https://mcp.openwaf.dev/mcp",
"headers": { "Authorization": "Bearer owf_…" }
}
}
}Codex and other clients
Any MCP client with the Streamable HTTP transport works: add https://mcp.openwaf.dev/mcp as a remote server. If the client supports MCP authorization, the URL is enough; otherwise set the header Authorization: Bearer owf_….
By hand, to check a token:
curl -sS https://mcp.openwaf.dev/mcp \
-H "Authorization: Bearer $OPENWAF_TOKEN" -H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Transport rules
Every client must meet these rules:
Acceptmust include bothapplication/jsonandtext/event-stream.GETandDELETEanswer 405, because there are no sessions.- Each request carries one JSON-RPC message: batches (an array) answer 400
bad_request. - The body is at most 1 MiB (413
too_large). - Each token has at most 4 MCP requests in flight; the next answers HTTP 429
rate_limitedwithRetry-After: 1.
Check the connection
Ask the assistant to list your zones. It calls list_zones and answers with the zones the credential can see. If a zone is missing, the token is probably limited to a client or a zone; if the write tools are missing, its role is readonly.
To keep the assistant's context small, connect with the lite profile instead.