prowler-test-mcp

Write pytest tests for the Prowler MCP Server using in-memory FastMCP clients and mocked httpx transports.

14.7k|2.4k|Updated Aug 24, 2016
One-click install
npx skills add https://github.com/prowler-cloud/prowler --skill prowler-test-mcp
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: prowler-test-mcp
Source: https://github.com/prowler-cloud/prowler/tree/main/skills/prowler-test-mcp
Command: npx skills add https://github.com/prowler-cloud/prowler --skill prowler-test-mcp

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill requires fastmcp, pytest, httpx, pydantic, and includes assets (resource) components.

What problem does it solve?

Writing tests for the Prowler MCP Server involves subtle pitfalls: pydantic Field defaults that only resolve through the FastMCP protocol, a ProwlerAPIClient singleton captured at import time, and JSON:API response shapes that must be built correctly. This Skill encodes the fixtures, patterns, and critical rules so tests are deterministic and never touch the real network.

Core Features & Use Cases

  • In-memory tool testing: Drive MCP tools through async with Client(mcp_root_server) so pydantic defaults resolve, and assert on structured result.data plus the recorded HTTP request.
  • Mocked API layer: Use the mock_api_client and MockRouter fixtures to register JSON:API routes, replay response sequences for polling, and inspect query parameters and paths.
  • Model and contract tests: Build JSON:API documents with helper functions to test from_api_response() parsing, and enforce namespacing and description coverage across every registered tool.
  • Use Case: When adding a new findings tool under mcp_server/, generate a tool test that registers a mocked /api/v1/findings/latest route, calls the tool through the in-memory client, and asserts both the returned payload and the translated filter query parameters.

Quick Start

Write a pytest test for the prowler_search_security_findings MCP tool using the mock_api_client and mock_router fixtures.

Frequently Asked Questions about prowler-test-mcp

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I test FastMCP tools without a running server?

Use an in-memory client: `async with Client(mcp_root_server)` and call tools through it. This is required because pydantic Field defaults on tool parameters only resolve through the FastMCP wrapper; direct calls leave omitted arguments as truthy FieldInfo objects.

How do I mock the Prowler API in MCP server tests?

Use the mock_api_client fixture, which patches the ProwlerAPIClient singleton's httpx transport in place. Never construct a new ProwlerAPIClient, because tool instances captured the singleton by reference at import time.

Why does my MCP tool test build wrong filters when calling the tool directly?

Calling a tool method directly with an omitted argument leaves it as a raw FieldInfo object, which is truthy, so conditions like `if email:` build filters from the FieldInfo repr. Always drive tools through the in-memory FastMCP client or pass every argument explicitly.

Can I clear SingletonMeta._instances to reset the API client in tests?

No. Clearing the registry orphans every registered tool on an instance holding a real httpx.AsyncClient. Use the isolated_api_client fixture when you genuinely need a fresh instance for construction or identity tests.

Why did all prowler_ tools disappear from the test server?

Tools are built at import time and construction failures are swallowed, so stripping the PROWLER_API_KEY environment variable silently drops the whole prowler_ namespace to zero tools. The key is pinned in pytest env configuration and must not be removed.

How do I test a polling tool that waits for task completion?

Register the same route multiple times on MockRouter to return a response sequence, such as executing then completed; the last response repeats. Then call poll_task_until_complete with poll_interval=0 and assert the terminal state.