integrate-sdk 0.2.4 → 0.3.1
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 +148 -242
- package/dist/adapters/auto-routes.d.ts +51 -0
- package/dist/adapters/auto-routes.d.ts.map +1 -0
- package/dist/adapters/base-handler.d.ts +106 -0
- package/dist/adapters/base-handler.d.ts.map +1 -0
- package/dist/adapters/nextjs.d.ts +223 -0
- package/dist/adapters/nextjs.d.ts.map +1 -0
- package/dist/adapters/tanstack-start.d.ts +169 -0
- package/dist/adapters/tanstack-start.d.ts.map +1 -0
- package/dist/config/types.d.ts +20 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/oauth/manager.d.ts +6 -4
- package/dist/oauth/manager.d.ts.map +1 -1
- package/dist/oauth.js +194 -0
- package/dist/plugins/github.d.ts +24 -7
- package/dist/plugins/github.d.ts.map +1 -1
- package/dist/plugins/gmail.d.ts +25 -7
- package/dist/plugins/gmail.d.ts.map +1 -1
- package/dist/plugins/types.d.ts +16 -4
- package/dist/plugins/types.d.ts.map +1 -1
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/src/index.js +1556 -0
- package/dist/{index.js → src/server.js} +232 -71
- package/oauth.ts +20 -0
- package/package.json +13 -3
- package/server.ts +12 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js OAuth Route Adapter
|
|
3
|
+
* Provides OAuth route handlers for Next.js App Router
|
|
4
|
+
*
|
|
5
|
+
* Note: This file uses type imports only to avoid requiring Next.js at build time.
|
|
6
|
+
* The actual Next.js types are used at runtime when available.
|
|
7
|
+
*/
|
|
8
|
+
import { type OAuthHandlerConfig } from './base-handler.js';
|
|
9
|
+
type NextRequest = any;
|
|
10
|
+
type NextResponse = any;
|
|
11
|
+
/**
|
|
12
|
+
* Create Next.js OAuth route handlers
|
|
13
|
+
*
|
|
14
|
+
* Use this to create secure OAuth API routes in your Next.js application
|
|
15
|
+
* that handle authorization with server-side secrets.
|
|
16
|
+
*
|
|
17
|
+
* @param config - OAuth handler configuration with provider credentials
|
|
18
|
+
* @returns Object with authorize, callback, and status route handlers, plus a unified handler
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* **Simple Setup (Recommended)** - One route file handles everything:
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // app/api/integrate/oauth/[action]/route.ts
|
|
25
|
+
* import { createNextOAuthHandler } from 'integrate-sdk';
|
|
26
|
+
*
|
|
27
|
+
* const handler = createNextOAuthHandler({
|
|
28
|
+
* providers: {
|
|
29
|
+
* github: {
|
|
30
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
31
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
32
|
+
* },
|
|
33
|
+
* },
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* export const { POST, GET } = handler.createRoutes();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* **Advanced Setup** - Separate routes for each action:
|
|
41
|
+
*
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // app/api/integrate/oauth/authorize/route.ts
|
|
44
|
+
* export const POST = handler.authorize;
|
|
45
|
+
*
|
|
46
|
+
* // app/api/integrate/oauth/callback/route.ts
|
|
47
|
+
* export const POST = handler.callback;
|
|
48
|
+
*
|
|
49
|
+
* // app/api/integrate/oauth/status/route.ts
|
|
50
|
+
* export const GET = handler.status;
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export declare function createNextOAuthHandler(config: OAuthHandlerConfig): {
|
|
54
|
+
/**
|
|
55
|
+
* POST /api/integrate/oauth/authorize
|
|
56
|
+
*
|
|
57
|
+
* Request authorization URL from MCP server with server-side OAuth credentials
|
|
58
|
+
*
|
|
59
|
+
* Request body:
|
|
60
|
+
* ```json
|
|
61
|
+
* {
|
|
62
|
+
* "provider": "github",
|
|
63
|
+
* "scopes": ["repo", "user"],
|
|
64
|
+
* "state": "random-state-string",
|
|
65
|
+
* "codeChallenge": "pkce-code-challenge",
|
|
66
|
+
* "codeChallengeMethod": "S256",
|
|
67
|
+
* "redirectUri": "https://yourapp.com/oauth/callback"
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* Response:
|
|
72
|
+
* ```json
|
|
73
|
+
* {
|
|
74
|
+
* "authorizationUrl": "https://github.com/login/oauth/authorize?..."
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* // app/api/integrate/oauth/authorize/route.ts
|
|
81
|
+
* import { createNextOAuthHandler } from 'integrate-sdk';
|
|
82
|
+
*
|
|
83
|
+
* const handler = createNextOAuthHandler({
|
|
84
|
+
* * providers: {
|
|
85
|
+
* github: {
|
|
86
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
87
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
88
|
+
* },
|
|
89
|
+
* },
|
|
90
|
+
* });
|
|
91
|
+
*
|
|
92
|
+
* export const POST = handler.authorize;
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
authorize(req: NextRequest): Promise<NextResponse>;
|
|
96
|
+
/**
|
|
97
|
+
* POST /api/integrate/oauth/callback
|
|
98
|
+
*
|
|
99
|
+
* Exchange authorization code for session token
|
|
100
|
+
*
|
|
101
|
+
* Request body:
|
|
102
|
+
* ```json
|
|
103
|
+
* {
|
|
104
|
+
* "provider": "github",
|
|
105
|
+
* "code": "authorization-code",
|
|
106
|
+
* "codeVerifier": "pkce-code-verifier",
|
|
107
|
+
* "state": "state-from-authorize"
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* Response:
|
|
112
|
+
* ```json
|
|
113
|
+
* {
|
|
114
|
+
* "sessionToken": "session-token-123",
|
|
115
|
+
* "provider": "github",
|
|
116
|
+
* "scopes": ["repo", "user"],
|
|
117
|
+
* "expiresAt": 1234567890
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* // app/api/integrate/oauth/callback/route.ts
|
|
124
|
+
* import { createNextOAuthHandler } from 'integrate-sdk';
|
|
125
|
+
*
|
|
126
|
+
* const handler = createNextOAuthHandler({
|
|
127
|
+
* * providers: {
|
|
128
|
+
* github: {
|
|
129
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
130
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
131
|
+
* },
|
|
132
|
+
* },
|
|
133
|
+
* });
|
|
134
|
+
*
|
|
135
|
+
* export const POST = handler.callback;
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
callback(req: NextRequest): Promise<NextResponse>;
|
|
139
|
+
/**
|
|
140
|
+
* GET /api/integrate/oauth/status?provider=github
|
|
141
|
+
*
|
|
142
|
+
* Check if a provider is currently authorized
|
|
143
|
+
*
|
|
144
|
+
* Query parameters:
|
|
145
|
+
* - provider: Provider to check (e.g., "github")
|
|
146
|
+
*
|
|
147
|
+
* Headers:
|
|
148
|
+
* - X-Session-Token: Session token from previous authorization
|
|
149
|
+
*
|
|
150
|
+
* Response:
|
|
151
|
+
* ```json
|
|
152
|
+
* {
|
|
153
|
+
* "authorized": true,
|
|
154
|
+
* "provider": "github",
|
|
155
|
+
* "scopes": ["repo", "user"],
|
|
156
|
+
* "expiresAt": 1234567890
|
|
157
|
+
* }
|
|
158
|
+
* ```
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* // app/api/integrate/oauth/status/route.ts
|
|
163
|
+
* import { createNextOAuthHandler } from 'integrate-sdk';
|
|
164
|
+
*
|
|
165
|
+
* const handler = createNextOAuthHandler({
|
|
166
|
+
* * providers: {
|
|
167
|
+
* github: {
|
|
168
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
169
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
170
|
+
* },
|
|
171
|
+
* },
|
|
172
|
+
* });
|
|
173
|
+
*
|
|
174
|
+
* export const GET = handler.status;
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
status(req: NextRequest): Promise<NextResponse>;
|
|
178
|
+
/**
|
|
179
|
+
* Create unified route handlers for catch-all route
|
|
180
|
+
*
|
|
181
|
+
* This is the simplest way to set up OAuth routes - create a single catch-all
|
|
182
|
+
* route file that handles all OAuth actions.
|
|
183
|
+
*
|
|
184
|
+
* @returns Object with POST and GET handlers for Next.js dynamic routes
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* // app/api/integrate/oauth/[action]/route.ts
|
|
189
|
+
* import { createNextOAuthHandler } from 'integrate-sdk';
|
|
190
|
+
*
|
|
191
|
+
* const handler = createNextOAuthHandler({
|
|
192
|
+
* providers: {
|
|
193
|
+
* github: {
|
|
194
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
195
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
196
|
+
* },
|
|
197
|
+
* },
|
|
198
|
+
* });
|
|
199
|
+
*
|
|
200
|
+
* export const { POST, GET } = handler.createRoutes();
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
createRoutes(): {
|
|
204
|
+
/**
|
|
205
|
+
* POST handler for authorize and callback actions
|
|
206
|
+
*/
|
|
207
|
+
POST(req: NextRequest, context: {
|
|
208
|
+
params: {
|
|
209
|
+
action: string;
|
|
210
|
+
};
|
|
211
|
+
}): Promise<NextResponse>;
|
|
212
|
+
/**
|
|
213
|
+
* GET handler for status action
|
|
214
|
+
*/
|
|
215
|
+
GET(req: NextRequest, context: {
|
|
216
|
+
params: {
|
|
217
|
+
action: string;
|
|
218
|
+
};
|
|
219
|
+
}): Promise<NextResponse>;
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
export {};
|
|
223
|
+
//# sourceMappingURL=nextjs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs.d.ts","sourceRoot":"","sources":["../../src/adapters/nextjs.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG1E,KAAK,WAAW,GAAG,GAAG,CAAC;AACvB,KAAK,YAAY,GAAG,GAAG,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,kBAAkB;IAI7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;mBACkB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAcxD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;kBACiB,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAcvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;gBACe,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA8BrD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;;QAGC;;WAEG;kBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,GACtC,OAAO,CAAC,YAAY,CAAC;QAiBxB;;WAEG;iBAEI,WAAW,WACP;YAAE,MAAM,EAAE;gBAAE,MAAM,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,GACtC,OAAO,CAAC,YAAY,CAAC;;EAiB/B"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TanStack Start OAuth Route Adapter
|
|
3
|
+
* Provides OAuth route handlers for TanStack Start
|
|
4
|
+
*/
|
|
5
|
+
import { type OAuthHandlerConfig } from './base-handler.js';
|
|
6
|
+
/**
|
|
7
|
+
* Create TanStack Start OAuth route handlers
|
|
8
|
+
*
|
|
9
|
+
* Use this to create secure OAuth API routes in your TanStack Start application
|
|
10
|
+
* that handle authorization with server-side secrets.
|
|
11
|
+
*
|
|
12
|
+
* @param config - OAuth handler configuration with MCP server URL and provider credentials
|
|
13
|
+
* @returns Object with authorize, callback, and status route handlers
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* // app/routes/api/integrate/oauth/authorize.ts
|
|
18
|
+
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
19
|
+
* import { json } from '@tanstack/start';
|
|
20
|
+
*
|
|
21
|
+
* const handler = createTanStackOAuthHandler({
|
|
22
|
+
* providers: {
|
|
23
|
+
* github: {
|
|
24
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
25
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
26
|
+
* },
|
|
27
|
+
* gmail: {
|
|
28
|
+
* clientId: process.env.GMAIL_CLIENT_ID!,
|
|
29
|
+
* clientSecret: process.env.GMAIL_CLIENT_SECRET!,
|
|
30
|
+
* },
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* export const POST = handler.authorize;
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function createTanStackOAuthHandler(config: OAuthHandlerConfig): {
|
|
38
|
+
/**
|
|
39
|
+
* POST /api/integrate/oauth/authorize
|
|
40
|
+
*
|
|
41
|
+
* Request authorization URL from MCP server with server-side OAuth credentials
|
|
42
|
+
*
|
|
43
|
+
* Request body:
|
|
44
|
+
* ```json
|
|
45
|
+
* {
|
|
46
|
+
* "provider": "github",
|
|
47
|
+
* "scopes": ["repo", "user"],
|
|
48
|
+
* "state": "random-state-string",
|
|
49
|
+
* "codeChallenge": "pkce-code-challenge",
|
|
50
|
+
* "codeChallengeMethod": "S256",
|
|
51
|
+
* "redirectUri": "https://yourapp.com/oauth/callback"
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*
|
|
55
|
+
* Response:
|
|
56
|
+
* ```json
|
|
57
|
+
* {
|
|
58
|
+
* "authorizationUrl": "https://github.com/login/oauth/authorize?..."
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* // app/routes/api/integrate/oauth/authorize.ts
|
|
65
|
+
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
66
|
+
*
|
|
67
|
+
* const handler = createTanStackOAuthHandler({
|
|
68
|
+
* * providers: {
|
|
69
|
+
* github: {
|
|
70
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
71
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
72
|
+
* },
|
|
73
|
+
* },
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* export const POST = handler.authorize;
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
authorize({ request }: {
|
|
80
|
+
request: Request;
|
|
81
|
+
}): Promise<Response>;
|
|
82
|
+
/**
|
|
83
|
+
* POST /api/integrate/oauth/callback
|
|
84
|
+
*
|
|
85
|
+
* Exchange authorization code for session token
|
|
86
|
+
*
|
|
87
|
+
* Request body:
|
|
88
|
+
* ```json
|
|
89
|
+
* {
|
|
90
|
+
* "provider": "github",
|
|
91
|
+
* "code": "authorization-code",
|
|
92
|
+
* "codeVerifier": "pkce-code-verifier",
|
|
93
|
+
* "state": "state-from-authorize"
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* Response:
|
|
98
|
+
* ```json
|
|
99
|
+
* {
|
|
100
|
+
* "sessionToken": "session-token-123",
|
|
101
|
+
* "provider": "github",
|
|
102
|
+
* "scopes": ["repo", "user"],
|
|
103
|
+
* "expiresAt": 1234567890
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* ```typescript
|
|
109
|
+
* // app/routes/api/integrate/oauth/callback.ts
|
|
110
|
+
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
111
|
+
*
|
|
112
|
+
* const handler = createTanStackOAuthHandler({
|
|
113
|
+
* * providers: {
|
|
114
|
+
* github: {
|
|
115
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
116
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
117
|
+
* },
|
|
118
|
+
* },
|
|
119
|
+
* });
|
|
120
|
+
*
|
|
121
|
+
* export const POST = handler.callback;
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
callback({ request }: {
|
|
125
|
+
request: Request;
|
|
126
|
+
}): Promise<Response>;
|
|
127
|
+
/**
|
|
128
|
+
* GET /api/integrate/oauth/status?provider=github
|
|
129
|
+
*
|
|
130
|
+
* Check if a provider is currently authorized
|
|
131
|
+
*
|
|
132
|
+
* Query parameters:
|
|
133
|
+
* - provider: Provider to check (e.g., "github")
|
|
134
|
+
*
|
|
135
|
+
* Headers:
|
|
136
|
+
* - X-Session-Token: Session token from previous authorization
|
|
137
|
+
*
|
|
138
|
+
* Response:
|
|
139
|
+
* ```json
|
|
140
|
+
* {
|
|
141
|
+
* "authorized": true,
|
|
142
|
+
* "provider": "github",
|
|
143
|
+
* "scopes": ["repo", "user"],
|
|
144
|
+
* "expiresAt": 1234567890
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*
|
|
148
|
+
* @example
|
|
149
|
+
* ```typescript
|
|
150
|
+
* // app/routes/api/integrate/oauth/status.ts
|
|
151
|
+
* import { createTanStackOAuthHandler } from 'integrate-sdk';
|
|
152
|
+
*
|
|
153
|
+
* const handler = createTanStackOAuthHandler({
|
|
154
|
+
* * providers: {
|
|
155
|
+
* github: {
|
|
156
|
+
* clientId: process.env.GITHUB_CLIENT_ID!,
|
|
157
|
+
* clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
158
|
+
* },
|
|
159
|
+
* },
|
|
160
|
+
* });
|
|
161
|
+
*
|
|
162
|
+
* export const GET = handler.status;
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
status({ request }: {
|
|
166
|
+
request: Request;
|
|
167
|
+
}): Promise<Response>;
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=tanstack-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tanstack-start.d.ts","sourceRoot":"","sources":["../../src/adapters/tanstack-start.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB;IAIjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCG;2BAC0B;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAwBrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;0BACyB;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;IAwBpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;wBACuB;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC;EAmDrE"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -128,6 +128,26 @@ export interface MCPClientConfig<TPlugins extends readonly MCPPlugin[]> {
|
|
|
128
128
|
* ```
|
|
129
129
|
*/
|
|
130
130
|
sessionToken?: string;
|
|
131
|
+
/**
|
|
132
|
+
* Base URL for OAuth API routes
|
|
133
|
+
* These routes should be mounted in your application to handle OAuth securely
|
|
134
|
+
*
|
|
135
|
+
* The SDK will call:
|
|
136
|
+
* - POST {oauthApiBase}/authorize - Get authorization URL
|
|
137
|
+
* - POST {oauthApiBase}/callback - Exchange code for token
|
|
138
|
+
* - GET {oauthApiBase}/status - Check authorization status
|
|
139
|
+
*
|
|
140
|
+
* @default '/api/integrate/oauth'
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* const client = createMCPClient({
|
|
145
|
+
* plugins: [githubPlugin({ ... })],
|
|
146
|
+
* oauthApiBase: '/api/integrate/oauth'
|
|
147
|
+
* });
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
oauthApiBase?: string;
|
|
131
151
|
}
|
|
132
152
|
/**
|
|
133
153
|
* Helper type to infer enabled tools from plugins
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE;IACpE,iCAAiC;IACjC,OAAO,EAAE,QAAQ,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,yBAAyB;IACzB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC;IAEjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAE7C;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE;QACV,+DAA+D;QAC/D,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QAC5B,oDAAoD;QACpD,YAAY,CAAC,EAAE;YACb,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,sDAAsD;QACtD,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACnF,CAAC;IAEF;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE,IACjE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE,IAAI;KACnE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;CAC/C,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,KAAK,EAAE,mBAAmB,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE;IACpE,iCAAiC;IACjC,OAAO,EAAE,QAAQ,CAAC;IAElB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,yBAAyB;IACzB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAEF;;;;;;;;;;;;;;;;;;;OAmBG;IACH,gBAAgB,CAAC,EAAE,aAAa,CAAC;IAEjC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAE7C;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,EAAE;QACV,+DAA+D;QAC/D,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;QAC5B,oDAAoD;QACpD,YAAY,CAAC,EAAE;YACb,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,MAAM,CAAC,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,sDAAsD;QACtD,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACnF,CAAC;IAEF;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE,IACjE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpC;;GAEG;AACH,MAAM,MAAM,gBAAgB,CAAC,QAAQ,SAAS,SAAS,SAAS,EAAE,IAAI;KACnE,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;CAC/C,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,10 @@ export { OAuthManager } from "./oauth/manager.js";
|
|
|
8
8
|
export { OAuthWindowManager, sendCallbackToOpener } from "./oauth/window-manager.js";
|
|
9
9
|
export { generateCodeVerifier, generateCodeChallenge, generateState } from "./oauth/pkce.js";
|
|
10
10
|
export type { OAuthFlowConfig, PopupOptions, AuthStatus, PendingAuth, AuthorizationUrlResponse, OAuthCallbackResponse, OAuthCallbackParams, } from "./oauth/types.js";
|
|
11
|
+
export { OAuthHandler } from "./adapters/base-handler.js";
|
|
12
|
+
export type { OAuthHandlerConfig, AuthorizeRequest, AuthorizeResponse, CallbackRequest, CallbackResponse, StatusResponse, } from "./adapters/base-handler.js";
|
|
13
|
+
export { createNextOAuthHandler } from "./adapters/nextjs.js";
|
|
14
|
+
export { createTanStackOAuthHandler } from "./adapters/tanstack-start.js";
|
|
11
15
|
export type { MCPClientConfig, ReauthContext, ReauthHandler } from "./config/types.js";
|
|
12
16
|
export { IntegrateSDKError, AuthenticationError, AuthorizationError, TokenExpiredError, ConnectionError, ToolCallError, isAuthError, isTokenExpiredError, isAuthorizationError, parseServerError, } from "./errors.js";
|
|
13
17
|
export type { MCPPlugin, OAuthConfig, ExtractPluginIds, ExtractPluginTools, } from "./plugins/types.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7F,YAAY,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,WAAW,EACX,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE/F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG3F,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,YAAY,EACV,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,OAAO,EACP,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EACV,cAAc,EACd,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAC7F,YAAY,EACV,eAAe,EACf,YAAY,EACZ,UAAU,EACV,WAAW,EACX,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EACV,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,cAAc,GACf,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAG1E,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvF,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE/F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAG3F,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAGrE,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AACrC,YAAY,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAGhE,YAAY,EACV,cAAc,EACd,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,OAAO,EACP,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,YAAY,EACV,cAAc,EACd,2BAA2B,GAC5B,MAAM,6BAA6B,CAAC"}
|
package/dist/oauth/manager.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare class OAuthManager {
|
|
|
13
13
|
private sessionToken?;
|
|
14
14
|
private windowManager;
|
|
15
15
|
private flowConfig;
|
|
16
|
-
private
|
|
17
|
-
constructor(
|
|
16
|
+
private oauthApiBase;
|
|
17
|
+
constructor(oauthApiBase: string, flowConfig?: Partial<OAuthFlowConfig>);
|
|
18
18
|
/**
|
|
19
19
|
* Initiate OAuth authorization flow
|
|
20
20
|
*
|
|
@@ -76,11 +76,13 @@ export declare class OAuthManager {
|
|
|
76
76
|
*/
|
|
77
77
|
clearSessionToken(): void;
|
|
78
78
|
/**
|
|
79
|
-
* Request authorization URL from
|
|
79
|
+
* Request authorization URL from user's API route
|
|
80
|
+
* The API route will add OAuth secrets and forward to MCP server
|
|
80
81
|
*/
|
|
81
82
|
private getAuthorizationUrl;
|
|
82
83
|
/**
|
|
83
|
-
* Exchange authorization code for session token
|
|
84
|
+
* Exchange authorization code for session token via user's API route
|
|
85
|
+
* The API route will forward to MCP server
|
|
84
86
|
*/
|
|
85
87
|
private exchangeCodeForToken;
|
|
86
88
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/oauth/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EACV,eAAe,EAEf,UAAU,EAGX,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/oauth/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EACV,eAAe,EAEf,UAAU,EAGX,MAAM,YAAY,CAAC;AAIpB;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAAuC;IAC3D,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,YAAY,CAAS;gBAG3B,YAAY,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAWvC;;;;;;;;;;;;;;;;OAgBG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAwCxE;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA8ClE;;;;;;;;;;;;;OAaG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAoC5D;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;;OAGG;YACW,mBAAmB;IAiCjC;;;OAGG;YACW,oBAAoB;IA8BlC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/oauth.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, {
|
|
5
|
+
get: all[name],
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
set: (newValue) => all[name] = () => newValue
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
|
+
|
|
13
|
+
// src/adapters/base-handler.ts
|
|
14
|
+
var MCP_SERVER_URL = "https://mcp.integrate.dev/api/v1/mcp";
|
|
15
|
+
|
|
16
|
+
class OAuthHandler {
|
|
17
|
+
config;
|
|
18
|
+
serverUrl = MCP_SERVER_URL;
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
}
|
|
22
|
+
async handleAuthorize(request) {
|
|
23
|
+
const providerConfig = this.config.providers[request.provider];
|
|
24
|
+
if (!providerConfig) {
|
|
25
|
+
throw new Error(`Provider ${request.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
26
|
+
}
|
|
27
|
+
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
28
|
+
throw new Error(`Missing OAuth credentials for ${request.provider}. Check your environment variables.`);
|
|
29
|
+
}
|
|
30
|
+
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
31
|
+
url.searchParams.set("provider", request.provider);
|
|
32
|
+
url.searchParams.set("client_id", providerConfig.clientId);
|
|
33
|
+
url.searchParams.set("client_secret", providerConfig.clientSecret);
|
|
34
|
+
url.searchParams.set("scope", request.scopes.join(","));
|
|
35
|
+
url.searchParams.set("state", request.state);
|
|
36
|
+
url.searchParams.set("code_challenge", request.codeChallenge);
|
|
37
|
+
url.searchParams.set("code_challenge_method", request.codeChallengeMethod);
|
|
38
|
+
const redirectUri = request.redirectUri || providerConfig.redirectUri;
|
|
39
|
+
if (redirectUri) {
|
|
40
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
41
|
+
}
|
|
42
|
+
const response = await fetch(url.toString(), {
|
|
43
|
+
method: "GET"
|
|
44
|
+
});
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
const error = await response.text();
|
|
47
|
+
throw new Error(`MCP server failed to generate authorization URL: ${error}`);
|
|
48
|
+
}
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
async handleCallback(request) {
|
|
53
|
+
const url = new URL("/oauth/callback", this.serverUrl);
|
|
54
|
+
const response = await fetch(url.toString(), {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/json"
|
|
58
|
+
},
|
|
59
|
+
body: JSON.stringify({
|
|
60
|
+
provider: request.provider,
|
|
61
|
+
code: request.code,
|
|
62
|
+
code_verifier: request.codeVerifier,
|
|
63
|
+
state: request.state
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const error = await response.text();
|
|
68
|
+
throw new Error(`MCP server failed to exchange authorization code: ${error}`);
|
|
69
|
+
}
|
|
70
|
+
const data = await response.json();
|
|
71
|
+
return data;
|
|
72
|
+
}
|
|
73
|
+
async handleStatus(provider, sessionToken) {
|
|
74
|
+
const url = new URL("/oauth/status", this.serverUrl);
|
|
75
|
+
url.searchParams.set("provider", provider);
|
|
76
|
+
const response = await fetch(url.toString(), {
|
|
77
|
+
method: "GET",
|
|
78
|
+
headers: {
|
|
79
|
+
"X-Session-Token": sessionToken
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
if (!response.ok) {
|
|
83
|
+
if (response.status === 401) {
|
|
84
|
+
return {
|
|
85
|
+
authorized: false,
|
|
86
|
+
provider
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const error = await response.text();
|
|
90
|
+
throw new Error(`MCP server failed to check authorization status: ${error}`);
|
|
91
|
+
}
|
|
92
|
+
const data = await response.json();
|
|
93
|
+
return data;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// src/adapters/auto-routes.ts
|
|
98
|
+
var globalOAuthConfig = null;
|
|
99
|
+
function setGlobalOAuthConfig(config) {
|
|
100
|
+
globalOAuthConfig = config;
|
|
101
|
+
}
|
|
102
|
+
async function POST(req, context) {
|
|
103
|
+
if (!globalOAuthConfig) {
|
|
104
|
+
throw new Error("OAuth configuration not found. Did you configure oauthProviders in createMCPClient?");
|
|
105
|
+
}
|
|
106
|
+
const handler = new OAuthHandler(globalOAuthConfig);
|
|
107
|
+
const action = context?.params?.action;
|
|
108
|
+
if (!action) {
|
|
109
|
+
return createErrorResponse("Missing action parameter", 400);
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
if (action === "authorize") {
|
|
113
|
+
const body = await parseRequestBody(req);
|
|
114
|
+
const result = await handler.handleAuthorize(body);
|
|
115
|
+
return createSuccessResponse(result);
|
|
116
|
+
}
|
|
117
|
+
if (action === "callback") {
|
|
118
|
+
const body = await parseRequestBody(req);
|
|
119
|
+
const result = await handler.handleCallback(body);
|
|
120
|
+
return createSuccessResponse(result);
|
|
121
|
+
}
|
|
122
|
+
return createErrorResponse(`Unknown action: ${action}`, 404);
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.error(`[OAuth ${action}] Error:`, error);
|
|
125
|
+
return createErrorResponse(error.message, 500);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function GET(req, context) {
|
|
129
|
+
if (!globalOAuthConfig) {
|
|
130
|
+
throw new Error("OAuth configuration not found. Did you configure oauthProviders in createMCPClient?");
|
|
131
|
+
}
|
|
132
|
+
const handler = new OAuthHandler(globalOAuthConfig);
|
|
133
|
+
const action = context?.params?.action;
|
|
134
|
+
if (!action) {
|
|
135
|
+
return createErrorResponse("Missing action parameter", 400);
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
if (action === "status") {
|
|
139
|
+
const { provider, sessionToken } = parseQueryParams(req);
|
|
140
|
+
if (!provider || !sessionToken) {
|
|
141
|
+
return createErrorResponse("Missing provider or session token", 400);
|
|
142
|
+
}
|
|
143
|
+
const result = await handler.handleStatus(provider, sessionToken);
|
|
144
|
+
return createSuccessResponse(result);
|
|
145
|
+
}
|
|
146
|
+
return createErrorResponse(`Unknown action: ${action}`, 404);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(`[OAuth ${action}] Error:`, error);
|
|
149
|
+
return createErrorResponse(error.message, 500);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function parseRequestBody(req) {
|
|
153
|
+
if (typeof req.json === "function") {
|
|
154
|
+
return await req.json();
|
|
155
|
+
}
|
|
156
|
+
throw new Error("Unable to parse request body");
|
|
157
|
+
}
|
|
158
|
+
function parseQueryParams(req) {
|
|
159
|
+
let url;
|
|
160
|
+
if (req.nextUrl) {
|
|
161
|
+
url = new URL(req.nextUrl);
|
|
162
|
+
} else if (req.url) {
|
|
163
|
+
url = new URL(req.url);
|
|
164
|
+
} else {
|
|
165
|
+
return {};
|
|
166
|
+
}
|
|
167
|
+
const provider = url.searchParams.get("provider") || undefined;
|
|
168
|
+
const sessionToken = req.headers?.get?.("x-session-token") || undefined;
|
|
169
|
+
return { provider, sessionToken };
|
|
170
|
+
}
|
|
171
|
+
function createSuccessResponse(data) {
|
|
172
|
+
if (typeof globalThis.NextResponse !== "undefined") {
|
|
173
|
+
const NextResponse = globalThis.NextResponse;
|
|
174
|
+
return NextResponse.json(data);
|
|
175
|
+
}
|
|
176
|
+
return new Response(JSON.stringify(data), {
|
|
177
|
+
status: 200,
|
|
178
|
+
headers: { "Content-Type": "application/json" }
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
function createErrorResponse(message, status) {
|
|
182
|
+
if (typeof globalThis.NextResponse !== "undefined") {
|
|
183
|
+
const NextResponse = globalThis.NextResponse;
|
|
184
|
+
return NextResponse.json({ error: message }, { status });
|
|
185
|
+
}
|
|
186
|
+
return new Response(JSON.stringify({ error: message }), {
|
|
187
|
+
status,
|
|
188
|
+
headers: { "Content-Type": "application/json" }
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
export {
|
|
192
|
+
POST,
|
|
193
|
+
GET
|
|
194
|
+
};
|