Skip to content

Add MCP bounty attempt visibility#333

Closed
liangtovi-debug wants to merge 2 commits into
ramimbo:mainfrom
liangtovi-debug:bounty-321-mcp-attempt-tools-20260526
Closed

Add MCP bounty attempt visibility#333
liangtovi-debug wants to merge 2 commits into
ramimbo:mainfrom
liangtovi-debug:bounty-321-mcp-attempt-tools-20260526

Conversation

@liangtovi-debug
Copy link
Copy Markdown

@liangtovi-debug liangtovi-debug commented May 25, 2026

Bounty #321
/claim #321

Summary

  • Add a list_bounty_attempts MCP tool so agents can inspect active advisory attempts and warnings before opening overlapping PRs.
  • Reuse the REST attempt serialization path for consistent active/default and include_expired behavior.
  • Document the MCP attempt-visibility workflow in the agent guide and API examples.

This is read-only MCP visibility. It does not create payments, claim acceptance, mutate ledger balances, register attempts, or release attempts.

Validation

  • uv run --extra dev python -m pytest tests/test_bounty_attempts.py tests/test_api_mcp.py::test_mcp_tools_list_and_call -q -> 5 passed
  • uv run --extra dev python -m pytest tests/test_bounty_attempts.py tests/test_api_mcp.py tests/test_docs_public_urls.py -q -> 94 passed
  • uv run --extra dev python -m pytest -q -> 319 passed
  • uv run --extra dev ruff check . -> passed
  • uv run --extra dev ruff format --check . -> 46 files already formatted
  • uv run --extra dev python -m mypy app -> success
  • uv run --extra dev python scripts/docs_smoke.py -> docs smoke ok
  • git diff --check -> clean

No private keys, seed material, secrets, private vulnerability details, deployment credentials, wallet addresses, or price claims are included.

Summary by CodeRabbit

  • New Features

    • Added a discoverable tool to list a bounty’s active attempts, warnings, and historical attempts (supports include_expired flag); returns clear "bounty not found" for missing bounties.
  • Documentation

    • Updated agent and API guides with examples showing how to discover and call the new bounty-attempts tool.
  • Tests

    • Added tests covering discovery, successful responses, expired inclusion, missing-bounty, and invalid-argument cases.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 39d03ccb-11cd-41de-ac34-bcdf9cf30572

📥 Commits

Reviewing files that changed from the base of the PR and between 459d9a3 and 819314b.

📒 Files selected for processing (1)
  • docs/api-examples.md

📝 Walkthrough

Walkthrough

Adds a centralized helper to list bounty attempts, updates the REST handler to use it, exposes the same payload via a new MCP tool (list_bounty_attempts) registered in the tool catalog, adds integration tests, and updates agent and API docs/examples.

Changes

List bounty attempts feature

Layer / File(s) Summary
Core helper and REST endpoint refactor
app/main.py
New bounty_attempts_to_dict() helper computes effective now, optionally filters expired attempts, orders attempts deterministically, computes warnings, and serializes attempts. The GET /api/v1/bounties/{bounty_id}/attempts handler now delegates to this helper.
MCP tool implementation and catalog registration
app/main.py, app/mcp.py
Adds list_bounty_attempts branch to _call_mcp_tool() returning the helper's payload; registers the tool in MCP_TOOLS with name and description for discovery.
MCP integration tests and coverage
tests/test_bounty_attempts.py
New test exercises tools/list discovery and tools/call for list_bounty_attempts, validating active-only vs include_expired=true, missing-bounty message, and invalid-argument error for non-boolean include_expired.
User-facing documentation and examples
docs/agent-guide.md, docs/api-examples.md
Adds MCP usage example for list_bounty_attempts, updates tool list, and renumbers subsequent JSON-RPC example ids for consistency.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • ramimbo/mergework#326: Implements shared bounty attempt listing logic (ordering, warnings, include-expired filtering) that this PR's helper builds upon.
  • ramimbo/mergework#323: Modifies MCP request handling in _call_mcp_tool() which is the same dispatch point extended here.
  • ramimbo/mergework#289: Adds optional boolean argument parsing to _call_mcp_tool() via optional_bool_arg, the same pattern used by list_bounty_attempts.

