{
  "markdown": "# Universal Test Framework (UTF)\n\n> **Contract-driven test enforcement and reporting for LLM-generated code — via MCP, VS Code, Copilot CLI, Claude, Cursor, or Python SDK.**\n\nUTF is an **MCP server and contract enforcement engine**. It does not replace your AI coding assistant — it gives every test your AI writes a mandatory quality gate, a structured audit trail, and a comprehensive compliance report.\n\n[![PyPI version](https://img.shields.io/pypi/v/universal-test-framework)](https://pypi.org/project/universal-test-framework/)\n[![Python](https://img.shields.io/pypi/pyversions/universal-test-framework)](https://pypi.org/project/universal-test-framework/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n\n<!-- mcp-name: io.github.phoenice-labs/universal-test-framework -->\n\n---\n\n## Why UTF? (Not Another Test Generator)\n\nAI tools — GitHub Copilot, Claude, Cursor, Gemini — generate tests fast. The problem: **fast ≠ trustworthy**.\n\n| Without UTF | With UTF |\n|---|---|\n| Tests exist but nobody knows *why* | Every test is linked to a requirement |\n| \"Covers everything\" — nobody can prove it | Traceability matrix maps REQ → test |\n| CI passes; real behavior untested | Gap analysis flags what is NOT covered |\n| LLM wrote a test that asserts `True` | Meaningfulness check rejects trivial assertions |\n| No history of what was tested | Persistent registry survives session restarts |\n| Report shows pass/fail counts only | 8-section per-test detail cards in HTML report |\n\n### UTF vs Markdown Instructions / Prompt Files\n\nYou may already use markdown files (`AGENTS.md`, `copilot-instructions.md`, `.cursorrules`) to guide your AI. UTF is complementary — not competing:\n\n| Markdown instructions | UTF |\n|---|---|\n| Describe *how* to write tests | **Enforce** a contract on *every* test produced |\n| Rely on LLM to follow instructions | Block tests that fail the contract at generation time |\n| No verification after generation | Score each test 0–1 against 8 measurable criteria |\n| No persistent state between sessions | SQLite registry persists all tests and results |\n| No compliance report | HTML report with per-test 8-section detail cards |\n\nUse markdown instructions to *shape* how your AI thinks. Use UTF to *verify* and *report on* what it produced.\n\n---\n\n## Key Features\n\n- **13 MCP tools** — generate, validate, register, analyze, trace, execute, mutate, report, and query tests\n- **6 languages** — Python, TypeScript, JavaScript, Java, Go, C++\n- **7 test types** — unit, integration, API, E2E, contract, performance, security\n- **8-section contract** — every test must pass all 8 sections or it is blocked (minimum score: 0.85)\n- **3-segment test IDs** — `TC-{PRJ}-{MODULE}-{NNN}` and classic `TC-{MODULE}-{NNN}` both accepted\n- **Five install modes** — `uvx` (zero-clone), local clone, Docker, GitHub MCP Registry, pip SDK\n- **VS Code @utf** — chat participant with slash commands\n- **CI/CD ready** — GitHub Actions, GitLab CI, pre-commit hooks\n- **Per-project overrides** — YAML rules in `.utf/rules/` override global defaults\n\n---\n\n## Quick Start\n\n### Setup Method Comparison\n\n| # | Method | How Started | Registry Location | `@utf` Slash Cmds | Best For |\n|---|--------|-------------|-------------------|-------------------|----------|\n| **1** | **uvx (zero-install)** | `mcp.json` + uvx | `<workspace>/.utf/utf.db` | ❌ use natural language | Any developer with uv |\n| **2** | **Local Clone** | `install-vscode-mcp.ps1` | `<workspace>/.utf/utf.db` | ✅ with extension | Contributing / customizing UTF |\n| **3** | **Docker / HTTP** | `docker compose up` | Named volume or bind mount | ❌ use natural language | Team / remote / CI |\n| **4** | **GitHub MCP Registry** | Auto via client | `<workspace>/.utf/utf.db` | ❌ use natural language | Discoverable via MCP marketplace |\n| **5** | **pip + SDK** | Python import | Caller controls cwd | N/A | CI scripts / programmatic |\n\nAll methods (1, 2, 4) using `stdio` transport write the registry to **`${workspaceFolder}/.utf/utf.db`** — isolated per project and persistent across sessions.\n\n---\n\n### Method 1 — uvx (Zero-Install, Recommended)\n\nRequires [uv](https://docs.astral.sh/uv/getting-started/installation/). No cloning, no venv.\n\nAdd to `%APPDATA%\\Code\\User\\mcp.json` (Windows) or `~/.config/Code/User/mcp.json` (macOS/Linux):\n\n```json\n{\n  \"servers\": {\n    \"utf\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"universal-test-framework\", \"utf-server\", \"--transport\", \"stdio\"],\n      \"cwd\": \"${workspaceFolder}\",\n      \"env\": {\n        \"UTF_PROJECT_DIR\": \"${workspaceFolder}\"\n      }\n    }\n  }\n}\n```\n\n> **Registry**: `.utf/utf.db` inside `${workspaceFolder}` — isolated per project, persistent across sessions.  \n> **Reload VS Code** after editing `mcp.json`.\n\n---\n\n### Method 2 — Local Clone (VS Code + Copilot)\n\n```powershell\ngit clone https://github.com/phoenice-labs/Universal-Test-Framework\ncd Universal-Test-Framework\n\n# Register MCP server, install @utf extension, copy global prompts\n.\\scripts\\install-vscode-mcp.ps1\n\n# Optionally scaffold a specific project\n.\\scripts\\install-vscode-mcp.ps1 -InitProject -ProjectDir C:\\my-project\n```\n\nReload VS Code → open Copilot Chat → ask naturally: `generate e2e tests for my backend`.\n\nThe install script writes this entry to `mcp.json`:\n\n```json\n{\n  \"utf\": {\n    \"type\": \"stdio\",\n    \"command\": \"<python>\",\n    \"args\": [\"-m\", \"mcp_server.server\", \"--transport\", \"stdio\"],\n    \"cwd\": \"${workspaceFolder}\",\n    \"env\": { \"PYTHONPATH\": \"<UTF_install_dir>\" }\n  }\n}\n```\n\n> **Registry**: `${workspaceFolder}/.utf/utf.db` — isolated per project.  \n> **`@utf` slash commands** are available after the VSIX extension is installed.\n\n---\n\n### Method 3 — Docker (Team / Remote)\n\n```bash\n# Start the UTF server\ncd Universal-Test-Framework\ndocker compose -f docker/docker-compose.yml up -d\n\n# MCP server available at http://localhost:8765/sse\n```\n\nConnect from VS Code by adding to `mcp.json`:\n\n```json\n{\n  \"servers\": {\n    \"utf-remote\": {\n      \"type\": \"sse\",\n      \"url\": \"http://localhost:8765/sse\"\n    }\n  }\n}\n```\n\n> **Registry**: persisted in a named Docker volume (`utf_registry → /app/.utf/utf.db`).  \n> For per-project isolation with Docker, use a bind-mount in `docker-compose.yml`:\n> ```yaml\n> volumes:\n>   - /path/to/your/project/.utf:/app/.utf\n> ```\n> Because Docker uses HTTP/SSE transport (no `${workspaceFolder}` templating), pass `project_dir`\n> explicitly in tool calls, or set `UTF_PROJECT_DIR` in the container environment.\n\n**Per-project Docker workflow:**\n\n```yaml\n# docker-compose.override.yml\nservices:\n  utf-server:\n    volumes:\n      - ./my-project/.utf:/app/.utf\n    environment:\n      UTF_PROJECT_DIR: /app\n```\n\n---\n\n### Method 4 — GitHub MCP Registry\n\nOnce published, UTF is discoverable via the MCP marketplace. Clients that support `server.json` install it automatically. The generated `mcp.json` entry is equivalent to Method 1 (uvx).\n\n> **Registry isolation**: The MCP registry schema does not support a `cwd` field at the registry level.  \n> UTF resolves project isolation via (in priority order):\n> 1. `project_dir` argument passed to each tool call\n> 2. `UTF_PROJECT_DIR` environment variable\n> 3. `Path.cwd()` fallback (server's working directory)\n>\n> For correct isolation, ensure the MCP client writes `\"cwd\": \"${workspaceFolder}\"` and\n> `\"UTF_PROJECT_DIR\": \"${workspaceFolder}\"` in the generated entry (UTF's `mcp-gallery.json` does this).\n\n---\n\n### Method 5 — pip + Python SDK\n\n```bash\npip install universal-test-framework\n```\n\n```python\nfrom mcp_server.tools.generate_tests import generate_tests\nfrom pathlib import Path\n\nresult = generate_tests(\n    test_type=\"unit\",\n    source_code=open(\"src/auth.py\").read(),\n    project_dir=str(Path.cwd()),   # ← pass explicitly for correct registry isolation\n)\nprint(result[\"suite_code\"])\n```\n\n> **Registry**: `<project_dir>/.utf/utf.db` when `project_dir` is passed; falls back to `Path.cwd()`.\n\n---\n\n\n## MCP Tools Reference\n\n| Tool | Description |\n|------|-------------|\n| `generate_tests` | Generate a complete test suite satisfying the 8-section contract |\n| `validate_test_contract` | Validate any test (generated or hand-written) against the contract |\n| `analyze_coverage` | Identify coverage gaps in an existing test suite |\n| `build_traceability_matrix` | Build a requirements → tests traceability matrix |\n| `suggest_test_types` | Recommend test types with rationale from source code |\n| `detect_language_framework` | Auto-detect programming language and test framework |\n| `import_test_results` | **Import JUnit XML** from any test run into the UTF registry |\n| `query_registry` | Query the persistent per-project test registry |\n| `run_tests` | Execute test files and return structured CI results |\n| `run_mutation_tests` | Run mutation testing and return mutation score |\n| `feedback_status` | Get gap analysis, coverage health, and trend report |\n| `generate_report` | Generate HTML / JUnit / JSON contract compliance report |\n| `health` | Server health check: version, uptime, tool count |\n\n---\n\n## The 8-Section Test Contract\n\nEvery test generated by UTF must satisfy all 8 sections. Tests that fail any hard section are **blocked** — returned in `blocked_tests`, never silently included.\n\n| # | Section | What It Must Contain | Weight |\n|---|---------|----------------------|--------|\n| 1 | `test_id` | Unique ID: `TC-{TYPE}-{NNN}` (e.g. `TC-US-042`) | 10% |\n| 2 | `why_generated` | Rationale tied to a requirement (≥50 chars) | 10% |\n| 3 | `requirement_mapping` | At least one `US-`, `AC-`, `REQ-`, `JIRA-`, `BUG-`, or `NFR-` reference | 15% |\n| 4 | `how_it_exercises` | GIVEN / WHEN / THEN with inputs, mocks, assertions (≥100 chars) | 20% |\n| 5 | `coverage_contribution` | Coverage type + module + estimated % | 15% |\n| 6 | `expected_outcome` | Precise return values, status codes, state changes (≥50 chars) | 15% |\n| 7 | `gaps_missing` | Honest list of what this test does NOT cover (≥40 chars) | 10% |\n| 8 | `meaningfulness_check` | Self-assessment: meaningful / redundant / hallucinated (≥50 chars) | 5% |\n\n**Minimum passing score: 0.85.** Tests below this threshold are blocked regardless of individual section presence. \"none\" in gaps or vague rationale like \"to test the function\" are rejected.\n\n---\n\n## Supported Matrix\n\n| Language | Frameworks | Test Types |\n|----------|------------|------------|\n| Python | pytest | unit, integration, api, e2e, security, performance |\n| TypeScript | Jest, Vitest, Playwright | unit, integration, e2e, api |\n| JavaScript | Jest, Vitest | unit, integration |\n| Java | JUnit 5 + AssertJ, Maven | unit, integration, api |\n| Go | go-test + testify | unit, integration, api |\n| C++ | Google Test | unit |\n\n---\n\n## The UTF 3-Phase E2E Workflow\n\nThis is the **canonical flow** for using UTF with any AI CLI (Copilot, Claude, Cursor) or VS Code. Follow the phases in order — skipping Phase 1 registration means the report has no Per-Test Contract Detail cards.\n\n```\n┌─────────────────────────────────────────────────────────────────────────┐\n│  PHASE 1 — CONTRACT GENERATION (LLM writes, UTF validates + registers) │\n│                                                                         │\n│  ① generate_tests (scaffold)                                           │\n│  ② LLM writes real test methods — each with its own TC-ID and         │\n│     8-section comment block (WHY / REQ / HOW / COV / OUT / GAP / MEAN)│\n│  ③ validate_test_contract — score must be ≥ 0.85 per test             │\n│  ④ register_contracts — parse test file, upsert status=generated rows  │\n│  ⑤ generate_report — verify Per-Test Contract Detail cards appear      │\n│                                                                         │\n│  PHASE 2 — EXECUTION (pytest/jest/maven runs, results captured)        │\n│                                                                         │\n│  ⑥ pytest --junit-xml=utf-tests/reports/results.xml                   │\n│  ⑦ import_test_results — upsert executed/failed rows                   │\n│  ⑧ generate_report — now shows contract cards AND pass/fail status     │\n│                                                                         │\n│  PHASE 3 — HEALTH (ongoing coverage quality)                           │\n│                                                                         │\n│  ⑨ feedback_status — gap analysis, drift alerts, trend over 30 days   │\n│  ⑩ Address gaps → add tests → back to Phase 1                         │\n└─────────────────────────────────────────────────────────────────────────┘\n```\n\n> **Why register before running?**\n> The UTF registry has two record types. `status=generated` records (created by `register_contracts`)\n> drive the Per-Test Contract Detail cards in the HTML report. `status=executed/failed` records\n> (created by `import_test_results`) drive the Execution Results table. Both must exist for a test\n> to appear in both sections. Running pytest before registering means you get execution rows but\n> no 8-section detail cards.\n\n### Per-Method 8-Section Comment Block (mandatory)\n\nEvery test **METHOD** must have its own inline comment block — **not a class docstring**:\n\n```python\ndef test_health_returns_200(self, live_backend):\n    # ─── TC-FIQ-HLT-001 ──────────────────────────────────────────────────────\n    # WHY_GENERATED: The /health endpoint is the primary liveness signal for\n    #   load balancers and K8s probes. Non-200 = platform unavailable.\n    # REQUIREMENT_MAPPING: REQ-E2E-001\n    # HOW_IT_EXERCISES: GIVEN backend is running at http://localhost:8001\n    #   WHEN GET /health is called THEN HTTP 200 is returned.\n    # COVERAGE_CONTRIBUTION: Line coverage of health route; ~15% of health module\n    # EXPECTED_OUTCOME: HTTP 200; elapsed < 500ms\n    # GAPS_MISSING: Does not test health under load; no auth header tested\n    # MEANINGFULNESS_CHECK: Meaningful — gateway test for all other tests\n    # ─────────────────────────────────────────────────────────────────────────\n    r = requests.get(f\"{live_backend}/health\", timeout=5)\n    assert r.status_code == 200\n```\n\nTest ID formats accepted: `TC-HLT-001` (2-segment) or `TC-FIQ-HLT-001` (3-segment project-prefixed).\n\n---\n\n## Invoking UTF from AI CLIs\n\n### GitHub Copilot CLI\n\nUTF tools are called via **natural language** — no special syntax required:\n\n```\n# Phase 1 — Generate and register\ngenerate e2e tests for backend/app/api/routes/\nregister contracts for utf-tests/test_myapp_e2e.py\nutf report\n\n# Phase 2 — After running pytest\nimport junit xml utf-tests/reports/results.xml\nutf report\n\n# Phase 3 — Health check\nutf status\nwhat are my coverage gaps?\nbuild a traceability matrix\n```\n\n### Claude (claude.ai / Claude CLI / MCP client)\n\nClaude supports MCP servers natively. With UTF added to your MCP config:\n\n```\n# Natural language triggers UTF MCP tools automatically\n\"Generate e2e tests for my FastAPI backend at backend/app/\"\n\"Register contracts for utf-tests/test_myapp_e2e.py\"\n\"Generate the UTF report\"\n\"Show UTF status and gaps\"\n\"Validate this test against the 8-section contract: [paste test]\"\n```\n\nTo add UTF to Claude's MCP config (`~/.config/claude/mcp.json` or equivalent):\n\n```json\n{\n  \"mcpServers\": {\n    \"utf\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"universal-test-framework\", \"utf-server\", \"--transport\", \"stdio\"],\n      \"env\": { \"UTF_PROJECT_DIR\": \"/path/to/your/project\" }\n    }\n  }\n}\n```\n\n### Cursor\n\nIn Cursor, add UTF as an MCP server in `.cursor/mcp.json` (project-level) or `~/.cursor/mcp.json` (global):\n\n```json\n{\n  \"mcpServers\": {\n    \"utf\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"universal-test-framework\", \"utf-server\", \"--transport\", \"stdio\"],\n      \"cwd\": \"${workspaceFolder}\",\n      \"env\": { \"UTF_PROJECT_DIR\": \"${workspaceFolder}\" }\n    }\n  }\n}\n```\n\nThen ask Cursor naturally:\n```\nGenerate unit tests for src/auth.py using UTF\nUTF report\nRegister contracts for tests/test_api.py\n```\n\n### Any MCP-Compatible Client (Windsurf, Continue, etc.)\n\nThe MCP entry is identical regardless of client:\n\n```json\n{\n  \"utf\": {\n    \"type\": \"stdio\",\n    \"command\": \"uvx\",\n    \"args\": [\"--from\", \"universal-test-framework\", \"utf-server\", \"--transport\", \"stdio\"],\n    \"cwd\": \"${workspaceFolder}\",\n    \"env\": { \"UTF_PROJECT_DIR\": \"${workspaceFolder}\" }\n  }\n}\n```\n\nUTF uses natural language detection — the same prompts work across all MCP-compatible AI clients.\n\n---\n\n## GitHub Copilot CLI Usage\n\nUTF is invoked via **natural language** in the GitHub Copilot CLI — there are no special slash commands or `@utf` syntax at the CLI prompt. Simply describe what you want and the MCP tools are called automatically.\n\n### How to Invoke UTF from the CLI\n\n```\n# In the GitHub Copilot CLI terminal (gh copilot / copilot-cli)\ngenerate unit tests for backend/app/routes/auth.py\ngenerate e2e tests covering REQ-001 through REQ-024\nregister contracts for utf-tests/test_myapp_e2e.py\nutf report\nshow utf status\nvalidate this test against the 8-section contract\nwhat are the coverage gaps?\nsuggest test types for my project\nbuild a traceability matrix\n```\n\n### Full Command Reference (Natural Language → MCP Tool)\n\n| What you say | UTF MCP tool invoked | What happens |\n|---|---|---|\n| `generate unit tests for <file>` | `generate_tests` | Scans source, infers requirements, produces 8-section test suite |\n| `generate e2e tests` | `generate_tests` | E2E suite with happy path + negatives + edge cases |\n| `generate api tests` | `generate_tests` | API contract tests with HTTP assertions |\n| `generate security tests` | `generate_tests` | Auth, injection, and boundary security tests |\n| `register contracts for <test_file.py>` | `register_contracts` | Parses test file, extracts per-method 8-section blocks, upserts generated rows |\n| `validate this test` | `validate_test_contract` | Scores test 0–1 against all 8 contract sections |\n| `utf status` / `show utf status` | `feedback_status` | Gap analysis, coverage health, trend report |\n| `utf report` / `generate report` | `generate_report` | HTML + JUnit + JSON contract compliance report |\n| `import junit xml <path>` | `import_test_results` | Register results from an existing pytest/Maven run |\n| `coverage gaps` | `analyze_coverage` | Identifies uncovered symbols and missing test paths |\n| `traceability matrix` | `build_traceability_matrix` | Requirements → tests coverage mapping |\n| `suggest test types` | `suggest_test_types` | Recommends test types from source or requirements |\n| `query registry` | `query_registry` | Lists registered tests for the current project |\n| `run tests` | `run_tests` | Executes test files and records results in registry |\n| `run mutation tests` | `run_mutation_tests` | Mutation score with killed/survived breakdown |\n| `utf health` | `health` | Server uptime, version, tool count |\n\n### Registry Persistence\n\nThe UTF SQLite registry persists **per-project** across all sessions:\n\n```\nyour-project/\n└── .utf/\n    ├── utf.db          ← SQLite registry (persists between sessions)\n    ├── utf-config.yaml ← Optional project overrides\n    ├── rules/          ← Optional YAML rule overrides\n    └── reports/\n        ├── contract_YYYYMMDD_HHMMSS.html\n        ├── contract_YYYYMMDD_HHMMSS.xml\n        └── contract_YYYYMMDD_HHMMSS.json\n```\n\nOnce tests are generated (`generate_tests`), they are registered in `.utf/utf.db`. Subsequent calls to `utf report`, `utf status`, and `query registry` read from this persistent store — **no re-generation required** between sessions.\n\n### Providing Project Context\n\nWhen the MCP server cannot infer your project root automatically, pass `project_dir` explicitly:\n\n```\ngenerate unit tests for src/auth.py in project C:/my-project\n```\n\nOr configure `\"cwd\": \"${workspaceFolder}\"` in your `mcp.json` (already set in the quickstart above) so the server always starts in the correct workspace.\n\n---\n\n## VS Code Copilot Chat Integration\n\nAfter running `.\\scripts\\install-vscode-mcp.ps1` (Option 2) or adding the `uvx` MCP entry (Option 1):\n\n> **Note:** The `@utf` prefix and `/slash-command` syntax only work if you have the **UTF VS Code Chat Participant** extension installed (included via Option 2). In **GitHub Copilot CLI** and standard **VS Code Copilot Chat** without the extension, use **natural language** — the MCP tools are invoked automatically. See [GitHub Copilot CLI Usage](#github-copilot-cli-usage) above.\n\n### VS Code Chat Participant Slash Commands (extension required)\n\n| Command | Effect |\n|---------|--------|\n| `@utf /generate-tests unit` | Unit tests for selected/active code |\n| `@utf /generate-tests api` | API tests |\n| `@utf /generate-tests integration` | Integration tests |\n| `@utf /generate-tests e2e` | End-to-end tests |\n| `@utf /generate-tests security` | Security / auth tests |\n| `@utf /generate-tests performance` | Performance / load tests |\n| `@utf /validate-contract` | Validate a test against the 8-section contract |\n| `@utf /coverage-gaps` | Identify coverage gaps in the current suite |\n| `@utf /traceability` | Build requirements → tests traceability matrix |\n| `@utf /report` | Generate HTML contract compliance report |\n| `@utf /status` | Server health and installation status |\n\n### Natural Language (no extension required)\n\nIn standard VS Code Copilot Chat or GitHub Copilot CLI, just ask:\n\n```\ngenerate unit tests for this file\nshow utf status\nutf report\nwhat are my coverage gaps?\nvalidate this test against the contract\n```\n\nUTF reads the open file, detects language and framework, infers requirements from function signatures, generates happy-path + negative + edge-case tests — all validated against the 8-section contract.\n\n---\n\n## Python SDK\n\nUse UTF directly in scripts or CI pipelines without the MCP server:\n\n```python\nfrom mcp_server.tools.generate_tests import generate_tests\nfrom mcp_server.tools.validate_contract import validate_test_contract\n\n# Generate tests — UTF infers language, framework, and requirements\nresult = generate_tests(\n    test_type=\"unit\",\n    source_code=open(\"src/auth.py\").read(),\n    requirements_text=\"US-101: Users must be authenticated before accessing dashboard\",\n)\n\nprint(result[\"suite_code\"])          # Executable test file\nprint(result[\"traceability_matrix\"]) # Requirements → tests mapping\nprint(result[\"gaps\"])                # Identified coverage gaps\n\n# Validate any existing test\nvalidation = validate_test_contract(test_content=my_test_markdown)\nprint(f\"Score: {validation['score']:.0%}  Valid: {validation['is_valid']}\")\n```\n\n---\n\n## CI/CD Integration\n\n### GitHub Actions\n\n```yaml\n# .github/workflows/test-quality-gate.yml\nname: UTF Contract Gate\non: [push, pull_request]\njobs:\n  contract-gate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-python@v5\n        with: { python-version: \"3.11\" }\n      - run: pip install universal-test-framework\n      - name: Validate test contract\n        run: |\n          python - <<'EOF'\n          from mcp_server.tools.validate_contract import validate_test_contract\n          import glob, sys, pathlib\n\n          failures = []\n          for f in glob.glob(\"tests/**/*.py\", recursive=True):\n              content = pathlib.Path(f).read_text()\n              result = validate_test_contract(test_content=content)\n              if not result[\"is_valid\"]:\n                  failures.append(f\"{f}: score {result['score']:.0%}\")\n          if failures:\n              print(\"Contract failures:\\n\" + \"\\n\".join(failures))\n              sys.exit(1)\n          print(\"All tests passed contract validation\")\n          EOF\n```\n\n---\n\n## Per-Project Configuration\n\nCreate `.utf/rules/project-overrides.yaml` in your project root:\n\n```yaml\n# Raise minimum score for safety-critical code\ncontract:\n  min_score: 0.90          # default: 0.85\n  hard_block_below: 0.75\n\n# Match your Jira project key\ntraceability:\n  requirement_id_pattern: \"^(PROJ-\\\\d+|AC-\\\\d+(\\\\.\\\\d+)?|NFR-\\\\d+)$\"\n\n# Tests generated per requirement per type\nscenario_counts:\n  happy_path: 1\n  negative: 2\n  boundary: 1\n  edge_case: 1\n\n# Coverage advisory thresholds (appear in report, do not block)\ncoverage:\n  line_target: 85\n  branch_target: 75\n  mutation_score_target: 70\n```\n\nRules are deep-merged: project overrides layer on top of UTF's global defaults. The 8-section contract structure itself cannot be overridden.\n\n---\n\n## Architecture\n\n```\nUTF MCP Server (stdio or HTTP/SSE)\n│\n├── mcp_server/server.py         — FastMCP entrypoint, 13 registered tools\n│\n├── mcp_server/engine/           — Core processing\n│   ├── language_detector.py     — Detects language + framework from code/path\n│   ├── rule_engine.py           — Loads and merges YAML rules\n│   ├── contract_validator.py    — Enforces 8-section contract, scores tests\n│   ├── template_renderer.py     — Jinja2 test file generation\n│   ├── context_resolver.py      — Resolves project context for generation\n│   └── framework_mapper.py      — Maps language → framework → test runner\n│\n├── mcp_server/tools/            — One module per MCP tool\n├── mcp_server/registry/         — SQLite per-project test registry\n├── mcp_server/execution/        — pytest, Vitest, Maven, go-test adapters\n├── mcp_server/mutation/         — mutmut, Stryker, PIT, Gremlins adapters\n├── mcp_server/reporting/        — HTML, JUnit XML, JSON report generation\n├── mcp_server/feedback/         — CI listener, trend analysis, gap reopener\n│\n├── rules/                       — Global YAML rules (language, framework, type)\n├── templates/                   — Jinja2 test templates per language/framework\n├── agent-customization/         — VS Code copilot-instructions + prompt palette\n└── vscode-extension/            — @utf VS Code Chat Participant (VSIX)\n```\n\n**Transport modes:**\n- `stdio` — default, used by VS Code MCP client and `uvx`\n- `HTTP/SSE` — for remote/team deployment (`--transport http --port 8765`)\n\n**SQLite registry** resolves to `.utf/utf.db` relative to the **caller's project root** (the `cwd` in `mcp.json`, or the `project_dir` parameter passed to any tool). Each project has its own isolated registry — no shared state. The registry persists across all sessions until explicitly cleared.\n\n---\n\n## Installation Options Summary\n\n| Method | Command | `cwd` / Registry Isolation | Requirements |\n|--------|---------|---------------------------|--------------|\n| **uvx** (zero-clone) | `uvx --from universal-test-framework utf-server` | `${workspaceFolder}` in `mcp.json` | [uv](https://docs.astral.sh/uv/) |\n| **Local clone** | `.\\scripts\\install-vscode-mcp.ps1` | `${workspaceFolder}` auto-written | Git, Python 3.11+ |\n| **Docker** | `docker compose up -d` | Named volume; bind-mount for per-project | Docker |\n| **GitHub MCP Registry** | Auto via MCP client | `UTF_PROJECT_DIR` env var | uv (auto-installed) |\n| **pip + SDK** | `pip install universal-test-framework` | Pass `project_dir` to each call | Python 3.11+ |\n\n### Registry Isolation Rules\n\nAll setups resolve the SQLite registry path using the same priority chain:\n\n```\n1. project_dir argument (explicit per-tool call)\n2. UTF_PROJECT_DIR environment variable\n3. Path.cwd() at server start (fallback — avoid for multi-project use)\n```\n\nThe recommended approach for all setups: set **both** `\"cwd\": \"${workspaceFolder}\"` **and**\n`\"env\": { \"UTF_PROJECT_DIR\": \"${workspaceFolder}\" }` in your `mcp.json` entry.\nThis ensures registry isolation works even if a tool call omits `project_dir`.\n\n\n## Security\n\n- All MCP tool inputs are validated via Pydantic before processing\n- No secrets, credentials, or PII are logged or stored\n- The registry (`utf.db`) is local to each project and never transmitted\n- Docker image runs as non-root user\n- Rate limiting is enforced on the HTTP/SSE transport\n\n---\n\n## License\n\nMIT — see [LICENSE](LICENSE)\n",
  "bytes": 27688,
  "sha": "535c2ddfe8b1a16df4b24c9aeb8ad79a040147f4ba55e48b909bb660adc2290d",
  "repo_slug": "phoenice-labs/universal-test-framework",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_phoenice_labs_universal_test_f_12fb774a/readme"
}