• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 32241985523
70%

Build:
DEFAULT BRANCH: main
Ran 19 Aug 2026 10:24AM UTC
Jobs 1
Files 879
Run time 3min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

19 Aug 2026 10:17AM UTC coverage: 70.515% (+0.08%) from 70.439%
32241985523

push

github

web-flow
Accept localhost dynamic-port loopback redirect_uris (#6215)

* Accept localhost dynamic-port redirect_uris

Native MCP clients registered via DCR (VS Code, Claude Code) register a
portless loopback redirect_uri such as http://localhost/callback and then
listen on an ephemeral port. RFC 8252 Section 7.3 requires the
authorization server to allow any port for loopback redirects, but
fosite's matcher recognises only IP literals (127.0.0.1, [::1]) -- it
compares "localhost" by exact string equality, so the dynamic-port
request is rejected and the flow cannot complete.

/authorize now rewrites the request form's redirect_uri to the client's
registered portless literal so fosite's exact-match validation accepts
it, then restores the requested dynamic-port URI for the pending
authorization. The authorization code stays bound to the exact port the
client asked for, so the token-endpoint check is unaffected.

Error paths keep the client's real listener as the redirect target. A
wrapper supplies the dynamic-port URI to fosite's error writer and
widens its redirect_uri validity check to cover the localhost loopback
case it cannot recognise on its own. The wrapper only ever widens that
answer, never narrows it, so a client whose redirect_uri fosite would
have accepted unaided still receives a proper error redirect rather
than a bare JSON body.

Loopback matching is stricter than fosite's: escaped paths are compared
literally, a bare "?" is significant, and fragments and userinfo are
rejected. Exact registered matches take precedence over dynamic-port
matches so a client that pinned a port is never rewritten to a
different registered entry. Dynamic-port matching is restricted to
public clients, since RFC 8252 loopback redirects are a native-app
pattern.

IP-literal loopback clients are left untouched, as fosite already
matches those natively on both success and error paths.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Update tests for merged registra... (continued)

98 of 107 new or added lines in 4 files covered. (91.59%)

8 existing lines in 3 files now uncovered.

85900 of 121818 relevant lines covered (70.52%)

99.06 hits per line

Uncovered Changes

Lines Coverage ∆ File
9
87.58
9.8% pkg/authserver/server/handlers/authorize.go

Coverage Regressions

Lines Coverage ∆ File
3
71.85
-1.11% pkg/ignore/processor.go
3
81.06
-0.69% pkg/transport/proxy/httpsse/http_proxy.go
2
75.56
-0.24% pkg/transport/proxy/streamable/streamable_proxy.go
Jobs
ID Job ID Ran Files Coverage
1 32241985523.1 19 Aug 2026 10:24AM UTC 879
70.52
GitHub Action Run
Source Files on build 32241985523
  • Tree
  • List 879
  • Changed 13
  • Source Changed 4
  • Coverage Changed 13
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #32241985523
  • 7af27d38 on github
  • Prev Build on main (#32241174145)
  • Next Build on main (#32264738558)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc