Bug Description
When a longLived: true MCP server is spawned before its secret is stored in the keychain, the container gets APIFY_TOKEN=<UNKNOWN> baked into its environment. This value persists permanently because long-lived containers are never recreated, even after the secret is correctly stored via docker mcp secret set.
Steps to Reproduce
- Enable a server with
longLived: true in the catalog (e.g., apify-mcp-server)
- Do not set its secret yet
- Invoke any tool from that server — the gateway spawns the container with
SECRET_VAR=<UNKNOWN>
- Now set the secret:
echo 'valid-token' | docker mcp secret set apify-mcp-server.apify_token
- Invoke the tool again — it still fails because the running container still has
<UNKNOWN>
Expected Behavior
Either:
- (A) The gateway should refuse to start a container when a required secret resolves to
<UNKNOWN>, instead of silently proceeding
- (B) The gateway should recreate long-lived containers when secrets change in the keychain
- (C) The
--watch flag should monitor the secret store, not just config files
Actual Behavior
- The gateway logs
Warning: Secret 'X' not found for server 'Y', setting Z=<UNKNOWN> but proceeds anyway
- The container starts and tools are listed successfully (tools/list works)
- Actual tool calls fail with cryptic upstream auth errors (e.g., "User was not found or authentication token is not valid")
- The container persists across sessions because
longLived: true
- Even after the secret is stored, the running container is never refreshed
Proof
# Container running with stale <UNKNOWN>
$ docker inspect c37a7f65a635 --format '{{range .Config.Env}}{{println .}}{{end}}'
APIFY_TOKEN=<UNKNOWN>
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NODE_VERSION=24.14.0
# Secret IS in the keychain
$ docker mcp secret ls | grep apify
docker/mcp/apify-mcp-server.apify_token | docker-pass
# Fresh gateway (via CLI) works fine — proves secret is stored correctly
$ echo '{"keywords":"test","limit":1}' | docker mcp tools call search-actors
# Returns valid results
Impact
- Affected servers: Any server with both
longLived: true AND secrets defined in the catalog. Currently: apify-mcp-server, schemacrawler-ai
- User impact: Hours of debugging. The error appears to be an auth/token issue, but the root cause is a stale container that was created before the secret existed
- Workaround:
docker kill <container_id> then restart the MCP client to get a fresh gateway connection
Environment
- Docker MCP Toolkit: v0.40.1
- Docker Desktop: macOS (Darwin 25.2.0)
- Credential store: docker-pass (via Docker Desktop)
Related Issues
Suggested Fix
In the gateway's container creation path, add a check:
// Before creating a long-lived container:
for _, secret := range server.Secrets {
if resolvedValue == "<UNKNOWN>" {
return fmt.Errorf("required secret %q not found for server %q; refusing to start container with placeholder value", secret.Name, server.Name)
}
}
Additionally, consider watching the secret store for changes and triggering container recreation for affected long-lived servers.
Bug Description
When a
longLived: trueMCP server is spawned before its secret is stored in the keychain, the container getsAPIFY_TOKEN=<UNKNOWN>baked into its environment. This value persists permanently because long-lived containers are never recreated, even after the secret is correctly stored viadocker mcp secret set.Steps to Reproduce
longLived: truein the catalog (e.g.,apify-mcp-server)SECRET_VAR=<UNKNOWN>echo 'valid-token' | docker mcp secret set apify-mcp-server.apify_token<UNKNOWN>Expected Behavior
Either:
<UNKNOWN>, instead of silently proceeding--watchflag should monitor the secret store, not just config filesActual Behavior
Warning: Secret 'X' not found for server 'Y', setting Z=<UNKNOWN>but proceeds anywaylongLived: trueProof
Impact
longLived: trueANDsecretsdefined in the catalog. Currently:apify-mcp-server,schemacrawler-aidocker kill <container_id>then restart the MCP client to get a fresh gateway connectionEnvironment
Related Issues
cmd.Envdrops parent environmentSuggested Fix
In the gateway's container creation path, add a check:
Additionally, consider watching the secret store for changes and triggering container recreation for affected long-lived servers.