Skip to content

TypeScript MCP server: --api-key flag defaults to empty string, breaking env var fallback #2028

Description

@alohaninja

Bug

When generating a TypeScript MCP server (enableMCPServer: true), the generated CLI code in impl.ts defaults the --api-key flag to "" (empty string) instead of undefined. This prevents the env var fallback from ever being reached.

Generated code (impl.ts)

// startStdio() and startSSE() both have:
const server = createMCPServer({
  ...
  ...{ apiKey: flags["api-key"] ?? "" },
  ...
});

When --api-key is not passed on the CLI, flags["api-key"] is undefined, so undefined ?? "" yields "".

Security resolution (security.ts)

export function resolveGlobalSecurity(security) {
  return resolveSecurity([{
    fieldName: "Authorization",
    type: "apiKey:header",
    value: security?.apiKey ?? env().LAUNCHDARKLY_API_KEY,
  }]);
}

Since "" is not null or undefined, the nullish coalescing operator (??) treats it as a valid value and never falls through to the LAUNCHDARKLY_API_KEY env var. The Authorization header is sent as an empty string, producing 401 errors.

Impact

Any MCP client that sets environment variables on the spawned process (Claude Code, VS Code, Cursor, etc.) instead of passing --api-key as a CLI flag gets silent auth failures. This is the default integration pattern for many MCP hosts — users set LAUNCHDARKLY_API_KEY in their shell environment and expect the SDK to pick it up.

This is particularly confusing because:

  • The env.ts module correctly defines the LAUNCHDARKLY_API_KEY env var
  • The security.ts module has correct fallback logic with ??
  • The bug is solely in the CLI flag defaulting to "" instead of undefined

Fix

In the TypeScript MCP server template, change:

// From:
...{ apiKey: flags["api-key"] ?? "" },

// To:
...{ apiKey: flags["api-key"] ?? undefined },

This appears in both startStdio() and startSSE() in the generated impl.ts.

Speakeasy versions

  • CLI: 1.736.1
  • Generation engine: 2.845.15
  • mcpServer feature: 0.9.4
  • envVarSecurityUsage feature: 0.1.2
  • Target: TypeScript

Downstream report

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

    bugSomething isn't workinggeneratorConcerns generated SDK output; the fix lands in speakeasy-api/openapi-generationmcpGenerated MCP serverstypescriptTypeScript SDK target

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions