← back to Cli Printing Press
fix(cli): authenticate mega MCP library fetches with GITHUB_TOKEN
1d4e642c31e39638ccde61336826bee35ba5b858 · 2026-04-18 00:39:01 -0400 · Matt Van Horn
The printing-press-mcp binary fetches registry.json and per-API
tools-manifest.json from raw.githubusercontent.com/mvanhorn/printing-press-library.
The library repo is private, so unauthenticated reads return 404 and
the mega MCP ships with an empty tool catalog.
When GITHUB_TOKEN is set, attach `Authorization: token <value>` to the
outbound GET. Same URL, same response shape, just with auth. Matches
the existing convention in internal/crowdsniff/github.go.
Plan: docs/plans/2026-04-17-002-fix-private-library-registry-auth-plan.md
🤖 Generated with Claude Opus 4.7 (1M context) via [Claude Code](https://claude.com/claude-code) + Compound Engineering v2.56.1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
M internal/megamcp/manifest.goM internal/megamcp/registry.goM internal/megamcp/registry_test.go
Diff
commit 1d4e642c31e39638ccde61336826bee35ba5b858
Author: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date: Sat Apr 18 00:39:01 2026 -0400
fix(cli): authenticate mega MCP library fetches with GITHUB_TOKEN
The printing-press-mcp binary fetches registry.json and per-API
tools-manifest.json from raw.githubusercontent.com/mvanhorn/printing-press-library.
The library repo is private, so unauthenticated reads return 404 and
the mega MCP ships with an empty tool catalog.
When GITHUB_TOKEN is set, attach `Authorization: token <value>` to the
outbound GET. Same URL, same response shape, just with auth. Matches
the existing convention in internal/crowdsniff/github.go.
Plan: docs/plans/2026-04-17-002-fix-private-library-registry-auth-plan.md
🤖 Generated with Claude Opus 4.7 (1M context) via [Claude Code](https://claude.com/claude-code) + Compound Engineering v2.56.1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
internal/megamcp/manifest.go | 12 +++++++++++-
internal/megamcp/registry.go | 15 +++++++++++++--
internal/megamcp/registry_test.go | 26 ++++++++++++++++++++++++++
3 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/internal/megamcp/manifest.go b/internal/megamcp/manifest.go
index 056077b1..b7955db9 100644
--- a/internal/megamcp/manifest.go
+++ b/internal/megamcp/manifest.go
@@ -279,8 +279,18 @@ func tryCache(cachePath, expectedChecksum string) (*ToolsManifest, error) {
}
// fetchManifestData downloads manifest data from a URL.
+// When GITHUB_TOKEN is set, an Authorization header is attached so private-repo
+// reads via raw.githubusercontent.com succeed.
func fetchManifestData(manifestURL string) ([]byte, error) {
- resp, err := http.Get(manifestURL)
+ req, err := http.NewRequest(http.MethodGet, manifestURL, nil)
+ if err != nil {
+ return nil, fmt.Errorf("building request: %w", err)
+ }
+ if token := os.Getenv("GITHUB_TOKEN"); token != "" {
+ req.Header.Set("Authorization", "token "+token)
+ }
+
+ resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request: %w", err)
}
diff --git a/internal/megamcp/registry.go b/internal/megamcp/registry.go
index 07a69586..33014675 100644
--- a/internal/megamcp/registry.go
+++ b/internal/megamcp/registry.go
@@ -5,17 +5,28 @@ import (
"fmt"
"io"
"net/http"
+ "os"
)
-// DefaultBaseURL is the default GitHub raw content URL for the public library repo.
+// DefaultBaseURL is the default GitHub raw content URL for the library repo.
const DefaultBaseURL = "https://raw.githubusercontent.com/mvanhorn/printing-press-library/main"
// FetchRegistry fetches registry.json from baseURL and parses it into a Registry.
// baseURL is injectable for testing (use httptest.NewServer).
+// When GITHUB_TOKEN is set, an Authorization header is attached so private-repo
+// reads via raw.githubusercontent.com succeed.
func FetchRegistry(baseURL string) (*Registry, error) {
registryURL := baseURL + "/registry.json"
- resp, err := http.Get(registryURL)
+ req, err := http.NewRequest(http.MethodGet, registryURL, nil)
+ if err != nil {
+ return nil, fmt.Errorf("building registry request: %w", err)
+ }
+ if token := os.Getenv("GITHUB_TOKEN"); token != "" {
+ req.Header.Set("Authorization", "token "+token)
+ }
+
+ resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, fmt.Errorf("fetching registry: %w", err)
}
diff --git a/internal/megamcp/registry_test.go b/internal/megamcp/registry_test.go
index 83ddf77b..34f668d3 100644
--- a/internal/megamcp/registry_test.go
+++ b/internal/megamcp/registry_test.go
@@ -96,3 +96,29 @@ func TestFetchRegistryInvalidJSON(t *testing.T) {
assert.Nil(t, result)
assert.Contains(t, err.Error(), "parsing registry JSON")
}
+
+func TestFetchRegistryAttachesGitHubToken(t *testing.T) {
+ var gotAuth string
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ gotAuth = r.Header.Get("Authorization")
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(Registry{SchemaVersion: 1})
+ }))
+ defer server.Close()
+
+ t.Run("with token set", func(t *testing.T) {
+ gotAuth = ""
+ t.Setenv("GITHUB_TOKEN", "ghp_testtoken123")
+ _, err := FetchRegistry(server.URL)
+ require.NoError(t, err)
+ assert.Equal(t, "token ghp_testtoken123", gotAuth)
+ })
+
+ t.Run("with token unset", func(t *testing.T) {
+ gotAuth = ""
+ t.Setenv("GITHUB_TOKEN", "")
+ _, err := FetchRegistry(server.URL)
+ require.NoError(t, err)
+ assert.Empty(t, gotAuth)
+ })
+}
← 3fd4a5a8 style(cli): simplify async-detect sibling-filter boolean
·
back to Cli Printing Press
·
feat(cli): printing-press patch — AST-inject PR #218 feature 16ed5a56 →