Skip to content

feat(mcp): add remote + stdio tool surfaces for loopover_get_repo_focus_manifest - #7909

Closed
xfodev wants to merge 1 commit into
JSONbored:mainfrom
xfodev:feat/get-repo-focus-manifest-two-surfaces-7808
Closed

feat(mcp): add remote + stdio tool surfaces for loopover_get_repo_focus_manifest#7909
xfodev wants to merge 1 commit into
JSONbored:mainfrom
xfodev:feat/get-repo-focus-manifest-two-surfaces-7808

Conversation

@xfodev

@xfodev xfodev commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the two missing MCP surfaces for loopover_get_repo_focus_manifest (a repo's own persisted focus manifest + compiled policy): a remote MCP tool in src/mcp/server.ts and a local stdio MCP tool in packages/loopover-mcp/bin. Mirrors the two-surface loopover_get_maintainer_noise shape but replicates the underlying GET /v1/repos/:owner/:repo/focus-manifest route's own auth — requireRepoAccess (the read-level maintainer/owner/operator + session-repo-access mirror), not the stricter requireRepoApprovalQueueAccess (which adds a live-write check the GET route does not perform).

Read-only, per the issue's scope boundary: no tool for the refresh(POST)/PUT write routes, no new REST route, no new human CLI verb.

What changed

  • src/mcp/server.ts: register loopover_get_repo_focus_manifest (input ownerRepoShape, focusManifestOutputSchema returning { repoFullName, manifest, policy }), add its MCP_TOOL_CATEGORIES entry ("maintainer"), and a getRepoFocusManifest handler calling loadRepoFocusManifest + compileFocusManifestPolicy exactly as the GET route does, behind requireRepoAccess.
  • packages/loopover-mcp/bin/loopover-mcp.ts: register the local stdio tool proxying GET ${repoBase}/focus-manifest via apiGet.

Testing / coverage

  • test/unit/mcp-output-schemas.test.ts: authorized success (seeded manifest → { repoFullName, manifest.present, policy }) and the forbidden branch (static mcp identity outside the read allowlist → cannot access this repository); added the tool to TOOLS_WITH_OUTPUT_SCHEMA. Both run in-process against LoopoverMcp(env).createServer(), so every changed line/branch in src/mcp/server.ts is Codecov-covered.
  • test/unit/mcp-cli-repo-focus-manifest.test.ts: in-process stdio invocation (via loopover_plan_repo_issues has no REST route, CLI command, or local stdio MCP tool #7764's isProcessEntrypoint guard + InMemoryTransport) so the bin tool's apiGet-proxy body gets real Codecov-measured coverage — a subprocess spawn can't be v8-instrumented.
  • test/unit/mcp-tool-rename-aliases.test.ts: tool-count invariant → 83. This also reconciles a pin drift — feat(mcp): add remote + stdio tool surfaces for loopover_get_activation_preview #7887 registered loopover_get_activation_preview's stdio tool without bumping this pin (live count had reached 82), documented inline in the same convention as the earlier #6942 note.

No REST/OpenAPI change (the focus-manifest route already exists), no migrations, no wrangler changes.

Closes #7808

…us_manifest

Register loopover_get_repo_focus_manifest as a remote MCP tool (src/mcp/server.ts)
and a local stdio MCP tool (packages/loopover-mcp/bin), mirroring the two-surface
loopover_get_maintainer_noise shape but replicating the GET
/v1/repos/:owner/:repo/focus-manifest route's own auth: requireRepoAccess (the
read-level maintainer/owner/operator + session-repo-access mirror), not the
stricter requireRepoApprovalQueueAccess. Read-only: no refresh/PUT tool, no new
REST route, no new human CLI verb.

Closes JSONbored#7808
@xfodev
xfodev requested a review from JSONbored as a code owner July 21, 2026 17:09
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.95%. Comparing base (b3e1bc3) to head (58e65dd).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #7909       +/-   ##
===========================================
+ Coverage   58.78%   81.95%   +23.16%     
===========================================
  Files         730       90      -640     
  Lines       74842    24387    -50455     
  Branches    22839     4691    -18148     
===========================================
- Hits        43999    19987    -24012     
+ Misses      27180     4162    -23018     
+ Partials     3663      238     -3425     
Flag Coverage Δ
shard-2 21.80% <45.45%> (-25.09%) ⬇️
shard-3 24.64% <72.72%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/loopover-mcp/bin/loopover-mcp.ts 13.46% <100.00%> (+0.16%) ⬆️
src/mcp/server.ts 84.26% <100.00%> (+36.47%) ⬆️

... and 640 files with indirect coverage changes

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 21, 2026
@loopover-orb

loopover-orb Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Caution

🛑 LoopOver review result - fixes required

Review updated: 2026-07-21 17:19:21 UTC

6 files · 1 AI reviewer · no blockers · CI failing · blocked

🛑 Suggested Action - Fix Blockers

Review summary
This PR adds the missing read-only remote and stdio MCP tool surfaces for loopover_get_repo_focus_manifest, faithfully mirroring GET /v1/repos/:owner/:repo/focus-manifest's requireRepoAccess gating (correctly not using the stricter requireRepoApprovalQueueAccess) and following the established loopover_get_maintainer_noise two-surface pattern. Both the authorized-success and forbidden-branch paths are tested in-process for the remote tool, and the stdio bin tool gets real coverage via the isProcessEntrypoint/InMemoryTransport pattern from #7808/#7764, with the tool-count pin bumped from 81 to 83 consistently across the rename-alias tests. The two FAILED checks (validate, validate-tests (1)) are unlabeled and the branch is 3 commits behind default, which is a plausible explanation; nothing in the visible diff points to a self-inflicted break.

Nits — 6 non-blocking
  • The 'generic_secret_assignment' flag on test/unit/mcp-cli-repo-focus-manifest.test.ts:29 is just a placeholder test token (`LOOPOVER_API_TOKEN = "in-process-token"`), not a real secret, but worth a quick glance to confirm it's not accidentally a live credential.
  • packages/loopover-mcp/bin/loopover-mcp.ts:1552 uses `async ({ owner, repo }: any) =>` for the new handler — matches the existing house style for these stdio tool bodies but is still an explicit `any` that a stricter tsconfig would flag.
  • The loopover_get_repo_focus_manifest (read-only) has a REST route but no remote MCP tool or local stdio MCP tool #7808 comment in src/mcp/server.ts documents the requireRepoAccess vs requireRepoApprovalQueueAccess distinction well, but the same rationale isn't restated in the bin's stdio registration — consider a one-line cross-reference there too since it's the same auth-shape claim behind a different call path (a plain apiGet proxy trusts the backend's own gating).
  • Consider adding a short assertion in the stdio in-process test confirming the request path hits `/v1/repos/owner/repo/focus-manifest` exactly (already implied by the fixture route match, but an explicit URL assertion would harden it against a future refactor of `apiGet`).
  • If the two failing 'validate' checks are unrelated to this diff, rebasing onto the current default branch (3 commits ahead) before merge would let CI re-run cleanly against the same base.
  • Possible secret-shaped assignment in the diff (generic_secret_assignment) — Verify the value is not a real credential.

CI checks failing

  • validate
  • validate-tests (1)

Decision drivers

  • ✅ Code review — No blockers (1 reviewer)
  • ✅ Gate result — Passing (No configured blocker found.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #7808
Related work ✅ No active overlap found No same-issue or scoped active PR overlap found.
Change scope ✅ 20/20 Low review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 88 registered-repo PR(s), 47 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor xfodev; Gittensor profile; 88 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor · LLM: minor
Linked issue satisfaction

Addressed
The PR adds both the remote MCP tool (with ownerRepoShape input, matching {repoFullName, manifest, policy} output, MCP_TOOL_CATEGORIES entry as "maintainer") and the stdio tool proxying GET .../focus-manifest, exactly as required, with no write-side tool or new CLI verb added. The one point of judgment is auth: rather than reimplementing requireAppRole([...]) + session check directly, it reuses th

Review context
  • Author: xfodev
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 88 PR(s), 0 issue(s).
  • PR-specific overlap: none found.
Contributor next steps
  • Keep the PR focused and include validation evidence before maintainer review.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb

loopover-orb Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

LoopOver is closing this pull request on the maintainer's behalf (CI is failing (validate, validate-tests (1))). This is an automated maintenance action — to pursue this change, please open a new pull request with the issues resolved. Closed PRs may be analyzed later to improve review accuracy, but they are not automatically reopened or re-reviewed.

@loopover-orb loopover-orb Bot closed this Jul 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

loopover_get_repo_focus_manifest (read-only) has a REST route but no remote MCP tool or local stdio MCP tool

1 participant