registry/cmd/publisher
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Yusufhan Sacak d1dcaf3fb3
Some checks failed
CI Pipeline / Build, Lint, and Validate (push) Has been cancelled
CI Pipeline / Tests (push) Has been cancelled
Deploy to Staging / Build and Push Image with ko (push) Has been cancelled
Deploy to Staging / Deploy to Staging (push) Has been cancelled
fix(publisher): tolerate transient device-flow failures during login polling (#1588)
Follow-up to my analysis on #1543.

Heads up on the shape first: this builds on #1290's poll-loop seams and
github wont let me target a fork branch, so the diff shows its two
commits too. Review only the last commit, the first two are #1290
unchanged, credit to @developer-ishan. Happy to rebase whichever way
#1290 goes, or split differently if that's easier to review.

What it does. pollForToken treats every non-pending answer as terminal,
so one flaky response kills a login the user may already have approved
in the browser. This spends a small grace budget (2 polls) on
incorrect_device_code before giving up, retries 5xx with a growing
backoff, and returns status plus body on other non-200s instead of dying
inside json.Unmarshal on an html error page. Terminal errors now carry
error_description and error_uri, and a timeout that happens after
polling recovered reports a plain timeout, not a stale error from
minutes earlier.

Also honours the interval and expires_in GitHub returns with the device
code (RFC 8628 3.2) instead of hardcoding 5/900, clamped (60s / 3600s)
so a misbehaving response can't stall the CLI or overflow the duration
math.

One thing I changed my mind on from the issue comment: I wrote there
that the client should wait one interval before the first poll. Dropped
that. My own repro test showed 40s of clean polling before authorize, so
the propagation theory doesn't hold, and the grace retry covers the same
window without taxing every fast login. First poll stays immediate,
pinned by a test.

Root cause note: I can't prove the GitHub-side race (cli/cli#9302 is the
same error class but was closed on an unconfirmed "platform race"). So
this isn't claimed as a root-cause fix, it makes the login recoverable
if the condition is transient and diagnosable if it isn't. Btw
incorrect_device_code is a GitHub extension, not an RFC 8628 3.5 code,
so there's no spec retry semantic being violated by the grace polls.

## Test

12 new tests in github_at_device_flow_internal_test.go, all green with
-race (33 in the package). #1290's four tests pass unmodified.
golangci-lint clean in the touched files under both v2.11.4 (this
branch's CI pin) and v2.13.1 (what main pins now).

## AI Disclosure

AI assistance (Claude) was used for issue research and during
development. All changes were reviewed and tested by the author.

Fixes #1543

---------

Co-authored-by: developer-ishan <igupta@groupon.com>
Co-authored-by: Ishan Gupta <62565307+developer-ishan@users.noreply.github.com>
Co-authored-by: developer-ishan <guptaishan849@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-16 18:42:30 +03:00
..
auth fix(publisher): tolerate transient device-flow failures during login polling (#1588) 2026-09-16 18:42:30 +03:00
commands test: isolates temp test fixtures (#1569) 2026-09-06 00:31:12 +03:00
main.go fix(publisher): document --algorithm for ECDSA login and fix validate --help (#1519) 2026-08-10 16:25:00 +03:00
README.md fix(publisher): document --algorithm for ECDSA login and fix validate --help (#1519) 2026-08-10 16:25:00 +03:00

MCP Publisher Tool - Development

CLI tool for publishing MCP servers to the registry.

These docs are for contributors. See the Publisher User Guide for end-user documentation.

Quick Development Setup

# Build the tool
make publisher

# Test locally 
make dev-compose  # Start local registry
./bin/mcp-publisher init
./bin/mcp-publisher login none --registry=http://localhost:8080
./bin/mcp-publisher publish

publish takes the registry URL from the token saved by login, so it accepts no --registry flag — passing one would be read as the server.json path.

Architecture

Commands

  • init - Generate server.json templates with auto-detection
  • login - Handle authentication (github, dns, http, none)
  • publish - Validate and upload servers to registry
  • status - Update server lifecycle status (active, deprecated, deleted)
  • validate - Validate server.json without publishing
  • logout - Clear stored credentials

Authentication Providers

  • github - Interactive OAuth flow
  • github-oidc - CI/CD with GitHub Actions
  • dns - Domain verification via DNS TXT records
  • http - Domain verification via HTTPS endpoints
  • none - No auth (testing only)

Signing Providers

Optional: enables dns and http methods to sign out-of-process without direct access to the private key.

  • google-kms - Google KMS signing
  • azure-key-vault - Azure Key Vault signing

Key Files

  • main.go - CLI setup and command routing
  • commands/ - Command implementations with auto-detection logic
  • auth/ - Authentication provider implementations