oauth-callback 1.2.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -19
- package/dist/auth/browser-auth.d.ts +3 -1
- package/dist/auth/browser-auth.d.ts.map +1 -1
- package/dist/index.d.ts +34 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +312 -309
- package/dist/mcp-types.d.ts +3 -2
- package/dist/mcp-types.d.ts.map +1 -1
- package/dist/mcp.js +340 -336
- package/dist/server.d.ts.map +1 -1
- package/dist/types.d.ts +37 -13
- package/dist/types.d.ts.map +1 -1
- package/package.json +14 -11
- package/src/auth/browser-auth.ts +62 -113
- package/src/index.ts +59 -30
- package/src/mcp-types.ts +4 -4
- package/src/server.ts +15 -22
- package/src/types.ts +42 -15
package/README.md
CHANGED
|
@@ -31,33 +31,38 @@ A lightweight OAuth 2.0 callback handler for Node.js, Deno, and Bun with built-i
|
|
|
31
31
|
## Installation
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
bun add oauth-callback
|
|
34
|
+
bun add oauth-callback open
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
Or with npm:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
npm install oauth-callback
|
|
40
|
+
npm install oauth-callback open
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
> **Note:** The `open` package is optional but recommended for browser launching. If using pnpm, install it explicitly: `pnpm add open`
|
|
44
|
+
|
|
43
45
|
## Quick Start
|
|
44
46
|
|
|
45
47
|
```typescript
|
|
48
|
+
import open from "open";
|
|
46
49
|
import { getAuthCode, OAuthError } from "oauth-callback";
|
|
47
50
|
|
|
48
|
-
// Simple usage
|
|
49
|
-
const result = await getAuthCode(
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
// Simple usage - pass `open` to launch browser
|
|
52
|
+
const result = await getAuthCode({
|
|
53
|
+
authorizationUrl:
|
|
54
|
+
"https://example.com/oauth/authorize?client_id=xxx&redirect_uri=http://localhost:3000/callback",
|
|
55
|
+
launch: open,
|
|
56
|
+
});
|
|
52
57
|
console.log("Authorization code:", result.code);
|
|
53
58
|
|
|
54
59
|
// MCP SDK integration - use specific import
|
|
55
60
|
import { browserAuth, fileStore } from "oauth-callback/mcp";
|
|
56
|
-
const authProvider = browserAuth({ store: fileStore() });
|
|
61
|
+
const authProvider = browserAuth({ launch: open, store: fileStore() });
|
|
57
62
|
|
|
58
63
|
// Or via namespace import
|
|
59
64
|
import { mcp } from "oauth-callback";
|
|
60
|
-
const authProvider = mcp.browserAuth({ store: mcp.fileStore() });
|
|
65
|
+
const authProvider = mcp.browserAuth({ launch: open, store: mcp.fileStore() });
|
|
61
66
|
```
|
|
62
67
|
|
|
63
68
|
## Usage Examples
|
|
@@ -65,6 +70,7 @@ const authProvider = mcp.browserAuth({ store: mcp.fileStore() });
|
|
|
65
70
|
### Basic OAuth Flow
|
|
66
71
|
|
|
67
72
|
```typescript
|
|
73
|
+
import open from "open";
|
|
68
74
|
import { getAuthCode, OAuthError } from "oauth-callback";
|
|
69
75
|
|
|
70
76
|
async function authenticate() {
|
|
@@ -78,7 +84,10 @@ async function authenticate() {
|
|
|
78
84
|
});
|
|
79
85
|
|
|
80
86
|
try {
|
|
81
|
-
const result = await getAuthCode(
|
|
87
|
+
const result = await getAuthCode({
|
|
88
|
+
authorizationUrl: authUrl,
|
|
89
|
+
launch: open,
|
|
90
|
+
});
|
|
82
91
|
console.log("Authorization code:", result.code);
|
|
83
92
|
console.log("State:", result.state);
|
|
84
93
|
|
|
@@ -98,10 +107,12 @@ async function authenticate() {
|
|
|
98
107
|
### Custom Port Configuration
|
|
99
108
|
|
|
100
109
|
```typescript
|
|
110
|
+
import open from "open";
|
|
101
111
|
import { getAuthCode } from "oauth-callback";
|
|
102
112
|
|
|
103
113
|
const result = await getAuthCode({
|
|
104
114
|
authorizationUrl: authUrl,
|
|
115
|
+
launch: open,
|
|
105
116
|
port: 8080, // Use custom port (default: 3000)
|
|
106
117
|
timeout: 60000, // Custom timeout in ms (default: 30000)
|
|
107
118
|
});
|
|
@@ -120,6 +131,7 @@ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/
|
|
|
120
131
|
const authProvider = browserAuth({
|
|
121
132
|
port: 3000,
|
|
122
133
|
scope: "read write",
|
|
134
|
+
launch: open, // Opens browser for OAuth consent
|
|
123
135
|
store: inMemoryStore(), // Or fileStore() for persistence
|
|
124
136
|
});
|
|
125
137
|
|
|
@@ -144,17 +156,20 @@ import { browserAuth, inMemoryStore, fileStore } from "oauth-callback/mcp";
|
|
|
144
156
|
|
|
145
157
|
// Ephemeral storage (tokens lost on restart)
|
|
146
158
|
const ephemeralAuth = browserAuth({
|
|
159
|
+
launch: open,
|
|
147
160
|
store: inMemoryStore(),
|
|
148
161
|
});
|
|
149
162
|
|
|
150
163
|
// Persistent file storage (default: ~/.mcp/tokens.json)
|
|
151
164
|
const persistentAuth = browserAuth({
|
|
165
|
+
launch: open,
|
|
152
166
|
store: fileStore(),
|
|
153
167
|
storeKey: "my-app-tokens", // Namespace for multiple apps
|
|
154
168
|
});
|
|
155
169
|
|
|
156
170
|
// Custom file location
|
|
157
171
|
const customAuth = browserAuth({
|
|
172
|
+
launch: open,
|
|
158
173
|
store: fileStore("/path/to/tokens.json"),
|
|
159
174
|
});
|
|
160
175
|
```
|
|
@@ -168,6 +183,7 @@ const authProvider = browserAuth({
|
|
|
168
183
|
clientId: "your-client-id",
|
|
169
184
|
clientSecret: "your-client-secret",
|
|
170
185
|
scope: "read write",
|
|
186
|
+
launch: open, // Opens browser for OAuth consent
|
|
171
187
|
store: fileStore(), // Persist tokens across sessions
|
|
172
188
|
});
|
|
173
189
|
```
|
|
@@ -175,9 +191,12 @@ const authProvider = browserAuth({
|
|
|
175
191
|
### Advanced Usage
|
|
176
192
|
|
|
177
193
|
```typescript
|
|
194
|
+
import open from "open";
|
|
195
|
+
|
|
178
196
|
// With custom HTML templates and logging
|
|
179
197
|
const result = await getAuthCode({
|
|
180
198
|
authorizationUrl: authUrl,
|
|
199
|
+
launch: open,
|
|
181
200
|
port: 3000,
|
|
182
201
|
hostname: "127.0.0.1", // Bind to specific IP
|
|
183
202
|
successHtml: "<h1>Success! You can close this window.</h1>",
|
|
@@ -209,7 +228,7 @@ try {
|
|
|
209
228
|
|
|
210
229
|
### `getAuthCode(input)`
|
|
211
230
|
|
|
212
|
-
Starts a local HTTP server
|
|
231
|
+
Starts a local HTTP server to capture OAuth callbacks. Optionally launches the authorization URL via the `launch` callback.
|
|
213
232
|
|
|
214
233
|
#### Parameters
|
|
215
234
|
|
|
@@ -219,7 +238,7 @@ Starts a local HTTP server and opens the authorization URL in the user's browser
|
|
|
219
238
|
- `hostname` (string): Hostname to bind the server to (default: "localhost")
|
|
220
239
|
- `callbackPath` (string): URL path for the OAuth callback (default: "/callback")
|
|
221
240
|
- `timeout` (number): Timeout in milliseconds (default: 30000)
|
|
222
|
-
- `
|
|
241
|
+
- `launch` (function): Optional callback to launch the authorization URL (e.g., `open`)
|
|
223
242
|
- `successHtml` (string): Custom HTML to display on successful authorization
|
|
224
243
|
- `errorHtml` (string): Custom HTML to display on authorization error
|
|
225
244
|
- `signal` (AbortSignal): AbortSignal for cancellation support
|
|
@@ -269,6 +288,7 @@ Available from `oauth-callback/mcp`. Creates an MCP SDK-compatible OAuth provide
|
|
|
269
288
|
- `clientSecret` (string): Pre-registered client secret (optional)
|
|
270
289
|
- `store` (TokenStore): Token storage implementation (default: inMemoryStore())
|
|
271
290
|
- `storeKey` (string): Storage key for tokens (default: "mcp-tokens")
|
|
291
|
+
- `launch` (function): Callback to launch auth URL (e.g., `open`)
|
|
272
292
|
- `authTimeout` (number): Authorization timeout in ms (default: 300000)
|
|
273
293
|
- `successHtml` (string): Custom success page HTML
|
|
274
294
|
- `errorHtml` (string): Custom error page HTML
|
|
@@ -311,7 +331,7 @@ TokenStore implementation for persistent token storage.
|
|
|
311
331
|
```
|
|
312
332
|
|
|
313
333
|
1. **Server Creation** — Spins up a temporary localhost HTTP server
|
|
314
|
-
2. **Browser Launch** — Opens the authorization URL
|
|
334
|
+
2. **Browser Launch** — Opens the authorization URL (if `launch` callback provided)
|
|
315
335
|
3. **User Authorization** — User grants permission on the OAuth provider's page
|
|
316
336
|
4. **Callback Capture** — Provider redirects to localhost with the authorization code
|
|
317
337
|
5. **Cleanup** — Server closes automatically, code is returned to your app
|
|
@@ -420,7 +440,11 @@ bun run example:notion # Notion MCP example with Dynamic Client Registration
|
|
|
420
440
|
If port 3000 is already in use, specify a different port:
|
|
421
441
|
|
|
422
442
|
```typescript
|
|
423
|
-
const result = await getAuthCode({
|
|
443
|
+
const result = await getAuthCode({
|
|
444
|
+
authorizationUrl: authUrl,
|
|
445
|
+
launch: open,
|
|
446
|
+
port: 8080,
|
|
447
|
+
});
|
|
424
448
|
```
|
|
425
449
|
|
|
426
450
|
### Firewall Warnings
|
|
@@ -433,13 +457,9 @@ If the browser doesn't open automatically, manually navigate to the authorizatio
|
|
|
433
457
|
|
|
434
458
|
## Contributing
|
|
435
459
|
|
|
436
|
-
Contributions are welcome!
|
|
460
|
+
Contributions are welcome! See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for setup instructions.
|
|
437
461
|
|
|
438
|
-
|
|
439
|
-
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
440
|
-
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
441
|
-
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
442
|
-
5. Open a Pull Request
|
|
462
|
+
**Maintainers wanted** — we're looking for people to help maintain this project. If interested, reach out on [Discord](https://discord.gg/bSsv7XM) or open an issue.
|
|
443
463
|
|
|
444
464
|
## License
|
|
445
465
|
|
|
@@ -8,9 +8,11 @@ import type { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.
|
|
|
8
8
|
*
|
|
9
9
|
* @example
|
|
10
10
|
* ```typescript
|
|
11
|
+
* import open from "open";
|
|
12
|
+
*
|
|
11
13
|
* const transport = new StreamableHTTPClientTransport(
|
|
12
14
|
* new URL("https://mcp.notion.com/mcp"),
|
|
13
|
-
* { authProvider: browserAuth() }
|
|
15
|
+
* { authProvider: browserAuth({ launch: open }) }
|
|
14
16
|
* );
|
|
15
17
|
* ```
|
|
16
18
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-auth.d.ts","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kBAAkB,EAMnB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"browser-auth.d.ts","sourceRoot":"","sources":["../../src/auth/browser-auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,kBAAkB,EAMnB,MAAM,cAAc,CAAC;AAItB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAQpF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,kBAAuB,GAC/B,mBAAmB,CAErB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,34 +1,58 @@
|
|
|
1
1
|
import { type CallbackResult } from "./server";
|
|
2
2
|
import type { GetAuthCodeOptions } from "./types";
|
|
3
3
|
export type { CallbackResult, CallbackServer, ServerOptions } from "./server";
|
|
4
|
-
export { OAuthError } from "./errors";
|
|
4
|
+
export { OAuthError, TimeoutError } from "./errors";
|
|
5
5
|
export type { GetAuthCodeOptions } from "./types";
|
|
6
6
|
export { inMemoryStore } from "./storage/memory";
|
|
7
7
|
export { fileStore } from "./storage/file";
|
|
8
8
|
import * as mcp from "./mcp";
|
|
9
9
|
export { mcp };
|
|
10
|
+
/**
|
|
11
|
+
* Builds the redirect URI for OAuth configuration.
|
|
12
|
+
* Use this to construct the redirect_uri parameter for your authorization URL.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const redirectUri = getRedirectUrl({ port: 3000 });
|
|
17
|
+
* // => "http://localhost:3000/callback"
|
|
18
|
+
*
|
|
19
|
+
* const authUrl = `https://oauth.example.com/authorize?redirect_uri=${encodeURIComponent(redirectUri)}`;
|
|
20
|
+
* console.log('Open:', authUrl);
|
|
21
|
+
* await getAuthCode({ port: 3000 });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function getRedirectUrl(options?: {
|
|
25
|
+
port?: number;
|
|
26
|
+
hostname?: string;
|
|
27
|
+
callbackPath?: string;
|
|
28
|
+
}): string;
|
|
10
29
|
/**
|
|
11
30
|
* Captures OAuth authorization code via localhost callback.
|
|
12
|
-
*
|
|
31
|
+
* Starts a temporary server, optionally launches auth URL, waits for redirect.
|
|
13
32
|
*
|
|
14
|
-
*
|
|
33
|
+
* Two modes:
|
|
34
|
+
* - **Managed**: Pass both `authorizationUrl` and `launch` — library opens browser
|
|
35
|
+
* - **Headless**: Pass neither — caller handles URL display (CI/SSH/custom UI)
|
|
36
|
+
*
|
|
37
|
+
* @param input - Auth URL string (auto-launches browser) or GetAuthCodeOptions
|
|
15
38
|
* @returns Promise<CallbackResult> with code and params
|
|
16
39
|
* @throws {OAuthError} Provider errors (access_denied, invalid_scope)
|
|
17
40
|
* @throws {Error} Timeout, network failures, port conflicts
|
|
18
41
|
*
|
|
19
42
|
* @example
|
|
20
43
|
* ```typescript
|
|
21
|
-
*
|
|
22
|
-
* const result = await getAuthCode('https://oauth.example.com/authorize?...');
|
|
23
|
-
* console.log('Code:', result.code);
|
|
44
|
+
* import open from "open";
|
|
24
45
|
*
|
|
25
|
-
* //
|
|
46
|
+
* // Managed mode: library launches browser
|
|
26
47
|
* const result = await getAuthCode({
|
|
27
48
|
* authorizationUrl: 'https://oauth.example.com/authorize?...',
|
|
28
|
-
*
|
|
29
|
-
* timeout: 60000,
|
|
30
|
-
* onRequest: (req) => console.log('Request:', req.url)
|
|
49
|
+
* launch: open,
|
|
31
50
|
* });
|
|
51
|
+
*
|
|
52
|
+
* // Headless mode: caller handles URL display
|
|
53
|
+
* const authUrl = 'https://oauth.example.com/authorize?...';
|
|
54
|
+
* console.log('Open this URL:', authUrl);
|
|
55
|
+
* const result = await getAuthCode({ port: 3000, timeout: 60000 });
|
|
32
56
|
* ```
|
|
33
57
|
*/
|
|
34
58
|
export declare function getAuthCode(input: GetAuthCodeOptions | string): Promise<CallbackResult>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,KAAK,GAAG,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,CAAC;AAEf;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CAClB,GACL,MAAM,CAOR;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,kBAAkB,GAAG,MAAM,GACjC,OAAO,CAAC,cAAc,CAAC,CAmDzB"}
|