inspector/core/mcp/remote/createRemoteLogger.ts
Cliff Hall da37692485
refactor(web): sweep AGENTS.md TypeScript + Mantine rule violations (#1771)
Codebase-wide sweep bringing the web client into strict compliance with the AGENTS.md TypeScript and Mantine/React conventions: ~170 inline 2+-static-prop elements extracted to named .withProps() constants across ~77 files, the AGENTS.md rule wording tightened to match (static-prop boundary + Accordion/Transition/data-*/Box exemptions), a real ScreenStage Box->Flex layout regression fixed (direction: column) with a Storybook regression guard, and an App.tsx double-cast tightened. Closes #1762.
2026-07-25 11:38:49 -04:00

64 lines
2.1 KiB
TypeScript

/**
* Creates a pino logger that POSTs log events to the remote /api/log endpoint
* via browser.transmit. Use in the browser when InspectorClient needs logging—
* logs are written server-side to the same file logger as Node mode.
*
* Uses pino/browser so transmit works in both Node (tests) and browser.
*/
// pino ships a browser build at `pino/browser.js` but no `.d.ts` for it, and TS
// resolves the real JS file (so an ambient `declare module` can't type it) —
// suppress the resulting implicit-any. Node ESM requires the explicit `.js`.
// @ts-expect-error - pino/browser.js exists but has no type declarations
import pino from "pino/browser.js";
import type { Logger, LogEvent } from "pino";
export interface RemoteLoggerOptions {
/** Base URL of the remote server (e.g. http://localhost:3000) */
baseUrl: string;
/** Optional auth token for x-mcp-remote-auth header */
authToken?: string;
/** Fetch function to use (default: globalThis.fetch) */
fetchFn?: typeof fetch;
/** Minimum level to send (default: 'info') */
level?: string;
}
/**
* Creates a pino logger that transmits log events to the remote /api/log endpoint.
* Returns a real pino.Logger; suitable for InspectorClient's logger option.
*/
export function createRemoteLogger(options: RemoteLoggerOptions): Logger {
const baseUrl = options.baseUrl.replace(/\/$/, "");
const fetchFn = options.fetchFn ?? globalThis.fetch;
const level = options.level ?? "info";
return pino({
level,
browser: {
write: () => {},
transmit: {
level,
send: (_level: unknown, logEvent: LogEvent) => {
const headers: Record<string, string> = {
"Content-Type": "application/json",
};
if (options.authToken) {
headers["x-mcp-remote-auth"] = `Bearer ${options.authToken}`;
}
fetchFn(`${baseUrl}/api/log`, {
method: "POST",
headers,
body: JSON.stringify(logEvent),
}).catch(() => {
// Silently ignore log delivery failures
});
},
},
},
});
}