@kajidog/mcp-tts-voicevox
Version:
VOICEVOX integration for MCP - Text-to-Speech server using VOICEVOX engine
1,294 lines (1,288 loc) • 226 kB
JavaScript
#!/usr/bin/env node
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// ../../node_modules/.pnpm/@hono+node-server@2.0.4_hono@4.12.23/node_modules/@hono/node-server/dist/constants-BLSFu_RU.mjs
var X_ALREADY_SENT;
var init_constants_BLSFu_RU = __esm({
"../../node_modules/.pnpm/@hono+node-server@2.0.4_hono@4.12.23/node_modules/@hono/node-server/dist/constants-BLSFu_RU.mjs"() {
"use strict";
X_ALREADY_SENT = "x-hono-already-sent";
}
});
// ../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/websocket/index.js
var defineWebSocketHelper;
var init_websocket = __esm({
"../../node_modules/.pnpm/hono@4.12.23/node_modules/hono/dist/helper/websocket/index.js"() {
"use strict";
defineWebSocketHelper = (handler) => {
return ((...args) => {
if (typeof args[0] === "function") {
const [createEvents, options] = args;
return async function upgradeWebSocket2(c, next) {
const events = await createEvents(c);
const result = await handler(c, events, options);
if (result) {
return result;
}
await next();
};
} else {
const [c, events, options] = args;
return (async () => {
const upgraded = await handler(c, events, options);
if (!upgraded) {
throw new Error("Failed to upgrade WebSocket");
}
return upgraded;
})();
}
});
};
}
});
// ../../node_modules/.pnpm/@hono+node-server@2.0.4_hono@4.12.23/node_modules/@hono/node-server/dist/index.mjs
var dist_exports = {};
__export(dist_exports, {
RequestError: () => RequestError,
createAdaptorServer: () => createAdaptorServer,
getRequestListener: () => getRequestListener,
serve: () => serve,
upgradeWebSocket: () => upgradeWebSocket
});
import { STATUS_CODES, createServer } from "http";
import { Http2ServerRequest, constants } from "http2";
import { Readable } from "stream";
async function readWithoutBlocking(readPromise) {
return Promise.race([readPromise, Promise.resolve().then(() => Promise.resolve(void 0))]);
}
function writeFromReadableStreamDefaultReader(reader, writable, currentReadPromise) {
const cancel = (error) => {
reader.cancel(error).catch(() => {
});
};
writable.on("close", cancel);
writable.on("error", cancel);
(currentReadPromise ?? reader.read()).then(flow, handleStreamError);
return reader.closed.finally(() => {
writable.off("close", cancel);
writable.off("error", cancel);
});
function handleStreamError(error) {
if (error) writable.destroy(error);
}
function onDrain() {
reader.read().then(flow, handleStreamError);
}
function flow({ done, value }) {
try {
if (done) writable.end();
else if (!writable.write(value)) writable.once("drain", onDrain);
else return reader.read().then(flow, handleStreamError);
} catch (e) {
handleStreamError(e);
}
}
}
function writeFromReadableStream(stream, writable) {
if (stream.locked) throw new TypeError("ReadableStream is locked.");
else if (writable.destroyed) return;
return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
}
var RequestError, reValidRequestUrl, reDotSegment, reValidHost, buildUrl, toRequestError, GlobalRequest, Request$1, newHeadersFromIncoming, wrapBodyStream, newRequestFromIncoming, getRequestCache, requestCache, incomingKey, urlKey, methodKey, headersKey, abortControllerKey, getAbortController, abortRequest, bodyBufferKey, bodyReadPromiseKey, bodyConsumedDirectlyKey, bodyLockReaderKey, abortReasonKey, newBodyUnusableError, rejectBodyUnusable, textDecoder, consumeBodyDirectOnce, toArrayBuffer, contentType, methodTokenRegExp, normalizeIncomingMethod, validateDirectReadMethod, readBodyWithFastPath, readRawBodyIfAvailable, readBodyDirect, requestPrototype, newRequest, defaultContentType, responseCache, getResponseCache, cacheKey, GlobalResponse, Response$1, validRedirectUrl, parseRedirectUrl, validRedirectStatuses, buildOutgoingHttpHeaders, outgoingEnded, incomingDraining, DRAIN_TIMEOUT_MS, MAX_DRAIN_BYTES, drainIncoming, makeCloseHandler, isImmediateCacheableResponse, handleRequestError, handleFetchError, handleResponseError, flushHeaders, responseViaCache, isPromise, responseViaResponseObject, getRequestListener, CloseEvent, generateConnectionSymbol, CONNECTION_SYMBOL_KEY, WAIT_FOR_WEBSOCKET_SYMBOL, responseHeadersToSkip, appendResponseHeaders, rejectUpgradeRequest, createUpgradeRequest, setupWebSocket, upgradeWebSocket, createAdaptorServer, serve;
var init_dist = __esm({
"../../node_modules/.pnpm/@hono+node-server@2.0.4_hono@4.12.23/node_modules/@hono/node-server/dist/index.mjs"() {
"use strict";
init_constants_BLSFu_RU();
init_websocket();
RequestError = class extends Error {
constructor(message, options) {
super(message, options);
this.name = "RequestError";
}
};
reValidRequestUrl = /^\/[!#$&-;=?-\[\]_a-z~]*$/;
reDotSegment = /\/\.\.?(?:[/?#]|$)/;
reValidHost = /^[a-z0-9._-]+(?::(?:[1-5]\d{3,4}|[6-9]\d{3}))?$/;
buildUrl = (scheme, host, incomingUrl) => {
const url = `${scheme}://${host}${incomingUrl}`;
if (!reValidHost.test(host)) {
const urlObj = new URL(url);
if (urlObj.hostname.length !== host.length && urlObj.hostname !== (host.includes(":") ? host.replace(/:\d+$/, "") : host).toLowerCase()) throw new RequestError("Invalid host header");
return urlObj.href;
} else if (incomingUrl.length === 0) return url + "/";
else {
if (incomingUrl.charCodeAt(0) !== 47) throw new RequestError("Invalid URL");
if (!reValidRequestUrl.test(incomingUrl) || reDotSegment.test(incomingUrl)) return new URL(url).href;
return url;
}
};
toRequestError = (e) => {
if (e instanceof RequestError) return e;
return new RequestError(e.message, { cause: e });
};
GlobalRequest = global.Request;
Request$1 = class extends GlobalRequest {
constructor(input, options) {
if (typeof input === "object" && getRequestCache in input) {
const hasReplacementBody = options !== void 0 && "body" in options && options.body != null;
if (input[bodyConsumedDirectlyKey] && !hasReplacementBody) throw new TypeError("Cannot construct a Request with a Request object that has already been used.");
input = input[getRequestCache]();
}
if (typeof options?.body?.getReader !== "undefined") options.duplex ??= "half";
super(input, options);
}
};
newHeadersFromIncoming = (incoming) => {
const headerRecord = [];
const rawHeaders = incoming.rawHeaders;
for (let i = 0, len = rawHeaders.length; i < len; i += 2) {
const key = rawHeaders[i];
if (key.charCodeAt(0) !== 58) headerRecord.push([key, rawHeaders[i + 1]]);
}
return new Headers(headerRecord);
};
wrapBodyStream = /* @__PURE__ */ Symbol("wrapBodyStream");
newRequestFromIncoming = (method, url, headers, incoming, abortController) => {
const init = {
method,
headers,
signal: abortController.signal
};
if (method === "TRACE") {
init.method = "GET";
const req = new Request$1(url, init);
Object.defineProperty(req, "method", { get() {
return "TRACE";
} });
return req;
}
if (!(method === "GET" || method === "HEAD")) if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) init.body = new ReadableStream({ start(controller) {
controller.enqueue(incoming.rawBody);
controller.close();
} });
else if (incoming[wrapBodyStream]) {
let reader;
init.body = new ReadableStream({ async pull(controller) {
try {
reader ||= Readable.toWeb(incoming).getReader();
const { done, value } = await reader.read();
if (done) controller.close();
else controller.enqueue(value);
} catch (error) {
controller.error(error);
}
} });
} else init.body = Readable.toWeb(incoming);
return new Request$1(url, init);
};
getRequestCache = /* @__PURE__ */ Symbol("getRequestCache");
requestCache = /* @__PURE__ */ Symbol("requestCache");
incomingKey = /* @__PURE__ */ Symbol("incomingKey");
urlKey = /* @__PURE__ */ Symbol("urlKey");
methodKey = /* @__PURE__ */ Symbol("methodKey");
headersKey = /* @__PURE__ */ Symbol("headersKey");
abortControllerKey = /* @__PURE__ */ Symbol("abortControllerKey");
getAbortController = /* @__PURE__ */ Symbol("getAbortController");
abortRequest = /* @__PURE__ */ Symbol("abortRequest");
bodyBufferKey = /* @__PURE__ */ Symbol("bodyBuffer");
bodyReadPromiseKey = /* @__PURE__ */ Symbol("bodyReadPromise");
bodyConsumedDirectlyKey = /* @__PURE__ */ Symbol("bodyConsumedDirectly");
bodyLockReaderKey = /* @__PURE__ */ Symbol("bodyLockReader");
abortReasonKey = /* @__PURE__ */ Symbol("abortReason");
newBodyUnusableError = () => {
return /* @__PURE__ */ new TypeError("Body is unusable");
};
rejectBodyUnusable = () => {
return Promise.reject(newBodyUnusableError());
};
textDecoder = new TextDecoder();
consumeBodyDirectOnce = (request) => {
if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
request[bodyConsumedDirectlyKey] = true;
};
toArrayBuffer = (buf) => {
return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
};
contentType = (request) => {
return (request[headersKey] ||= newHeadersFromIncoming(request[incomingKey])).get("content-type") || "";
};
methodTokenRegExp = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
normalizeIncomingMethod = (method) => {
if (typeof method !== "string" || method.length === 0) return "GET";
switch (method) {
case "DELETE":
case "GET":
case "HEAD":
case "OPTIONS":
case "POST":
case "PUT":
return method;
}
const upper = method.toUpperCase();
switch (upper) {
case "DELETE":
case "GET":
case "HEAD":
case "OPTIONS":
case "POST":
case "PUT":
return upper;
default:
return method;
}
};
validateDirectReadMethod = (method) => {
if (!methodTokenRegExp.test(method)) return /* @__PURE__ */ new TypeError(`'${method}' is not a valid HTTP method.`);
const normalized = method.toUpperCase();
if (normalized === "CONNECT" || normalized === "TRACK" || normalized === "TRACE" && method !== "TRACE") return /* @__PURE__ */ new TypeError(`'${method}' HTTP method is unsupported.`);
};
readBodyWithFastPath = (request, method, fromBuffer) => {
if (request[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
const methodName = request.method;
if (methodName === "GET" || methodName === "HEAD") return request[getRequestCache]()[method]();
const methodValidationError = validateDirectReadMethod(methodName);
if (methodValidationError) return Promise.reject(methodValidationError);
if (request[requestCache]) {
if (methodName !== "TRACE") return request[requestCache][method]();
}
const alreadyUsedError = consumeBodyDirectOnce(request);
if (alreadyUsedError) return alreadyUsedError;
const raw2 = readRawBodyIfAvailable(request);
if (raw2) {
const result = Promise.resolve(fromBuffer(raw2, request));
request[bodyBufferKey] = void 0;
return result;
}
return readBodyDirect(request).then((buf) => {
const result = fromBuffer(buf, request);
request[bodyBufferKey] = void 0;
return result;
});
};
readRawBodyIfAvailable = (request) => {
const incoming = request[incomingKey];
if ("rawBody" in incoming && incoming.rawBody instanceof Buffer) return incoming.rawBody;
};
readBodyDirect = (request) => {
if (request[bodyBufferKey]) return Promise.resolve(request[bodyBufferKey]);
if (request[bodyReadPromiseKey]) return request[bodyReadPromiseKey];
const incoming = request[incomingKey];
if (Readable.isDisturbed(incoming)) return rejectBodyUnusable();
const promise = new Promise((resolve3, reject) => {
const chunks = [];
let settled = false;
const finish = (callback) => {
if (settled) return;
settled = true;
cleanup();
callback();
};
const onData = (chunk) => {
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
};
const onEnd = () => {
finish(() => {
const buffer = chunks.length === 1 ? chunks[0] : Buffer.concat(chunks);
request[bodyBufferKey] = buffer;
resolve3(buffer);
});
};
const onError = (error) => {
finish(() => {
reject(error);
});
};
const onClose = () => {
if (incoming.readableEnded) {
onEnd();
return;
}
finish(() => {
if (incoming.errored) {
reject(incoming.errored);
return;
}
const reason = request[abortReasonKey];
if (reason !== void 0) {
reject(reason instanceof Error ? reason : new Error(String(reason)));
return;
}
reject(/* @__PURE__ */ new Error("Client connection prematurely closed."));
});
};
const cleanup = () => {
incoming.off("data", onData);
incoming.off("end", onEnd);
incoming.off("error", onError);
incoming.off("close", onClose);
request[bodyReadPromiseKey] = void 0;
};
incoming.on("data", onData);
incoming.on("end", onEnd);
incoming.on("error", onError);
incoming.on("close", onClose);
queueMicrotask(() => {
if (settled) return;
if (incoming.readableEnded) onEnd();
else if (incoming.errored) onError(incoming.errored);
else if (incoming.destroyed) onClose();
});
});
request[bodyReadPromiseKey] = promise;
return promise;
};
requestPrototype = {
get method() {
return this[methodKey];
},
get url() {
return this[urlKey];
},
get headers() {
return this[headersKey] ||= newHeadersFromIncoming(this[incomingKey]);
},
[abortRequest](reason) {
if (this[abortReasonKey] === void 0) this[abortReasonKey] = reason;
const abortController = this[abortControllerKey];
if (abortController && !abortController.signal.aborted) abortController.abort(reason);
},
[getAbortController]() {
this[abortControllerKey] ||= new AbortController();
if (this[abortReasonKey] !== void 0 && !this[abortControllerKey].signal.aborted) this[abortControllerKey].abort(this[abortReasonKey]);
return this[abortControllerKey];
},
[getRequestCache]() {
const abortController = this[getAbortController]();
if (this[requestCache]) return this[requestCache];
const method = this.method;
if (this[bodyConsumedDirectlyKey] && !(method === "GET" || method === "HEAD")) {
this[bodyBufferKey] = void 0;
const init = {
method: method === "TRACE" ? "GET" : method,
headers: this.headers,
signal: abortController.signal
};
if (method !== "TRACE") {
init.body = new ReadableStream({ start(c) {
c.close();
} });
init.duplex = "half";
}
const req = new Request$1(this[urlKey], init);
if (method === "TRACE") Object.defineProperty(req, "method", { get() {
return "TRACE";
} });
return this[requestCache] = req;
}
return this[requestCache] = newRequestFromIncoming(this.method, this[urlKey], this.headers, this[incomingKey], abortController);
},
get body() {
if (!this[bodyConsumedDirectlyKey]) return this[getRequestCache]().body;
const request = this[getRequestCache]();
if (!this[bodyLockReaderKey] && request.body) this[bodyLockReaderKey] = request.body.getReader();
return request.body;
},
get bodyUsed() {
if (this[bodyConsumedDirectlyKey]) return true;
if (this[requestCache]) return this[requestCache].bodyUsed;
return false;
}
};
Object.defineProperty(requestPrototype, "signal", { get() {
return this[getAbortController]().signal;
} });
[
"cache",
"credentials",
"destination",
"integrity",
"mode",
"redirect",
"referrer",
"referrerPolicy",
"keepalive"
].forEach((k) => {
Object.defineProperty(requestPrototype, k, { get() {
return this[getRequestCache]()[k];
} });
});
["clone", "formData"].forEach((k) => {
Object.defineProperty(requestPrototype, k, { value: function() {
if (this[bodyConsumedDirectlyKey]) {
if (k === "clone") throw newBodyUnusableError();
return rejectBodyUnusable();
}
return this[getRequestCache]()[k]();
} });
});
Object.defineProperty(requestPrototype, "text", { value: function() {
return readBodyWithFastPath(this, "text", (buf) => textDecoder.decode(buf));
} });
Object.defineProperty(requestPrototype, "arrayBuffer", { value: function() {
return readBodyWithFastPath(this, "arrayBuffer", (buf) => toArrayBuffer(buf));
} });
Object.defineProperty(requestPrototype, "blob", { value: function() {
return readBodyWithFastPath(this, "blob", (buf, request) => {
const type = contentType(request);
const init = type ? { headers: { "content-type": type } } : void 0;
return new Response(buf, init).blob();
});
} });
Object.defineProperty(requestPrototype, "json", { value: function() {
if (this[bodyConsumedDirectlyKey]) return rejectBodyUnusable();
return this.text().then(JSON.parse);
} });
Object.defineProperty(requestPrototype, /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
return `Request (lightweight) ${inspectFn({
method: this.method,
url: this.url,
headers: this.headers,
nativeRequest: this[requestCache]
}, {
...options,
depth: depth == null ? null : depth - 1
})}`;
} });
Object.setPrototypeOf(requestPrototype, Request$1.prototype);
newRequest = (incoming, defaultHostname) => {
const req = Object.create(requestPrototype);
req[incomingKey] = incoming;
req[methodKey] = normalizeIncomingMethod(incoming.method);
const incomingUrl = incoming.url || "";
if (incomingUrl[0] !== "/" && (incomingUrl.startsWith("http://") || incomingUrl.startsWith("https://"))) {
if (incoming instanceof Http2ServerRequest) throw new RequestError("Absolute URL for :path is not allowed in HTTP/2");
try {
req[urlKey] = new URL(incomingUrl).href;
} catch (e) {
throw new RequestError("Invalid absolute URL", { cause: e });
}
return req;
}
const host = (incoming instanceof Http2ServerRequest ? incoming.authority : incoming.headers.host) || defaultHostname;
if (!host) throw new RequestError("Missing host header");
let scheme;
if (incoming instanceof Http2ServerRequest) {
scheme = incoming.scheme;
if (!(scheme === "http" || scheme === "https")) throw new RequestError("Unsupported scheme");
} else scheme = incoming.socket && incoming.socket.encrypted ? "https" : "http";
try {
req[urlKey] = buildUrl(scheme, host, incomingUrl);
} catch (e) {
if (e instanceof RequestError) throw e;
else throw new RequestError("Invalid URL", { cause: e });
}
return req;
};
defaultContentType = "text/plain; charset=UTF-8";
responseCache = /* @__PURE__ */ Symbol("responseCache");
getResponseCache = /* @__PURE__ */ Symbol("getResponseCache");
cacheKey = /* @__PURE__ */ Symbol("cache");
GlobalResponse = global.Response;
Response$1 = class Response$12 {
#body;
#init;
[getResponseCache]() {
const cache = this[cacheKey];
const liveHeaders = cache && cache[2] instanceof Headers ? cache[2] : void 0;
delete this[cacheKey];
return this[responseCache] ||= new GlobalResponse(this.#body, liveHeaders ? {
...this.#init,
headers: liveHeaders
} : this.#init);
}
constructor(body, init) {
let headers;
this.#body = body;
if (init instanceof Response$12) {
const cachedGlobalResponse = init[responseCache];
if (cachedGlobalResponse) {
this.#init = cachedGlobalResponse;
this[getResponseCache]();
return;
} else {
this.#init = init.#init;
headers = new Headers(init.headers);
}
} else this.#init = init;
if (body == null || typeof body === "string" || typeof body?.getReader !== "undefined" || body instanceof Blob || body instanceof Uint8Array) this[cacheKey] = [
init?.status || 200,
body ?? null,
headers || init?.headers
];
}
get headers() {
const cache = this[cacheKey];
if (cache) {
if (!(cache[2] instanceof Headers)) cache[2] = new Headers(cache[2] || (cache[1] === null ? void 0 : { "content-type": defaultContentType }));
return cache[2];
}
return this[getResponseCache]().headers;
}
get status() {
return this[cacheKey]?.[0] ?? this[getResponseCache]().status;
}
get ok() {
const status = this.status;
return status >= 200 && status < 300;
}
};
[
"body",
"bodyUsed",
"redirected",
"statusText",
"trailers",
"type",
"url"
].forEach((k) => {
Object.defineProperty(Response$1.prototype, k, { get() {
return this[getResponseCache]()[k];
} });
});
[
"arrayBuffer",
"blob",
"clone",
"formData",
"json",
"text"
].forEach((k) => {
Object.defineProperty(Response$1.prototype, k, { value: function() {
return this[getResponseCache]()[k]();
} });
});
Object.defineProperty(Response$1.prototype, /* @__PURE__ */ Symbol.for("nodejs.util.inspect.custom"), { value: function(depth, options, inspectFn) {
return `Response (lightweight) ${inspectFn({
status: this.status,
headers: this.headers,
ok: this.ok,
nativeResponse: this[responseCache]
}, {
...options,
depth: depth == null ? null : depth - 1
})}`;
} });
Object.setPrototypeOf(Response$1, GlobalResponse);
Object.setPrototypeOf(Response$1.prototype, GlobalResponse.prototype);
validRedirectUrl = /^https?:\/\/[!#-;=?-[\]_a-z~A-Z]+$/;
parseRedirectUrl = (url) => {
if (url instanceof URL) return url.href;
if (validRedirectUrl.test(url)) return url;
return new URL(url).href;
};
validRedirectStatuses = /* @__PURE__ */ new Set([
301,
302,
303,
307,
308
]);
Object.defineProperty(Response$1, "redirect", {
value: function redirect(url, status = 302) {
if (!validRedirectStatuses.has(status)) throw new RangeError("Invalid status code");
return new Response$1(null, {
status,
headers: { location: parseRedirectUrl(url) }
});
},
writable: true,
configurable: true
});
Object.defineProperty(Response$1, "json", {
value: function json(data, init) {
const body = JSON.stringify(data);
if (body === void 0) throw new TypeError("The data is not JSON serializable");
const initHeaders = init?.headers;
let headers;
if (initHeaders) {
headers = new Headers(initHeaders);
if (!headers.has("content-type")) headers.set("content-type", "application/json");
} else headers = { "content-type": "application/json" };
return new Response$1(body, {
status: init?.status ?? 200,
statusText: init?.statusText,
headers
});
},
writable: true,
configurable: true
});
buildOutgoingHttpHeaders = (headers, defaultContentType2) => {
const res = {};
if (!(headers instanceof Headers)) headers = new Headers(headers ?? void 0);
if (headers.has("set-cookie")) {
const cookies = [];
for (const [k, v] of headers) if (k === "set-cookie") cookies.push(v);
else res[k] = v;
if (cookies.length > 0) res["set-cookie"] = cookies;
} else for (const [k, v] of headers) res[k] = v;
if (defaultContentType2) res["content-type"] ??= defaultContentType2;
return res;
};
outgoingEnded = /* @__PURE__ */ Symbol("outgoingEnded");
incomingDraining = /* @__PURE__ */ Symbol("incomingDraining");
DRAIN_TIMEOUT_MS = 500;
MAX_DRAIN_BYTES = 64 * 1024 * 1024;
drainIncoming = (incoming) => {
const incomingWithDrainState = incoming;
if (incoming.destroyed || incomingWithDrainState[incomingDraining]) return;
incomingWithDrainState[incomingDraining] = true;
if (incoming instanceof Http2ServerRequest) {
try {
incoming.stream?.close?.(constants.NGHTTP2_NO_ERROR);
} catch {
}
return;
}
let bytesRead = 0;
const cleanup = () => {
clearTimeout(timer);
incoming.off("data", onData);
incoming.off("end", cleanup);
incoming.off("error", cleanup);
};
const forceClose = () => {
cleanup();
const socket = incoming.socket;
if (socket && !socket.destroyed) socket.destroySoon();
};
const timer = setTimeout(forceClose, DRAIN_TIMEOUT_MS);
timer.unref?.();
const onData = (chunk) => {
bytesRead += chunk.length;
if (bytesRead > MAX_DRAIN_BYTES) forceClose();
};
incoming.on("data", onData);
incoming.on("end", cleanup);
incoming.on("error", cleanup);
incoming.resume();
};
makeCloseHandler = (req, incoming, outgoing, needsBodyCleanup) => () => {
if (incoming.errored) req[abortRequest](incoming.errored.toString());
else if (!outgoing.writableFinished) req[abortRequest]("Client connection prematurely closed.");
if (needsBodyCleanup && !incoming.readableEnded) setTimeout(() => {
if (!incoming.readableEnded) setTimeout(() => {
drainIncoming(incoming);
});
});
};
isImmediateCacheableResponse = (res) => {
if (!(cacheKey in res)) return false;
const body = res[cacheKey][1];
return body === null || typeof body === "string" || body instanceof Uint8Array;
};
handleRequestError = () => new Response(null, { status: 400 });
handleFetchError = (e) => new Response(null, { status: e instanceof Error && (e.name === "TimeoutError" || e.constructor.name === "TimeoutError") ? 504 : 500 });
handleResponseError = (e, outgoing) => {
const err = e instanceof Error ? e : new Error("unknown error", { cause: e });
if (err.code === "ERR_STREAM_PREMATURE_CLOSE") console.info("The user aborted a request.");
else {
console.error(e);
if (!outgoing.headersSent) outgoing.writeHead(500, { "Content-Type": "text/plain" });
outgoing.end(`Error: ${err.message}`);
outgoing.destroy(err);
}
};
flushHeaders = (outgoing) => {
if ("flushHeaders" in outgoing && outgoing.writable) outgoing.flushHeaders();
};
responseViaCache = async (res, outgoing) => {
let [status, body, header] = res[cacheKey];
if (!header) {
if (body === null) {
outgoing.writeHead(status);
outgoing.end();
} else if (typeof body === "string") {
outgoing.writeHead(status, {
"Content-Type": defaultContentType,
"Content-Length": Buffer.byteLength(body)
});
outgoing.end(body);
} else if (body instanceof Uint8Array) {
outgoing.writeHead(status, {
"Content-Type": defaultContentType,
"Content-Length": body.byteLength
});
outgoing.end(body);
} else if (body instanceof Blob) {
outgoing.writeHead(status, {
"Content-Type": defaultContentType,
"Content-Length": body.size
});
outgoing.end(new Uint8Array(await body.arrayBuffer()));
} else {
outgoing.writeHead(status, { "Content-Type": defaultContentType });
flushHeaders(outgoing);
await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
}
outgoing[outgoingEnded]?.();
return;
}
let hasContentLength = false;
if (header instanceof Headers) {
hasContentLength = header.has("content-length");
header = buildOutgoingHttpHeaders(header, body === null ? void 0 : defaultContentType);
} else if (Array.isArray(header)) {
const headerObj = new Headers(header);
hasContentLength = headerObj.has("content-length");
header = buildOutgoingHttpHeaders(headerObj, body === null ? void 0 : defaultContentType);
} else for (const key in header) if (key.length === 14 && key.toLowerCase() === "content-length") {
hasContentLength = true;
break;
}
if (!hasContentLength) {
if (typeof body === "string") header["Content-Length"] = Buffer.byteLength(body);
else if (body instanceof Uint8Array) header["Content-Length"] = body.byteLength;
else if (body instanceof Blob) header["Content-Length"] = body.size;
}
outgoing.writeHead(status, header);
if (body == null) outgoing.end();
else if (typeof body === "string" || body instanceof Uint8Array) outgoing.end(body);
else if (body instanceof Blob) outgoing.end(new Uint8Array(await body.arrayBuffer()));
else {
flushHeaders(outgoing);
await writeFromReadableStream(body, outgoing)?.catch((e) => handleResponseError(e, outgoing));
}
outgoing[outgoingEnded]?.();
};
isPromise = (res) => typeof res.then === "function";
responseViaResponseObject = async (res, outgoing, options = {}) => {
if (isPromise(res)) if (options.errorHandler) try {
res = await res;
} catch (err) {
const errRes = await options.errorHandler(err);
if (!errRes) return;
res = errRes;
}
else res = await res.catch(handleFetchError);
if (cacheKey in res) return responseViaCache(res, outgoing);
const resHeaderRecord = buildOutgoingHttpHeaders(res.headers, res.body === null ? void 0 : defaultContentType);
if (res.body) {
const reader = res.body.getReader();
const values = [];
let done = false;
let currentReadPromise = void 0;
if (resHeaderRecord["transfer-encoding"] !== "chunked") {
let maxReadCount = 2;
for (let i = 0; i < maxReadCount; i++) {
currentReadPromise ||= reader.read();
const chunk = await readWithoutBlocking(currentReadPromise).catch((e) => {
console.error(e);
done = true;
});
if (!chunk) {
if (i === 1) {
await new Promise((resolve3) => setTimeout(resolve3));
maxReadCount = 3;
continue;
}
break;
}
currentReadPromise = void 0;
if (chunk.value) values.push(chunk.value);
if (chunk.done) {
done = true;
break;
}
}
if (done && !("content-length" in resHeaderRecord)) resHeaderRecord["content-length"] = values.reduce((acc, value) => acc + value.length, 0);
}
outgoing.writeHead(res.status, resHeaderRecord);
values.forEach((value) => {
outgoing.write(value);
});
if (done) outgoing.end();
else {
if (values.length === 0) flushHeaders(outgoing);
await writeFromReadableStreamDefaultReader(reader, outgoing, currentReadPromise);
}
} else if (resHeaderRecord[X_ALREADY_SENT]) {
} else {
outgoing.writeHead(res.status, resHeaderRecord);
outgoing.end();
}
outgoing[outgoingEnded]?.();
};
getRequestListener = (fetchCallback, options = {}) => {
const autoCleanupIncoming = options.autoCleanupIncoming ?? true;
if (options.overrideGlobalObjects !== false && global.Request !== Request$1) {
Object.defineProperty(global, "Request", { value: Request$1 });
Object.defineProperty(global, "Response", { value: Response$1 });
}
return async (incoming, outgoing) => {
let res, req;
let needsBodyCleanup = false;
let closeHandlerAttached = false;
const ensureCloseHandler = () => {
if (!req || closeHandlerAttached) return;
closeHandlerAttached = true;
outgoing.on("close", makeCloseHandler(req, incoming, outgoing, needsBodyCleanup));
};
try {
req = newRequest(incoming, options.hostname);
needsBodyCleanup = autoCleanupIncoming && !(incoming.method === "GET" || incoming.method === "HEAD");
if (needsBodyCleanup) {
incoming[wrapBodyStream] = true;
if (incoming instanceof Http2ServerRequest) outgoing[outgoingEnded] = () => {
if (!incoming.readableEnded) setTimeout(() => {
if (!incoming.readableEnded) setTimeout(() => {
incoming.destroy();
outgoing.destroy();
});
});
};
}
res = fetchCallback(req, {
incoming,
outgoing
});
if (!isPromise(res) && isImmediateCacheableResponse(res)) {
if (needsBodyCleanup && !incoming.readableEnded) outgoing.once("finish", () => {
if (!incoming.readableEnded) drainIncoming(incoming);
});
return responseViaCache(res, outgoing);
}
ensureCloseHandler();
} catch (e) {
if (!res) if (options.errorHandler) {
ensureCloseHandler();
res = await options.errorHandler(req ? e : toRequestError(e));
if (!res) return;
} else if (!req) res = handleRequestError();
else res = handleFetchError(e);
else return handleResponseError(e, outgoing);
}
try {
return await responseViaResponseObject(res, outgoing, options);
} catch (e) {
return handleResponseError(e, outgoing);
}
};
};
CloseEvent = globalThis.CloseEvent ?? class extends Event {
#eventInitDict;
constructor(type, eventInitDict = {}) {
super(type, eventInitDict);
this.#eventInitDict = eventInitDict;
}
get wasClean() {
return this.#eventInitDict.wasClean ?? false;
}
get code() {
return this.#eventInitDict.code ?? 0;
}
get reason() {
return this.#eventInitDict.reason ?? "";
}
};
generateConnectionSymbol = () => /* @__PURE__ */ Symbol("connection");
CONNECTION_SYMBOL_KEY = /* @__PURE__ */ Symbol("CONNECTION_SYMBOL_KEY");
WAIT_FOR_WEBSOCKET_SYMBOL = /* @__PURE__ */ Symbol("WAIT_FOR_WEBSOCKET_SYMBOL");
responseHeadersToSkip = /* @__PURE__ */ new Set([
"connection",
"content-length",
"keep-alive",
"proxy-authenticate",
"proxy-authorization",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"sec-websocket-accept",
"sec-websocket-extensions",
"sec-websocket-protocol"
]);
appendResponseHeaders = (headers, responseHeaders) => {
if (!responseHeaders) return;
responseHeaders.forEach((value, key) => {
if (responseHeadersToSkip.has(key.toLowerCase())) return;
headers.push(`${key}: ${value}`);
});
};
rejectUpgradeRequest = (socket, status, responseHeaders) => {
const responseLines = ["Connection: close", "Content-Length: 0"];
appendResponseHeaders(responseLines, responseHeaders);
socket.end(`HTTP/1.1 ${status.toString()} ${STATUS_CODES[status] ?? ""}\r
${responseLines.join("\r\n")}\r
\r
`);
};
createUpgradeRequest = (request) => {
const protocol = request.socket.encrypted ? "https" : "http";
const url = new URL(request.url ?? "/", `${protocol}://${request.headers.host ?? "localhost"}`);
const headers = new Headers();
for (const key in request.headers) {
const value = request.headers[key];
if (!value) continue;
headers.append(key, Array.isArray(value) ? value[0] : value);
}
return new Request(url, { headers });
};
setupWebSocket = (options) => {
const { server: server2, fetchCallback, wss } = options;
const waiterMap = /* @__PURE__ */ new Map();
wss.on("connection", (ws, request) => {
const waiter = waiterMap.get(request);
if (waiter) {
waiter.resolve(ws);
waiterMap.delete(request);
}
});
const waitForWebSocket = (request, connectionSymbol) => {
return new Promise((resolve3) => {
waiterMap.set(request, {
resolve: resolve3,
connectionSymbol
});
});
};
server2.on("upgrade", async (request, socket, head) => {
if (request.headers.upgrade?.toLowerCase() !== "websocket") return;
const env = {
incoming: request,
outgoing: void 0,
wss,
[WAIT_FOR_WEBSOCKET_SYMBOL]: waitForWebSocket
};
let status = 400;
let responseHeaders;
try {
const response = await fetchCallback(createUpgradeRequest(request), env);
if (response instanceof Response) {
status = response.status;
responseHeaders = response.headers;
}
} catch {
if (server2.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, 500);
return;
}
const waiter = waiterMap.get(request);
if (!waiter || waiter.connectionSymbol !== env[CONNECTION_SYMBOL_KEY]) {
waiterMap.delete(request);
if (server2.listenerCount("upgrade") === 1) rejectUpgradeRequest(socket, status, responseHeaders);
return;
}
const addResponseHeaders = (headers) => {
appendResponseHeaders(headers, responseHeaders);
};
wss.on("headers", addResponseHeaders);
try {
wss.handleUpgrade(request, socket, head, (ws) => {
wss.emit("connection", ws, request);
});
} finally {
wss.off("headers", addResponseHeaders);
}
});
server2.on("close", () => {
wss.close();
});
};
upgradeWebSocket = defineWebSocketHelper(async (c, events, options) => {
if (c.req.header("upgrade")?.toLowerCase() !== "websocket") return;
const env = c.env;
const waitForWebSocket = env[WAIT_FOR_WEBSOCKET_SYMBOL];
if (!waitForWebSocket || !env.incoming) return new Response(null, { status: 500 });
const connectionSymbol = generateConnectionSymbol();
env[CONNECTION_SYMBOL_KEY] = connectionSymbol;
(async () => {
const ws = await waitForWebSocket(env.incoming, connectionSymbol);
const messagesReceivedInStarting = [];
const bufferMessage = (data, isBinary) => {
messagesReceivedInStarting.push([data, isBinary]);
};
ws.on("message", bufferMessage);
const ctx = {
binaryType: "arraybuffer",
close(code, reason) {
ws.close(code, reason);
},
protocol: ws.protocol,
raw: ws,
get readyState() {
return ws.readyState;
},
send(source, opts) {
ws.send(source, { compress: opts?.compress });
},
url: new URL(c.req.url)
};
try {
events?.onOpen?.(new Event("open"), ctx);
} catch (e) {
(options?.onError ?? console.error)(e);
}
const handleMessage = (data, isBinary) => {
const datas = Array.isArray(data) ? data : [data];
for (const data2 of datas) try {
events?.onMessage?.(new MessageEvent("message", { data: isBinary ? data2 instanceof ArrayBuffer ? data2 : data2.buffer.slice(data2.byteOffset, data2.byteOffset + data2.byteLength) : typeof data2 === "string" ? data2 : Buffer.from(data2).toString("utf-8") }), ctx);
} catch (e) {
(options?.onError ?? console.error)(e);
}
};
ws.off("message", bufferMessage);
for (const message of messagesReceivedInStarting) handleMessage(...message);
ws.on("message", (data, isBinary) => {
handleMessage(data, isBinary);
});
ws.on("close", (code, reason) => {
try {
events?.onClose?.(new CloseEvent("close", {
code,
reason: reason.toString()
}), ctx);
} catch (e) {
(options?.onError ?? console.error)(e);
}
});
ws.on("error", (error) => {
try {
events?.onError?.(new ErrorEvent("error", { error }), ctx);
} catch (e) {
(options?.onError ?? console.error)(e);
}
});
})();
return new Response();
});
createAdaptorServer = (options) => {
const fetchCallback = options.fetch;
const requestListener = getRequestListener(fetchCallback, {
hostname: options.hostname,
overrideGlobalObjects: options.overrideGlobalObjects,
autoCleanupIncoming: options.autoCleanupIncoming
});
const server2 = (options.createServer || createServer)(options.serverOptions || {}, requestListener);
if (options.websocket && options.websocket.server) {
if (options.websocket.server.options.noServer !== true) throw new Error("WebSocket server must be created with { noServer: true } option");
setupWebSocket({
server: server2,
fetchCallback,
wss: options.websocket.server
});
}
return server2;
};
serve = (options, listeningListener) => {
const server2 = createAdaptorServer(options);
server2.listen(options?.port ?? 3e3, options.hostname, () => {
const serverInfo = server2.address();
listeningListener && listeningListener(serverInfo);
});
return server2;
};
}
});
// src/index.ts
import { existsSync as existsSync2, readFileSync as readFileSync5, writeFileSync } from "fs";
import { dirname as dirname4, join as join6 } from "path";
import { fileURLToPath as fileURLToPath2 } from "url";
// ../../packages/mcp-core/dist/config-schema.js
function parseCliFromDefs(defs, argv) {
const config2 = {};
const flagMap = /* @__PURE__ */ new Map();
const negationMap = /* @__PURE__ */ new Map();
for (const [key, def] of Object.entries(defs)) {
flagMap.set(def.cli, { key, def });
if (def.type === "boolean") {
const baseName = def.cli.replace(/^--/, "");
negationMap.set(`--no-${baseName}`, key);
}
}
for (let i = 0; i < argv.length; i++) {
const arg = argv[i];
const nextArg = argv[i + 1];
const negKey = negationMap.get(arg);
if (negKey !== void 0) {
config2[negKey] = false;
continue;
}
const entry = flagMap.get(arg);
if (!entry)
continue;
const { key, def } = entry;
switch (def.type) {
case "boolean":
config2[key] = true;
break;
case "string":
if (nextArg && !nextArg.startsWith("-")) {
config2[key] = nextArg;
i++;
}
break;
case "number":
if (nextArg && !nextArg.startsWith("-")) {
const num = Number(nextArg);
if (Number.isFinite(num)) {
config2[key] = num;
}
i++;
}
break;
case "string[]":
if (nextArg && !nextArg.startsWith("-")) {
config2[key] = nextArg.split(",").map((s) => s.trim());
i++;
}
break;
}
}
return config2;
}
function parseEnvFromDefs(defs, env) {
const config2 = {};
for (const [key, def] of Object.entries(defs)) {
if (!def.env)
continue;
const val = env[def.env];
if (val === void 0)
continue;
switch (def.type) {
case "boolean":
if (val === "true")
config2[key] = true;
else if (val === "false")
config2[key] = false;
break;
case "number": {
if (val === "")
break;
const num = Number(val);
if (Number.isFinite(num))
config2[key] = num;
break;
}
case "string":
if (val)
config2[key] = val;
break;
case "string[]":
if (val)
config2[key] = val.split(",").map((s) => s.trim());
break;
}
}
return config2;
}
function parseConfigFileFromDefs(defs, fileContent) {
const config2 = {};
const cliNameMap = /* @__PURE__ */ new Map();
for (const [key, def] of Object.entries(defs)) {
const cliName = def.cli.replace(/^--/, "");
cliNameMap.set(cliName, { key, def });
const camelCase = cliName.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
if (camelCase !== cliName) {
cliNameMap.set(camelCase, { key, def });
}
cliNameMap.set(key, { key, def });
}
for (const [fileKey, val] of Object.entries(fileContent)) {
const entry = cliNameMap.get(fileKey);
if (!entry)
continue;
const { key, def } = entry;
switch (def.type) {
case "boolean":
if (typeof val === "boolean")
config2[key] = val;
break;
case "number":
if (typeof val === "number" && Number.isFinite(val))
config2[key] = val;
break;
case "string":
if (typeof val === "string" && val !== "")
config2[key] = val;
break;
case "string[]":
if (Array.isArray(val))
config2[key] = val.filter((v) => typeof v === "string");
else if (typeof val === "string")
config2[key] = val.split(",").map((s) => s.trim());
break;
}
}
return config2;
}
function getDefaultsFromDefs(defs) {
const defaults = {};
for (const [key, def] of Object.entries(defs)) {
if (def.default !== void 0) {
defaults[key] = def.default;
}
}
return defaults;
}
function generateHelp(defs, opts) {
const lines = [];
if (opts?.usage) {
lines.push(`Usage: ${opts.usage}`);
lines.push("");
}
lines.push("Options:");
lines.push(" --help, -h Show this help message");
lines.push(" --version, -v Show version number");
lines.push(" --init Generate .voicevoxrc.json with default settings");
lines.push("");
const groups = /* @__PURE__ */ new Map();
for (const [key, def] of Object.entries(defs)) {
const group = def.group;
if (!groups.has(group))
groups.set(group, []);
groups.get(group).push({ key, def });
}
for (const [groupName, entries] of groups) {
lines.push(` ${groupName}:`);
for (const { def } of entries) {
const flag = def.type === "boolean" ? def.cli : `${def.cli} ${def.valueName || "<value>"}`;
const defaultStr = def.default !== void 0 ? ` (default: ${Array.isArray(def.default) ? def.default.join(",") : def.default})` : "";
const line = ` ${flag.padEnd(28)}${def.description}${defaultStr}`;
lines.push(line);
if (def.type === "boolean") {
const baseName = def.cli.replace(/^--/, "");
const negFlag = `--no-${baseName}`;
lines.push(` ${negFlag.padEnd(28)}Disable ${def.description.toLowerCase().replace(/^enable /, "")}`);
}
}
lines.push("");
}
if (opts?.examples?.length) {
lines.push("Examples:");
for (const ex of opts.examples) {
lines.push(` ${ex}`);
}
lines.push("");
}
return lines.join("\n");
}
function generateConfigTemplate(defs, opts) {
const template = {};
const excludeSet = new Set(opts?.exclude ?? []);
for (const [key, def] of Object.entries(defs)) {
if (excludeSet.has(key))
continue;
if (def.default === void 0)
continue;
const cliName = def.cli.replace(/^--/, "");
template[cliName] = def.default;
}
return template;
}
function filterUndefined(obj) {
return Object.fromEntries(Object.entries(obj).filter(([_, v]) => v !== void 0));
}
// ../../packages/mcp-core/dist/config.js
var baseConfigDefs = {
httpMode: {
cli: "--http",
env: "MCP_HTTP_MODE",
description: "Enable HTTP server mode",
group: "Server Options