1- import { exec } from 'node:child_process' ;
21import fs from 'node:fs/promises' ;
32import { createServer } from 'node:http' ;
43import os from 'node:os' ;
54import path from 'node:path' ;
65import { URL } from 'node:url' ;
7- import { promisify } from 'node:util' ;
86import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js' ;
97import type {
108 OAuthClientInformation ,
119 OAuthClientInformationFull ,
1210 OAuthClientMetadata ,
1311 OAuthTokens ,
1412} from '@modelcontextprotocol/sdk/shared/auth.js' ;
15- import { throttle } from 'lodash' ;
16-
17- const execAsync = promisify ( exec ) ;
13+ import open from 'open' ;
1814
1915interface StoredTokens {
2016 tokens ?: OAuthTokens ;
@@ -31,7 +27,6 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
3127 private _clientInfo ?: OAuthClientInformationFull ;
3228 private _codeVerifier ?: string ;
3329 private tokenFilePath : string ;
34- private throttledOpenBrowser : ( url : string ) => Promise < void > ;
3530
3631 /**
3732 * Check for existing client information in storage
@@ -60,8 +55,6 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
6055 this . tokenFilePath =
6156 tokenStoragePath ||
6257 path . join ( os . homedir ( ) , '.pageindex-mcp' , 'oauth-tokens.json' ) ;
63-
64- this . throttledOpenBrowser = throttle ( this . openBrowser . bind ( this ) , 1000 ) ;
6558 }
6659
6760 get redirectUrl ( ) : string | URL {
@@ -107,7 +100,7 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
107100
108101 async redirectToAuthorization ( authorizationUrl : URL ) : Promise < void > {
109102 try {
110- await this . throttledOpenBrowser ( authorizationUrl . toString ( ) ) ;
103+ await open ( authorizationUrl . toString ( ) ) ;
111104 } catch ( error ) {
112105 console . error (
113106 error instanceof Error
@@ -221,7 +214,7 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
221214 res . end ( 'Not found' ) ;
222215 } ) ;
223216
224- server . listen ( port , ( ) => {
217+ server . listen ( port , 'localhost' , ( ) => {
225218 console . error ( `Listening for OAuth callback on port ${ port } ...\n` ) ;
226219 } ) ;
227220
@@ -239,24 +232,6 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
239232 } ) ;
240233 }
241234
242- private async openBrowser ( url : string ) : Promise < void > {
243- const platform = process . platform ;
244- let command : string ;
245-
246- switch ( platform ) {
247- case 'darwin' :
248- command = `open "${ url } "` ;
249- break ;
250- case 'win32' :
251- command = `start "${ url } "` ;
252- break ;
253- default :
254- command = `xdg-open "${ url } "` ;
255- break ;
256- }
257- await execAsync ( command ) ;
258- }
259-
260235 public async loadFromStorage ( ) : Promise < void > {
261236 try {
262237 const data = await fs . readFile ( this . tokenFilePath , 'utf-8' ) ;
@@ -281,6 +256,7 @@ export class PageIndexOAuthProvider implements OAuthClientProvider {
281256
282257 try {
283258 await fs . mkdir ( path . dirname ( this . tokenFilePath ) , { recursive : true } ) ;
259+ // Set restrictive file permissions (Unix-like systems only; ignored on Windows)
284260 await fs . writeFile ( this . tokenFilePath , JSON . stringify ( stored , null , 2 ) , {
285261 mode : 0o600 ,
286262 } ) ;
0 commit comments