Skip to content

Bundle MCP gateway config schema in binary via go:embed#2933

Merged
lpcox merged 5 commits intomainfrom
copilot/update-gateway-schema-fetch
Mar 31, 2026
Merged

Bundle MCP gateway config schema in binary via go:embed#2933
lpcox merged 5 commits intomainfrom
copilot/update-gateway-schema-fetch

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 31, 2026

The gateway schema was fetched at runtime from a pinned GitHub raw URL, causing startup failures in network-restricted environments and introducing a hard dependency on external availability.

Changes

  • Embed schema at build time: Added internal/config/schema/mcp-gateway-config.schema.json (v0.64.4) and a //go:embed directive with a embeddedSchemaBytes variable. getOrCompileSchema() now uses the embedded bytes directly — no network request.

  • Extract transformation logic: Split fetchAndFixSchema into two functions:

    • fixSchemaBytes([]byte) ([]byte, error) — pure JSON transformation (negative-lookahead fix, registry/guard-policies injection)
    • fetchAndFixSchema(url string) ([]byte, error) — HTTP fetch + fixSchemaBytes, retained for custom server schema validation
  • Remove schemaURL package var: The hardcoded GitHub URL is no longer needed for the main schema path. Update instructions are in the comment on embeddedSchemaBytes.

  • Simplify tests: fetch_and_fix_schema_test.go tests now call fixSchemaBytes directly with marshaled JSON instead of spinning up HTTP mock servers.

// Before: fetched from GitHub at runtime
schemaJSON, fetchErr := fetchAndFixSchema(schemaURL)

// After: uses bundled schema, zero network dependency
schemaJSON, fixErr := fixSchemaBytes(embeddedSchemaBytes)

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build1174324405/b340/launcher.test /tmp/go-build1174324405/b340/launcher.test -test.testlogfile=/tmp/go-build1174324405/b340/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build1174324405/b240/vet.cfg se 8413017/b047/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --gdwarf-5 --64 -o ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build31076197/b001/config.test /tmp/go-build31076197/b001/config.test -test.testlogfile=/tmp/go-build31076197/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.run=TestFetchAndFixSchema -test.v=true --local .13/x64/as user.email (dns block)
    • Triggering command: /tmp/go-build2540153460/b001/config.test /tmp/go-build2540153460/b001/config.test -test.testlogfile=/tmp/go-build2540153460/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo 64/src/log/internal/internal.go ache/go/1.25.8/x64/pkg/tool/linu-o gpg.program (dns block)
    • Triggering command: /tmp/go-build3088080346/b001/config.test /tmp/go-build3088080346/b001/config.test -test.testlogfile=/tmp/go-build3088080346/b001/testlog.txt -test.paniconexit0 -test.timeout=10m0s go_.�� 8958092/b096/_pkg_.a (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build1174324405/b340/launcher.test /tmp/go-build1174324405/b340/launcher.test -test.testlogfile=/tmp/go-build1174324405/b340/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build1174324405/b240/vet.cfg se 8413017/b047/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --gdwarf-5 --64 -o ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build1174324405/b340/launcher.test /tmp/go-build1174324405/b340/launcher.test -test.testlogfile=/tmp/go-build1174324405/b340/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build1174324405/b240/vet.cfg se 8413017/b047/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet --gdwarf-5 --64 -o ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build1174324405/b349/mcp.test /tmp/go-build1174324405/b349/mcp.test -test.testlogfile=/tmp/go-build1174324405/b349/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build1174324405/b256/vet.cfg se 8413017/b038/vet.cfg ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (compatibility issue with Go 1.25.0). Continuing with other checks..."; \ elif command -v golan vendor/golang.or-unsafeptr=false -lang=go1.25 ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI linked an issue Mar 31, 2026 that may be closed by this pull request
Copilot AI and others added 2 commits March 31, 2026 14:02
Copilot AI changed the title [WIP] Update gateway schema to bundle in go program Bundle MCP gateway config schema in binary via go:embed Mar 31, 2026
Copilot AI requested a review from lpcox March 31, 2026 14:05
lpcox and others added 2 commits March 31, 2026 07:44
Move //go:embed directive to immediately before the var declaration,
after the doc comment block, as required by gofmt.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox lpcox marked this pull request as ready for review March 31, 2026 14:50
Copilot AI review requested due to automatic review settings March 31, 2026 14:50
@lpcox lpcox merged commit 1e9fee1 into main Mar 31, 2026
13 checks passed
@lpcox lpcox deleted the copilot/update-gateway-schema-fetch branch March 31, 2026 14:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the MCP Gateway’s runtime dependency on fetching its JSON Schema over the network by bundling the schema into the binary with go:embed, while keeping remote fetch behavior for validating custom server schemas.

Changes:

  • Embedded the MCP gateway config JSON Schema at build time and switched schema compilation to use embedded bytes (no runtime HTTP fetch).
  • Refactored schema transformation logic into a pure fixSchemaBytes helper and reused it from both embedded and remote fetch paths.
  • Updated tests to exercise schema-fix behavior directly from bytes rather than via HTTP test servers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
internal/config/validation_schema.go Embeds the schema and refactors schema fix/fetch/compile flow to remove runtime network dependency.
internal/config/validation_schema_test.go Updates schema configuration test to validate embedded schema presence and compilation.
internal/config/schema/mcp-gateway-config.schema.json Adds the bundled MCP Gateway configuration schema JSON file to the repo.
internal/config/fetch_and_fix_schema_test.go Simplifies transformation tests to call fixSchemaBytes directly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +104 to 107
func fixSchemaBytes(schemaBytes []byte) ([]byte, error) {
fixStart := time.Now()
var schema map[string]interface{}
if err := json.Unmarshal(schemaBytes, &schema); err != nil {
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixSchemaBytes currently removes the type: "string" constraint from definitions.customServerConfig.properties.type (and only adds a not enum). That makes schema validation accept non-string values (e.g., numbers/objects) as a valid custom server type and drops the type-name format constraints, weakening config validation and producing less helpful downstream unmarshal errors. Suggest keeping type: "string" and replacing only the negative-lookahead portion with a Draft-7-safe equivalent (e.g., preserve the allowed-name pattern and add a not enum for reserved types).

Copilot uses AI. Check for mistakes.
Comment on lines 210 to 213
}
logSchema.Printf("Schema fixes applied in %v", time.Since(fixStart))

logSchema.Printf("Total schema fetch and fix completed in %v", time.Since(startTime))
return fixedBytes, nil
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixSchemaBytes unconditionally injects/overwrites several properties (e.g., trustedBots, guard-policies) in the schema map. Now that the bundled schema version already includes some of these fields, this risks clobbering upstream definitions/descriptions and leaves the inline comment about the field being absent in older released schemas stale. Consider only injecting these properties if they are missing (and refresh/remove the version-specific comment) to avoid silently diverging from the embedded schema source-of-truth.

Copilot uses AI. Check for mistakes.
"port": 8080,
"domain": "localhost",
"startupTimeout": 60,
"toolTimeout": 120
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second entry in the examples array has gateway missing the required apiKey field (gatewayConfig.required includes apiKey). Examples should be valid instances of the schema to avoid confusing users and downstream tooling; add an apiKey to this example (or adjust required fields if apiKey is intentionally optional).

Suggested change
"toolTimeout": 120
"toolTimeout": 120,
"apiKey": "gateway-secret-token"

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Schema outdated and failed to download

3 participants