From 2e1ce68a307ef3823e526d4e2eeaedabf9158d90 Mon Sep 17 00:00:00 2001 From: Oliver Kieselbach Date: Mon, 29 Jun 2026 21:55:12 +0200 Subject: [PATCH] chore(mcp): bump to 1.4.1 + log /mcp auth-failure paths for diagnostics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump version so the deployed build is visible at /health (it stayed 1.4.0 across several fixes, so neither side could tell what was live). Add one log line to each /mcp 401/403 branch in accessGuard. The success path stays quiet, but a stuck client — e.g. VS Code looping unauthenticated `initialize` — is otherwise invisible because the happy paths emit nothing. The trace records the JSON-RPC method and the failure reason so the next connection attempt is diagnosable from container logs. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/McpServer/autopilot-monitor-mcp/package.json | 2 +- .../autopilot-monitor-mcp/src/access-guard.ts | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/McpServer/autopilot-monitor-mcp/package.json b/src/McpServer/autopilot-monitor-mcp/package.json index d0bfe209..1e274ade 100644 --- a/src/McpServer/autopilot-monitor-mcp/package.json +++ b/src/McpServer/autopilot-monitor-mcp/package.json @@ -1,6 +1,6 @@ { "name": "autopilot-monitor-mcp", - "version": "1.4.0", + "version": "1.4.1", "description": "MCP server for Autopilot-Monitor — enables AI agents to query enrollment sessions, device properties, events and vulnerabilities", "type": "module", "bin": { diff --git a/src/McpServer/autopilot-monitor-mcp/src/access-guard.ts b/src/McpServer/autopilot-monitor-mcp/src/access-guard.ts index d762ebd4..1a54542d 100644 --- a/src/McpServer/autopilot-monitor-mcp/src/access-guard.ts +++ b/src/McpServer/autopilot-monitor-mcp/src/access-guard.ts @@ -202,8 +202,15 @@ export function accessGuard(req: Request, res: Response, next: NextFunction): vo const baseUrl = getPublicBaseUrl(req); const resourceMetadataUrl = `${baseUrl}/.well-known/oauth-protected-resource`; + // Lightweight auth-flow trace. The success path stays quiet (runWithCaller → + // next), but every 401/403 logs one line so a stuck client (e.g. VS Code + // looping unauthenticated `initialize`) is visible in container logs — the + // happy paths otherwise emit nothing and the flow is a black box. + const rpcMethod = (req.body as { method?: string } | undefined)?.method ?? '?'; + const authHeader = req.headers.authorization; if (!authHeader?.startsWith('Bearer ')) { + console.error(`[mcp-auth] 401 no-bearer (method=${rpcMethod}) — client has not attached a token yet`); res.setHeader('WWW-Authenticate', `Bearer resource_metadata="${resourceMetadataUrl}"`); res.status(401).json({ error: 'Missing or invalid Authorization header' }); return; @@ -212,12 +219,14 @@ export function accessGuard(req: Request, res: Response, next: NextFunction): vo const token = authHeader.slice(7); const claims = extractTokenClaims(token); if (!claims || !claims.upn) { + console.error(`[mcp-auth] 401 invalid-token-claims (method=${rpcMethod})`); res.setHeader('WWW-Authenticate', `Bearer resource_metadata="${resourceMetadataUrl}", error="invalid_token"`); res.status(401).json({ error: 'Invalid token: missing required claims' }); return; } if (isTokenExpired(claims)) { + console.error(`[mcp-auth] 401 token-expired (method=${rpcMethod}, upn=${claims.upn})`); res.setHeader('WWW-Authenticate', `Bearer resource_metadata="${resourceMetadataUrl}", error="invalid_token"`); res.status(401).json({ error: 'Token expired' }); return; @@ -242,9 +251,11 @@ export function accessGuard(req: Request, res: Response, next: NextFunction): vo // Backend could not reach a verdict (unreachable / malformed). Fail // closed, but do NOT tell the user they are "not whitelisted" — it is // not their fault and would send them chasing the wrong fix. + console.error(`[mcp-auth] 403 access-check-unavailable (method=${rpcMethod}, upn=${upn})`); res.status(403).json({ error: 'MCP access check unavailable', reason: result.reason }); return; } + console.error(`[mcp-auth] 403 not-whitelisted (method=${rpcMethod}, upn=${upn})`); // Genuine authorization denial — most commonly the user's account is not // on the MCP whitelist. Spell that out and tell them what to do, so they // can ask the MCP server owner to enable their account instead of being