MCP Server
Prowl can run as an MCP server, exposing QA as a small set of named tools that any MCP-capable agent can call over stdio. The agent triggers runs and reads structured results through these tools — it never needs shell access to your repo.
This is the deepest form of the agent integration: instead of shelling out to prowl run, an agent connects once and drives QA through list_hunts, run_hunt, run_suite, and list_projects.
Prerequisites
prowlmust be on yourPATH. Install it globally withnpm install -g prowl-tools, or launch it throughnpx(see the npx config below). If the binary can't be found, the MCP client fails to start the server with no hunt-specific error.- The target project must be initialized — a
.prowl/directory with a valid config and hunts. Runprowl initand author hunts first. Pointed at an uninitialized repo, MCP tool calls fail with a missing.prowl/config.ymlerror.
Starting the server
prowl mcp
This starts a stdio server for the current project — it discovers .prowl/ from the working directory, exactly like the other commands. To drive several repos from one server, pass a project registry:
prowl mcp --projects ~/.prowl/projects.yml
Configuring an MCP client
Point your MCP client at a command that starts the server from the initialized project. Most stdio MCP clients support command, args, and env; a cwd field is not portable, so these examples use a shell wrapper to enter the project directory before launching prowl mcp. If your client has a documented working-directory setting, you can use that instead.
- Generic
- Claude Desktop
- Cursor
- OpenClaw
- npx (no global install)
{
"mcpServers": {
"prowl": {
"command": "/bin/sh",
"args": ["-lc", "cd \"/path/to/your/project\" && exec prowl mcp"]
}
}
}
Add to claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"prowl": {
"command": "/bin/sh",
"args": ["-lc", "cd \"/path/to/your/project\" && exec prowl mcp"]
}
}
}
Restart Claude Desktop after editing. The Prowl tools then appear in the tools menu.
Add to .cursor/mcp.json (project-scoped) or ~/.cursor/mcp.json (global):
{
"mcpServers": {
"prowl": {
"command": "/bin/sh",
"args": ["-lc", "cd \"/path/to/your/project\" && exec prowl mcp"]
}
}
}
{
"mcpServers": {
"prowl": {
"command": "/bin/sh",
"args": ["-lc", "cd \"/path/to/your/project\" && exec prowl mcp"]
}
}
}
OpenClaw also lets you allow-list which tools the agent may call — see Controlling what the agent can do.
If prowl isn't installed globally, launch it through npx:
{
"mcpServers": {
"prowl": {
"command": "/bin/sh",
"args": ["-lc", "cd \"/path/to/your/project\" && exec npx -y prowl mcp"]
}
}
}
Tools
| Tool | Arguments | Returns |
|---|---|---|
list_hunts | project? | Hunt names in run order |
run_hunt | hunt, project? | The full RunResult for a single hunt |
run_suite | includeTags?, excludeTags?, parallel?, logBugs?, project? | Pass/fail/skip counts, the ci-result.json path, and the bug tickets created |
list_projects | — | Registered projects (empty unless a registry is configured) |
Existing guardrails (allowedDomains, forbiddenSelectors, maxSteps, maxTotalTimeMs) apply to every run the server triggers.
Controlling what the agent can do
Prowl exposes only these four tools and never runs arbitrary shell. To restrict the agent further, allow-list tool names in your MCP client (e.g. OpenClaw) config — for example, allow list_hunts and run_suite but withhold run_hunt. That allow-listing is configured on the agent/client side, not in Prowl.
Logging bugs automatically
run_suite runs every hunt and, by default, logs each failure as a deduplicated bug ticket in the project's docs/backlog.md, under a ## QA Findings (automated) section that stays separate from your hand-written items. A bug is identified by hunt + failing step + normalized error, so:
- a brand-new failure creates a
QA-NNNticket with the hunt, failing step, error, and a link to the run artifacts; - a failure that already has an open ticket is left alone (no duplicates);
- a failure matching something already in
docs/resolved.mdis logged as a regression that references the old ticket id.
Pass logBugs: false to run without touching the backlog. A run_suite response looks like this:
{
"status": "fail",
"totalHunts": 8,
"passed": 6,
"failed": 2,
"skipped": 0,
"resultPath": "/path/to/project/.prowl/runs/ci-2026-05-26_09-12-03-456/ci-result.json",
"bugs": {
"created": ["QA-014"],
"regressions": ["QA-015"],
"alreadyOpen": ["QA-009"],
"backlogPath": "/path/to/project/docs/backlog.md"
}
}
status is one of pass, fail, no-hunts, or all-skipped. When logBugs is false, the bugs arrays are empty and backlogPath is null.
The same bug-logging flow is available to non-MCP consumers via the updateBacklogFromSuite() library function.
Driving multiple projects
By default the server acts on the current directory. To drive several repos from a single server, give it a project registry — one YAML file that maps project names to repo roots. This file lives outside any repo (it spans many), not inside a target project:
# ~/.prowl/projects.yml
projects:
coupe:
root: /Users/you/projects/coupe
storefront:
root: /Users/you/projects/storefront
configPath: /custom/.prowl/config.yml # optional; defaults to <root>/.prowl/config.yml
The registry is resolved in priority order:
prowl mcp --projects <path>- the
PROWL_PROJECTSenvironment variable ~/.prowl/projects.yml
With a registry loaded, every tool accepts an optional project argument that selects which repo to act on, and list_projects enumerates what's available. For example, these run_suite arguments run the smoke suite for coupe and log any failures to coupe/docs/backlog.md:
{ "project": "coupe", "includeTags": ["smoke"] }
Omit project and the tool falls back to the current directory. Naming a project that isn't registered — or naming one when no registry is configured — returns a clear error.