Skip to content

feat(mcp): register loopover_get_contributor_profile as a local stdio MCP tool (#7760) - #7955

Closed
andriypolanski wants to merge 1 commit into
JSONbored:mainfrom
andriypolanski:feat/mcp-contributor-profile-stdio-7760
Closed

feat(mcp): register loopover_get_contributor_profile as a local stdio MCP tool (#7760)#7955
andriypolanski wants to merge 1 commit into
JSONbored:mainfrom
andriypolanski:feat/mcp-contributor-profile-stdio-7760

Conversation

@andriypolanski

Copy link
Copy Markdown
Contributor

Summary

  • loopover_get_contributor_profile was a remote MCP tool (src/mcp/server.ts) with a contributor-profile CLI mirror (CLI mirror for loopover_get_contributor_profile #6737), but had no local stdio MCP tool registration — so a self-host operator using the local stdio server (not the CLI or remote MCP) could not call it.
  • This registers the missing stdio tool, following the exact shape of its login-based sibling loopover_monitor_open_prs, and reuses the same REST endpoint the CLI already calls (no duplicated HTTP logic).

Closes #7760

Change

  • Local stdio MCP tool (packages/loopover-mcp/bin/loopover-mcp.ts): registered loopover_get_contributor_profile (loginShape) next to its sibling, with a matching STDIO_TOOL_DESCRIPTORS entry (discovery category). The tool summary is the remote tool's own fixed sentence (server.ts uses the identical string), so the two surfaces never drift; the full API payload rides along as structuredContent.
  • Shared call: extracted getContributorProfile(login) as the single source of truth for GET /v1/contributors/:login/profile, and pointed both the new stdio tool and the existing contributorProfileCli at it — the CLI no longer inlines the endpoint path.
  • Export: contributorProfileCli is now exported (like maintainCli) so an in-process test can drive it directly; the subprocess CLI harness is not v8-instrumentable, so this is what makes the shared call graded by Codecov.

Tests

  • New test/unit/mcp-cli-contributor-profile-inprocess.test.ts: in-process coverage (dynamic import + InMemoryTransport, mirroring mcp-cli-plan-issues.test.ts) — the stdio tool registers and proxies GET .../profile, url-encodes the login, and the exported contributorProfileCli prints the header + API summary (plain) and re-serializes the payload (--json).
  • test/unit/mcp-tool-rename-aliases.test.ts: bumped the live stdio-tool count pin 89 → 90 (comment + three assertions).
  • The existing subprocess test/unit/mcp-cli-contributor-profile.test.ts is unchanged.

Validation

  • git diff --check clean; npm run build:mcp + package build:tsc typecheck clean.
  • Targeted vitest suites pass (mcp-cli-contributor-profile-inprocess, mcp-cli-contributor-profile, mcp-tool-rename-aliases, mcp-cli-tools).
  • Codecov patch = 100%. packages/loopover-mcp/bin/**/*.ts is in Codecov's scope (not ignored), and its coverage comes only from in-process importers. Verified from coverage-final.json that every changed line is executed (stdio handler, the shared getContributorProfile call from both the tool and the CLI) and that there are zero branches on any changed line — the summary is a fixed string, not a branchy payload.summary ?? … helper, precisely to avoid an uncovered fallback arm.
  • No artifact regeneration needed (no REST/OpenAPI/schema/binding/migration changes).

UI Evidence

N/A — local stdio MCP tool + a one-line CLI refactor only; no apps/loopover-ui/** or other visible surface changed.

@superagent-security

Copy link
Copy Markdown
Contributor

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

@loopover-orb loopover-orb Bot added the gittensor:bug Gittensor-scored bug fix — scores a 0.05x multiplier. label Jul 21, 2026
@loopover-orb

loopover-orb Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-21 22:47:59 UTC

3 files · 1 AI reviewer · no blockers · CI green · dirty

⏸️ Suggested Action - Manual Review

Review summary
This PR registers the missing `loopover_get_contributor_profile` stdio MCP tool, mirroring the existing `loopover_monitor_open_prs` pattern exactly, and extracts `getContributorProfile(login)` as a shared helper used by both the new stdio tool and the existing `contributorProfileCli`. The tool-count pin bump (89→90) is correctly updated in `mcp-tool-rename-aliases.test.ts`, and the new in-process test exercises registration, proxying, URL-encoding, and both plain/`--json` CLI output paths against a real API call. The change is narrowly scoped, closes issue #7760 as required, and the diff is internally consistent with its stated intent.

Nits — 6 non-blocking
  • The `any` type annotations on `({ login }: any)` (loopover-mcp.ts:2323), `contributorProfileCli(options: any)` (loopover-mcp.ts:4177), and `getContributorProfile(login: any)` (loopover-mcp.ts:6091) match the file's existing loose-typing convention, but a `login: string` on the new `getContributorProfile` helper would have been free type safety since it's brand new code, not inherited legacy.
  • The external brief flags a 'generic_secret_assignment' at mcp-cli-contributor-profile-inprocess.test.ts:37 — this is `LOOPOVER_API_TOKEN = "in-process-token"`, a hardcoded fixture-server test token, not a real leaked secret; worth a quick human glance but not actionable.
  • Consider adding a short comment on the new `getContributorProfile` helper mirroring the one on `getOpenPrMonitor` just above it for consistency, though the block comment above the stdio tool registration already covers the rationale.
  • packages/loopover-mcp/bin/loopover-mcp.ts:6091 — type the new helper as `function getContributorProfile(login: string)` since it's newly introduced code, not something inherited from the surrounding `any`-typed style.
  • No functional changes needed — the extraction and registration both trace cleanly to the shared `apiGet` call and the existing `GET /v1/contributors/:login/profile` route already used by the CLI and remote tool.
  • Possible secret-shaped assignment in the diff (generic_secret_assignment) — Verify the value is not a real credential.

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 #7760
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High 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: 184 registered-repo PR(s), 118 merged, 22 issue(s).
Contributor context ✅ Confirmed Gittensor contributor andriypolanski; Gittensor profile; 184 PR(s), 22 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Linked issue satisfaction

Addressed
The PR registers loopover_get_contributor_profile as a stdio tool via registerStdioTool with a stdioToolDescription entry, reuses the shared getContributorProfile() call (also refactoring the CLI to use it instead of duplicating the HTTP path), and updates related tool-count tests.

Review context
  • Author: andriypolanski
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: Python, TypeScript, JavaScript, Rust, Cuda, Kotlin, MDX, Scala
  • Official Gittensor activity: 184 PR(s), 22 issue(s).
  • Related work: Titles/paths share 9 meaningful terms. (PR #7956)
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 2 steps in the Signals table above.
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 <question> answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat <question> 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 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LoopOver approves — the gate is satisfied and CI is green.

@JSONbored JSONbored left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Merge conflicts:

This branch has conflicts that must be resolved
Use the [web editor](https://github.com/JSONbored/loopover/pull/7955/conflicts) or the command line to resolve conflicts before continuing.

test/unit/mcp-tool-rename-aliases.test.ts

@JSONbored JSONbored 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:bug Gittensor-scored bug fix — scores a 0.05x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Register loopover_get_contributor_profile as a local stdio MCP tool

3 participants