#!/usr/bin/env node

// packages/tiny-stdio-mcp-test-server/src/cli.ts
import { Command } from "commander";
import { existsSync, readFileSync, writeFileSync } from "node:fs";
import { access } from "node:fs/promises";

// packages/tiny-stdio-mcp-test-server/package.json
var package_default = {
  name: "tiny-stdio-mcp-test-server",
  version: "0.1.0",
  description: "Test MCP server with example tools for integration testing",
  type: "module",
  main: "dist/index.js",
  types: "dist/index.d.ts",
  bin: {
    "tiny-stdio-mcp-test-server": "dist/cli.js"
  },
  exports: {
    ".": {
      types: "./dist/index.d.ts",
      import: "./dist/index.js"
    }
  },
  scripts: {
    build: "node ../../scripts/guard-package-dist.mjs && tsc",
    prepack: "node ../../scripts/set-bin-executable.mjs",
    prepublishOnly: "tsc"
  },
  files: [
    "dist"
  ],
  engines: {
    node: ">=20"
  },
  repository: {
    type: "git",
    url: "https://github.com/poe-platform/poe-code.git",
    directory: "packages/tiny-stdio-mcp-test-server"
  },
  license: "MIT",
  keywords: [
    "mcp",
    "model-context-protocol",
    "test",
    "server"
  ],
  dependencies: {
    "tiny-stdio-mcp-server": "^0.1.0",
    commander: "^14.0.3"
  },
  devDependencies: {
    "@modelcontextprotocol/sdk": "^1.25.3"
  }
};

// packages/tiny-stdio-mcp-server/src/server.ts
import * as readline from "readline";
import AjvModule from "ajv";
import uriTemplateParser from "uri-template";
import UriTemplate from "uri-template-lite";

// packages/tiny-stdio-mcp-server/src/types.ts
var JSON_RPC_ERROR_CODES = Object.freeze({
  PARSE_ERROR: -32700,
  INVALID_REQUEST: -32600,
  METHOD_NOT_FOUND: -32601,
  INVALID_PARAMS: -32602,
  INTERNAL_ERROR: -32603,
  RESOURCE_NOT_FOUND: -32002
});
var ToolError = class extends Error {
  constructor(code, message) {
    if (!Number.isFinite(code)) {
      throw new Error("ToolError code must be a finite number");
    }
    super(message);
    this.code = code;
    this.name = "ToolError";
  }
  code;
};

// packages/tiny-stdio-mcp-server/src/jsonrpc.ts
function parseMessage(line) {
  let parsed;
  try {
    parsed = JSON.parse(line);
  } catch {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.PARSE_ERROR,
        message: "Parse error"
      },
      id: null
    };
  }
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      },
      id: null
    };
  }
  const obj = parsed;
  const hasId = "id" in obj;
  const id = typeof obj.id === "string" ? obj.id : typeof obj.id === "number" && Number.isFinite(obj.id) ? obj.id : obj.id === null ? null : null;
  if ("params" in obj && (typeof obj.params !== "object" || obj.params === null)) {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      },
      id
    };
  }
  if (obj.jsonrpc !== "2.0") {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      },
      id
    };
  }
  if (typeof obj.method !== "string") {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      },
      id
    };
  }
  if (!hasId) {
    return {
      success: true,
      isNotification: true,
      request: {
        jsonrpc: "2.0",
        method: obj.method,
        params: obj.params
      }
    };
  }
  if (obj.id !== null && id === null) {
    return {
      success: false,
      error: {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      },
      id: null
    };
  }
  return {
    success: true,
    isNotification: false,
    request: {
      jsonrpc: "2.0",
      id,
      method: obj.method,
      params: obj.params
    }
  };
}
function formatSuccessResponse(id, result) {
  const response = {
    jsonrpc: "2.0",
    id,
    result
  };
  return JSON.stringify(response);
}
function formatErrorResponse(id, error) {
  const response = {
    jsonrpc: "2.0",
    id,
    error
  };
  return JSON.stringify(response);
}

// packages/tiny-stdio-mcp-server/src/content/file-type.ts
function fileTypeFromBuffer(data) {
  if (data.length < 12) {
    return void 0;
  }
  if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71 && data[4] === 13 && data[5] === 10 && data[6] === 26 && data[7] === 10) {
    return { mime: "image/png", ext: "png" };
  }
  if (data[0] === 255 && data[1] === 216 && data[2] === 255) {
    return { mime: "image/jpeg", ext: "jpg" };
  }
  if (data[0] === 71 && data[1] === 73 && data[2] === 70 && data[3] === 56) {
    return { mime: "image/gif", ext: "gif" };
  }
  if (data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70 && data[8] === 87 && data[9] === 69 && data[10] === 66 && data[11] === 80) {
    return { mime: "image/webp", ext: "webp" };
  }
  if (data[0] === 255 && (data[1] === 251 || data[1] === 250) || data[0] === 73 && data[1] === 68 && data[2] === 51) {
    return { mime: "audio/mpeg", ext: "mp3" };
  }
  if (data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70 && data[8] === 87 && data[9] === 65 && data[10] === 86 && data[11] === 69) {
    return { mime: "audio/wav", ext: "wav" };
  }
  if (data[0] === 79 && data[1] === 103 && data[2] === 103 && data[3] === 83) {
    return { mime: "audio/ogg", ext: "ogg" };
  }
  if (data[4] === 102 && data[5] === 116 && data[6] === 121 && data[7] === 112 && data[8] === 77 && data[9] === 52 && data[10] === 65) {
    return { mime: "audio/mp4", ext: "m4a" };
  }
  if (data[4] === 102 && data[5] === 116 && data[6] === 121 && data[7] === 112) {
    return { mime: "video/mp4", ext: "mp4" };
  }
  if (data[0] === 26 && data[1] === 69 && data[2] === 223 && data[3] === 163) {
    return { mime: "video/webm", ext: "webm" };
  }
  return void 0;
}

