The custom source routes CLI binary downloads and dev-stack image pulls through your own hosted infrastructure instead of MongoDB’s GitHub Releases and GHCR. It is designed for isolated-network environments (air-gapped, egress-restricted) where ghcr.io or github.com is unreachable.
How it works
Two independent knobs, each optional:
Block | Controls | Commands affected |
|---|---|---|
| CLI binary download host |
|
| Dev image host (5 images) |
|
Custom source swaps only the host — image repository names and tags stay baked at build time, so your mirror can copy mechanically: same names, same tags, your host.
The five dev-stack images are: playground-ui, orchestration-engine, memory-server, runner-base, runner-base-typescript-langgraph.
flowchart LR Y["source.yaml<br/>(base + release + registry)"] --> R["release block"] Y --> G["registry block"] R --> SU["agentengine self-update<br/>+ update notice"] G --> DU["agentengine dev up<br/>(5 dev images)"] Y -. "omitted block falls back to base<br/>(internal | public baked defaults;<br/>self-update: gateway then GitHub;<br/>version/notice: GitHub or static)" .-> B["base source"]
Prerequisites
AP_SOURCE=customin your environmentsource.yamlat~/.agentengine/source.yaml(or at a path set in$AP_SOURCE_FILE)Your corporate CA must be in the OS trust store — there is no
--insecureflag (see Security)
Note
Variable names change with the public-artifact flag. This page uses the names in effect while that flag is off. When the platform turns it on, the CLI prefers AGENTENGINE_IMAGE_SOURCE and AGENTENGINE_IMAGE_SOURCE_FILE instead. Only the names change — the values, this file’s format, and base: are all identical either way.
Either name works on an isolated network. The flag that selects the preferred name is fetched from the platform, which an air-gapped or egress-restricted machine cannot reach — so the CLI honors whichever name is actually set rather than the one the flag would have chosen. Setting only AGENTENGINE_IMAGE_SOURCE=custom works with no connectivity at all. Set both names and the flag decides which wins, and the CLI says so.
To skip the flag read entirely on such a machine, set AGENTENGINE_SKIP_PLATFORM_FLAGS=1; otherwise each command waits out a short timeout the first time, and once a minute after that. agentengine version --full reports which names are live. See public-artifacts.
Step 1 — Get image names and tags
Run agentengine version --full to get the exact image names and tag for the current CLI build:
agentengine version --full
Example output (internal source):
1.4.2 (commit: abc1234) runner-base: ghcr.io/10gen/magenta-client-libraries/runner-base:v1.4.2 runner-base-typescript-langgraph: ghcr.io/10gen/magenta-client-libraries/runner-base-typescript-langgraph:v1.4.2 playground-ui: ghcr.io/10gen/magenta-client-libraries/playground-ui:v1.4.2 orchestrator: ghcr.io/10gen/magenta-client-libraries/orchestration-engine:v1.4.2 memory-server: ghcr.io/10gen/magenta-client-libraries/memory-server:v1.4.2
Use these exact names and tags when mirroring. They are stable across patch releases within a major version; only the version suffix changes.
Step 2 — Mirror images (if mirroring the dev stack)
docker login ghcr.io # read access to MongoDB's GHCR docker login artifactory.example.com # write access to your registry for img in playground-ui orchestration-engine memory-server runner-base runner-base-typescript-langgraph; do docker pull ghcr.io/10gen/magenta-client-libraries/$img:v1.4.2 docker tag ghcr.io/10gen/magenta-client-libraries/$img:v1.4.2 artifactory.example.com/acme-docker/$img:v1.4.2 docker push artifactory.example.com/acme-docker/$img:v1.4.2 done
Repeat for each new CLI version. Repository names and the tag format are stable; only the version number changes.
Step 3 — Host the CLI binary (if mirroring binary downloads)
If your network also blocks GitHub releases, host the CLI binaries on an HTTPS server (an Artifactory generic repository works well) and publish a manifest.json matching the static manifest
format.
Upload the binary files for each OS/arch combination, then create the manifest pointing at them. The manifest URL becomes release.url in source.yaml.
Step 4 — Write source.yaml
Place at ~/.agentengine/source.yaml, or at the path you set in $AP_SOURCE_FILE.
Recommended: generate it with the CLI
agentengine agent source setup # interactive wizard: asks base/release/registry, validates before writing agentengine agent source template # writes a commented, ready-to-edit starting point instead agentengine agent source template --stdout # print the template instead of writing it
Both write to the standard discovery path (or --force to skip the overwrite prompt on an existing file) and self-validate before writing, so the result is guaranteed to load. Use agentengine agent source setup when answering prompts is easier than hand-editing YAML; use agentengine agent source template when you’d rather edit the file yourself — the examples below show what to fill in.
Full mirror — binary and images from your host
base: internal release: type: static url: https://artifactory.example.com/acme-generic/agentic-cli/manifest.json registry: prefix: artifactory.example.com/acme-docker
Images only — binary stays on GitHub
Use when your network allows github.com but blocks ghcr.io:
base: internal registry: prefix: artifactory.example.com/acme-docker
Binary only — images stay on GHCR
Use when your network allows ghcr.io but blocks GitHub release downloads:
base: internal release: type: static url: https://nexus.example.com/agentic-cli/manifest.json
GitHub-shaped release API — on-prem GitHub Enterprise
Use when your infrastructure exposes a releases API with GitHub’s JSON shape (e.g. GitHub Enterprise) instead of hosting a static manifest:
base: internal release: type: github url: https://ghe.example.internal/api/v3/repos/acme/agentic-cli/releases registry: prefix: registry.example.internal/agentic
Public base — mirroring the mongodb/atlasap release
For deployments that mirror the public release artifacts instead of the internal ones:
base: public release: type: static url: https://artifactory.example.com/agentic-cli/manifest.json registry: prefix: artifactory.example.com/atlasap-mirror
base: public inherits whatever public currently resolves to, including the fallback to the pre-preview artifacts when the public-preview repositories are unreadable. That applies only to blocks you do not override: a pinned registry.prefix or release.url is yours and is never redirected. Pin the block to be certain of it. See public-artifacts.md.
source.yaml field reference
Field | Required | Description |
|---|---|---|
| No (default: | Fallback source for anything not overridden: |
| Yes if |
|
| Yes if | Full HTTPS URL of the manifest (static) or API base (github). Must use |
| Yes if | Registry host + path, no scheme, no tag (e.g. |
At least one of release or registry is required — a source.yaml with neither is equivalent to the base source and is rejected.
$AP_SOURCE_FILE overrides the ~/.agentengine/source.yaml discovery path. When set, a missing or unreadable file is a hard error rather than a silent fallback to the home file.
Step 5 — Verify
agentengine agent source validate checks the file without requiring $AP_SOURCE to be set first, and on success prints the exact env vars to activate it:
agentengine agent source validate # standard discovery path agentengine agent source validate ./some/other/source.yaml # or an explicit path
AP_SOURCE=custom AP_SOURCE_FILE=/Users/you/.agentengine/source.yaml
Validation failures surface the same pinned messages listed in Troubleshooting below, whether the file came from agentengine agent source setup, agentengine agent source template, or hand-editing.
Then activate it and confirm the resolved routing:
export AP_SOURCE=custom agentengine version --full
For a full mirror you should see:
1.4.2 (commit: abc1234) source: custom release: https://artifactory.example.com/acme-generic/agentic-cli/manifest.json (static) registry: artifactory.example.com/acme-docker runner-base: artifactory.example.com/acme-docker/runner-base:v1.4.2 runner-base-typescript-langgraph: artifactory.example.com/acme-docker/runner-base-typescript-langgraph:v1.4.2 playground-ui: artifactory.example.com/acme-docker/playground-ui:v1.4.2 orchestrator: artifactory.example.com/acme-docker/orchestration-engine:v1.4.2 memory-server: artifactory.example.com/acme-docker/memory-server:v1.4.2
The images in the output are the exact strings passed to docker pull by agentengine dev up.
Then run agentengine self-update to test the binary update path, and agentengine dev up to confirm image pulls succeed.
Static release manifest format
The CLI fetches this file from release.url, picks the highest semver version, and selects the asset matching the current OS and architecture. There is no latest field — the CLI computes the maximum version from the releases array, so a stale pointer can never disagree with the available assets.
{ "releases": [ { "version": "1.4.2", "assets": [ { "os": "darwin", "arch": "arm64", "url": "https://artifactory.example.com/acme-generic/agentic-cli/1.4.2/agentic_darwin_arm64", "sha256": "9f2b...e1" }, { "os": "linux", "arch": "amd64", "url": "https://artifactory.example.com/acme-generic/agentic-cli/1.4.2/agentic_linux_amd64", "sha256": "4c7a...bd" } ] } ] }
Field | Type | Description |
|---|---|---|
| array | One entry per version. CLI picks the highest semver. |
| string | Semantic version (e.g. |
| array | One entry per OS/arch combination |
| string |
|
| string |
|
| string | Full HTTPS URL for the binary |
| string | 64-character hex SHA-256 digest of the binary |
The CLI validates that sha256 is a 64-character hex string at parse time and re-verifies the downloaded binary before installation.
Security
HTTPS is required, no ``--insecure`` override. SHA-256 verifies the binary matches the manifest, but nothing cryptographically signs the manifest itself. Over plain HTTP an attacker can rewrite both the download URL and the hash together and verification still passes. TLS is the only manifest-integrity guarantee. On-premises release servers must use TLS.
Corporate CA. Air-gapped enterprises typically run an internal certificate authority. The CLI uses Go’s TLS stack, which follows the OS certificate trust store. Your corporate CA must be installed in the OS trust store before using AP_SOURCE=custom with an internal HTTPS host. There is no --insecure or --cacert flag. A TLS verify failure against an internal host is a trust-store problem, not a CLI bug.
Registry authentication. The CLI never stores or manages Docker credentials. If your registry requires authentication, run docker login <registry> once before running agentengine dev up. The CLI passes image references to Docker, which uses its own ambient credential store.
``source.yaml`` discovery. The CLI loads source.yaml only from $AP_SOURCE_FILE (when set) or ~/.agentengine/source.yaml. It never auto-loads from the current working directory — doing so would allow a cloned repository to redirect self-update to an attacker-controlled host.
Troubleshooting
Error | Cause | Fix |
|---|---|---|
| No file at either searched path | Create |
|
| Check the path; the file must exist when the env var is set |
| URL starts with | Use |
| Prefix has | Remove the scheme; use bare |
| Prefix includes | Use only host + path (no colon after the last |
| Neither block present | Add at least one block |
| Wrong URL or file not yet uploaded | Check |
| Missing OS/arch entry | Add the missing asset entry to your manifest |
| Digest too short or non-hex | Compute |
TLS verify failure on internal host | Corporate CA not in OS trust store | Install your CA; there is no |
Image pull failed on | Image not mirrored, or | Mirror the image; run |