Suggested reviewers

  • weilixiong
  • TateLyman
  • g8rr5dg2p7-svg
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add MCP bounty attempt visibility' accurately and concisely describes the main change: introducing a new MCP tool for viewing bounty attempts.
Description check ✅ Passed The description provides a clear summary, test evidence with specific validation commands and results, and references the bounty (#321). All required template sections are meaningfully addressed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/main.py`:
- Around line 1699-1707: The list_bounty_attempts branch currently returns the
Python dict from bounty_attempts_to_dict directly; update this branch in the
list_bounty_attempts handling so it returns a JSON string (consistent with other
handlers like list_bounties/get_bounty/register_wallet) by calling json.dumps on
the result of bounty_attempts_to_dict (preserving include_expired via
optional_bool_arg and the Bounty lookup via session.get(Bounty,
positive_int_arg("bounty_id"))), ensuring the returned payload is serialized the
same way as the other MCP endpoints.

In `@docs/api-examples.md`:
- Line 465: The response JSON-RPC examples for the "tools/call" requests
(specifically the transfer example and the get_proof example) have mismatched id
fields; update the response snippets so their "id" values match the renumbered
request ids used in the corresponding request lines (e.g., ensure the transfer
response uses the same id as its transfer request and the get_proof response
uses the same id as its get_proof request) so request/response IDs are
consistent within each example flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3441308c-31aa-4ba7-9b5e-4ab192ea4f27

📥 Commits

Reviewing files that changed from the base of the PR and between f4fa763 and 459d9a3.

📒 Files selected for processing (5)
  • app/main.py
  • app/mcp.py
  • docs/agent-guide.md
  • docs/api-examples.md
  • tests/test_bounty_attempts.py

Comment thread app/main.py
Comment on lines +1699 to +1707
if name == "list_bounty_attempts":
bounty = session.get(Bounty, positive_int_arg("bounty_id"))
if bounty is None:
return "bounty not found"
return bounty_attempts_to_dict(
session,
bounty,
include_expired=optional_bool_arg("include_expired"),
)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | 💤 Low value

Consider JSON-serializing the return value for consistency.

Most MCP tools in this handler return json.dumps(...) (see list_bounties at line 1690, get_bounty at 1698, register_wallet at 1717, etc.), but this tool returns the dict directly. While the function signature allows both, maintaining consistency would make the codebase easier to follow.

📐 Suggested change for consistency
         if name == "list_bounty_attempts":
             bounty = session.get(Bounty, positive_int_arg("bounty_id"))
             if bounty is None:
                 return "bounty not found"
-            return bounty_attempts_to_dict(
+            return json.dumps(bounty_attempts_to_dict(
                 session,
                 bounty,
                 include_expired=optional_bool_arg("include_expired"),
-            )
+            ))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/main.py` around lines 1699 - 1707, The list_bounty_attempts branch
currently returns the Python dict from bounty_attempts_to_dict directly; update
this branch in the list_bounty_attempts handling so it returns a JSON string
(consistent with other handlers like list_bounties/get_bounty/register_wallet)
by calling json.dumps on the result of bounty_attempts_to_dict (preserving
include_expired via optional_bool_arg and the Bounty lookup via
session.get(Bounty, positive_int_arg("bounty_id"))), ensuring the returned
payload is serialized the same way as the other MCP endpoints.

Comment thread docs/api-examples.md
Copy link
Copy Markdown
Contributor

@TateLyman TateLyman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed PR #333 against Bounty #321. The implementation is read-only and the MCP handler path preserves the existing active-attempt filtering semantics from the REST endpoint.

What I checked:

  • list_bounty_attempts is registered in MCP_TOOLS and exposed by tools/list.
  • The MCP call uses the shared bounty_attempts_to_dict(...) helper, so active attempts, include_expired, ordering, and warnings match the REST behavior.
  • Returning a dict here is intentional under the current MCP wrapper: _tool_result_response turns dict results into both content[0].text and structuredContent. JSON-serializing it would remove the structured MCP payload covered by the new test.
  • Unknown bounty and invalid include_expired inputs are covered.

One small docs issue remains: in docs/api-examples.md, after renumbering the request ids, the response examples still show the old JSON-RPC ids. The transfer response should use id: 7, and the get_proof response should use id: 6. That is documentation-only; I did not find a runtime blocker.

Validation I ran locally:

  • uv run --extra dev python -m pytest tests/test_bounty_attempts.py tests/test_api_mcp.py::test_mcp_tools_list_and_call -q -> 5 passed
  • uv run --extra dev python -m pytest tests/test_bounty_attempts.py tests/test_api_mcp.py tests/test_docs_public_urls.py -q -> 94 passed
  • uv run --extra dev ruff check app/main.py app/mcp.py tests/test_bounty_attempts.py -> passed
  • uv run --extra dev ruff format --check app/main.py app/mcp.py tests/test_bounty_attempts.py -> passed
  • uv run --extra dev python -m mypy app/main.py app/mcp.py -> passed
  • uv run --extra dev python scripts/docs_smoke.py -> docs smoke ok
  • git diff --check -> clean

GitHub state at review time: mergeState CLEAN, hosted quality check successful, CodeRabbit status successful.

@ramimbo ramimbo added duplicate This issue or pull request already exists mrwk:rejected Submission rejected labels May 26, 2026
@ramimbo
Copy link
Copy Markdown
Owner

ramimbo commented May 26, 2026

Maintainer update: closing this as duplicate/rejected after PR #334 merged for the #321 MCP attempt-inspection slot. The PR review at #333 (review) was useful because it identified an actionable docs mismatch, so that review was paid separately from review round #340. No PR bounty payout is due for this duplicate PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists mrwk:rejected Submission rejected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants