GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — fix(scanner): inspect only the scanned server's tools, keep peers as index context by Dumbris · Pull Request #1812 · smart-mcp-proxy/mcpproxy-go

Conversation

@Dumbris

@Dumbris Dumbris commented Nov 1, 2026

Copy link
Copy Markdown
Member

Summary

Closes #1724 (core at >100% CPU while idle, battery drain).

Root cause. The per-tool change-gate scan (Runtime.scanToolEvidence → scanner.ScanToolMetadataVerdict) feeds every other connected server's tools to the detect engine as cross-server context (needed by the shadowing/impersonation check), but Engine.Scan then ran every check — phrase and bundle regex detection included — over the whole fleet for each held tool, and threw the peer findings away afterwards. Every 5-minute discovery pass re-evaluates every still-held (changed/pending) tool, so the cost is held tools × fleet size × all checks per pass. The reporting install has 471 tools on 11 servers with 108 held changes: ~11 minutes at 100% CPU, then a 5-minute gap, forever.

Fix. detect.NewScopedRegistryView(targets, peers): only the scanned server's tools go into the scan set (Tools); peers are indexed into ToolsByName/ToolNames, which is the only way any check (Shadowing) reads them. Peers are no longer normalized or inspected. Target findings are identical to a full view's — the cross-server rug-pull tests still fire. Both scanner entry points (ScanToolMetadataVerdict and detectEngineFindings) use it.

Measured. BenchmarkScanToolMetadataVerdict_PerToolWithPeers (11 servers, 43 tools each, one held tool per op) on an M4 Pro:

ns/op allocs/op
before 3,065,462,617 (3.07 s) 2,339,383
after 5,416,844 (5.4 ms) 6,682

Peer collection (collectPeerToolMetadata, ~1.5 ms for 470 schemas) was measured and left as is: a pass with 108 held tools now spends well under a second every 5 minutes.

Test plan

  • TestNewScopedRegistryView_InspectsTargetsOnly / _TargetFindingsMatchFullView (new, fail without the fix)
  • go test ./internal/security/detect/... ./internal/security/scanner/...
  • go test -race ./internal/security/detect/...
  • go test ./internal/runtime/ -run 'Scan|Quarantine|Approval|Baseline|Peer|Shadow'
  • golangci-lint run --config .github/.golangci.yml ./internal/security/... — 0 issues

🤖 Generated with Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@Dumbris @claude
fix(scanner): inspect only the scanned server's tools, keep peers as …
498fcf2
…index context (#1724)

The per-tool change-gate scan (trust_mode: scan approval and the manual-mode
hold evidence) fed every other connected server's tools to the detect engine
as cross-server context, and Engine.Scan then ran every check — the phrase
and bundle regex detection included — over the whole fleet for each held
tool, discarding the peer findings afterwards. Every discovery pass rescans
every still-held tool, so an install with a few hundred tools and a few
dozen held changes burned tools x fleet every 5 minutes: 471 tools, 108 held,
~11 minutes at 100% CPU per pass on the reporting machine.

detect.NewScopedRegistryView(targets, peers) puts only the targets in the
scan set and indexes peers into ToolsByName/ToolNames, which is the only way
a check (Shadowing) ever reads them. Target findings are identical to a full
view's; peers are no longer normalized or inspected. Both scanner entry
points (ScanToolMetadataVerdict, detectEngineFindings) use it. One held-tool
scan against a 470-tool fleet: ~3 s -> ~5 ms
(BenchmarkScanToolMetadataVerdict_PerToolWithPeers).

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 1, 2026

Copy link
Copy Markdown

Deploying mcpproxy-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: 498fcf2
Status: ✅  Deploy successful!
Preview URL: https://a69e59cc.mcpproxy-docs.pages.dev
Branch Preview URL: https://claude-mcpproxy-high-cpu-idl.mcpproxy-docs.pages.dev

View logs

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Dumbris
Dumbris enabled auto-merge (squash) November 1, 2026 11:23
@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

📦 Build Artifacts

Workflow Run: View Run
Branch: claude/mcpproxy-high-cpu-idle-5c313c

Available Artifacts

  • archive-darwin-amd64 (32 MB)
  • archive-darwin-arm64 (29 MB)
  • archive-linux-amd64 (20 MB)
  • archive-linux-arm64 (18 MB)
  • archive-windows-amd64 (32 MB)
  • archive-windows-arm64 (28 MB)
  • frontend-dist-pr (0 MB)
  • installer-dmg-darwin-amd64 (28 MB)
  • installer-dmg-darwin-arm64 (25 MB)
  • smart-mcp-proxymcpproxy-go89QQZU.dockerbuild (0 MB)

How to Download

Option 1: GitHub Web UI (easiest)

  1. Go to the workflow run page linked above
  2. Scroll to the bottom "Artifacts" section
  3. Click on the artifact you want to download

Option 2: GitHub CLI

gh run download 41301136638 --repo smart-mcp-proxy/mcpproxy-go

Note: Artifacts expire in 14 days.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Dumbris
Dumbris merged commit 62401d5 into main Nov 1, 2026
55 of 56 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@codecov-commenter

codecov-commenter commented Nov 1, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@Dumbris Dumbris mentioned this pull request Nov 2, 2026
test(launcher): make WaitForURL late-bind test immune to port reuse #1816
Merged
4 tasks done
Dumbris added a commit that referenced this pull request Nov 2, 2026
@Dumbris @claude
test(launcher): make WaitForURL late-bind test immune to port reuse (#…
c320362
…1816)

## Summary
- `TestWaitForURL_BoundLate` reserved `127.0.0.1:0`, closed it, then
re-bound 400 ms later. On CI another process/test took the port first
(`bind: address already in use`, seen on #1812), failing the E2E job.
- `NeverBound` and `ContextCanceled` used the same reserve-and-release
pattern and could pass/fail spuriously if a stray listener took the
port.
- Fix: drive `WaitForURLWithDial` with a dial func that refuses
(ECONNREFUSED) until a deadline. `BoundLate` holds its listener for the
whole test so the port can't be stolen; the other two use no real port.
Portable across darwin/linux/windows (cross-vet clean). `WaitForURL`
itself is unchanged, so no CHANGELOG entry.

## Test plan
- [x] `go test -race -count=50 -run TestWaitForURL
./internal/upstream/launcher/`
- [x] `go test -race ./internal/upstream/launcher/`
- [x] `golangci-lint run --config .github/.golangci.yml
./internal/upstream/launcher/` — 0 issues
- [x] `GOOS=windows go vet`, `GOOS=linux go vet`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <[email protected]>
@antongulin antongulin mentioned this pull request Nov 7, 2026
Release request: ship #1812 and #1813 (v0.72.0 spends ~89 s per held tool on a ~3,000-tool fleet) #1837
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

[bug] Hi, I noticed today that mcp proxy is using very high CPU (>100%) even when idl

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@Dumbris @codecov-commenter
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.