UNPKG

@cyanheads/jinaai-mcp-server

Version:

A Model Context Protocol (MCP) server that provides intelligent web reading capabilities using the Jina AI Reader API. It extracts clean, LLM-ready content from any URL.

139 lines 5.25 kB
/** * @fileoverview Provides a high-fidelity bridge between the MCP SDK's Node.js-style * streamable HTTP transport and Hono's Web Standards-based streaming response. * This class is essential for adapting the Node.js `http.ServerResponse` API * to a format consumable by modern web frameworks. * @module src/mcp-server/transports/core/honoNodeBridge */ import { PassThrough } from "stream"; /** * A mock `http.ServerResponse` that pipes all written data to a `PassThrough` stream. * * This class serves as a critical compatibility layer, emulating the behavior of a * Node.js `ServerResponse` to capture status codes, headers, and the response body. * The captured data can then be used to construct a Web-standard `Response` object, * for instance in a Hono application. It pays close attention to the timing of when * headers are considered "sent" to mimic Node.js behavior accurately. */ export class HonoStreamResponse extends PassThrough { statusCode = 200; headers = {}; _headersSent = false; constructor() { super(); } /** * A getter that reports whether the headers have been sent. * In this emulation, headers are considered sent the first time `write()` or `end()` is called. */ get headersSent() { return this._headersSent; } /** * Sets the status code and headers for the response, mimicking `http.ServerResponse.writeHead`. * * @param statusCode - The HTTP status code. * @param statusMessageOrHeaders - An optional status message (string) or headers object. * @param headers - An optional headers object, used if the second argument is a status message. * @returns The instance of the class for chaining. */ writeHead(statusCode, statusMessageOrHeaders, headers) { if (this._headersSent) { // Per Node.js spec, do nothing if headers are already sent. return this; } this.statusCode = statusCode; const headersArg = typeof statusMessageOrHeaders === "string" ? headers : statusMessageOrHeaders; if (headersArg) { for (const [key, value] of Object.entries(headersArg)) { if (value !== undefined) { this.setHeader(key, value); } } } return this; } /** * Sets a single header value. * * @param name - The name of the header. * @param value - The value of the header. * @returns The instance of the class for chaining. */ setHeader(name, value) { if (this._headersSent) { // This is a deviation from Node.js (which would throw), but provides a // more graceful warning for this emulation layer. console.warn(`[HonoBridge] Warning: Cannot set header "${name}" after headers are sent.`); return this; } this.headers[name.toLowerCase()] = value; return this; } /** * Gets a header that has been queued for the response. * @param name - The name of the header. * @returns The value of the header, or undefined if not set. */ getHeader(name) { return this.headers[name.toLowerCase()]; } /** * Returns a copy of the current outgoing headers. */ getHeaders() { return { ...this.headers }; } /** * Removes a header that has been queued for the response. * @param name - The name of the header to remove. */ removeHeader(name) { if (this._headersSent) { console.warn(`[HonoBridge] Warning: Cannot remove header "${name}" after headers are sent.`); return; } delete this.headers[name.toLowerCase()]; } /** * A private helper to mark headers as sent. This is called implicitly * before any part of the body is written. */ ensureHeadersSent() { if (!this._headersSent) { this._headersSent = true; } } /** * Writes a chunk of the response body, mimicking `http.ServerResponse.write`. * This is the first point where headers are implicitly flushed. */ write(chunk, encodingOrCallback, callback) { this.ensureHeadersSent(); const encoding = typeof encodingOrCallback === "string" ? encodingOrCallback : undefined; const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : callback; if (encoding) { return super.write(chunk, encoding, cb); } return super.write(chunk, cb); } /** * Finishes sending the response, mimicking `http.ServerResponse.end`. * This also implicitly flushes headers if they haven't been sent yet. */ end(chunk, encodingOrCallback, callback) { this.ensureHeadersSent(); const encoding = typeof encodingOrCallback === "string" ? encodingOrCallback : undefined; const cb = typeof encodingOrCallback === "function" ? encodingOrCallback : callback; if (encoding) { super.end(chunk, encoding, cb); } else { super.end(chunk, cb); } return this; } } //# sourceMappingURL=honoNodeBridge.js.map