Builders & Images
Registry server images are built by CI (the build-images.yml workflow) from generic builder Dockerfiles under images/ in the registry repo. The builder is selected by the image.builder field in the server's manifest; omitting it selects go-static.
image:
ref: ghcr.io/gigmcp/myserver-mcp
digest: sha256:...
entrypoint: /app/server
builder: node # omit or "go-static" for static Go binaries
Under the hood, registryctl build-args reads the manifest and emits BUILDER=<value> into $GITHUB_ENV; the workflow passes -f "images/${BUILDER}/Dockerfile" to docker buildx build. See registryctl.
The /app/server convention
Every builder places the executable at /app/server inside the image, and the manifest's image.entrypoint should always be /app/server. This is the path the gateway uses when it mounts or runs the server inside the sandbox.
| Builder | Runtime image base | /app/server artifact |
|---|---|---|
go-static | scratch (no OS) | Static ELF binary (CGO_ENABLED=0) |
toolpack | scratch (no OS) | Static toolpack engine + baked-in /app/manifest.yaml and /app/toolspec.yaml |
node | node:22-bookworm-slim | esbuild-bundled JS with #!/usr/bin/env node shebang |
python | python:3.13-slim-bookworm | shiv zipapp with #!/usr/local/bin/python3 shebang |
go-static (default)
The default builder for standalone Go MCP servers.
source.repo— the Go module root, or any git repo with Go source.source.package— the directory containing themainpackage (e.g. a subdirectory of the author's repo); defaults to.(repo root).- The builder runs
CGO_ENABLED=0 go build -trimpath -o /out/server .in that directory and copies the result into aFROM scratchimage. No OS layer, no shell, no libc — the smallest possible attack surface.
toolpack
Builds the generic toolpack engine and bakes the server's spec into the image.
source.repo/source.tag— the generic engine (github.com/gigmcp/toolpack); built exactly likego-static.- Additionally copies
manifests/<name>/<version>.yamlandtoolspecs/<name>/<version>.yamlfrom the registry repo (the build context) into the image as/app/manifest.yamland/app/toolspec.yaml. The workflow passesNAME/VERSIONbuild args to select them. - At runtime the engine reads the manifest for the credential-inject contract and the toolspec for the tool→HTTP mappings.
registryctl lint-toolspecsenforces their coherence in CI, and lint requires a toolspec to exist for every manifest that selects this builder.
node
source.repo/source.tag— a git repo whose checkout contains apackage.jsonatsource.package(defaults to repo root).- The
package.jsonmust declare either abinentry (string, or object with exactly one entry) or amainentry pointing to the server's JS/TS entry point. - esbuild bundles everything into a single self-contained CJS file with a
#!/usr/bin/env nodeshebang at/app/server, on anode:22-bookworm-slimbase.
python
source.repo/source.tag— a git repo containing apyproject.tomlatsource.package(defaults to repo root).- The
pyproject.tomlmust declare exactly one[project.scripts]entry; shiv uses that entry's name as the console-script entrypoint and bundles the project plus all dependencies into a single executable zipapp at/app/server, on apython:3.13-slim-bookwormbase.
:::warning node and python images are not yet installable
The Gig'MCP gateway sandbox currently mounts a single static binary from a scratch-based image. Running node or python images requires a full runtime rootfs (OS layer, interpreter on PATH), which depends on the gateway's rootfs sandbox extension — designed but not yet shipped.
The node and python builders exist so manifests can already declare builder: node or builder: python and CI can build the images today; those images become installable once the gateway extension ships. Until then, only go-static and toolpack images are runnable.
:::
Custom per-server Dockerfiles
For servers that don't fit any generic builder (unusual CGO flags, pre-built assets, multi-step toolchains), you may add images/<name>/Dockerfile to the registry repo. This overrides the generic builder — point image.builder at the directory name that matches your custom Dockerfile. Note that the manifest schema currently whitelists only the four generic builder values, so a custom builder name also requires extending the schema's builder whitelist (coordinate in your PR).
Custom Dockerfiles are the exception; prefer the generic builders when possible. See submitting a server for the full contribution flow.