QONTO-WP-0003-T06: MCP smoke script + operator runbook update

Add scripts/smoke_mcp.py, same shape as smoke_rest_api.py (random port,
subprocess-launch against QONTO_FIXTURE_DIR, wait on /v1/health, assert,
clean teardown), but goes further: generates a fresh
QONTO_ASSISTANT_MCP_TOKEN per run and connects through it with the mcp
SDK's streamablehttp_client, so the smoke exercises T03's bearer-token gate
instead of bypassing it. Lists tools, calls all four, and confirms an
out-of-catalog tool name comes back as a normal isError result through the
real wire protocol rather than a crash.

Extend docs/operator-runbook.md with a "One-command MCP smoke" section next
to the REST one; cross-link from docs/mcp-integration.md's manual smoke
walkthrough so the two don't drift.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
tegwick 2026-07-23 11:04:39 +02:00
parent c1e33decd9
commit 0dc001bf53
4 changed files with 208 additions and 1 deletions

View file

@ -109,6 +109,24 @@ This starts the service on a random local port against the fixture payloads,
checks `/v1/health`, `/v1/accounts`, a recent `31`-day snapshot, and a wider
`90`-day cost-review snapshot, then shuts the process down.
## One-command MCP smoke
```bash
../state-hub/.venv/bin/python scripts/smoke_mcp.py \
--python ../state-hub/.venv/bin/python
```
Same shape as the REST smoke: starts the service on a random local port
against the fixture payloads, this time with `QONTO_ASSISTANT_MCP_TOKEN` set
to a freshly generated token so the auth layer (`docs/mcp-integration.md`) is
exercised too, not bypassed. Connects with the `mcp` SDK's
`streamablehttp_client`, lists tools, calls `qonto_ping`,
`qonto_org_summary`, `qonto_list_transactions`, and
`qonto_cost_run_rate_hints`, then confirms an out-of-catalog tool name
(`qonto_transfer_funds`, never registered) comes back as a normal
`isError` result rather than a crash or a policy bypass. No real Qonto
credentials involved.
## Example calls
Minimal local call: