diff --git a/actions/setup/js/mcp_cli_bridge.cjs b/actions/setup/js/mcp_cli_bridge.cjs
index 0ec0fc6826a..b68015a49eb 100644
--- a/actions/setup/js/mcp_cli_bridge.cjs
+++ b/actions/setup/js/mcp_cli_bridge.cjs
@@ -54,6 +54,12 @@ const KEEPALIVE_PING_INTERVAL_MS = 10000;
 /** Starting JSON-RPC ID for keepalive ping requests */
 const KEEPALIVE_PING_ID_START = 1000;
 
+/** Preferred max lines for generated CLI help output */
+const TOP_HELP_MAX_LINES = 20;
+const TOOL_HELP_MAX_LINES = 30;
+const TOOL_DESC_MAX_LEN = 90;
+const COMPACT_NAME_LINE_TARGET_WIDTH = 110;
+
 // ---------------------------------------------------------------------------
 // Audit logging
 // ---------------------------------------------------------------------------
@@ -763,20 +769,18 @@ function loadTools(toolsFile) {
  * @param {Array<{name: string, description?: string}>} tools - Tool list
  */
 function showHelp(serverName, tools) {
-  const lines = [`Usage: ${serverName} <command> [options]`, ""];
-  lines.push("Available commands:");
+  const lines = [`Usage: ${serverName} <command> [--param value ...]`, `Tip: ${serverName} <command> --help`, "", `Commands (${tools.length}):`];
   if (tools.length > 0) {
-    // Calculate column width for aligned output
-    const maxNameLen = Math.max(...tools.map(t => t.name.length));
-    for (const tool of tools) {
-      const padded = tool.name.padEnd(maxNameLen + 2);
-      lines.push(`  ${padded}${tool.description || "No description"}`);
-    }
+    const maxCommandLines = Math.max(1, TOP_HELP_MAX_LINES - lines.length);
+    lines.push(
+      ...formatCompactNameLines(
+        tools.map(tool => tool.name),
+        maxCommandLines
+      )
+    );
   } else {
     lines.push("  (tool list unavailable)");
   }
-  lines.push("");
-  lines.push(`Run '${serverName} <command> --help' for more information on a command.`);
   process.stdout.write(lines.join("\n") + "\n");
 }
 
@@ -796,40 +800,97 @@ function showToolHelp(serverName, toolName, tools) {
     return;
   }
 
-  const lines = [`Command: ${toolName}`, `Description: ${tool.description || "No description"}`];
+  const lines = [
+    `Command: ${toolName}`,
+    `Description: ${summarizeHelpText(tool.description || "No description", TOOL_DESC_MAX_LEN)}`,
+    `Usage: ${serverName} ${toolName} [--param value ...]`,
+    `JSON mode: printf '{"param":"value",...}' | ${serverName} ${toolName} .`,
+  ];
 
   const props = tool.inputSchema?.properties;
   const required = new Set(tool.inputSchema?.required || []);
   if (props && Object.keys(props).length > 0) {
     lines.push("");
-    lines.push("Options:");
-    const maxKeyLen = Math.max(...Object.keys(props).map(k => k.length));
-    for (const [key, val] of Object.entries(props)) {
-      const flagPad = `--${key}`.padEnd(maxKeyLen + 4);
-      const parts = [getTypeStr(val.type)];
-      if (required.has(key)) parts.push("(required)");
-      if (val.description) parts.push(val.description);
-      lines.push(`  ${flagPad}${parts.join(" ")}`);
+    lines.push(`Options (${Object.keys(props).length}):`);
+    const optionEntries = Object.entries(props);
+    const hasRequiredOptions = required.size > 0;
+    const maxOptionLines = Math.max(1, TOOL_HELP_MAX_LINES - lines.length - (hasRequiredOptions ? 1 : 0));
+    lines.push(
+      ...formatCompactNameLines(
+        optionEntries.map(([key]) => `--${key}${required.has(key) ? "*" : ""}`),
+        maxOptionLines
+      )
+    );
+    if (hasRequiredOptions) {
+      lines.push("Required options are marked with *.");
     }
-
-    lines.push("");
-    lines.push(`Usage: ${serverName} ${toolName} [--param value ...]`);
-    lines.push(`  or:  printf '{"param":"value",...}' | ${serverName} ${toolName} .`);
   }
 
   process.stdout.write(lines.join("\n") + "\n");
 }
 
 /**
- * Format a JSON schema type value as a short bracketed string.
+ * Collapse whitespace and trim long help text for compact output.
  *
- * @param {string|string[]|undefined} type
+ * @param {string} value
+ * @param {number} maxLen
  * @returns {string}
  */
-function getTypeStr(type) {
-  if (!type) return "(string)";
-  const types = Array.isArray(type) ? type.filter(t => t !== "null") : [type];
-  return `(${types.length > 0 ? types.join("|") : "null"})`;
+function summarizeHelpText(value, maxLen) {
+  const normalized = String(value || "")
+    .replace(/\s+/g, " ")
+    .trim();
+  if (!Number.isFinite(maxLen) || maxLen <= 0) {
+    return normalized;
+  }
+  if (normalized.length <= maxLen) {
+    return normalized;
+  }
+  return `${normalized.slice(0, maxLen - 1)}…`;
+}
+
+/**
+ * Render names as comma-separated compact lines and keep all names visible.
+ * Width is a soft target; the final line may exceed it to avoid dropping names.
+ *
+ * @param {string[]} names
+ * @param {number} maxLines - Preferred line budget; non-positive/invalid values force one compact line
+ * @returns {string[]}
+ */
+function formatCompactNameLines(names, maxLines) {
+  if (!Array.isArray(names) || names.length === 0) {
+    // Callers spread the result into help lines, so empty input should contribute no lines.
+    return [];
+  }
+  if (!Number.isFinite(maxLines) || maxLines <= 0) {
+    return [`  ${names.join(", ")}`];
+  }
+  const lines = [];
+  let current = "  ";
+  for (const name of names) {
+    const token = current.trim() ? `, ${name}` : name;
+    // A single very long name may still exceed the width target; we keep it intact.
+    const shouldStartNewLine = current.length + token.length > COMPACT_NAME_LINE_TARGET_WIDTH;
+    if (shouldStartNewLine) {
+      lines.push(current);
+      current = `  ${name}`;
+      continue;
+    }
+    current += token;
+  }
+  if (current.trim()) {
+    lines.push(current);
+  }
+  if (lines.length > maxLines) {
+    // Keep maxLines - 1 full lines and collapse the remaining names into the final allowed line.
+    const compactTail = lines
+      .slice(maxLines - 1)
+      // Trim per-line indentation before rebuilding a single indented tail line.
+      .map(line => line.trim())
+      .join(", ");
+    return [...lines.slice(0, maxLines - 1), `  ${compactTail}`];
+  }
+  return lines;
 }
 
 // ---------------------------------------------------------------------------
@@ -1130,6 +1191,8 @@ module.exports = {
   extractJSONRPCMessages,
   renderProgressMessages,
   formatResponse,
+  showHelp,
+  showToolHelp,
   hasStdinJsonPayload,
   readStdinSync,
   main,
diff --git a/actions/setup/js/mcp_cli_bridge.test.cjs b/actions/setup/js/mcp_cli_bridge.test.cjs
index 89476c12846..587bb018930 100644
--- a/actions/setup/js/mcp_cli_bridge.test.cjs
+++ b/actions/setup/js/mcp_cli_bridge.test.cjs
@@ -1,6 +1,6 @@
 import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
 
-import { formatResponse, hasStdinJsonPayload, parseToolArgs, readStdinSync } from "./mcp_cli_bridge.cjs";
+import { formatResponse, hasStdinJsonPayload, parseToolArgs, readStdinSync, showHelp, showToolHelp } from "./mcp_cli_bridge.cjs";
 
 describe("mcp_cli_bridge.cjs", () => {
   let originalCore;
@@ -212,6 +212,121 @@ describe("mcp_cli_bridge.cjs", () => {
     expect(process.exitCode).toBe(0);
   });
 
+  it("keeps top-level help compact for many commands", () => {
+    const tools = Array.from({ length: 25 }, (_, i) => ({
+      name: `tool_${i + 1}`,
+      description: `Description for command ${i + 1} that is intentionally verbose for truncation checks.`,
+    }));
+
+    showHelp("safeoutputs", tools);
+
+    const outputLines = stdoutChunks.join("").trimEnd().split("\n");
+    const output = outputLines.join("\n");
+    expect(outputLines.length).toBeLessThanOrEqual(20);
+    expect(output).not.toMatch(/\.\.\. \+\d+ more command\(s\)/);
+    for (const tool of tools) {
+      expect(output).toContain(tool.name);
+    }
+  });
+
+  it("does not truncate top-level help when commands exactly fit the line budget", () => {
+    const tools = Array.from({ length: 14 }, (_, i) => ({
+      name: `tool_${i + 1}`,
+      description: `Description for command ${i + 1}.`,
+    }));
+
+    showHelp("safeoutputs", tools);
+
+    const outputLines = stdoutChunks.join("").trimEnd().split("\n");
+    const output = outputLines.join("\n");
+    expect(outputLines.length).toBeLessThanOrEqual(20);
+    expect(output).not.toMatch(/\.\.\. \+\d+ more command\(s\)/);
+    for (const tool of tools) {
+      expect(output).toContain(tool.name);
+    }
+  });
+
+  it("keeps command help compact for many options", () => {
+    const properties = {};
+    for (let i = 1; i <= 24; i++) {
+      properties[`field_${i}`] = { type: "string", description: `Field ${i} description with additional details for truncation.` };
+    }
+
+    showToolHelp("safeoutputs", "create_issue", [
+      {
+        name: "create_issue",
+        description: "Create an issue with many available fields and optional metadata.",
+        inputSchema: {
+          properties,
+          required: ["field_1", "field_2"],
+        },
+      },
+    ]);
+
+    const outputLines = stdoutChunks.join("").trimEnd().split("\n");
+    const output = outputLines.join("\n");
+    expect(outputLines.length).toBeLessThanOrEqual(30);
+    expect(output).not.toMatch(/\.\.\. \+\d+ more option\(s\)/);
+    expect(output).toContain("Required options are marked with *.");
+    for (let i = 1; i <= 24; i++) {
+      expect(output).toContain(`--field_${i}`);
+    }
+    expect(output).toContain("--field_1*");
+    expect(output).toContain("--field_2*");
+  });
+
+  it("does not truncate command help when options exactly fit the line budget", () => {
+    const properties = {};
+    for (let i = 1; i <= 13; i++) {
+      properties[`field_${i}`] = { type: "string", description: `Field ${i}.` };
+    }
+
+    showToolHelp("safeoutputs", "create_issue", [
+      {
+        name: "create_issue",
+        description: "Create an issue.",
+        inputSchema: {
+          properties,
+          required: ["field_1"],
+        },
+      },
+    ]);
+
+    const outputLines = stdoutChunks.join("").trimEnd().split("\n");
+    const output = outputLines.join("\n");
+    expect(outputLines.length).toBeLessThanOrEqual(30);
+    expect(output).not.toMatch(/\.\.\. \+\d+ more option\(s\)/);
+    expect(output).toContain("Required options are marked with *.");
+    for (let i = 1; i <= 13; i++) {
+      expect(output).toContain(`--field_${i}`);
+    }
+  });
+
+  it("keeps required note when required options are in the compact list", () => {
+    const properties = {};
+    for (let i = 1; i <= 24; i++) {
+      properties[`field_${i}`] = { type: "string", description: `Field ${i}.` };
+    }
+
+    showToolHelp("safeoutputs", "create_issue", [
+      {
+        name: "create_issue",
+        description: "Create an issue.",
+        inputSchema: {
+          properties,
+          required: ["field_23", "field_24"],
+        },
+      },
+    ]);
+
+    const outputLines = stdoutChunks.join("").trimEnd().split("\n");
+    const output = outputLines.join("\n");
+    expect(output).not.toMatch(/\.\.\. \+\d+ more option\(s\)/);
+    expect(output).toContain("Required options are marked with *.");
+    expect(output).toContain("--field_23*");
+    expect(output).toContain("--field_24*");
+  });
+
   describe("stdin placeholder removed — '-' is always a literal value", () => {
     it("passes '--key -' as literal '-' (space-separated form)", () => {
       const schemaProperties = { body: { type: "string" } };
