Setup in Cursor
Before configuring, choose a distribution (Docker or npm) and set up authentication (API key or OAuth 2.0). Then add the matching configuration below.
Axe MCP server can be added at either the project or global level:
- Project-level: Create a file at
.cursor/mcp.jsonin your project's root directory - Global-level: Open Cursor settings, go to Features > MCP, and click Add New MCP Server. This will open your global configuration file.
If you already have other servers defined, add the axe-mcp-server block inside the existing mcpServers object.
Docker
API key
One-click install
Click the link below to install the axe MCP server directly in Cursor:
Install axe MCP server in Cursor
Cursor will prompt you to confirm the installation. Alternatively, follow the manual setup below.
Manual setup
{
"mcpServers": {
"axe-mcp-server": {
"command": "docker",
"args": [
"run",
"--add-host=host.docker.internal:host-gateway",
"-i",
"--rm",
"-e",
"AXE_SERVER_URL",
"-e",
"AXE_API_KEY",
"dequesystems/axe-mcp-server:latest"
],
"env": {
"AXE_API_KEY": "${env:AXE_API_KEY}"
}
}
}
}The configuration uses "AXE_API_KEY": "${env:AXE_API_KEY}" for secure input handling. The ${env:AXE_API_KEY} syntax instructs Cursor to pull the value from your system variables. For more information, see the Cursor MCP documentation.
Using a regional, private cloud, or on-premises axe instance? Add AXE_SERVER_URL to the env block with your instance's base URL:
"env": {
"AXE_API_KEY": "${env:AXE_API_KEY}",
"AXE_SERVER_URL": "https://your-axe-instance.example.com"
}If omitted, the server defaults to https://axe.deque.com (Deque's shared US SaaS instance). See Configuration Reference for details.
OAuth 2.0
Before configuring, complete Step 1: Authenticate in the Authentication guide.
Launch the server through @deque/axe-auth run, which keeps the running server's access token fresh for as long as the session lasts.
{
"mcpServers": {
"axe-mcp-server": {
"command": "npx",
"args": [
"-y",
"@deque/axe-auth",
"run",
"--",
"docker",
"run",
"--add-host=host.docker.internal:host-gateway",
"-i",
"--rm",
"-p",
"127.0.0.1:9223:9223",
"-e",
"AXE_ACCESS_TOKEN",
"-e",
"AXE_TOKEN_REFRESH_PORT",
"-e",
"AXE_TOKEN_REFRESH_SECRET",
"-e",
"AXE_TOKEN_REFRESH_HOST=0.0.0.0",
"dequesystems/axe-mcp-server:latest"
],
"env": {
"AXE_TOKEN_REFRESH_PORT": "9223"
}
}
}
}Token refresh reached the axe MCP Server in v1.5.0. npx -y @deque/axe-auth always fetches the current CLI, but a Docker image pulled before that release has no refresh listener for run to push to — re-pull it with docker pull dequesystems/axe-mcp-server:latest.
npx -y @deque/axe-auth run launches the container and supervises it for the life of the session, pushing a freshly minted access token to the running server before the current one expires. Your refresh token never leaves your machine — only short-lived access tokens reach the server. The -y flag skips the first-run "Ok to proceed?" prompt that npx would otherwise ask in a non-interactive shell.
The remaining flags exist to make that push reachable inside the container:
-p 127.0.0.1:9223:9223publishes the server's refresh listener on host loopback only, keeping it off your machine's external interfaces.-e AXE_ACCESS_TOKEN,-e AXE_TOKEN_REFRESH_PORT, and-e AXE_TOKEN_REFRESH_SECRETforward the valuesrungenerates into the container. Pass the names alone, with no=value—runsupplies them.-e AXE_TOKEN_REFRESH_HOST=0.0.0.0binds the listener to the container's network interface. A published port forwards there rather than to the container's loopback, so the default loopback bind would be unreachable. The shared secret, not container isolation, is what guards the endpoint.
9223 is an example — any free port on your machine works, as long as AXE_TOKEN_REFRESH_PORT and the -p publish name the same one. See Token refresh variables for the full reference.
Using a regional, private cloud, or on-premises axe instance? Add AXE_SERVER_URL to the Docker command and to the env block, alongside the refresh port:
"args": [
"-y",
"@deque/axe-auth",
"run",
"--",
"docker",
"run",
"--add-host=host.docker.internal:host-gateway",
"-i",
"--rm",
"-p",
"127.0.0.1:9223:9223",
"-e",
"AXE_SERVER_URL",
"-e",
"AXE_ACCESS_TOKEN",
"-e",
"AXE_TOKEN_REFRESH_PORT",
"-e",
"AXE_TOKEN_REFRESH_SECRET",
"-e",
"AXE_TOKEN_REFRESH_HOST=0.0.0.0",
"dequesystems/axe-mcp-server:latest"
],
"env": {
"AXE_TOKEN_REFRESH_PORT": "9223",
"AXE_SERVER_URL": "https://your-axe-instance.example.com"
}Use the same URL you passed to --server when you logged in, so the tokens axe-auth mints come from the instance the server calls. If omitted, the server defaults to https://axe.deque.com (Deque's shared US SaaS instance). See Configuration Reference for details.
npm
The npm distribution runs on Node.js and requires 22.19.0 or later. An active Node.js LTS release satisfies this, but an older Node 22 patch release may not.
The npm distribution needs a Chromium browser — either install one via Playwright or point at an existing binary. See Choosing a Distribution.
API key
Create a .cursor/mcp.json file in your project's root directory (project-level) or add the server through Cursor's global MCP settings:
{
"mcpServers": {
"axe-mcp-server": {
"command": "npx",
"args": ["-y", "axe-mcp-server"],
"env": {
"AXE_API_KEY": "your-api-key-here"
}
}
}
}Your configuration contains a credential in its env block. Project-level files like .cursor/mcp.json live in your repository — add them to .gitignore, or keep credentials in your global configuration instead.
OAuth 2.0
OAuth 2.0 is supported with the npm distribution as well. Wrap the server in @deque/axe-auth run exactly as above — there is no container to publish a port into, so the command is shorter:
{
"mcpServers": {
"axe-mcp-server": {
"command": "npx",
"args": [
"-y",
"@deque/axe-auth",
"run",
"--",
"npx",
"-y",
"axe-mcp-server"
],
"env": {
"AXE_TOKEN_REFRESH_PORT": "9223"
}
}
}
}npx -y @deque/axe-auth run launches the server and supervises it for the life of the session, pushing a freshly minted access token to the running process before the current one expires. No port publish is needed here: the wrapped process inherits AXE_TOKEN_REFRESH_PORT directly and the listener stays on loopback. 9223 is an example — any free port on your machine works, and the variable is optional here: omit it and run picks a free port for the session.
Unlike a container, the npm distribution inherits your entire shell environment. If AXE_API_KEY is exported there, it reaches the server alongside the OAuth token and the server refuses to start. Unset it in the shell you launch your editor from, or use the Docker configuration above, which only receives the variables passed with explicit -e flags.
See Authentication for the full flow.
Set either AXE_API_KEY or AXE_ACCESS_TOKEN — not both. The server will fail at startup if both variables are set.
Usage and verification
Once added, the status indicator in Cursor Settings should show that the server is running:
- Open Cursor Settings
- Go to Features > MCP
- You should see axe-mcp-server listed under Installed MCP Servers with the analyze, remediate, and igt tools available.
For recommended custom instructions that guide Cursor through the analyze-then-remediate workflow, see Configuring Your AI Agent.
