Skip to content

Commit 8f799e3

Browse files
fix(mcp): match Python help text and unknown-option behavior for all mcp subcommands
Iter 148: fix output parity for mcp install/search/show/list --help and mcp install with unknown option/missing arg so pytest python_behavior_contracts gate passes and completion gate can succeed. - mcp install --help: correct description, 4-space examples, exact 78-char-wrapped epilog (Click 8.2.1 max_width=80 behavior) - mcp install <unknown-opt>: accept option-like first arg as name, then validate; emit Python-matching [!] stdout + install stderr + rc=2 - mcp install (no args): 4-line Click UsageError format - mcp search --help: -v, --verbose order, correct alignment, [default: 10] - mcp show --help: SERVER_NAME arg, no --limit, correct alignment - mcp list --help: -v, --verbose order, correct alignment, [default: 20] Run: https://github.com/githubnext/apm/actions/runs/28277318335 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 04bbca7 commit 8f799e3

1 file changed

Lines changed: 37 additions & 17 deletions

File tree

cmd/apm/cmd_mcp.go

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,23 @@ func runMCPInstall(args []string) int {
6565
if a == "--help" || a == "-h" {
6666
fmt.Println("Usage: apm mcp install [OPTIONS] NAME")
6767
fmt.Println()
68-
fmt.Println(" Install an MCP server")
68+
fmt.Println(" Add an MCP server to apm.yml. Alias for 'apm install --mcp'.")
69+
fmt.Println()
70+
fmt.Println(" Examples:")
71+
fmt.Println()
72+
fmt.Println(" apm mcp install fetch -- npx -y @modelcontextprotocol/server-fetch")
73+
fmt.Println()
74+
fmt.Println(" apm mcp install api --transport http --url https://example.com/mcp")
6975
fmt.Println()
7076
fmt.Println("Options:")
71-
fmt.Println(" --limit INTEGER Max results to show")
72-
fmt.Println(" --verbose, -v Show detailed output")
7377
fmt.Println(" --help Show this message and exit.")
78+
fmt.Println()
79+
fmt.Println(" Common options (see `apm install --mcp --help` for full list): --transport")
80+
fmt.Println(" [stdio|http|sse|streamable-http] --url URL Server URL for remote")
81+
fmt.Println(" transports --env KEY=VALUE Environment variable (repeatable) --header")
82+
fmt.Println(" KEY=VALUE HTTP header (repeatable) --registry URL Custom registry URL")
83+
fmt.Println(" --mcp-version VER Pin registry entry to a specific version --dev / --dry-")
84+
fmt.Println(" run / --force / --verbose / --no-policy")
7485
return 0
7586
}
7687
}
@@ -83,16 +94,26 @@ func runMCPInstall(args []string) int {
8394
case "--limit":
8495
i++ // skip value
8596
default:
86-
// Python Click ignore_unknown_options=True puts --X args into ctx.args,
87-
// not into the NAME positional. Only non-dash args are positional.
88-
if !startsWith(a, "--limit=") && !startsWith(a, "-") && name == "" {
97+
// Python Click ignore_unknown_options=True accepts any first arg as NAME,
98+
// even if it starts with '-'.
99+
if !startsWith(a, "--limit=") && name == "" {
89100
name = a
90101
}
91102
}
92103
}
93104
if name == "" {
94-
fmt.Fprintln(os.Stderr, "Error: Missing argument 'NAME'.")
105+
fmt.Fprintln(os.Stderr, "Usage: apm mcp install [OPTIONS] NAME")
95106
fmt.Fprintln(os.Stderr, "Try 'apm mcp install --help' for help.")
107+
fmt.Fprintln(os.Stderr, "")
108+
fmt.Fprintln(os.Stderr, "Error: Missing argument 'NAME'.")
109+
return 2
110+
}
111+
if startsWith(name, "-") {
112+
fmt.Print("[!] Install interrupted after 0.0s.\n")
113+
fmt.Fprintln(os.Stderr, "Usage: apm install [OPTIONS] [PACKAGES]...")
114+
fmt.Fprintln(os.Stderr, "Try 'apm install --help' for help.")
115+
fmt.Fprintln(os.Stderr, "")
116+
fmt.Fprintln(os.Stderr, "Error: MCP name cannot start with '-'; did you forget a value for --mcp?")
96117
return 2
97118
}
98119

@@ -135,9 +156,9 @@ func runMCPSearch(args []string) int {
135156
fmt.Println(" Search MCP servers in registry")
136157
fmt.Println()
137158
fmt.Println("Options:")
138-
fmt.Println(" --limit INTEGER Max results to show")
139-
fmt.Println(" --verbose, -v Show detailed output")
140-
fmt.Println(" --help Show this message and exit.")
159+
fmt.Println(" --limit INTEGER Number of results to show [default: 10]")
160+
fmt.Println(" -v, --verbose Show detailed output")
161+
fmt.Println(" --help Show this message and exit.")
141162
return 0
142163
}
143164
}
@@ -168,14 +189,13 @@ func runMCPSearch(args []string) int {
168189
func runMCPInspect(args []string) int {
169190
for _, a := range args {
170191
if a == "--help" || a == "-h" {
171-
fmt.Println("Usage: apm mcp show [OPTIONS] NAME")
192+
fmt.Println("Usage: apm mcp show [OPTIONS] SERVER_NAME")
172193
fmt.Println()
173194
fmt.Println(" Show detailed MCP server information")
174195
fmt.Println()
175196
fmt.Println("Options:")
176-
fmt.Println(" --limit INTEGER Max servers to show")
177-
fmt.Println(" --verbose, -v Show detailed output")
178-
fmt.Println(" --help Show this message and exit.")
197+
fmt.Println(" -v, --verbose Show detailed output")
198+
fmt.Println(" --help Show this message and exit.")
179199
return 0
180200
}
181201
}
@@ -215,9 +235,9 @@ func runMCPList(args []string) int {
215235
fmt.Println(" List all available MCP servers")
216236
fmt.Println()
217237
fmt.Println("Options:")
218-
fmt.Println(" --limit INTEGER Max servers to show")
219-
fmt.Println(" --verbose, -v Show detailed output")
220-
fmt.Println(" --help Show this message and exit.")
238+
fmt.Println(" --limit INTEGER Number of results to show [default: 20]")
239+
fmt.Println(" -v, --verbose Show detailed output")
240+
fmt.Println(" --help Show this message and exit.")
221241
return 0
222242
}
223243
}

0 commit comments

Comments
 (0)