Skip to content

fix(tools): trim raw GitHub payloads from write-tool responses#279

Merged
saidsef merged 2 commits into
mainfrom
fix/trim-write-tool-responses
Jul 10, 2026
Merged

fix(tools): trim raw GitHub payloads from write-tool responses#279
saidsef merged 2 commits into
mainfrom
fix/trim-write-tool-responses

Conversation

@saidsef

@saidsef saidsef commented Jul 9, 2026

Copy link
Copy Markdown
Owner

What

Seven write tools shipped the raw GitHub API response straight to the LLM client - 1.5-3KB per call of user objects, reactions, _links and dozens of *_url fields. The CommentData/IssueData return annotations promised a compact shape, but FastMCP does no schema-based key stripping (verified in fastmcp-slim 3.4.2 convert_result, which serialises the raw return value), so the wire response never matched the advertised output schema.

This trims the seven offenders to the compact contracts the codebase already uses in get_pr_content, create_pr and list_open_issues_prs:

  • add_pr_comments, add_inline_pr_comment -> {id, body, author, html_url, created_at}
  • create_issue, update_issue -> {number, title, body, state, author, labels: string[], html_url, created_at, updated_at}
  • update_reviews -> {id, state, body, html_url, submitted_at}
  • create_release -> {id, tag_name, name, html_url, draft, prerelease, body} (body kept - it carries generated release notes)
  • update_assignees -> one unified {status, assignees_requested, assignees_applied, issue_url} shape; previously the partial branch embedded the entire raw issue

Three small module-level helpers (_pick, _comment_result, _issue_result) do the trimming.

Why

  • Every call to these tools cost the client roughly 300-700 wasted tokens.
  • Measured end-to-end through the MCP layer: create_issue wire response drops from 1,085 bytes (mocked payload - real ones are 2-3x larger) to 219 bytes.
  • Output schemas are now truthful: what tools/list advertises is what the tool returns.

Not changed

merge_pr, update_pr_branch and create_tag - GitHub already returns small payloads for these, and merge_pr has passthrough tests. get_pr_diff is untouched; the diff is the product.

Testing

  • 64 tests pass (8 new: exact-equality assertions for all seven tools against realistic bloated payloads, including the two-request inline-comment flow and both update_assignees branches)
  • ruff check . clean (also fixes two pre-existing violations in the test file), pyright 0 errors
  • Booted the server locally in HTTP mode and confirmed via tools/list that all 24 tools register and the regenerated output schemas show the new shapes

Seven write tools returned the raw GitHub API response verbatim
(1.5-3KB of user objects, reactions, _links and *_url fields per
call), while their CommentData/IssueData annotations advertised a
compact schema that was never honoured at runtime - FastMCP does no
schema-based key stripping.

Trim add_pr_comments, add_inline_pr_comment, create_issue,
update_issue, update_reviews, update_assignees and create_release to
compact results via three small helpers (_pick, _comment_result,
_issue_result), completing the pattern already used by get_pr_content,
create_pr and list_open_issues_prs. update_assignees now returns one
unified status shape instead of embedding the full raw issue.

Wire responses shrink ~85-90% (create_issue: ~2.5-3KB to ~0.3KB) and
structured content now matches the declared output schemas.

Tests: exact-equality coverage for all seven tools against realistic
bloated payloads; merge_pr, update_pr_branch and create_tag are
untouched (GitHub already returns small payloads there).
@saidsef saidsef added python Pull requests that update python code fix github-integration MCP-tool labels Jul 9, 2026
@saidsef saidsef self-assigned this Jul 9, 2026
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 1 minor

Results:
1 new issue

Category Results
Documentation 1 minor

View in Codacy

🟢 Metrics 15 complexity

Metric Results
Complexity 15

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 21 package(s) with unknown licenses.
See the Details below.

License Issues

uv.lock

PackageVersionLicenseIssue Type
anyio4.14.1NullUnknown License
cffi2.1.0NullUnknown License
click8.4.2NullUnknown License
cyclopts4.21.0NullUnknown License
fastmcp-slim3.4.4NullUnknown License
griffelib2.1.0NullUnknown License
joserfc1.7.3NullUnknown License
mcp1.28.1NullUnknown License
opentelemetry-api1.43.0NullUnknown License
pydantic-settings2.14.2NullUnknown License
pydocket0.23.0NullUnknown License
pytest9.1.1NullUnknown License
redis8.0.1NullUnknown License
rich-rst2.1.0NullUnknown License
rpds-py2026.6.3NullUnknown License
ruff0.15.21NullUnknown License
sse-starlette3.4.5NullUnknown License
typer0.26.8NullUnknown License
typing-extensions4.16.0NullUnknown License
uv0.11.28NullUnknown License
uvicorn0.51.0NullUnknown License

OpenSSF Scorecard

Scorecard details
PackageVersionScoreDetails
pip/anyio 4.14.1 UnknownUnknown
pip/cffi 2.1.0 UnknownUnknown
pip/click 8.4.2 UnknownUnknown
pip/cyclopts 4.21.0 UnknownUnknown
pip/fastmcp-slim 3.4.4 UnknownUnknown
pip/griffelib 2.1.0 UnknownUnknown
pip/joserfc 1.7.3 UnknownUnknown
pip/mcp 1.28.1 UnknownUnknown
pip/opentelemetry-api 1.43.0 UnknownUnknown
pip/pydantic-settings 2.14.2 UnknownUnknown
pip/pydocket 0.23.0 UnknownUnknown
pip/pyright 1.1.411 🟢 3.8
Details
CheckScoreReason
Maintained🟢 33 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 3
Code-Review⚠️ 0Found 1/30 approved changesets -- score normalized to 0
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Binary-Artifacts🟢 10no binaries found in the repo
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Security-Policy⚠️ 0security policy file not detected
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Branch-Protection🟢 3branch protection is not maximal on development and all release branches
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
SAST⚠️ 0SAST tool is not run on all commits -- score normalized to 0
Packaging🟢 10packaging workflow detected
pip/pytest 9.1.1 UnknownUnknown
pip/redis 8.0.1 UnknownUnknown
pip/rich-rst 2.1.0 UnknownUnknown
pip/rpds-py 2026.6.3 UnknownUnknown
pip/ruff 0.15.21 UnknownUnknown
pip/sse-starlette 3.4.5 UnknownUnknown
pip/typer 0.26.8 UnknownUnknown
pip/typing-extensions 4.16.0 UnknownUnknown
pip/uv 0.11.28 UnknownUnknown
pip/uvicorn 0.51.0 UnknownUnknown

Scanned Files

  • uv.lock

github-actions[bot]
github-actions Bot previously approved these changes Jul 9, 2026
- fastmcp-slim 3.4.2 -> 3.4.4, redis 8.0.0 -> 8.0.1 (mcp 1.28.1 transitively)
- dev: pyright 1.1.411, pytest 9.1.1, ruff 0.15.21, uv 0.11.28
- drop removed ANN101/ANN102 codes from the ruff ignore list

All patch-level with no code changes. ruff and pyright clean, 64 tests
pass, server boots and registers all 24 tools.
@saidsef
saidsef merged commit 739a948 into main Jul 10, 2026
7 checks passed
@saidsef
saidsef deleted the fix/trim-write-tool-responses branch July 10, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix github-integration MCP-tool python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant