Context
src/mcp/server.ts exposes three read-only maintainer-report MCP tools that each claim in their own
code comment to mirror a specific REST route's access gate, but actually use a stricter gate than the
route they claim to mirror:
getMaintainerNoise (src/mcp/server.ts:3458-3466)
getAmsMinerCohort (src/mcp/server.ts:3468-3480)
getActivationPreview (src/mcp/server.ts:3495-3518)
All three call await this.requireRepoApprovalQueueAccess(fullName) (defined at
src/mcp/server.ts:3383-3411), which additionally performs a live GitHub collaborator-permission
lookup via getRepositoryCollaboratorPermission on top of the cached role/scope check.
But the REST routes these three tools' own comments say they mirror —
src/api/routes.ts:3262-3278 (maintainer-noise, ams-miner-cohort) and src/api/routes.ts:3202-3220
(activation-preview) — actually use the weaker requireRepoMaintainer (cached role + scope check
only, no live GitHub API lookup).
Every other structurally-identical read-only "maintainer-authenticated" report tool in the same file
(getRepoOutcomePatterns, getOutcomeCalibration, getGatePrecision, getSelftuneOverrideAudit,
getBurdenForecast, getConfigRecommendation, getRegistrationReadiness, getLabelAudit,
getMaintainerLane, getIssueQuality) correctly uses requireRepoAccess, whose underlying
canLoginAccessRepo check is the MCP-side equivalent of requireRepoMaintainer — i.e. it matches its
REST counterpart. The three tools above are the only outliers, and their own inline comments
(getAmsMinerCohort's comment literally says "same maintainer gate as getMaintainerNoise ... mirrors
GET /v1/repos/:owner/:repo/ams-miner-cohort") are factually wrong about which gate the REST route
actually uses.
Practical effect: a caller who is a legitimate maintainer by every other read tool's standard
(cached authorAssociation / installation-owner scope) but whose live GitHub collaborator lookup
fails, errors, or reflects team-based (non-collaborator-list) repo access gets denied specifically on
these three reports while every structurally identical sibling report tool succeeds for the same
caller. This is a functional regression relative to the tools' own documented intent, not an
over-permission/security bug — the fix tightens nothing, it aligns behavior with what's already
documented and with every sibling tool.
No existing test exercises the gap. test/unit/mcp-automation-state.test.ts directly exercises
requireRepoApprovalQueueAccess in-process with session identities, but only for the write tools
(propose_action, list/decide_pending_action, set_agent_paused, set_action_autonomy). The only
tests referencing loopover_get_maintainer_noise / loopover_get_ams_miner_cohort /
loopover_get_activation_preview (test/unit/mcp-cli-maintainer-noise.test.ts,
mcp-cli-ams-miner-cohort.test.ts, mcp-cli-activation-preview.test.ts) are stdio-proxy tests that
hit the REST endpoint over HTTP and never exercise LoopoverMcp's own gate branch as a session
identity — so this divergence has zero direct coverage today.
Requirements
- Change all three handlers —
getMaintainerNoise, getAmsMinerCohort, getActivationPreview — to
call await this.requireRepoAccess(fullName) instead of
await this.requireRepoApprovalQueueAccess(fullName), matching their documented REST mirrors and
every structurally identical sibling read tool listed above.
- Update the stale inline comments on all three handlers that currently claim parity with
requireRepoApprovalQueueAccess/requireRepoWriteAccess-style gating — they must accurately
describe the requireRepoAccess gate after the fix.
- Do not touch
requireRepoApprovalQueueAccess itself, or any of the write-action tools
(propose_action, list/decide_pending_action, set_agent_paused, set_action_autonomy) that
correctly and intentionally use the stricter gate — this issue is scoped to the three read-only
report tools named above only.
- Do not change
src/api/routes.ts — the REST routes are already correct; only the MCP tool handlers
are the mismatch.
Deliverables
Test Coverage Requirements
This repo's Codecov patch gate is 99%+ of changed lines and branches (src/** is covered,
coverage.include). The new/changed lines in src/mcp/server.ts (the three requireRepoAccess call
sites) must be exercised by the new regression test above, plus both branches of the identity check
covered by the existing suite's pattern (cached-maintainer-pass and non-maintainer-reject cases) for
all three tools.
Expected Outcome
A caller who passes the maintainer check on any other read-only MCP report tool in this file also
passes it on getMaintainerNoise, getAmsMinerCohort, and getActivationPreview — no more silent,
undocumented stricter gate on exactly these three tools. Tool behavior matches both the code's own
inline documentation and its REST-route counterpart.
Links & Resources
src/mcp/server.ts:3458-3518 — the three tool handlers to fix
src/mcp/server.ts:3383-3411 — requireRepoApprovalQueueAccess (the gate to stop using here)
src/api/routes.ts:3202-3220, :3262-3278 — the REST routes these tools claim to mirror
test/unit/mcp-automation-state.test.ts — existing pattern for in-process session-identity tests
against MCP gate functions
Context
src/mcp/server.tsexposes three read-only maintainer-report MCP tools that each claim in their owncode comment to mirror a specific REST route's access gate, but actually use a stricter gate than the
route they claim to mirror:
getMaintainerNoise(src/mcp/server.ts:3458-3466)getAmsMinerCohort(src/mcp/server.ts:3468-3480)getActivationPreview(src/mcp/server.ts:3495-3518)All three call
await this.requireRepoApprovalQueueAccess(fullName)(defined atsrc/mcp/server.ts:3383-3411), which additionally performs a live GitHub collaborator-permissionlookup via
getRepositoryCollaboratorPermissionon top of the cached role/scope check.But the REST routes these three tools' own comments say they mirror —
src/api/routes.ts:3262-3278(maintainer-noise, ams-miner-cohort) andsrc/api/routes.ts:3202-3220(activation-preview) — actually use the weaker
requireRepoMaintainer(cached role + scope checkonly, no live GitHub API lookup).
Every other structurally-identical read-only "maintainer-authenticated" report tool in the same file
(
getRepoOutcomePatterns,getOutcomeCalibration,getGatePrecision,getSelftuneOverrideAudit,getBurdenForecast,getConfigRecommendation,getRegistrationReadiness,getLabelAudit,getMaintainerLane,getIssueQuality) correctly usesrequireRepoAccess, whose underlyingcanLoginAccessRepocheck is the MCP-side equivalent ofrequireRepoMaintainer— i.e. it matches itsREST counterpart. The three tools above are the only outliers, and their own inline comments
(
getAmsMinerCohort's comment literally says "same maintainer gate as getMaintainerNoise ... mirrorsGET /v1/repos/:owner/:repo/ams-miner-cohort") are factually wrong about which gate the REST route
actually uses.
Practical effect: a caller who is a legitimate maintainer by every other read tool's standard
(cached
authorAssociation/ installation-owner scope) but whose live GitHub collaborator lookupfails, errors, or reflects team-based (non-collaborator-list) repo access gets denied specifically on
these three reports while every structurally identical sibling report tool succeeds for the same
caller. This is a functional regression relative to the tools' own documented intent, not an
over-permission/security bug — the fix tightens nothing, it aligns behavior with what's already
documented and with every sibling tool.
No existing test exercises the gap.
test/unit/mcp-automation-state.test.tsdirectly exercisesrequireRepoApprovalQueueAccessin-process with session identities, but only for the write tools(
propose_action,list/decide_pending_action,set_agent_paused,set_action_autonomy). The onlytests referencing
loopover_get_maintainer_noise/loopover_get_ams_miner_cohort/loopover_get_activation_preview(test/unit/mcp-cli-maintainer-noise.test.ts,mcp-cli-ams-miner-cohort.test.ts,mcp-cli-activation-preview.test.ts) are stdio-proxy tests thathit the REST endpoint over HTTP and never exercise
LoopoverMcp's own gate branch as a sessionidentity — so this divergence has zero direct coverage today.
Requirements
getMaintainerNoise,getAmsMinerCohort,getActivationPreview— tocall
await this.requireRepoAccess(fullName)instead ofawait this.requireRepoApprovalQueueAccess(fullName), matching their documented REST mirrors andevery structurally identical sibling read tool listed above.
requireRepoApprovalQueueAccess/requireRepoWriteAccess-style gating — they must accuratelydescribe the
requireRepoAccessgate after the fix.requireRepoApprovalQueueAccessitself, or any of the write-action tools(
propose_action,list/decide_pending_action,set_agent_paused,set_action_autonomy) thatcorrectly and intentionally use the stricter gate — this issue is scoped to the three read-only
report tools named above only.
src/api/routes.ts— the REST routes are already correct; only the MCP tool handlersare the mismatch.
Deliverables
getMaintainerNoise,getAmsMinerCohort,getActivationPreviewinsrc/mcp/server.tsall userequireRepoAccessinstead ofrequireRepoApprovalQueueAccess.mirrors.
test/unit/mcp-automation-state.test.ts's pattern) that constructs a session identity withcached-maintainer-level access but a failing/absent live collaborator-permission lookup, and
asserts all three tools now succeed (regression test proving the gate now matches
requireRepoAccess's behavior, notrequireRepoApprovalQueueAccess's).Test Coverage Requirements
This repo's Codecov patch gate is 99%+ of changed lines and branches (
src/**is covered,coverage.include). The new/changed lines insrc/mcp/server.ts(the threerequireRepoAccesscallsites) must be exercised by the new regression test above, plus both branches of the identity check
covered by the existing suite's pattern (cached-maintainer-pass and non-maintainer-reject cases) for
all three tools.
Expected Outcome
A caller who passes the maintainer check on any other read-only MCP report tool in this file also
passes it on
getMaintainerNoise,getAmsMinerCohort, andgetActivationPreview— no more silent,undocumented stricter gate on exactly these three tools. Tool behavior matches both the code's own
inline documentation and its REST-route counterpart.
Links & Resources
src/mcp/server.ts:3458-3518— the three tool handlers to fixsrc/mcp/server.ts:3383-3411—requireRepoApprovalQueueAccess(the gate to stop using here)src/api/routes.ts:3202-3220,:3262-3278— the REST routes these tools claim to mirrortest/unit/mcp-automation-state.test.ts— existing pattern for in-process session-identity testsagainst MCP gate functions