Environment
- Freebuff Desktop 0.0.150 (win-x64)
- Windows
MCP configuration (~/.agents/mcp.json)
{
"mcpServers": {
"tripo-ai": {
"command": "npx",
"args": ["-y", "tripo-ai-mcp-server"],
"env": {
"TRIPO_API_SECRET": "$TRIPO_API_SECRET"
}
}
}
}
What happens
The Connectors UI reports:
tripo-ai : Missing credential binding for TRIPO_API_SECRET
The connector is never registered and never launches. The variable is set for the user account and is present in the user-session process environment (verified by boolean presence only; the value was never read, logged, or displayed).
Suspected cause
Inspection of the shipped 0.0.150 Desktop bundle (resources/orchestrator/orchestrator.js) shows that the stdio MCP configuration path resolves $NAME references through credential bindings and a hardcoded RESOLVABLE_BASE allowlist:
const RESOLVABLE_BASE = new Set([
"HOME", "PATH", "SHELL", "USER", "LANG", "TMPDIR"
])
TRIPO_API_SECRET matches neither source, so it is reported as missing before launch approval or process spawning.
The current build also contains a credentialBindings field in the sidecar schema, but I could not identify a working path in the shipped bundle that populates a binding for this environment variable.
Inconsistency with the public runtime
The public Freebuff CLI/SDK MCP loader resolves arbitrary $VAR references from process.env (for example, sdk/src/agents/load-mcp-config.ts).
Therefore the Desktop connector behavior differs from the public runtime behavior for the same MCP configuration convention.
Suggested fix
This is a proposed fix, not a claim about the private Desktop source.
After credential bindings and the existing base-variable handling, allow the resolver to fall back to the orchestrator's environment:
if (base[name] !== undefined) return base[name]
and make the MCP config store's environment available as the orchestrator's process.env.
The existing declared-environment-only child process behavior should remain unchanged: only variables explicitly referenced in the MCP configuration should be forwarded.
Security requirements
The fix should preserve:
- credential bindings taking priority over
process.env
- only explicitly referenced variables being forwarded to MCP child processes
- resolved secret values never being persisted to
mcp.json or sidecar state
- fingerprints/approvals containing environment variable names, not resolved values
- secret values never being logged
Minimal regression test
Please add a regression test using a fake variable such as TEST_FAKE_SECRET, never a real credential:
$TEST_FAKE_SECRET resolves from the orchestrator environment
- an unset variable still produces the expected missing-variable error
- credential bindings still take priority over
process.env
- fingerprints do not contain resolved secret values
If useful, I can provide the full bundle-level trace from McpConfigStore.load() through fingerprintOf() / resolveValue() to the failed connector registration.
Environment
MCP configuration (
~/.agents/mcp.json){ "mcpServers": { "tripo-ai": { "command": "npx", "args": ["-y", "tripo-ai-mcp-server"], "env": { "TRIPO_API_SECRET": "$TRIPO_API_SECRET" } } } }What happens
The Connectors UI reports:
The connector is never registered and never launches. The variable is set for the user account and is present in the user-session process environment (verified by boolean presence only; the value was never read, logged, or displayed).
Suspected cause
Inspection of the shipped 0.0.150 Desktop bundle (
resources/orchestrator/orchestrator.js) shows that the stdio MCP configuration path resolves $NAME references through credential bindings and a hardcodedRESOLVABLE_BASEallowlist:TRIPO_API_SECRETmatches neither source, so it is reported as missing before launch approval or process spawning.The current build also contains a
credentialBindingsfield in the sidecar schema, but I could not identify a working path in the shipped bundle that populates a binding for this environment variable.Inconsistency with the public runtime
The public Freebuff CLI/SDK MCP loader resolves arbitrary
$VARreferences fromprocess.env(for example,sdk/src/agents/load-mcp-config.ts).Therefore the Desktop connector behavior differs from the public runtime behavior for the same MCP configuration convention.
Suggested fix
This is a proposed fix, not a claim about the private Desktop source.
After credential bindings and the existing base-variable handling, allow the resolver to fall back to the orchestrator's environment:
and make the MCP config store's environment available as the orchestrator's
process.env.The existing declared-environment-only child process behavior should remain unchanged: only variables explicitly referenced in the MCP configuration should be forwarded.
Security requirements
The fix should preserve:
process.envmcp.jsonor sidecar stateMinimal regression test
Please add a regression test using a fake variable such as
TEST_FAKE_SECRET, never a real credential:$TEST_FAKE_SECRETresolves from the orchestrator environmentprocess.envIf useful, I can provide the full bundle-level trace from
McpConfigStore.load()throughfingerprintOf()/resolveValue()to the failed connector registration.