example-remote-server/src/handlers/common.ts
Jerome f4aed937f0
Replace console.log with structured logging for Cloud Run
- Add structured logger utility with Cloud Run trace context support
- Uses AsyncLocalStorage for request context propagation
- Replace all console.log/error/warn statements with structured logger
- Add logging middleware to capture request/response metadata
- Support Google Cloud Logging severity levels and trace correlation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-10 10:55:57 +01:00

63 lines
1.8 KiB
TypeScript

import { NextFunction, Request, Response } from "express";
import { withContext } from "../context.js";
import { readMcpInstallation } from "../services/auth.js";
import { logger } from "../utils/logger.js";
import { JSONRPCError, JSONRPCNotification, JSONRPCRequest, JSONRPCResponse } from "@modelcontextprotocol/sdk/types.js";
export function logMcpMessage(
message: JSONRPCError | JSONRPCNotification | JSONRPCRequest | JSONRPCResponse,
sessionId: string,
) {
// check if message has a method field
if ("method" in message) {
if (message.method === "tools/call") {
logger.info('Processing MCP method', {
sessionId,
method: message.method,
toolName: message.params?.name
});
} else {
logger.info('Processing MCP method', {
sessionId,
method: message.method
});
}
} else if ("error" in message) {
logger.warning('Received error message', {
sessionId,
errorMessage: message.error.message,
errorCode: message.error.code
});
}
}
export async function authContext(
req: Request,
res: Response,
next: NextFunction,
) {
const authInfo = req.auth
if (!authInfo) {
res.set("WWW-Authenticate", 'Bearer error="invalid_token"');
res.status(401).json({ error: "Invalid access token" });
return;
}
const token = authInfo.token;
// Load UpstreamInstallation based on the access token
const mcpInstallation = await readMcpInstallation(token);
if (!mcpInstallation) {
res.set("WWW-Authenticate", 'Bearer error="invalid_token"');
res.status(401).json({ error: "Invalid access token" });
return;
}
// Wrap the rest of the request handling in the context
withContext({ mcpAccessToken: token, fakeUpstreamInstallation: mcpInstallation.fakeUpstreamInstallation }, () =>
next(),
);
}