Skip to content

Add QIT MCP server - #467

Open
zhongruige wants to merge 11 commits into
trunkfrom
qit-974-qit-mcp-server
Open

Add QIT MCP server#467
zhongruige wants to merge 11 commits into
trunkfrom
qit-974-qit-mcp-server

Conversation

@zhongruige

@zhongruige zhongruige commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

Refs QIT-974.

This adds a read-only QIT MCP server for stdio MCP clients such as Magellan. The MVP is focused on reporting and debugging context for existing QIT runs: what happened, why a run failed, and what to inspect next.

The server intentionally does not enqueue tests, mutate local environments, upload packages, or wrap arbitrary CLI commands.

New command

qit mcp

qit mcp starts a stdio MCP server. MCP mode is detected early in CLI bootstrap so stdout is reserved for JSON-RPC protocol messages only. Normal CLI sync notices, tips, update notices, and Symfony human-readable errors are suppressed in this mode; diagnostics go to stderr or are returned as structured MCP tool errors.

Example MCP client config:

{
  "mcpServers": {
    "qit": {
      "command": "qit",
      "args": ["mcp"]
    }
  }
}

MCP tools

  • qit_get_run: returns normalized run metadata, status, product identifiers, report URL, timestamps, decoded result fields, and artifact hints.
  • qit_get_results: returns CTRF results when available, otherwise legacy result JSON.
  • qit_get_failures: summarizes failed/error tests, messages, traces/snippets, debug log signals, and next-step hints.
  • qit_get_last_local_run_context: reads the local ~/.qit/last-run.json context.
  • qit_list_environments: returns known local QIT environments and status.
  • qit_get_artifacts: returns known report URLs, local artifact paths, traces, screenshots, logs, and result files.

Sensitive URLs and known secrets are redacted by default. Report URLs can be included with include_sensitive_urls=true, while known secret values remain redacted.

Testing instructions

Build the packaged CLI before manual MCP smoke testing:

make build
./qit --version

Manual MCP protocol smoke test using the built binary:

printf "%s\n" "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"initialize\",\"params\":{}}" | ./qit mcp

Expected behavior: stdout contains only a single JSON-RPC initialize response, with no human-readable CLI notices mixed into the protocol stream.

Client smoke test against the built binary:

{
  "mcpServers": {
    "qit-local": {
      "command": "/absolute/path/to/qit-cli/qit",
      "args": ["mcp"]
    }
  }
}
  1. Add the built ./qit binary as the stdio MCP server command in the client config.
  2. Start the client and confirm tools/list includes the six QIT tools above.
  3. Call qit_get_last_local_run_context after a local QIT run, or call qit_get_run / qit_get_failures with a known test_run_id.
  4. Confirm sensitive URLs are redacted by default and tool failures return structured MCP errors.

Regression workflows worth verifying

These are the areas most likely to be affected by MCP bootstrap and reporting reuse:

  • Normal packaged CLI bootstrap still behaves normally outside MCP mode:
./qit --help
./qit backend:current
./qit env:list
  • Existing run lookup and JSON result output still match current behavior:
./qit get <known_ctrf_test_run_id> --json-results
./qit get <known_legacy_or_security_test_run_id> --json-results
  • Human-readable CLI errors are still human-readable outside MCP mode:
./qit get <missing_or_private_test_run_id>
  • Manager auth, backend selection, and proxy behavior still work for a real run lookup, since MCP run tools reuse the same RequestBuilder path as existing CLI commands.
  • Local environment monitoring still works with existing environments, since qit_list_environments reads the same local monitor state used by env:list.
  • If a recent local run exists, compare qit_get_last_local_run_context and qit_get_artifacts with the local ~/.qit/last-run.json context and expected report/artifact paths.

Note: PHPUnit currently emits PHP 8.5 deprecation notices from existing test bootstrap paths, but the targeted tests pass.

@zhongruige zhongruige self-assigned this Jul 6, 2026
@zhongruige
zhongruige requested a review from alopezari July 6, 2026 22:39
@zhongruige
zhongruige marked this pull request as ready for review July 6, 2026 22:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant