Skip to content

Commit 4fe1374

Browse files
committed
Add debug logging for OAuth flow troubleshooting
Add logging to track authorization flow steps and token introspection to help diagnose issues with separate mode authentication.
1 parent b32d638 commit 4fe1374

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/auth/provider.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
saveRefreshToken,
1919
} from '../services/auth.js';
2020
import { InvalidTokenError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
21+
import { logger } from '../utils/logger.js';
2122

2223
/**
2324
* Implementation of the OAuthRegisteredClientsStore interface using the existing client registration system
@@ -67,6 +68,12 @@ export class EverythingAuthProvider implements OAuthServerProvider {
6768
state: params.state,
6869
});
6970

71+
logger.debug('Saved pending authorization', {
72+
authorizationCode: authorizationCode.substring(0, 8) + '...',
73+
clientId: client.client_id,
74+
state: params.state?.substring(0, 8) + '...'
75+
});
76+
7077
// TODO: should we use a different key, other than the authorization code, to store the pending authorization?
7178

7279
// You can redirect to another page, or you can send an html response directly

src/handlers/fakeauth.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Request, Response } from "express";
22
import { generateMcpTokens, readPendingAuthorization, saveMcpInstallation, saveRefreshToken, saveTokenExchange } from "../services/auth.js";
33
import { McpInstallation } from "../types.js";
4+
import { logger } from "../utils/logger.js";
45

56
// this module has a fake upstream auth server that returns a fake auth code, it also allows you to authorize or fail
67
// authorization, to test the different flows
@@ -266,6 +267,12 @@ export async function handleFakeAuthorizeRedirect(req: Request, res: Response) {
266267
userId, // User ID from the authorization flow
267268
} = req.query;
268269

270+
logger.debug('Fake auth redirect received', {
271+
mcpAuthorizationCode: typeof mcpAuthorizationCode === 'string' ? mcpAuthorizationCode.substring(0, 8) + '...' : mcpAuthorizationCode,
272+
upstreamAuthorizationCode: typeof upstreamAuthorizationCode === 'string' ? upstreamAuthorizationCode.substring(0, 8) + '...' : upstreamAuthorizationCode,
273+
userId
274+
});
275+
269276
// This is where you'd exchange the upstreamAuthorizationCode for access/refresh tokens
270277
// In this case, we're just going to fake it
271278
const upstreamTokens = await fakeUpstreamTokenExchange(upstreamAuthorizationCode as string);
@@ -276,12 +283,21 @@ export async function handleFakeAuthorizeRedirect(req: Request, res: Response) {
276283
}
277284

278285
const pendingAuth = await readPendingAuthorization(mcpAuthorizationCode);
286+
logger.debug('Reading pending authorization', {
287+
mcpAuthorizationCode: mcpAuthorizationCode.substring(0, 8) + '...',
288+
found: !!pendingAuth
289+
});
290+
279291
if (!pendingAuth) {
280292
throw new Error("No matching authorization found");
281293
}
282294

283-
295+
logger.debug('Generating MCP tokens');
284296
const mcpTokens = generateMcpTokens();
297+
logger.debug('MCP tokens generated', {
298+
hasAccessToken: !!mcpTokens.access_token,
299+
hasRefreshToken: !!mcpTokens.refresh_token
300+
});
285301

286302
const mcpInstallation: McpInstallation = {
287303
fakeUpstreamInstallation: {
@@ -294,25 +310,37 @@ export async function handleFakeAuthorizeRedirect(req: Request, res: Response) {
294310
userId: (userId as string) || 'anonymous-user', // Include user ID from auth flow
295311
}
296312

313+
logger.debug('Saving MCP installation');
297314
// Store the upstream authorization data
298315
await saveMcpInstallation(mcpTokens.access_token, mcpInstallation);
316+
logger.debug('MCP installation saved');
299317

300318
// Store the refresh token -> access token mapping
301319
if (mcpTokens.refresh_token) {
320+
logger.debug('Saving refresh token mapping');
302321
await saveRefreshToken(mcpTokens.refresh_token, mcpTokens.access_token);
322+
logger.debug('Refresh token mapping saved');
303323
}
304324

325+
logger.debug('Saving token exchange data');
305326
// Store the token exchange data
306327
await saveTokenExchange(mcpAuthorizationCode, {
307328
mcpAccessToken: mcpTokens.access_token,
308329
alreadyUsed: false,
309330
});
331+
logger.debug('Token exchange data saved');
310332

311333
// Redirect back to the original application with the authorization code and state
312334
const redirectUrl = pendingAuth.state ?
313335
`${pendingAuth.redirectUri}?code=${mcpAuthorizationCode}&state=${pendingAuth.state}` :
314336
`${pendingAuth.redirectUri}?code=${mcpAuthorizationCode}`;
337+
338+
logger.debug('Redirecting to callback', {
339+
redirectUrl,
340+
hasState: !!pendingAuth.state
341+
});
315342
res.redirect(redirectUrl);
343+
logger.debug('Redirect completed');
316344
};
317345

318346
function fakeUpstreamTokenExchange(

0 commit comments

Comments
 (0)