[BUG] `claude mcp add` passthrough arg parser breaks on bare -p flag in subcommand args

Status Fixed / completed
Reported on v2.1.216
Maintainer reply None cached
Activity 2 comments · opened Jul 21, 2026 · closed Aug 25, 2026

Description

claude mcp add <name> -s <scope> -- <command> [args...] fails to parse when the passthrough command args (after --) contain a bare short flag -p (as in docker run ... -p 127.0.0.1:8085:8085). The CLI's own top-level option parser appears to rescan the args after -- and misfires on an unrelated top-level flag, rather than treating everything after -- as opaque passthrough.

This breaks the documented Docker-based local setup for MCP servers that need a published port (e.g. GitHub's official MCP server local/OAuth setup, per https://github.com/github/github-mcp-server/blob/main/docs/installation-guides/install-claude.md).

Environment

  • Claude Code CLI version: 2.1.216
  • OS: macOS (Darwin 25.5.0)

Steps to reproduce

# Fails: "error: unknown option '-s'"
claude mcp add testA -s user -- docker run -i --rm -p 127.0.0.1:8085:8085 alpine

# Fails the same way even with a simple non-colon value:
claude mcp add testC -s user -- docker run -i --rm -p 8085 alpine

Expected behavior

Everything after -- should be treated as opaque args for the subprocess command and never re-parsed as top-level CLI options — this is the standard meaning of -- in POSIX-style CLIs (and is what commander.js does by default).

Actual behavior

error: unknown option '-s'

The reported "unknown option" is whichever top-level option was passed before -- (-s, -e, or --scope, depending on order) — i.e. the presence of -p later in the passthrough args corrupts parsing of earlier, valid top-level options.

Workaround

Replacing the short flag with its long form in the passthrough command avoids the bug entirely, since it's specifically the bare -p token that trips the parser:

# Works:
claude mcp add testB -s user -- docker run -i --rm --publish 127.0.0.1:8085:8085 alpine

Minimal isolation

| Command tail (after --rm) | Result |
|---|---|
| -p 127.0.0.1:8085:8085 alpine | ❌ unknown option '-s' |
| -p 8085 alpine | ❌ unknown option '-s' |
| --publish 127.0.0.1:8085:8085 alpine | ✅ works |
| (no -p/-e at all) | ✅ works |
| single -e FOO=bar (no -p) | ✅ works |

Adding -p anywhere in the passthrough args reproduces the failure regardless of whether -e is also present.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