// packages/tiny-stdio-mcp-server/src/content/mime.ts
function parseContentType(value) {
  if (!value) {
    return {};
  }
  const [rawMimeType, ...parameters] = value.split(";");
  const mimeType = rawMimeType?.trim().toLowerCase();
  const charsetParameter = parameters.find(
    (parameter) => parameter.trim().toLowerCase().startsWith("charset=")
  );
  const rawCharset = charsetParameter?.split("=", 2)[1]?.trim();
  const charset = rawCharset?.startsWith('"') && rawCharset.endsWith('"') ? rawCharset.slice(1, -1) : rawCharset;
  return {
    ...mimeType ? { mimeType } : {},
    ...charset ? { charset } : {}
  };
}
function assertBase64(value) {
  if (value.length % 4 !== 0) {
    throw new Error("Invalid base64 content");
  }
  let paddingStarted = false;
  let paddingCount = 0;
  for (const character of value) {
    if (character === "=") {
      paddingStarted = true;
      paddingCount += 1;
      continue;
    }
    const code = character.charCodeAt(0);
    const isValid = code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || character === "+" || character === "/";
    if (!isValid || paddingStarted) {
      throw new Error("Invalid base64 content");
    }
  }
  if (paddingCount > 2) {
    throw new Error("Invalid base64 content");
  }
}
function safeRemoteLabel(url) {
  try {
    const parsed = new URL(url);
    return `${parsed.origin}${parsed.pathname}`;
  } catch {
    return "remote resource";
  }
}

// packages/tiny-stdio-mcp-server/src/content/remote.ts
var DEFAULT_FROM_URL_MAX_BYTES = 5 * 1024 * 1024;
function resolveMaxBytes(options) {
  const maxBytes = options?.maxBytes ?? DEFAULT_FROM_URL_MAX_BYTES;
  if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
    throw new Error("maxBytes must be a positive integer");
  }
  return maxBytes;
}
function createSizeError(kind, url, maxBytes) {
  return new Error(`Remote ${kind} from ${safeRemoteLabel(url)} exceeds maximum size of ${maxBytes} bytes`);
}
function readContentLength(response) {
  const rawContentLength = response.headers.get("content-length");
  if (typeof rawContentLength !== "string") {
    return void 0;
  }
  const contentLength = Number(rawContentLength.trim());
  if (!Number.isSafeInteger(contentLength) || contentLength < 0) {
    return void 0;
  }
  return contentLength;
}
function combineChunks(chunks, totalBytes) {
  const combined = new Uint8Array(totalBytes);
  let offset = 0;
  for (const chunk of chunks) {
    combined.set(chunk, offset);
    offset += chunk.byteLength;
  }
  return combined;
}
async function readStreamBytes(body, kind, url, maxBytes) {
  const reader = body.getReader();
  const chunks = [];
  let totalBytes = 0;
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        return combineChunks(chunks, totalBytes);
      }
      totalBytes += value.byteLength;
      if (totalBytes > maxBytes) {
        await reader.cancel().catch(() => void 0);
        throw createSizeError(kind, url, maxBytes);
      }
      chunks.push(value);
    }
  } finally {
    reader.releaseLock();
  }
}
async function readRemoteBytes(response, kind, url, options) {
  const maxBytes = resolveMaxBytes(options);
  const contentLength = readContentLength(response);
  if (contentLength !== void 0 && contentLength > maxBytes) {
    throw createSizeError(kind, url, maxBytes);
  }
  if (response.body) {
    return readStreamBytes(response.body, kind, url, maxBytes);
  }
  const arrayBuffer = await response.arrayBuffer();
  if (arrayBuffer.byteLength > maxBytes) {
    throw createSizeError(kind, url, maxBytes);
  }
  return new Uint8Array(arrayBuffer);
}

// packages/tiny-stdio-mcp-server/src/content/image.ts
var SUPPORTED_IMAGE_MIMES = /* @__PURE__ */ new Set([
  "image/png",
  "image/jpeg",
  "image/gif",
  "image/webp"
]);
var Image = class _Image {
  constructor(base64Data, mimeType) {
    this.base64Data = base64Data;
    this.mimeType = mimeType;
  }
  base64Data;
  mimeType;
  static async fromUrl(url, options) {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch image from ${safeRemoteLabel(url)}: ${response.status} ${response.statusText}`);
    }
    const data = await readRemoteBytes(response, "image", url, options);
    const detected = fileTypeFromBuffer(data);
    let mimeType;
    if (detected && SUPPORTED_IMAGE_MIMES.has(detected.mime)) {
      mimeType = detected.mime;
    } else {
      const contentType = parseContentType(response.headers.get("content-type")).mimeType;
      if (contentType && SUPPORTED_IMAGE_MIMES.has(contentType)) {
        mimeType = contentType;
      } else {
        throw new Error(`Unable to detect image MIME type from ${safeRemoteLabel(url)}`);
      }
    }
    const base64 = Buffer.from(data).toString("base64");
    return new _Image(base64, mimeType);
  }
  static fromBytes(data, format) {
    let mimeType;
    if (format) {
      mimeType = (format.includes("/") ? format : `image/${format}`).toLowerCase();
      if (!SUPPORTED_IMAGE_MIMES.has(mimeType)) {
        throw new Error(`Unsupported image MIME type: ${mimeType}`);
      }
    } else {
      const detected = fileTypeFromBuffer(data);
      if (!detected || !SUPPORTED_IMAGE_MIMES.has(detected.mime)) {
        throw new Error("Unable to detect image MIME type from bytes");
      }
      mimeType = detected.mime;
    }
    const base64 = Buffer.from(data).toString("base64");
    return new _Image(base64, mimeType);
  }
  static fromBase64(base64, mimeType) {
    assertBase64(base64);
    const normalizedMimeType = mimeType.toLowerCase();
    if (!SUPPORTED_IMAGE_MIMES.has(normalizedMimeType)) {
      throw new Error(`Unsupported image MIME type: ${normalizedMimeType}`);
    }
    return new _Image(base64, normalizedMimeType);
  }
  toContentBlock() {
    return {
      type: "image",
      data: this.base64Data,
      mimeType: this.mimeType
    };
  }
};

// packages/tiny-stdio-mcp-server/src/content/audio.ts
var SUPPORTED_AUDIO_MIMES = /* @__PURE__ */ new Set([
  "audio/mpeg",
  "audio/wav",
  "audio/ogg",
  "audio/mp4"
]);
var AUDIO_FORMAT_MAP = {
  mp3: "audio/mpeg",
  wav: "audio/wav",
  ogg: "audio/ogg",
  m4a: "audio/mp4",
  mpeg: "audio/mpeg"
};
var Audio = class _Audio {
  constructor(base64Data, mimeType) {
    this.base64Data = base64Data;
    this.mimeType = mimeType;
  }
  base64Data;
  mimeType;
  static async fromUrl(url, options) {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch audio from ${safeRemoteLabel(url)}: ${response.status} ${response.statusText}`);
    }
    const data = await readRemoteBytes(response, "audio", url, options);
    const detected = fileTypeFromBuffer(data);
    let mimeType;
    if (detected && SUPPORTED_AUDIO_MIMES.has(detected.mime)) {
      mimeType = detected.mime;
    } else {
      const contentType = parseContentType(response.headers.get("content-type")).mimeType;
      if (contentType && SUPPORTED_AUDIO_MIMES.has(contentType)) {
        mimeType = contentType;
      } else {
        throw new Error(`Unable to detect audio MIME type from ${safeRemoteLabel(url)}`);
      }
    }
    const base64 = Buffer.from(data).toString("base64");
    return new _Audio(base64, mimeType);
  }
  static fromBytes(data, format) {
    let mimeType;
    if (format) {
      if (format.includes("/")) {
        mimeType = format.toLowerCase();
      } else {
        mimeType = AUDIO_FORMAT_MAP[format.toLowerCase()] || `audio/${format}`;
      }
      if (!SUPPORTED_AUDIO_MIMES.has(mimeType)) {
        throw new Error(`Unsupported audio MIME type: ${mimeType}`);
      }
    } else {
      const detected = fileTypeFromBuffer(data);
      if (!detected || !SUPPORTED_AUDIO_MIMES.has(detected.mime)) {
        throw new Error("Unable to detect audio MIME type from bytes");
      }
      mimeType = detected.mime;
    }
    const base64 = Buffer.from(data).toString("base64");
    return new _Audio(base64, mimeType);
  }
  static fromBase64(base64, mimeType) {
    assertBase64(base64);
    const normalizedMimeType = mimeType.toLowerCase();
    if (!SUPPORTED_AUDIO_MIMES.has(normalizedMimeType)) {
      throw new Error(`Unsupported audio MIME type: ${normalizedMimeType}`);
    }
    return new _Audio(base64, normalizedMimeType);
  }
  toContentBlock() {
    return {
      type: "audio",
      data: this.base64Data,
      mimeType: this.mimeType
    };
  }
};

