@@ -96,9 +96,11 @@ await client.connect(transport);
9696Store tokens across sessions:
9797
9898``` typescript
99+ import open from " open" ;
99100import { browserAuth , fileStore } from " oauth-callback/mcp" ;
100101
101102const authProvider = browserAuth ({
103+ launch: open ,
102104 store: fileStore (), // Persists to ~/.mcp/tokens.json
103105 scope: " read write" ,
104106});
@@ -111,10 +113,13 @@ const authProvider = browserAuth({
111113If you have pre-registered OAuth credentials:
112114
113115``` typescript
116+ import open from " open" ;
117+
114118const authProvider = browserAuth ({
115119 clientId: process .env .OAUTH_CLIENT_ID ,
116120 clientSecret: process .env .OAUTH_CLIENT_SECRET ,
117121 scope: " read write admin" ,
122+ launch: open ,
118123 store: fileStore (),
119124});
120125```
@@ -124,9 +129,11 @@ const authProvider = browserAuth({
124129Store tokens in a specific location:
125130
126131``` typescript
132+ import open from " open" ;
127133import { browserAuth , fileStore } from " oauth-callback/mcp" ;
128134
129135const authProvider = browserAuth ({
136+ launch: open ,
130137 store: fileStore (" /path/to/my-tokens.json" ),
131138 storeKey: " my-app-production" , // Namespace for multiple environments
132139});
@@ -137,10 +144,13 @@ const authProvider = browserAuth({
137144Configure the callback server:
138145
139146``` typescript
147+ import open from " open" ;
148+
140149const authProvider = browserAuth ({
141150 port: 8080 ,
142151 hostname: " 127.0.0.1" ,
143152 callbackPath: " /oauth/callback" ,
153+ launch: open ,
144154 store: fileStore (),
145155});
146156```
@@ -157,7 +167,10 @@ Ensure your OAuth app's redirect URI matches your configuration:
157167Provide branded callback pages:
158168
159169``` typescript
170+ import open from " open" ;
171+
160172const authProvider = browserAuth ({
173+ launch: open ,
161174 successHtml: `
162175 <!DOCTYPE html>
163176 <html>
@@ -208,7 +221,10 @@ const authProvider = browserAuth({
208221Monitor OAuth flow for debugging:
209222
210223``` typescript
224+ import open from " open" ;
225+
211226const authProvider = browserAuth ({
227+ launch: open ,
212228 onRequest : (req ) => {
213229 const url = new URL (req .url );
214230 console .log (` [OAuth] ${req .method } ${url .pathname } ` );
@@ -263,9 +279,12 @@ sequenceDiagram
263279No pre-registration needed:
264280
265281``` typescript
282+ import open from " open" ;
283+
266284// No clientId or clientSecret required!
267285const authProvider = browserAuth ({
268286 scope: " read write" ,
287+ launch: open ,
269288 store: fileStore (), // Persist dynamically registered client
270289});
271290
@@ -317,9 +336,11 @@ interface OAuthStore extends TokenStore {
317336Ephemeral storage (tokens lost on restart):
318337
319338``` typescript
339+ import open from " open" ;
320340import { browserAuth , inMemoryStore } from " oauth-callback/mcp" ;
321341
322342const authProvider = browserAuth ({
343+ launch: open ,
323344 store: inMemoryStore (),
324345});
325346```
@@ -335,15 +356,18 @@ const authProvider = browserAuth({
335356Persistent storage to JSON file:
336357
337358``` typescript
359+ import open from " open" ;
338360import { browserAuth , fileStore } from " oauth-callback/mcp" ;
339361
340362// Default location: ~/.mcp/tokens.json
341363const authProvider = browserAuth ({
364+ launch: open ,
342365 store: fileStore (),
343366});
344367
345368// Custom location
346369const customAuth = browserAuth ({
370+ launch: open ,
347371 store: fileStore (" /path/to/tokens.json" ),
348372});
349373```
@@ -388,6 +412,7 @@ class RedisStore implements TokenStore {
388412
389413// Use custom store
390414const authProvider = browserAuth ({
415+ launch: open ,
391416 store: new RedisStore (redisClient ),
392417});
393418```
@@ -409,8 +434,10 @@ PKCE prevents authorization code interception attacks by:
409434The provider automatically generates secure state parameters:
410435
411436``` typescript
437+ import open from " open" ;
438+
412439// State is automatically generated and validated
413- const authProvider = browserAuth ();
440+ const authProvider = browserAuth ({ launch: open } );
414441// No manual state handling needed!
415442```
416443
@@ -430,8 +457,11 @@ Tokens are automatically managed with expiry tracking:
430457File storage uses restrictive permissions:
431458
432459``` typescript
460+ import open from " open" ;
461+
433462// Files are created with mode 0600 (owner read/write only)
434463const authProvider = browserAuth ({
464+ launch: open ,
435465 store: fileStore (), // Secure file permissions
436466});
437467```
@@ -472,7 +502,10 @@ The provider includes automatic retry for transient failures:
472502Configure timeout for different scenarios:
473503
474504``` typescript
505+ import open from " open" ;
506+
475507const authProvider = browserAuth ({
508+ launch: open ,
476509 authTimeout: 600000 , // 10 minutes for first-time setup
477510});
478511```
@@ -484,13 +517,15 @@ const authProvider = browserAuth({
484517Full example with Dynamic Client Registration:
485518
486519``` typescript
520+ import open from " open" ;
487521import { browserAuth , fileStore } from " oauth-callback/mcp" ;
488522import { Client } from " @modelcontextprotocol/sdk/client/index.js" ;
489523import { StreamableHTTPClientTransport } from " @modelcontextprotocol/sdk/client/streamableHttp.js" ;
490524
491525async function connectToNotion() {
492526 // No client credentials needed - uses DCR!
493527 const authProvider = browserAuth ({
528+ launch: open , // Opens browser for OAuth consent
494529 store: fileStore (), // Persist tokens and client registration
495530 scope: " read write" ,
496531 onRequest : (req ) => {
@@ -536,24 +571,28 @@ connectToNotion();
536571Support development, staging, and production:
537572
538573``` typescript
539- import { browserAuth , fileStore } from " oauth-callback/mcp" ;
574+ import open from " open" ;
575+ import { browserAuth , fileStore , inMemoryStore } from " oauth-callback/mcp" ;
540576
541577function createAuthProvider(environment : " dev" | " staging" | " prod" ) {
542578 const configs = {
543579 dev: {
544580 port: 3000 ,
581+ launch: open ,
545582 store: inMemoryStore (), // No persistence in dev
546583 authTimeout: 60000 ,
547- onRequest : (req ) => console .log (" [DEV]" , req .url ),
584+ onRequest : (req : Request ) => console .log (" [DEV]" , req .url ),
548585 },
549586 staging: {
550587 port: 3001 ,
588+ launch: open ,
551589 store: fileStore (" ~/.mcp/staging-tokens.json" ),
552590 storeKey: " staging" ,
553591 authTimeout: 120000 ,
554592 },
555593 prod: {
556594 port: 3002 ,
595+ launch: open ,
557596 store: fileStore (" ~/.mcp/prod-tokens.json" ),
558597 storeKey: " production" ,
559598 authTimeout: 300000 ,
@@ -576,9 +615,11 @@ const authProvider = createAuthProvider(
576615While automatic refresh is pending full implementation, you can handle expired tokens:
577616
578617``` typescript
618+ import open from " open" ;
579619import { browserAuth , fileStore } from " oauth-callback/mcp" ;
580620
581621const authProvider = browserAuth ({
622+ launch: open ,
582623 store: fileStore (),
583624 scope: " offline_access" , // Request refresh token
584625});
@@ -701,8 +742,11 @@ describe("OAuth Flow Integration", () => {
701742::: details Port Already in Use
702743
703744``` typescript
745+ import open from " open" ;
746+
704747// Use a different port
705748const authProvider = browserAuth ({
749+ launch: open ,
706750 port: 8080 , // Try alternative port
707751});
708752```
@@ -712,8 +756,11 @@ const authProvider = browserAuth({
712756::: details Tokens Not Persisting
713757
714758``` typescript
759+ import open from " open" ;
760+
715761// Ensure you're using file store, not in-memory
716762const authProvider = browserAuth ({
763+ launch: open ,
717764 store: fileStore (), // ✅ Persistent
718765 // store: inMemoryStore() // ❌ Lost on restart
719766});
@@ -725,8 +772,11 @@ const authProvider = browserAuth({
725772Some servers may not support Dynamic Client Registration:
726773
727774``` typescript
775+ import open from " open" ;
776+
728777// Fallback to pre-registered credentials
729778const authProvider = browserAuth ({
779+ launch: open ,
730780 clientId: " your-client-id" ,
731781 clientSecret: " your-client-secret" ,
732782});
0 commit comments