Yeachan-Heo/oh-my-codex · warning · Error

Unknown MCP target: ${firstArg} ${MCP_SERVE_USAGE}

Error message

Unknown MCP target: ${firstArg}
${MCP_SERVE_USAGE}

What it means

mcp-serve routes to an MCP server target by normalizing the first argument; only a fixed set of targets (keys of MCP_SERVE_LOADERS after normalization) are valid. An unrecognized first argument throws `Unknown MCP target: <arg>` together with the serve usage text.

Source

Thrown at src/cli/mcp-serve.ts:81

  if (typeof rawTarget !== "string") return null;
  const normalized = rawTarget.trim().toLowerCase();
  if (!normalized) return null;
  return MCP_SERVE_TARGET_ALIASES[normalized] ?? null;
}

export async function mcpServeCommand(
  args: string[],
  options: McpServeCommandOptions = {},
): Promise<void> {
  const firstArg = args[0];
  if (!firstArg || firstArg === "--help" || firstArg === "-h" || firstArg === "help") {
    console.log(MCP_SERVE_USAGE);
    return;
  }

  const target = normalizeOmxMcpServeTarget(firstArg);
  if (!target) {
    throw new Error(`Unknown MCP target: ${firstArg}\n${MCP_SERVE_USAGE}`);
  }

  if (args.length > 1) {
    throw new Error(`Unexpected arguments: ${args.slice(1).join(" ")}\n${MCP_SERVE_USAGE}`);
  }

  const env = options.env ?? process.env;
  const loaders = options.loaders ?? MCP_SERVE_LOADERS;
  env[MCP_ENTRYPOINT_MARKER_ENV] = target;
  await loaders[target]();
  if (options.keepProcessAlive === false) return;

  // MCP server modules start their stdio lifecycle as a top-level import side
  // effect. Keep the CLI command from returning after that import so the MCP
  // client can complete initialize and continue using the inherited stdio
  // transport. The server bootstrap owns shutdown when stdin closes, the parent
  // exits, or the transport disconnects.
  await new Promise<never>(() => undefined);

View on GitHub (pinned to 3ad79a8a6f)

Solutions

  1. Check MCP_SERVE_USAGE in the error output for the enumerated valid targets
  2. Fix the target spelling to exactly match a listed target
  3. Compare against your installed version's supported targets (they may differ from upstream docs)

Example fix

# before
mycli mcp serve allmcp

# after
mycli mcp serve omx
Defensive patterns

Strategy: validation

Validate before calling

const VALID_TARGETS = new Set(['omx']); // mirror MCP_SERVE_LOADERS keys
if (!VALID_TARGETS.has(normalizeTarget(firstArg))) {
  console.error(`Valid targets: ${[...VALID_TARGETS].join(', ')}`);
  process.exit(2);
}

Type guard

function isServeTarget(v: string, loaders: Record<string, unknown>): boolean {
  return Object.prototype.hasOwnProperty.call(loaders, normalizeOmxMcpServeTarget(v) ?? '');
}

Try / catch

try { await mcpServeCommand(args); }
catch (e) { if (/Unknown MCP target/.test(String(e))) { console.error(e.message); process.exit(2); } throw e; }

Prevention

When it happens

Trigger: Running `mcp serve <target>` where target is not one of the supported normalized targets — e.g. 'omx', 'everything', etc. typos or targets that don't exist in this build.

Common situations: Target renamed or added between versions; copy-pasting a target name from docs for a different distribution; assuming a generic 'start'/'all' target exists.

Related errors


AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27). Data as JSON: /api/errors/09de108e83883216. Report an issue: GitHub.