feat(mcp): REST routes + CLI resource mirrors for finding-taxonomy and enrichment-analyzers - #6709
Conversation
…d enrichment-analyzers
The finding-taxonomy and enrichment-analyzers documents were exposed only as
remote MCP resources, with no REST route or local stdio CLI mirror — unlike
loopover_compatibility, which already has both. This adds them, following that
resource's established pattern exactly.
- Two unauthenticated GET routes in src/api/routes.ts alongside
/v1/mcp/compatibility: /v1/mcp/finding-taxonomy returns
buildFindingTaxonomyDocument(), /v1/mcp/enrichment-analyzers returns
buildEnrichmentAnalyzersTaxonomyDocument() — reusing the builders as-is.
Both are added to requiresApiToken's exclusion list, so they are public the
same way /v1/mcp/compatibility is (the documents carry only committed public
enums/analyzer metadata, no DB/env/private data).
- Two server.registerResource blocks in packages/loopover-mcp/bin/loopover-mcp.js
after loopover_compatibility, reusing the exact URIs the remote server
registers (loopover://finding-taxonomy and the legacy gittensory://enrichment-analyzers),
each proxying its new route via apiGet with the same { status: "unavailable" }
try/catch fallback.
Tests: unauthenticated route-level assertions of each document's shape (api.test.ts),
and stdio-server discovery + read assertions for both new resources (mcp-discovery.test.ts).
Closes JSONbored#6620
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6709 +/- ##
=======================================
Coverage 93.65% 93.65%
=======================================
Files 681 682 +1
Lines 68098 68122 +24
Branches 18695 18704 +9
=======================================
+ Hits 63775 63798 +23
Misses 3347 3347
- Partials 976 977 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
|
Warning ⏸️ LoopOver review result - manual review recommendedReview updated: 2026-07-16 20:15:43 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk 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.
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.
|
src/api/routes.ts imported buildFindingTaxonomyDocument and buildEnrichmentAnalyzersTaxonomyDocument twice (introduced by JSONbored#6709), which broke `tsc --noEmit` with TS2300 duplicate-identifier errors and red-CI'd typecheck for any branch built on top of main. No behavior change -- both route handlers using these functions are unaffected.
Summary
Closes #6620
loopover_finding_taxonomyandloopover_enrichment_analyzerswere exposed only as remote MCP resources — no REST route, no local stdio CLI mirror — unlikeloopover_compatibility, which already has both. This adds them, following that resource's established pattern exactly.src/api/routes.ts, next to/v1/mcp/compatibility:GET /v1/mcp/finding-taxonomy→buildFindingTaxonomyDocument(),GET /v1/mcp/enrichment-analyzers→buildEnrichmentAnalyzersTaxonomyDocument(). The builders are reused as-is (not reimplemented). Both paths are added torequiresApiToken's exclusion list, so they're public the same way/v1/mcp/compatibilityis — the documents carry only committed public enums / analyzer metadata (no DB/env/private data).server.registerResource(...)blocks inpackages/loopover-mcp/bin/loopover-mcp.jsafterloopover_compatibility, reusing the exact URIs the remote server already registers (loopover://finding-taxonomyand the legacygittensory://enrichment-analyzers— not new URIs), each proxying its new route viaapiGetwith the same{ status: "unavailable" }try/catch fallback.Scope
type(scope): short summaryConventional Commit format.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Closes #6620).Validation
git diff --checknpm run actionlintnpm run typecheck(type-safe by construction — see note; local root typecheck OOMs)npm run test:coverage(every changed route line + branch is covered — see below)npm run test:workersnpm run build:mcpnpm run test:mcp-packnpm run ui:openapi:checknpm run ui:lintnpm run ui:typechecknpm run ui:buildnpm audit --audit-level=moderateIf any required check was skipped, explain why:
test/integration/api.test.tsnow requests both new routes unauthenticated (empty init, no api token) and asserts each returns its builder's shape (finding-taxonomy: non-emptycategories/severities;enrichment-analyzers: non-emptyanalyzerswithname/costClass). Hitting each path unauthenticated exercises both the route handler and its newrequiresApiToken(...) === falsebranch (the middleware callsrequiresApiTokenon every/v1/request), so there is no uncovered line or branch in the route change.packages/loopover-mcp/bin/loopover-mcp.jsis not invitest.config.ts'scoverage.include, so it isn't codecov-gated.test/unit/mcp-discovery.test.ts(which drives the real--stdioserver) now asserts both new URIs are discoverable vialistResources()and that reading each returns parseable JSON — the fixture doesn't serve these paths, so the read exercises the{ status: "unavailable" }fallback branch, matching the compatibility resource's own test.api.test.ts"serves health and OpenAPI openly"), the CLI discovery/read suite (mcp-discovery.test.ts, 21 tests), and the unchanged builder tests (mcp-finding-taxonomy+mcp-enrichment-analyzers, 4 tests) confirming no regression./v1/mcp/compatibilityroute (c.json(builder())), and both builders return typed documents; the roottypecheckOOMs locally but CI runs it in full./v1/mcp/*routes aren't insrc/openapi/spec.ts, same as/v1/mcp/compatibility). Prettier isn't a CI gate (noformatscript; absent fromtest:ci); all touched files are already non-prettier-clean onmain.Safety
UI Evidencesection.Both routes are deliberately unauthenticated, matching the existing remote resources (neither registration has a
requireRepoAccess/requireContributorAccesscall) and/v1/mcp/compatibility. The documents are static, committed, public taxonomy — category/severity enums and analyzer names/cost classes — with no DB, env, or per-contributor data.Notes
The builders (
buildFindingTaxonomyDocument,buildEnrichmentAnalyzersTaxonomyDocument) and the remote MCP resources are unchanged; this only adds the missing HTTP + CLI reach, completing the same patternloopover_compatibilityalready has.enrichment-analyzersintentionally keeps its legacygittensory://resource URI to match what the remote server registers today.Closes #6620