// packages/tiny-stdio-mcp-server/src/content/file.ts
function isTextMimeType(mimeType) {
  const normalizedMimeType = mimeType.toLowerCase();
  return normalizedMimeType.startsWith("text/") || normalizedMimeType === "application/json" || normalizedMimeType.endsWith("+json") || normalizedMimeType === "application/xml" || normalizedMimeType.endsWith("+xml") || normalizedMimeType === "application/javascript" || normalizedMimeType === "application/typescript";
}
var File = class _File {
  constructor(data, mimeType, isText, name, charset = "utf-8") {
    this.data = data;
    this.mimeType = mimeType;
    this.isText = isText;
    this.name = name;
    this.charset = charset;
  }
  data;
  mimeType;
  isText;
  name;
  charset;
  static async fromUrl(url, options) {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`Failed to fetch file from ${safeRemoteLabel(url)}: ${response.status} ${response.statusText}`);
    }
    const data = await readRemoteBytes(response, "file", url, options);
    const detected = fileTypeFromBuffer(data);
    let mimeType;
    if (detected) {
      mimeType = detected.mime;
    } else {
      const contentType2 = parseContentType(response.headers.get("content-type"));
      if (contentType2.mimeType) {
        mimeType = contentType2.mimeType;
      } else {
        throw new Error(`Unable to detect MIME type from ${safeRemoteLabel(url)}`);
      }
    }
    const contentType = parseContentType(response.headers.get("content-type"));
    const charset = contentType.charset ?? "utf-8";
    let isText = isTextMimeType(mimeType);
    if (isText) {
      try {
        new TextDecoder(charset);
      } catch {
        isText = false;
      }
    }
    const name = new URL(url).pathname.split("/").pop() || "file";
    return new _File(data, mimeType, isText, name, charset);
  }
  static fromBytes(data, mimeType) {
    const isText = isTextMimeType(mimeType);
    return new _File(data, mimeType, isText);
  }
  static fromText(text, mimeType = "text/plain") {
    return new _File(text, mimeType, isTextMimeType(mimeType));
  }
  static fromBase64(base64, mimeType) {
    assertBase64(base64);
    const data = Buffer.from(base64, "base64");
    const isText = isTextMimeType(mimeType);
    return new _File(new Uint8Array(data), mimeType, isText);
  }
  toContentBlock() {
    const uri = this.name ? `file:///${this.name}` : "file:///data";
    if (this.isText) {
      let text;
      if (typeof this.data === "string") {
        text = this.data;
      } else {
        text = new TextDecoder(this.charset).decode(this.data);
      }
      return {
        type: "resource",
        resource: {
          uri,
          mimeType: this.mimeType,
          text
        }
      };
    } else {
      let blob;
      if (typeof this.data === "string") {
        blob = Buffer.from(this.data).toString("base64");
      } else {
        blob = Buffer.from(this.data).toString("base64");
      }
      return {
        type: "resource",
        resource: {
          uri,
          mimeType: this.mimeType,
          blob
        }
      };
    }
  }
};

// packages/tiny-stdio-mcp-server/src/content/convert.ts
function convertSingleValue(value) {
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
    return { type: "text", text: String(value) };
  }
  if (value === null) {
    return { type: "text", text: "null" };
  }
  if (value instanceof Image) {
    return value.toContentBlock();
  }
  if (value instanceof Audio) {
    return value.toContentBlock();
  }
  if (value instanceof File) {
    return value.toContentBlock();
  }
  if (isContentBlock(value)) {
    return value;
  }
  return { type: "text", text: JSON.stringify(value) };
}
function toContentBlocks(result) {
  if (result === void 0) {
    return [];
  }
  if (Array.isArray(result)) {
    return result.flatMap((item) => toContentBlocks(item));
  }
  return [convertSingleValue(result)];
}
function isContentBlock(value) {
  if (!hasOwnProperty(value, "type") || typeof value.type !== "string") {
    return false;
  }
  if (value.type === "text") {
    return hasOwnProperty(value, "text") && typeof value.text === "string";
  }
  if (value.type === "image" || value.type === "audio") {
    return hasOwnProperty(value, "data") && typeof value.data === "string" && hasOwnProperty(value, "mimeType") && typeof value.mimeType === "string";
  }
  if (value.type !== "resource" || !hasOwnProperty(value, "resource")) {
    return false;
  }
  const resource = value.resource;
  return typeof resource === "object" && resource !== null && hasOwnProperty(resource, "uri") && typeof resource.uri === "string" && (!hasOwnProperty(resource, "mimeType") || typeof resource.mimeType === "string") && (hasOwnProperty(resource, "text") && typeof resource.text === "string" || hasOwnProperty(resource, "blob") && typeof resource.blob === "string");
}
function hasOwnProperty(value, name) {
  return Object.prototype.hasOwnProperty.call(value, name);
}

