Skip to content

Desktop MCP connector rejects valid $ENV_VAR references with "Missing credential binding" #1444

Description

@houbi39

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:desktopThe Electron desktop appbot:triagedClassified by the community triage bottype:bugA defect in the code with a reproducible failure

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions