Skip to content

mcp: add loopover_list_bounties + loopover_get_bounty_lifecycle tools (sibling loopover_get_bounty_advisory already exists) #9296

Description

@JSONbored

⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.

⚠️ Required pattern: mirror the shape of loopover_get_bounty_advisory in src/mcp/server.ts
(registered around the register("loopover_get_bounty_advisory", ...) call, input bountyShape,
handler backed by getBounty).

Context

src/api/routes.ts exposes three bounty endpoints, all documented in src/openapi/spec.ts:

  • GET /v1/bountiesapp.get("/v1/bounties", async (c) => c.json(await listBounties(c.env)));
  • GET /v1/bounties/:id/advisory — has an MCP mirror: loopover_get_bounty_advisory in
    src/mcp/server.ts (bountyShape input, bountyAdvisoryOutputSchema output, calls
    getBounty/buildBountyAdvisory).
  • GET /v1/bounties/:id/lifecycleapp.get("/v1/bounties/:id/lifecycle", ...), calls
    getBounty + listBountyLifecycleEvents, returns { bountyId, events }.

Only the advisory route has an MCP tool. The list route (GET /v1/bounties) and the lifecycle
route (GET /v1/bounties/:id/lifecycle) are real, publicly documented REST endpoints
(BountySchema / BountyLifecycleEventsSchema are already registered OpenAPI components) with no
agent-facing MCP equivalent — an agent using the MCP tool surface can inspect one specific bounty's
advisory but cannot discover which bounties exist or read a bounty's lifecycle history at all.

Requirements

  • Add a new MCP tool loopover_list_bounties in src/mcp/server.ts, registered the same way as
    every other read-only tool (register("loopover_list_bounties", { description, inputSchema, outputSchema }, handler)), with _meta.category set via the existing MCP_TOOL_CATEGORIES map
    (use "discovery", matching loopover_get_bounty_advisory's category). It takes no repo/owner
    input — mirror listBounties(c.env) from the REST route exactly (same data, no added filtering).
  • Add a new MCP tool loopover_get_bounty_lifecycle in src/mcp/server.ts, same registration
    pattern, input shape bountyShape (reuse the existing { id: z.string().min(1) } shape used by
    loopover_get_bounty_advisory), calling getBounty + listBountyLifecycleEvents and returning
    the same { bountyId, events } shape the REST route returns. Return the same "bounty not found"
    error behavior as the REST route (404) — surfaced as a tool error, not a silent empty result.
  • Both tools are read-only lookups with no repo/owner auth scoping in the REST route today — do not
    add new auth requirements the REST route doesn't have.
  • Add both tool names + their categories to the MCP_TOOL_CATEGORIES map at the top of
    src/mcp/server.ts, next to loopover_get_bounty_advisory: "discovery".
  • No OpenAPI/schema regeneration is required for this issue: GET /v1/bounties and
    GET /v1/bounties/:id/lifecycle are unchanged REST routes, already documented in
    src/openapi/spec.ts (BountySchema, BountyLifecycleEventsSchema) — this issue only adds new
    MCP tool wrappers around existing, already-documented responses. No request/response contract
    changes anywhere.

Deliverables

  • loopover_list_bounties tool registered in src/mcp/server.ts, backed by listBounties,
    returning the same data as GET /v1/bounties.
  • loopover_get_bounty_lifecycle tool registered in src/mcp/server.ts, backed by getBounty +
    listBountyLifecycleEvents, returning the same { bountyId, events } shape as
    GET /v1/bounties/:id/lifecycle, including the not-found case.
  • Both tools added to MCP_TOOL_CATEGORIES.
  • Unit tests for both tools (happy path + not-found path for the lifecycle tool).

All deliverables are required in this one PR — there is no follow-up issue.

Test Coverage Requirements

New code must hit this repo's 99%+ Codecov patch target (codecov/patch, measured unsharded via
npm run test:coverage) — every branch of both new tool handlers, including the bounty-not-found
error path for loopover_get_bounty_lifecycle, needs a direct unit test in src/mcp/server.test.ts
(or the sibling test file this repo already uses for MCP tool tests). Include a regression test
asserting the tool output for a fixture bounty matches the equivalent REST route's response shape.

Expected Outcome

An MCP client can list all bounties and read a specific bounty's lifecycle history — the same data
already available over REST and already documented in the OpenAPI spec — without needing to fall
back to the REST API directly, closing the last gap in bounty read-parity between the two surfaces.

Links & Resources

  • src/api/routes.ts: GET /v1/bounties, GET /v1/bounties/:id/advisory, GET /v1/bounties/:id/lifecycle
  • src/mcp/server.ts: existing loopover_get_bounty_advisory tool (the sibling to mirror)
  • src/openapi/spec.ts / src/openapi/schemas.ts: BountySchema, BountyAdvisorySchema,
    BountyLifecycleEventsSchema (already registered; reuse, don't redefine)

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.help wantedExtra attention is needed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions