|
| 1 | +# Konflux DevLake MCP Server - Agent Quick Reference |
| 2 | + |
| 3 | +Python MCP server providing engineering metrics tools for Konflux DevLake databases. |
| 4 | + |
| 5 | +## Data Flow |
| 6 | + |
| 7 | +Request -> `server/handlers/tool_handler.py` (security + RBAC) -> `tools/tools_manager.py` (routing) -> `tools/devlake/<tool>.py` (SQL + logic) -> `utils/db.py` (async MySQL pool, type conversion) -> `toon_encode()` response |
| 8 | + |
| 9 | +## Key Paths |
| 10 | + |
| 11 | +`tools/devlake/` metric tools | `tools/base/base_tool.py` BaseTool ABC | `tools/tools_manager.py` registry |
| 12 | +`server/` MCP core | `utils/db.py` async MySQL pool | `utils/security.py` SQL injection detection |
| 13 | +`skills/` Claude Code skills (must stay in sync with tools) | `tests/conftest.py` shared fixtures |
| 14 | + |
| 15 | +## Adding a Tool |
| 16 | + |
| 17 | +1. Create `tools/devlake/my_tool.py` extending `BaseTool` |
| 18 | +2. `get_tools()` -> `List[mcp.types.Tool]` with JSON `inputSchema` |
| 19 | +3. `async call_tool()` -> `toon_encode(result, {"delimiter": ",", "indent": 2, "lengthMarker": ""})` |
| 20 | +4. Register in `tools/tools_manager.py` `_tool_modules` list |
| 21 | +5. Add tool name to `utils/rbac.py` viewer/admin permissions list |
| 22 | +6. Add unit test: `tests/unit/test_my_tool.py` with `@pytest.mark.unit` |
| 23 | +7. Update `skills/devlake/` if tool interface or SQL changed (see Skill Update Rule) |
| 24 | + |
| 25 | +## Test Suite |
| 26 | + |
| 27 | +Every tool in `tools/tools_manager.py` `_tool_modules` (12 modules) must have a dedicated `tests/unit/test_<name>.py`. Each test file validates: `get_tools()` returns correct tool names and schemas, `call_tool()` with mocked DB rows returns `toon_decode()`-parseable results with `success: True`, error paths return `success: False`, and filter/limit arguments are respected. Integration tests in `tests/integration/` use real MySQL and `clean_database` fixture. |
| 28 | + |
| 29 | +When investigating a bug or adding a feature, verify `tests/unit/test_<name>.py` exists and covers `call_tool()` execution with expected computed values (scores, averages, classifications) -- not just response structure. If tests are missing or incomplete, add them. |
| 30 | +Commands: `make test-unit` (mocked DB) | `make test-integration` (docker compose MySQL) | `make test-e2e` (requires `GEMINI_API_KEY`, seeds from `testdata/mysql/`) |
| 31 | + |
| 32 | +- `asyncio_mode = strict`: async tests need `@pytest.mark.asyncio` |
| 33 | +- Strict markers: `unit`, `integration`, `security`, `slow` (undeclared = test failure) |
| 34 | +- Unit fixtures: `mock_db_connection` (AsyncMock), `mock_config` in `tests/conftest.py` |
| 35 | +- Integration fixtures: `integration_db_connection`, `clean_database` in `tests/integration/conftest.py` |
| 36 | + |
| 37 | +## SQL Rules |
| 38 | + |
| 39 | +- Always qualify: `lake.table_name` — no CTEs, use subqueries |
| 40 | +- CAST DECIMAL to CHAR in SELECT results |
| 41 | +- NEVER interpolate user input via f-strings in SQL. Validate ALL user-supplied values through `SQLInjectionDetector` (`utils/security.py`) before embedding in queries |
| 42 | + |
| 43 | +## Code Style |
| 44 | + |
| 45 | +- Python 3.11+ with type hints, async for all I/O |
| 46 | +- `black --line-length 100`, `flake8`, `yamllint` (run via `pre-commit run --all-files`) |
| 47 | +- TOON format for tool responses (not JSON) — use `toon_encode()`/`toon_decode()` |
| 48 | +- `log_tool_call()` required in every `call_tool()` implementation |
| 49 | +- No emojis in code, comments, docstrings, or project files |
| 50 | + |
| 51 | +## Skill Update Rule |
| 52 | + |
| 53 | +When modifying tools, update the corresponding skills: |
| 54 | +- SQL or schema changed? Update `skills/devlake/references/devlake-schema.md` and `sql-patterns.md` |
| 55 | +- Tool added/removed or input/output changed? Update `skills/devlake/SKILL.md` |
| 56 | +- Skills target the **deployed** version (`skills/VERSION`), not `main` |
| 57 | + |
| 58 | +## Core Dependencies |
| 59 | + |
| 60 | +`mcp>=1.23.0` | `aiomysql` | `toon-format` (from git) | `uvicorn`/`starlette` | `PyJWT`/`httpx` |
0 commit comments