feat: add DORA query tools for agent reasoning #31
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
test:label-a
test:label-b
test:set-label
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/forgejo-mcp!31
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "28-dora-query-tools"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds four new MCP tools that let agents query PR velocity, lead time, rework rate, and deployment frequency directly from Forgejo PR data. This enables data-driven DORA metric reasoning without external tooling.
Changes
src/forgejo_mcp/tools/dora.py(new) -- Four DORA query tools:get_pr_velocity-- merge count and merges/week over a configurable time windowget_pr_lead_time-- min/max/mean/median hours from PR open to mergeget_rework_rate-- percentage of PRs with REQUEST_CHANGES reviews (proxy for change failure rate)get_deployment_frequency-- DORA tier classification (elite/high/medium/low) based on merge cadencesrc/forgejo_mcp/tools/__init__.py-- Register the newdoramodule inregister_all_tools()tests/test_dora_tools.py(new) -- 20 unit tests covering all four tools: correct calculations, pagination, empty repos, time window filtering, API error handling, DORA tier classification, median edge cases, review paginationTest Plan
pytest tests/test_dora_tools.py -v)ruff checkcleanruff formatcleanget_pr_velocity("ldraney", "forgejo-mcp", 90)and verify structured outputget_deployment_frequency("ldraney", "forgejo-mcp", 30)and verify DORA tierReview Checklist
__init__.pyRelated Notes
PR #31 Review
DOMAIN REVIEW
Stack: Python 3.10+ / FastMCP / Pydantic / Forgejo SDK
This PR adds four DORA metric query tools in a new
src/forgejo_mcp/tools/dora.pymodule (390 lines) with 20 unit tests intests/test_dora_tools.py(495 lines). Registration is correctly wired into__init__.py.Pattern compliance: The new module follows established conventions exactly --
Annotatedparams withField(description=...),json.dumps(indent=2)returns,_error_response(exc)error handling, consistent imports from..server. The@mcp.tool()decorator usage matchesworkflows.py.Pagination:
_fetch_merged_prscorrectly paginates through closed PRs and filters client-side bymerged_atwithin the time window. Theget_rework_ratetool also paginates reviews per PR. Both use the same_PAGE_SIZE = 50constant and thelen(batch) < _PAGE_SIZEstop condition, consistent with the pagination pattern inset_label.Time handling:
_parse_isohandles bothZand+00:00suffixes, with a comment explaining Python 3.10 compatibility._resolve_time_windowcorrectly uses UTC-aware datetimes. Themax(days / 7, 1)andmax(days, 1)guards prevent division-by-zero at boundary values.DORA tier classification: The thresholds in
get_deployment_frequencyare mathematically sound -->1/day(elite),>=1/7/day(high),>=1/30/day(medium), else low. The boundary values are well-tested (tests cover all four tiers).Median calculation: The manual median in
get_pr_lead_timeis correct for both odd and even counts, with dedicated tests for both cases. Could usestatistics.median()from stdlib but the manual implementation is sound and avoids an import.Test quality: 20 unit tests covering:
Tests mock at the correct level (
forgejo_mcp.tools.dora.get_client) and useside_effectfor multi-page scenarios, consistent with thetest_set_label_pagination.pypattern.BLOCKERS
None.
Annotated[str/int, Field()]NITS
Dead fallback in
_fetch_merged_prs(line 57 of dora.py):merge_baseis a git ref/SHA string, not a timestamp. Ifmerged_atisNone,_parse_isowill fail on the SHA and returnNone, so the PR gets skipped correctly -- no functional bug. But theor pr.get("merge_base")fallback is misleading dead code. Consider removing it:Import-inside-function pattern in tests: Each test method imports the tool function inside the method body (
from forgejo_mcp.tools.dora import get_pr_velocity). This works but is unconventional. Module-level imports at the top of the test file (or class level) would be more standard. Non-blocking since it works and the existing integration tests in this repo use a similar pattern with direct function imports.No README update: The README lists all MCP tools. The four new DORA tools are not documented there. This is a follow-up item, not a blocker for this PR -- tracking as a separate doc update is fine (same pattern as issue #26 which caught missing
update_issuedocs).statistics.median()available: Python stdlibstatistics.median()handles both odd/even counts. The manual implementation is correct but the stdlib function would be more concise and battle-tested. Minor preference, not blocking.SOP COMPLIANCE
feat: add DORA query tools...)Closes #28)PROCESS OBSERVATIONS
VERDICT: APPROVED