|
| 1 | +# mcp-tool-server Specification |
| 2 | + |
| 3 | +## Purpose |
| 4 | +TBD - created by archiving change 2026-09-22-fix-gate-trigger-and-mcp. Update Purpose after archive. |
| 5 | +## Requirements |
| 6 | +### Requirement: The MCP server SHALL expose three tools over stdio JSON-RPC |
| 7 | +`scripts/run_check.py --mcp` MUST start an stdio JSON-RPC server using the official `mcp` Python SDK and register exactly three tools: `check_code_style`, `auto_fix`, and `list_languages`. The server MUST NOT take any other CLI flag in MCP mode. |
| 8 | + |
| 9 | +#### Scenario: Listing tools at startup |
| 10 | + |
| 11 | +- **WHEN** a client sends `tools/list` |
| 12 | +- **THEN** the response enumerates `check_code_style`, `auto_fix`, `list_languages` with their input schemas |
| 13 | + |
| 14 | +### Requirement: `check_code_style` SHALL return a structured envelope with full stderr on disk |
| 15 | +`check_code_style(path, languages?)` MUST run the configured linters, write the full stderr of any failing invocation to `<log_dir>/.codeguard-last.log` (default `<project>/out/.codeguard-last.log`), and return a JSON envelope with one entry per language: `{language, passed: bool, exit_code: int, stderr_path: str, log_path: str}`. |
| 16 | + |
| 17 | +#### Scenario: One language fails |
| 18 | + |
| 19 | +- **WHEN** the path contains a single Python project whose ruff lint fails |
| 20 | +- **THEN** the envelope contains one entry with `passed=false`, `exit_code` from ruff, `stderr_path` pointing at the on-disk log, and `log_path` echoing the same path |
| 21 | + |
| 22 | +#### Scenario: All languages pass |
| 23 | + |
| 24 | +- **WHEN** every linter exits 0 |
| 25 | +- **THEN** every entry has `passed=true`, `exit_code=0`, and the log file is either empty or absent (no stderr written) |
| 26 | + |
| 27 | +### Requirement: `auto_fix` SHALL run formatters and re-verify |
| 28 | +`auto_fix(path, languages?)` MUST invoke the per-language formatter chain (`format` from `scripts/languages.json`) and then re-run `check_code_style` on the same scope before returning. The response envelope MUST contain both `fixed: bool` (whether any file was modified) and the `check_code_style` envelope for the post-fix re-check. |
| 29 | + |
| 30 | +#### Scenario: Formatter succeeds and lint passes |
| 31 | + |
| 32 | +- **WHEN** ruff `--fix` removes unused imports and the re-check passes |
| 33 | +- **THEN** `fixed=true` and the embedded `check_code_style` envelope is all-pass |
| 34 | + |
| 35 | +#### Scenario: Formatter succeeds but lint still fails |
| 36 | + |
| 37 | +- **WHEN** ruff `--fix` ran but a remaining error is non-fixable |
| 38 | +- **THEN** `fixed=true` and the embedded `check_code_style` envelope contains at least one failing entry |
| 39 | + |
| 40 | +### Requirement: `list_languages` SHALL return id + name only |
| 41 | +`list_languages()` MUST return a JSON array of `{id, name}` objects from `scripts/languages.json`, omitting the rest of each language record (lint command, format command, install hint, etc.) so internal commands are not exposed as part of the MCP surface. |
| 42 | + |
| 43 | +#### Scenario: Listing all supported languages |
| 44 | + |
| 45 | +- **WHEN** the client calls `list_languages` |
| 46 | +- **THEN** the response enumerates every entry in `scripts/languages.json` with exactly two fields (`id`, `name`) per record |
| 47 | + |
0 commit comments