// packages/tiny-stdio-mcp-server/src/server.ts
var PROTOCOL_VERSION = "2025-11-25";
var SUPPORTED_PROTOCOL_VERSIONS = /* @__PURE__ */ new Set([
  "2025-03-26",
  "2025-06-18",
  PROTOCOL_VERSION
]);
function createServer(options) {
  const Ajv = "default" in AjvModule ? AjvModule.default : AjvModule;
  const jsonSchemaValidator = new Ajv({ strict: false });
  const supportNotifications = options.supportNotifications !== false;
  const supportResourceSubscriptions = options.supportResourceSubscriptions !== false;
  const tools = /* @__PURE__ */ new Map();
  const prompts = /* @__PURE__ */ new Map();
  const resources = /* @__PURE__ */ new Map();
  const resourceTemplates = /* @__PURE__ */ new Map();
  const notificationListeners = /* @__PURE__ */ new Set();
  const connectionNotificationListeners = /* @__PURE__ */ new Map();
  const defaultLifecycle = {
    initialized: false,
    initializeAccepted: false,
    notificationReady: false,
    resourceSubscriptions: /* @__PURE__ */ new Set()
  };
  const messageLifecycles = /* @__PURE__ */ new Set([defaultLifecycle]);
  const handleMessageWithLifecycle = async (method, lifecycle, params) => {
    if (method === "ping") {
      return { result: {} };
    }
    if (method === "initialize") {
      lifecycle.initializeAccepted = true;
      lifecycle.initialized = true;
      lifecycle.notificationReady = false;
      const requestedProtocol = typeof params?.protocolVersion === "string" ? params.protocolVersion : void 0;
      const result = {
        protocolVersion: requestedProtocol !== void 0 && SUPPORTED_PROTOCOL_VERSIONS.has(requestedProtocol) ? requestedProtocol : PROTOCOL_VERSION,
        capabilities: {
          tools: {
            ...supportNotifications ? { listChanged: true } : {}
          },
          prompts: {
            ...supportNotifications ? { listChanged: true } : {}
          },
          resources: {
            ...supportNotifications ? { listChanged: true } : {},
            ...supportResourceSubscriptions ? { subscribe: true } : {}
          }
        },
        serverInfo: {
          name: options.name,
          version: options.version
        }
      };
      return { result };
    }
    if (method === "notifications/initialized") {
      if (!lifecycle.initializeAccepted) {
        return {
          error: {
            code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
            message: "Server not initialized"
          }
        };
      }
      lifecycle.notificationReady = true;
      return { result: void 0 };
    }
    if (!lifecycle.initialized) {
      return {
        error: {
          code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
          message: "Server not initialized"
        }
      };
    }
    if (method === "tools/list") {
      const toolList = [];
      for (const tool of tools.values()) {
        const descriptor = { ...tool };
        delete descriptor.handler;
        toolList.push({
          ...descriptor
        });
      }
      return { result: { tools: toolList } };
    }
    if (method === "tools/call") {
      const toolName = params?.name;
      if (!toolName) {
        return {
          error: {
            code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
            message: "Tool name required"
          }
        };
      }
      const tool = tools.get(toolName);
      if (!tool) {
        return {
          error: {
            code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
            message: `Tool not found: ${toolName}`
          }
        };
      }
      const toolArgs = params?.arguments ?? {};
      if (options.validateToolArguments !== false && !jsonSchemaValidator.validate(tool.inputSchema, toolArgs)) {
        return {
          error: {
            code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
            message: "Invalid tool arguments"
          }
        };
      }
      try {
        const handlerResult = await tool.handler(toolArgs);
        const result = normalizeToolResult(handlerResult, tool.outputSchema);
        if (tool.outputSchema !== void 0 && !jsonSchemaValidator.validate(tool.outputSchema, result.structuredContent)) {
          throw new ToolError(
            JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
            "Invalid structured tool result"
          );
        }
        return { result };
      } catch (err) {
        if (err instanceof ToolError) {
          return {
            error: {
              code: err.code,
              message: err.message
            }
          };
        }
        const errorMessage = err instanceof Error ? err.message : String(err);
        const result = {
          content: [{ type: "text", text: `Error: ${errorMessage}` }],
          isError: true
        };
        return { result };
      }
    }
    if (method === "prompts/list") {
      return {
        result: {
          prompts: [...prompts.values()].map(({ handler: _handler, ...prompt }) => prompt)
        }
      };
    }
    if (method === "prompts/get") {
      const promptName = typeof params?.name === "string" ? params.name : void 0;
      if (promptName === void 0) {
        return invalidParams("Prompt name required");
      }
      const prompt = prompts.get(promptName);
      if (prompt === void 0) {
        return invalidParams(`Prompt not found: ${promptName}`);
      }
      const args = toStringArguments(params?.arguments);
      if (args === void 0 || !hasRequiredPromptArguments(prompt, args)) {
        return invalidParams("Invalid prompt arguments");
      }
      try {
        const result = await prompt.handler(args);
        if (!isGetPromptResult(result)) {
          return internalError("Invalid prompt result");
        }
        return { result };
      } catch (error) {
        return internalError(toErrorMessage(error));
      }
    }
    if (method === "resources/list") {
      return {
        result: {
          resources: [...resources.values()].map(({ handler: _handler, ...resource }) => resource)
        }
      };
    }
    if (method === "resources/templates/list") {
      return {
        result: {
          resourceTemplates: [...resourceTemplates.values()].map(
            ({ handler: _handler, ...resourceTemplate }) => resourceTemplate
          )
        }
      };
    }
    if (method === "resources/read") {
      const uri = typeof params?.uri === "string" ? params.uri : void 0;
      if (uri === void 0 || !isValidUri(uri)) {
        return invalidParams("Resource URI required");
      }
      const resource = findReadableResource(uri, resources, resourceTemplates);
      if (resource === void 0) {
        return resourceNotFound(uri);
      }
      try {
        const result = await resource.handler(uri);
        if (!isReadResourceResult(result)) {
          return internalError("Invalid resource result");
        }
        return { result };
      } catch (error) {
        return internalError(toErrorMessage(error));
      }
    }
    if (method === "resources/subscribe" || method === "resources/unsubscribe") {
      if (!supportResourceSubscriptions) {
        return {
          error: {
            code: JSON_RPC_ERROR_CODES.METHOD_NOT_FOUND,
            message: "Method not found"
          }
        };
      }
      const uri = typeof params?.uri === "string" ? params.uri : void 0;
      if (uri === void 0 || !isValidUri(uri)) {
        return invalidParams("Resource URI required");
      }
      if (method === "resources/subscribe" && findReadableResource(uri, resources, resourceTemplates) === void 0) {
        return resourceNotFound(uri);
      }
      if (method === "resources/subscribe") {
        lifecycle.resourceSubscriptions.add(uri);
      } else {
        lifecycle.resourceSubscriptions.delete(uri);
      }
      return { result: {} };
    }
    return {
      error: {
        code: JSON_RPC_ERROR_CODES.METHOD_NOT_FOUND,
        message: "Method not found"
      }
    };
  };
  const createMessageSession = (listener) => {
    const lifecycle = {
      initialized: false,
      initializeAccepted: false,
      notificationReady: false,
      resourceSubscriptions: /* @__PURE__ */ new Set()
    };
    messageLifecycles.add(lifecycle);
    if (listener !== void 0) {
      connectionNotificationListeners.set(listener, lifecycle);
    }
    return {
      handleMessage: (method, params) => handleMessageWithLifecycle(method, lifecycle, params),
      close: () => {
        if (listener !== void 0) {
          connectionNotificationListeners.delete(listener);
        }
        messageLifecycles.delete(lifecycle);
      }
    };
  };
  const handleMessage = (method, params) => handleMessageWithLifecycle(method, defaultLifecycle, params);
  const processLine = async (line, write, messageHandler) => {
    const parsed = parseMessage(line);
    if (!parsed.success) {
      write(formatErrorResponse(parsed.id, parsed.error) + "\n");
      return;
    }
    const { request, isNotification } = parsed;
    if (isNotification && request.method === "initialize") {
      return;
    }
    if (!isNotification && request.method === "notifications/initialized") {
      const requestWithId2 = request;
      write(formatErrorResponse(requestWithId2.id, {
        code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
        message: "Invalid Request"
      }) + "\n");
      return;
    }
    const { result, error } = await messageHandler(request.method, request.params);
    if (isNotification) {
      return;
    }
    const requestWithId = request;
    if (error) {
      write(formatErrorResponse(requestWithId.id, error) + "\n");
    } else if (result !== void 0) {
      write(formatSuccessResponse(requestWithId.id, result) + "\n");
    }
  };
  const broadcastNotification = async (method, params, canSend = () => true) => {
    const notification = {
      jsonrpc: "2.0",
      method,
      ...params === void 0 ? {} : { params }
    };
    for (const listener of notificationListeners) {
      listener(notification);
    }
    await Promise.all(
      [...connectionNotificationListeners].map(async ([listener, lifecycle]) => {
        if (lifecycle.notificationReady && canSend(lifecycle)) {
          await listener(notification);
        }
      })
    );
  };
  const server = {
    tool(name, description, inputSchema, handler, outputSchema) {
      assertNonEmptyName(name, "Tool name required");
      if (outputSchema !== void 0) {
        assertSupportedOutputSchema(outputSchema);
      }
      tools.set(name, {
        name,
        description,
        inputSchema,
        ...outputSchema === void 0 ? {} : { outputSchema },
        handler
      });
      return server;
    },
    registerTool(definition, handler) {
      assertNonEmptyName(definition.name, "Tool name required");
      if (definition.outputSchema !== void 0) {
        assertSupportedOutputSchema(definition.outputSchema);
      }
      tools.set(definition.name, {
        ...definition,
        handler
      });
      return server;
    },
    prompt(definition, handler) {
      assertNonEmptyName(definition.name, "Prompt name required");
      prompts.set(definition.name, { ...definition, handler });
      return server;
    },
    resource(definition, handler) {
      if (!isValidUri(definition.uri)) {
        throw new Error(`Invalid resource URI: ${definition.uri}`);
      }
      resources.set(definition.uri, { ...definition, handler });
      return server;
    },
    resourceTemplate(definition, handler) {
      assertReadableUriTemplate(definition.uriTemplate);
      new UriTemplate(definition.uriTemplate);
      resourceTemplates.set(definition.uriTemplate, { ...definition, handler });
      return server;
    },
    onNotification(listener) {
      notificationListeners.add(listener);
      return () => {
        notificationListeners.delete(listener);
      };
    },
    removeTool(name) {
      return tools.delete(name);
    },
    removePrompt(name) {
      return prompts.delete(name);
    },
    removeResource(uri) {
      return resources.delete(uri);
    },
    removeResourceTemplate(uriTemplate) {
      return resourceTemplates.delete(uriTemplate);
    },
    async notifyToolsChanged() {
      if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
        await broadcastNotification("notifications/tools/list_changed");
      }
    },
    async notifyPromptsChanged() {
      if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
        await broadcastNotification("notifications/prompts/list_changed");
      }
    },
    async notifyResourcesChanged() {
      if (supportNotifications && [...messageLifecycles].some((lifecycle) => lifecycle.notificationReady)) {
        await broadcastNotification("notifications/resources/list_changed");
      }
    },
    async notifyResourceUpdated(uri) {
      if (!supportResourceSubscriptions) {
        return;
      }
      await broadcastNotification(
        "notifications/resources/updated",
        { uri },
        (lifecycle) => lifecycle.resourceSubscriptions.has(uri)
      );
    },
    createMessageSession,
    handleMessage,
    async listen() {
      return server.connect({
        readable: process.stdin,
        writable: process.stdout
      });
    },
    async connect(transport) {
      return new Promise((resolve) => {
        const lifecycle = { initialized: false, initializeAccepted: false, notificationReady: false, resourceSubscriptions: /* @__PURE__ */ new Set() };
        const messageHandler = (method, params) => handleMessageWithLifecycle(method, lifecycle, params);
        messageLifecycles.add(lifecycle);
        const listener = (notification) => {
          transport.writable.write(`${JSON.stringify(notification)}
`);
        };
        connectionNotificationListeners.set(listener, lifecycle);
        const rl = readline.createInterface({
          input: transport.readable,
          crlfDelay: Infinity
        });
        const pendingMessages = /* @__PURE__ */ new Set();
        rl.on("line", (line) => {
          const message = processLine(line, (data) => transport.writable.write(data), messageHandler);
          pendingMessages.add(message);
          void message.finally(() => {
            pendingMessages.delete(message);
          });
        });
        rl.on("close", async () => {
          await Promise.all([...pendingMessages]);
          connectionNotificationListeners.delete(listener);
          messageLifecycles.delete(lifecycle);
          resolve();
        });
      });
    },
    async connectSDK(transport) {
      return new Promise((resolve, reject) => {
        const lifecycle = { initialized: false, initializeAccepted: false, notificationReady: false, resourceSubscriptions: /* @__PURE__ */ new Set() };
        const messageHandler = (method, params) => handleMessageWithLifecycle(method, lifecycle, params);
        messageLifecycles.add(lifecycle);
        const listener = (notification) => transport.send(notification);
        connectionNotificationListeners.set(listener, lifecycle);
        transport.onmessage = async (message) => {
          if (!("method" in message)) {
            return;
          }
          if (!("id" in message) || message.id === void 0) {
            if (message.method === "initialize") {
              return;
            }
            await messageHandler(message.method, message.params);
            return;
          }
          if (message.method === "notifications/initialized") {
            await transport.send({
              jsonrpc: "2.0",
              id: message.id,
              error: {
                code: JSON_RPC_ERROR_CODES.INVALID_REQUEST,
                message: "Invalid Request"
              }
            });
            return;
          }
          const request = message;
          const { result, error } = await messageHandler(request.method, request.params);
          if (error) {
            const response = {
              jsonrpc: "2.0",
              id: request.id,
              error
            };
            await transport.send(response);
          } else if (result !== void 0) {
            const response = {
              jsonrpc: "2.0",
              id: request.id,
              result
            };
            await transport.send(response);
          }
        };
        transport.onclose = () => {
          connectionNotificationListeners.delete(listener);
          messageLifecycles.delete(lifecycle);
          resolve();
        };
        void transport.start().catch((error) => {
          connectionNotificationListeners.delete(listener);
          messageLifecycles.delete(lifecycle);
          reject(error);
        });
      });
    }
  };
  return server;
}
function invalidParams(message) {
  return {
    error: {
      code: JSON_RPC_ERROR_CODES.INVALID_PARAMS,
      message
    }
  };
}
function internalError(message) {
  return {
    error: {
      code: JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
      message
    }
  };
}
function resourceNotFound(uri) {
  return {
    error: {
      code: JSON_RPC_ERROR_CODES.RESOURCE_NOT_FOUND,
      message: `Resource not found: ${uri}`
    }
  };
}
function toErrorMessage(error) {
  return error instanceof Error ? error.message : String(error);
}
function isValidUri(uri) {
  try {
    new URL(uri);
    return true;
  } catch {
    return false;
  }
}
function assertNonEmptyName(name, message) {
  if (name.length === 0) {
    throw new Error(message);
  }
}
function assertReadableUriTemplate(uriTemplate) {
  const parsed = uriTemplateParser.parse(uriTemplate);
  const expanded = parsed.expand(
    new Proxy({}, {
      get: (_target, property) => typeof property === "string" ? "value" : void 0
    })
  );
  if (typeof expanded !== "string" || !isValidUri(expanded)) {
    throw new Error(`Invalid resource URI template: ${uriTemplate}`);
  }
}
function toStringArguments(value) {
  if (value === void 0) {
    return {};
  }
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
    return void 0;
  }
  const args = {};
  for (const [name, argument] of Object.entries(value)) {
    if (typeof argument !== "string") {
      return void 0;
    }
    args[name] = argument;
  }
  return args;
}
function hasRequiredPromptArguments(prompt, args) {
  return (prompt.arguments ?? []).every(
    (argument) => argument.required !== true || args[argument.name] !== void 0
  );
}
function findReadableResource(uri, resources, resourceTemplates) {
  const resource = resources.get(uri);
  if (resource !== void 0) {
    return resource;
  }
  return [...resourceTemplates.values()].find(
    (template) => matchesUriTemplate(template.uriTemplate, uri)
  );
}
function matchesUriTemplate(template, uri) {
  try {
    return new UriTemplate(template).match(uri) !== null;
  } catch {
    return false;
  }
}
function isCallToolResult(value) {
  if (!hasContentArray(value) || !value.content.every(isContentItem)) {
    return false;
  }
  if (hasOwnProperty2(value, "structuredContent") && value.structuredContent !== void 0 && !isJsonObject(value.structuredContent)) {
    return false;
  }
  return !(hasOwnProperty2(value, "isError") && value.isError !== void 0 && typeof value.isError !== "boolean");
}
function normalizeToolResult(handlerResult, outputSchema) {
  if (hasContentArray(handlerResult) && !isCallToolResult(handlerResult)) {
    throw new Error("Invalid tool result");
  }
  if (outputSchema === void 0) {
    const result = isCallToolResult(handlerResult) ? handlerResult : { content: toContentBlocks(handlerResult) };
    if (!isCallToolResult(result)) {
      throw new Error("Invalid tool result");
    }
    return result;
  }
  const structuredContent = isCallToolResult(handlerResult) ? handlerResult.structuredContent : handlerResult;
  if (!isJsonObject(structuredContent)) {
    throw new ToolError(
      JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
      "Structured tool result must be an object"
    );
  }
  return {
    content: [{ type: "text", text: JSON.stringify(structuredContent) }],
    ...isCallToolResult(handlerResult) && handlerResult.isError !== void 0 ? { isError: handlerResult.isError } : {},
    structuredContent
  };
}
function assertSupportedOutputSchema(schema) {
  assertObjectRootSchema(schema, "outputSchema");
  assertSupportedJsonSchema(schema, "outputSchema");
}
function assertObjectRootSchema(schema, path) {
  if (schema.type !== "object") {
    throw new Error(`${path} root type must be "object"`);
  }
}
function assertSupportedJsonSchema(schema, path) {
  for (const keyword of ["anyOf", "allOf", "not", "if", "then", "else", "contains", "prefixItems"]) {
    if (schema[keyword] !== void 0) {
      throw new Error(`${path} uses unsupported keyword "${keyword}"`);
    }
  }
  const type = schema.type;
  if (Array.isArray(type)) {
    const supported = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "object", "array", "null"]);
    for (const item of type) {
      if (!supported.has(item)) {
        throw new Error(`${path} uses unsupported type "${item}"`);
      }
    }
  } else if (type !== void 0 && type !== "string" && type !== "number" && type !== "integer" && type !== "boolean" && type !== "object" && type !== "array") {
    throw new Error(`${path} uses unsupported type "${type}"`);
  }
  if (isJsonObject(schema.properties)) {
    for (const [key, child] of Object.entries(schema.properties)) {
      if (isJsonObject(child)) {
        assertSupportedJsonSchema(child, `${path}.properties.${key}`);
      } else {
        throw new Error(`${path}.properties.${key} must be an object schema`);
      }
    }
  } else if (schema.properties !== void 0) {
    throw new Error(`${path}.properties must be an object`);
  }
  const additionalProperties = schema.additionalProperties;
  if (typeof additionalProperties === "object" && additionalProperties !== null) {
    if (Array.isArray(additionalProperties)) {
      throw new Error(`${path}.additionalProperties must be an object schema or boolean`);
    }
    assertSupportedJsonSchema(additionalProperties, `${path}.additionalProperties`);
  } else if (additionalProperties !== void 0 && typeof additionalProperties !== "boolean") {
    throw new Error(`${path}.additionalProperties must be an object schema or boolean`);
  }
  const items = schema.items;
  if (Array.isArray(items)) {
    throw new Error(`${path}.items uses unsupported tuple array schemas`);
  }
  if (typeof items === "object" && items !== null && !Array.isArray(items)) {
    assertSupportedJsonSchema(items, `${path}.items`);
  } else if (items !== void 0 && typeof items !== "boolean") {
    throw new Error(`${path}.items must be an object schema or boolean`);
  }
  const oneOf = schema.oneOf;
  if (Array.isArray(oneOf)) {
    for (const [index, child] of oneOf.entries()) {
      if (typeof child === "object" && child !== null && !Array.isArray(child)) {
        assertSupportedJsonSchema(child, `${path}.oneOf[${index}]`);
      } else {
        throw new Error(`${path}.oneOf[${index}] must be an object schema`);
      }
    }
  } else if (oneOf !== void 0) {
    throw new Error(`${path}.oneOf must be an array`);
  }
}
function isJsonObject(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function isGetPromptResult(value) {
  if (typeof value !== "object" || value === null || !hasOwnProperty2(value, "messages")) {
    return false;
  }
  return (!hasOwnProperty2(value, "description") || value.description === void 0 || typeof value.description === "string") && Array.isArray(value.messages) && value.messages.every(
    (message) => typeof message === "object" && message !== null && hasOwnProperty2(message, "role") && (message.role === "user" || message.role === "assistant") && hasOwnProperty2(message, "content") && isPromptContentItem(message.content)
  );
}
function isReadResourceResult(value) {
  if (typeof value !== "object" || value === null || !hasOwnProperty2(value, "contents")) {
    return false;
  }
  return Array.isArray(value.contents) && value.contents.every(isResourceContents);
}
function hasContentArray(value) {
  return typeof value === "object" && value !== null && hasOwnProperty2(value, "content") && Array.isArray(value.content);
}
function isContentItem(value) {
  if (typeof value !== "object" || value === null || !hasOwnProperty2(value, "type")) {
    return false;
  }
  const block = value;
  if (!hasValidContentAnnotations(block)) {
    return false;
  }
  if (block.type === "text") {
    return hasOwnProperty2(block, "text") && typeof block.text === "string";
  }
  if (block.type === "image" || block.type === "audio") {
    return hasOwnProperty2(block, "data") && typeof block.data === "string" && isBase64(block.data) && hasOwnProperty2(block, "mimeType") && typeof block.mimeType === "string";
  }
  if (block.type === "resource_link") {
    return hasOwnProperty2(block, "uri") && typeof block.uri === "string" && isValidUri(block.uri) && hasOwnProperty2(block, "name") && typeof block.name === "string" && (!hasOwnProperty2(block, "title") || block.title === void 0 || typeof block.title === "string") && (!hasOwnProperty2(block, "description") || block.description === void 0 || typeof block.description === "string") && (!hasOwnProperty2(block, "mimeType") || block.mimeType === void 0 || typeof block.mimeType === "string") && (!hasOwnProperty2(block, "size") || block.size === void 0 || typeof block.size === "number");
  }
  if (block.type !== "resource" || !hasOwnProperty2(block, "resource") || typeof block.resource !== "object" || block.resource === null) {
    return false;
  }
  return isResourceContents(block.resource);
}
function isResourceContents(value) {
  if (typeof value !== "object" || value === null || !hasOwnProperty2(value, "uri") || typeof value.uri !== "string" || !isValidUri(value.uri)) {
    return false;
  }
  if (hasOwnProperty2(value, "mimeType") && value.mimeType !== void 0 && typeof value.mimeType !== "string") {
    return false;
  }
  return hasOwnProperty2(value, "text") && typeof value.text === "string" || hasOwnProperty2(value, "blob") && typeof value.blob === "string" && isBase64(value.blob);
}
function hasValidContentAnnotations(value) {
  if (!hasOwnProperty2(value, "annotations") || value.annotations === void 0) {
    return true;
  }
  if (!isJsonObject(value.annotations)) {
    return false;
  }
  const { audience, priority, lastModified } = value.annotations;
  return (audience === void 0 || Array.isArray(audience) && audience.every((item) => item === "user" || item === "assistant")) && (priority === void 0 || typeof priority === "number") && (lastModified === void 0 || typeof lastModified === "string");
}
function isBase64(value) {
  if (value.length === 0) {
    return true;
  }
  if (value.length % 4 !== 0) {
    return false;
  }
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  const paddingStart = value.indexOf("=");
  const encoded = paddingStart === -1 ? value : value.slice(0, paddingStart);
  const padding = paddingStart === -1 ? "" : value.slice(paddingStart);
  if (padding.length > 2 || [...padding].some((character) => character !== "=")) {
    return false;
  }
  if ([...encoded].some((character) => !alphabet.includes(character))) {
    return false;
  }
  return Buffer.from(value, "base64").toString("base64") === value;
}
function isPromptContentItem(value) {
  if (!isContentItem(value)) {
    return false;
  }
  return !(typeof value === "object" && value !== null && hasOwnProperty2(value, "type") && value.type === "resource_link");
}
function hasOwnProperty2(value, name) {
  return Object.prototype.hasOwnProperty.call(value, name);
}

// packages/tiny-stdio-mcp-server/src/schema.ts
function defineSchema(definition) {
  const properties = {};
  const required = [];
  for (const [key, prop] of Object.entries(definition)) {
    const jsonSchemaProperty = {};
    for (const [propertyKey, propertyValue] of Object.entries(prop)) {
      if (propertyKey !== "optional") {
        jsonSchemaProperty[propertyKey] = propertyValue;
      }
    }
    Object.defineProperty(properties, key, {
      enumerable: true,
      configurable: true,
      writable: true,
      value: jsonSchemaProperty
    });
    if (!prop.optional) {
      required.push(key);
    }
  }
  return {
    type: "object",
    properties,
    required
  };
}

// packages/tiny-stdio-mcp-test-server/src/index.ts
import { appendFileSync } from "node:fs";
var SERVER_NAME = "tiny-stdio-mcp-test-server";
var SERVER_VERSION = package_default.version;
var caesarCipherSchema = defineSchema({
  text: { type: "string", description: "The text to encrypt" },
  shift: {
    type: "integer",
    description: "The shift amount (default: 3)",
    optional: true
  }
});
function caesarEncrypt(text, shift) {
  if (!Number.isInteger(shift)) {
    throw new Error("Caesar cipher shift must be a finite integer");
  }
  const normalizedShift = (shift % 26 + 26) % 26;
  return text.split("").map((char) => {
    if (char >= "a" && char <= "z") {
      return String.fromCharCode(
        (char.charCodeAt(0) - 97 + normalizedShift) % 26 + 97
      );
    }
    if (char >= "A" && char <= "Z") {
      return String.fromCharCode(
        (char.charCodeAt(0) - 65 + normalizedShift) % 26 + 65
      );
    }
    return char;
  }).join("");
}
var wordOfTheDaySchema = defineSchema({});
function createEncryptServer() {
  return createServer({
    name: SERVER_NAME,
    version: SERVER_VERSION
  }).tool(
    "caesar_cipher_encrypt",
    "Encrypts text using the Caesar cipher",
    caesarCipherSchema,
    ({ text, shift }) => {
      recordToolCall("caesar_cipher_encrypt");
      const actualShift = shift ?? 3;
      return caesarEncrypt(text, actualShift);
    }
  );
}
function recordToolCall(name) {
  const filePath = process.env.TOOLCRAFT_TEST_TOOL_CALL_FILE;
  if (filePath !== void 0) {
    appendFileSync(filePath, `${name}
`);
  }
}
function createWordOfTheDayServer() {
  return createServer({
    name: SERVER_NAME,
    version: SERVER_VERSION
  }).tool(
    "word_of_the_day",
    "Returns the word of the day",
    wordOfTheDaySchema,
    () => {
      recordToolCall("word_of_the_day");
      return "Bumfuzzle - to confuse or fluster someone";
    }
  );
}

// packages/tiny-stdio-mcp-test-server/src/cli-support.ts
var SERVE_TOOL_NAMES = ["encrypt", "word-of-the-day"];
function isServeToolName(value) {
  return SERVE_TOOL_NAMES.includes(value);
}
function parseSpawnCount(value) {
  const trimmed = value.trim();
  if (trimmed === "") {
    return 0;
  }
  for (const character of trimmed) {
    if (character < "0" || character > "9") {
      throw new Error("TOOLCRAFT_TEST_SPAWN_COUNT_FILE must contain a non-negative integer");
    }
  }
  const count = Number(trimmed);
  if (!Number.isSafeInteger(count)) {
    throw new Error("TOOLCRAFT_TEST_SPAWN_COUNT_FILE must contain a non-negative integer");
  }
  return count;
}
function getNextSpawnCount(currentValue) {
  return (currentValue === void 0 ? 0 : parseSpawnCount(currentValue)) + 1;
}

// packages/tiny-stdio-mcp-test-server/src/cli.ts
var program = new Command();
program.name("tiny-stdio-mcp-test-server").description("Test MCP server with example tools for integration testing").version(package_default.version);
program.command("serve").description("Start an MCP server on stdin/stdout").argument("<tool>", "Tool to serve (encrypt, word-of-the-day)").action(async (tool) => {
  if (!isServeToolName(tool)) {
    console.error(`Unknown tool: ${tool}. Available: ${SERVE_TOOL_NAMES.join(", ")}`);
    process.exit(1);
  }
  try {
    recordProcessStart();
  } catch (error) {
    console.error(error instanceof Error ? error.message : String(error));
    process.exit(1);
  }
  const startupDelayMs = Number(process.env.TOOLCRAFT_TEST_STARTUP_DELAY_MS ?? "0");
  if (startupDelayMs > 0) {
    await new Promise((resolve) => setTimeout(resolve, startupDelayMs));
  }
  const startupGateFile = process.env.TOOLCRAFT_TEST_STARTUP_GATE_FILE;
  if (startupGateFile !== void 0) {
    await waitForFile(startupGateFile);
  }
  const servers = /* @__PURE__ */ Object.create(null);
  Object.assign(servers, {
    encrypt: () => createEncryptServer().listen(),
    "word-of-the-day": () => createWordOfTheDayServer().listen()
  });
  await servers[tool]();
});
program.parse();
function recordProcessStart() {
  const countFile = process.env.TOOLCRAFT_TEST_SPAWN_COUNT_FILE;
  if (countFile !== void 0) {
    const currentValue = existsSync(countFile) ? readFileSync(countFile, "utf8") : void 0;
    writeFileSync(countFile, String(getNextSpawnCount(currentValue)));
  }
  const pidFile = process.env.TOOLCRAFT_TEST_WRAPPER_PID_FILE;
  if (pidFile !== void 0) {
    writeFileSync(pidFile, String(process.pid));
  }
}
async function waitForFile(filePath) {
  while (true) {
    try {
      await access(filePath);
      return;
    } catch {
      await new Promise((resolve) => setTimeout(resolve, 5));
    }
  }
}
