#!/usr/bin/env node
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
import {
  buildTransportFromSpec,
  preflightStdioSpec
} from "./chunk-EQATK2L2.js";
import {
  McpClient,
  inspectMcpServer
} from "./chunk-HIYTRCSW.js";
import "./chunk-25T6CVUP.js";
import {
  normalizeMcpConfig,
  overlayMatchedSpec,
  parseMcpSpec,
  readConfig
} from "./chunk-WMTMMSXU.js";
import "./chunk-XXC2BYTV.js";
import "./chunk-TUK7OWJA.js";

// src/cli/commands/mcp-inspect.ts
async function mcpInspectCommand(opts) {
  const parsed = parseMcpSpec(opts.spec);
  const cfg = readConfig();
  const normalized = normalizeMcpConfig(cfg);
  const matched = parsed.name ? normalized.find((s) => s.name === parsed.name) : void 0;
  const spec = overlayMatchedSpec(parsed, matched);
  if (spec.transport === "stdio") preflightStdioSpec(spec);
  const transport = buildTransportFromSpec(spec);
  const client = new McpClient({ transport });
  try {
    await client.initialize();
    const report = await inspectMcpServer(client);
    if (opts.json) {
      console.log(JSON.stringify(report, null, 2));
    } else {
      console.log(formatReport(spec.name ?? "(anon)", report));
    }
  } finally {
    await client.close();
  }
}
function formatMcpInspectFailure(err) {
  const error = err instanceof Error ? err : new Error(String(err));
  const message = error.message;
  const code = error.code;
  if (code === "ENOENT") {
    const command = message.match(/^spawn\s+([^\s]+)\s+ENOENT$/)?.[1] ?? "the command";
    return `${message} \u2014 try: install or verify \`${command}\`, then check the MCP spec's command spelling`;
  }
  if (code === "ECONNREFUSED") {
    const target = message.match(/\b(https?:\/\/\S+|\d+\.\d+\.\d+\.\d+:\d+|localhost:\d+)\b/i)?.[1];
    return `${message} \u2014 try: confirm ${target ?? "the MCP server"} is running and the host/port match the spec`;
  }
  if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
    return `${message} \u2014 try: confirm the hostname is spelled correctly and DNS resolution is working (check your network/VPN)`;
  }
  if (code === "ECONNRESET") {
    return `${message} \u2014 try: retry the request; if it keeps happening, check the server's logs for crashes or rate limits`;
  }
  if (code === "ETIMEDOUT") {
    return `${message} \u2014 try: confirm the host is reachable and no firewall/proxy is blocking the port`;
  }
  if (code === "CERT_HAS_EXPIRED" || code === "DEPTH_ZERO_SELF_SIGNED_CERT" || code === "UNABLE_TO_VERIFY_LEAF_SIGNATURE" || code === "SELF_SIGNED_CERT_IN_CHAIN") {
    return `${message} \u2014 try: renew or trust the server's TLS certificate, or point the spec at an endpoint with a valid cert`;
  }
  const httpStatus = matchTransportHttpStatus(message);
  if (httpStatus !== null) {
    return `${message}${hintForHttpStatus(httpStatus)}`;
  }
  if (/^MCP request initialize \(id=\d+\) timed out after \d+ms$/.test(message)) {
    return `${message} \u2014 try: confirm the target speaks MCP and completes the handshake before the request timeout`;
  }
  if (/^(empty MCP spec|MCP spec ".*" has name but no command)/.test(message)) {
    return `${message} \u2014 try: pass \`name=command args\` or an http(s):// URL`;
  }
  return message;
}
function matchTransportHttpStatus(message) {
  const m = message.match(/^SSE handshake \S+ → (\d{3})\b/) ?? message.match(/^MCP SSE POST \S+ failed: (\d{3})\b/) ?? message.match(/^MCP Streamable HTTP POST \S+ → (\d{3})\b/);
  return m ? Number(m[1]) : null;
}
function hintForHttpStatus(status) {
  if (status === 401) {
    return " \u2014 try: check the spec's auth header (e.g. `Authorization: Bearer \u2026`) or confirm the token isn't expired";
  }
  if (status === 403) {
    return " \u2014 try: confirm the credentials have permission to reach this MCP endpoint";
  }
  if (status === 404) {
    return " \u2014 try: confirm the endpoint path in the spec matches what the server actually exposes";
  }
  if (status >= 500 && status <= 599) {
    return " \u2014 try: retry shortly; if the failure persists, check the MCP server's logs";
  }
  return "";
}
function formatReport(nsName, r) {
  const lines = [];
  lines.push(`MCP server [${nsName}]`);
  lines.push(
    `  server     ${r.serverInfo.name || "(unknown)"}${r.serverInfo.version ? ` v${r.serverInfo.version}` : ""}`
  );
  lines.push(`  protocol   ${r.protocolVersion}`);
  const capKeys = Object.keys(r.capabilities);
  lines.push(`  caps       ${capKeys.length > 0 ? capKeys.join(", ") : "(none advertised)"}`);
  if (r.instructions) {
    lines.push(`  notes      ${r.instructions.trim().slice(0, 200)}`);
  }
  lines.push("");
  lines.push(formatSection("Tools", r.tools, toolLine));
  lines.push(formatSection("Resources", r.resources, resourceLine));
  lines.push(formatSection("Prompts", r.prompts, promptLine));
  return lines.join("\n");
}
function formatSection(title, section, render) {
  if (!section.supported) {
    return `${title}: (not supported \u2014 ${section.reason})`;
  }
  if (section.items.length === 0) {
    return `${title}: (none)`;
  }
  const lines = [`${title} (${section.items.length}):`];
  for (const item of section.items) lines.push(`  ${render(item)}`);
  return lines.join("\n");
}
function toolLine(t) {
  const desc = t.description ? ` \u2014 ${oneLine(t.description, 80)}` : "";
  return `\xB7 ${t.name}${desc}`;
}
function resourceLine(r) {
  const mime = r.mimeType ? ` [${r.mimeType}]` : "";
  return `\xB7 ${r.name}${mime}  ${r.uri}`;
}
function promptLine(p) {
  const argPart = p.arguments && p.arguments.length > 0 ? ` (${p.arguments.map((a) => a.required ? a.name : `${a.name}?`).join(", ")})` : "";
  const desc = p.description ? ` \u2014 ${oneLine(p.description, 80)}` : "";
  return `\xB7 ${p.name}${argPart}${desc}`;
}
function oneLine(s, max) {
  const flat = s.replace(/\s+/g, " ").trim();
  return flat.length <= max ? flat : `${flat.slice(0, max - 1)}\u2026`;
}
export {
  formatMcpInspectFailure,
  mcpInspectCommand
};
//# sourceMappingURL=mcp-inspect-ZMYUNFDS.js.map