integrate-sdk 0.2.3 → 0.2.4
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 +181 -0
- package/dist/client.d.ts +93 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/config/types.d.ts +40 -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/index.js +415 -0
- package/dist/oauth/manager.d.ts +91 -0
- package/dist/oauth/manager.d.ts.map +1 -0
- package/dist/oauth/pkce.d.ts +47 -0
- package/dist/oauth/pkce.d.ts.map +1 -0
- package/dist/oauth/types.d.ts +84 -0
- package/dist/oauth/types.d.ts.map +1 -0
- package/dist/oauth/window-manager.d.ts +103 -0
- package/dist/oauth/window-manager.d.ts.map +1 -0
- package/dist/transport/http-session.d.ts +23 -0
- package/dist/transport/http-session.d.ts.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -98,6 +98,187 @@ await client.server.listToolsByIntegration({ integration: "github" });
|
|
|
98
98
|
await client._callToolByName("slack_send_message", { channel: "#general", text: "Hello" });
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
## OAuth Authorization
|
|
102
|
+
|
|
103
|
+
The SDK implements OAuth 2.0 Authorization Code Flow with PKCE for secure third-party service authorization. Users must authorize your application to access their GitHub, Gmail, or other accounts.
|
|
104
|
+
|
|
105
|
+
### How It Works
|
|
106
|
+
|
|
107
|
+
1. **Your App**: Creates client with OAuth configuration
|
|
108
|
+
2. **SDK**: Initiates OAuth flow (popup or redirect)
|
|
109
|
+
3. **User**: Authorizes permissions on provider's website
|
|
110
|
+
4. **Provider**: Redirects back with authorization code
|
|
111
|
+
5. **Your Server**: Exchanges code for tokens and stores them
|
|
112
|
+
6. **SDK**: Includes session token in all API requests
|
|
113
|
+
7. **Your Server**: Uses stored OAuth tokens for API calls
|
|
114
|
+
|
|
115
|
+
### Quick Start
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { createMCPClient, githubPlugin } from "integrate-sdk";
|
|
119
|
+
|
|
120
|
+
// Create client with OAuth flow configuration
|
|
121
|
+
const client = createMCPClient({
|
|
122
|
+
plugins: [
|
|
123
|
+
githubPlugin({
|
|
124
|
+
clientId: process.env.GITHUB_CLIENT_ID!,
|
|
125
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
|
126
|
+
scopes: ["repo", "user"],
|
|
127
|
+
redirectUri: "http://localhost:3000/oauth/callback",
|
|
128
|
+
}),
|
|
129
|
+
],
|
|
130
|
+
oauthFlow: {
|
|
131
|
+
mode: 'popup', // or 'redirect'
|
|
132
|
+
popupOptions: { width: 600, height: 700 },
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Check if authorized
|
|
137
|
+
const isAuthorized = await client.isAuthorized('github');
|
|
138
|
+
|
|
139
|
+
if (!isAuthorized) {
|
|
140
|
+
// Initiate OAuth flow - opens popup or redirects
|
|
141
|
+
await client.authorize('github');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Now you can use GitHub tools
|
|
145
|
+
const repos = await client.github.listOwnRepos({});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Popup Flow (Recommended for SPAs)
|
|
149
|
+
|
|
150
|
+
Best for single-page applications - authorization happens in a popup without leaving your app.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const client = createMCPClient({
|
|
154
|
+
plugins: [githubPlugin({ ... })],
|
|
155
|
+
oauthFlow: { mode: 'popup' },
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// This opens a popup for authorization
|
|
159
|
+
await client.authorize('github');
|
|
160
|
+
|
|
161
|
+
// After user approves, continues automatically
|
|
162
|
+
const repos = await client.github.listOwnRepos({});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Callback Page**: Create `/oauth/callback.html`:
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<!DOCTYPE html>
|
|
169
|
+
<html>
|
|
170
|
+
<head>
|
|
171
|
+
<title>OAuth Callback</title>
|
|
172
|
+
<script type="module">
|
|
173
|
+
import { sendCallbackToOpener } from 'integrate-sdk';
|
|
174
|
+
|
|
175
|
+
const params = new URLSearchParams(window.location.search);
|
|
176
|
+
sendCallbackToOpener({
|
|
177
|
+
code: params.get('code'),
|
|
178
|
+
state: params.get('state'),
|
|
179
|
+
error: params.get('error')
|
|
180
|
+
});
|
|
181
|
+
</script>
|
|
182
|
+
</head>
|
|
183
|
+
<body>
|
|
184
|
+
<p>Authorization successful! Closing...</p>
|
|
185
|
+
</body>
|
|
186
|
+
</html>
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Redirect Flow (Traditional Web Apps)
|
|
190
|
+
|
|
191
|
+
Best for traditional server-rendered applications.
|
|
192
|
+
|
|
193
|
+
```typescript
|
|
194
|
+
// Main page
|
|
195
|
+
const client = createMCPClient({
|
|
196
|
+
plugins: [githubPlugin({ ... })],
|
|
197
|
+
oauthFlow: { mode: 'redirect' },
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
if (!await client.isAuthorized('github')) {
|
|
201
|
+
await client.authorize('github'); // Redirects to GitHub
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Callback page (e.g., /oauth/callback)
|
|
205
|
+
const params = new URLSearchParams(window.location.search);
|
|
206
|
+
await client.handleOAuthCallback({
|
|
207
|
+
code: params.get('code')!,
|
|
208
|
+
state: params.get('state')!
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
// Save session token for future use
|
|
212
|
+
const sessionToken = client.getSessionToken();
|
|
213
|
+
localStorage.setItem('session_token', sessionToken);
|
|
214
|
+
|
|
215
|
+
// Redirect back to main app
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Session Token Management
|
|
219
|
+
|
|
220
|
+
Store and restore sessions to avoid re-authorization:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
// Restore previous session
|
|
224
|
+
const client = createMCPClient({
|
|
225
|
+
plugins: [githubPlugin({ ... })],
|
|
226
|
+
sessionToken: localStorage.getItem('session_token'),
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
// Check if session is still valid
|
|
230
|
+
if (!await client.isAuthorized('github')) {
|
|
231
|
+
await client.authorize('github');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Store token after new authorization
|
|
235
|
+
const token = client.getSessionToken();
|
|
236
|
+
localStorage.setItem('session_token', token);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Multiple Providers
|
|
240
|
+
|
|
241
|
+
Authorize multiple services independently:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
const client = createMCPClient({
|
|
245
|
+
plugins: [
|
|
246
|
+
githubPlugin({ ... }),
|
|
247
|
+
gmailPlugin({ ... }),
|
|
248
|
+
],
|
|
249
|
+
oauthFlow: { mode: 'popup' },
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Get list of all authorized providers
|
|
253
|
+
const authorized = await client.authorizedProviders();
|
|
254
|
+
console.log('Authorized:', authorized); // ['github', 'gmail']
|
|
255
|
+
|
|
256
|
+
// Or check and authorize each provider individually
|
|
257
|
+
if (!await client.isAuthorized('github')) {
|
|
258
|
+
await client.authorize('github');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (!await client.isAuthorized('gmail')) {
|
|
262
|
+
await client.authorize('gmail');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Use both services
|
|
266
|
+
const repos = await client.github.listOwnRepos({});
|
|
267
|
+
const messages = await client.gmail.listMessages({});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Server Requirements
|
|
271
|
+
|
|
272
|
+
Your MCP server must implement these OAuth endpoints:
|
|
273
|
+
|
|
274
|
+
**GET `/oauth/authorize`** - Returns authorization URL
|
|
275
|
+
**POST `/oauth/callback`** - Exchanges code for tokens, returns session token
|
|
276
|
+
**GET `/oauth/status`** - Checks authorization status
|
|
277
|
+
|
|
278
|
+
All tool endpoints must accept `X-Session-Token` header and use stored OAuth tokens for API calls.
|
|
279
|
+
|
|
280
|
+
[→ View complete OAuth flow implementation guide](/docs/guides/oauth-flow.md)
|
|
281
|
+
|
|
101
282
|
## Built-in Plugins
|
|
102
283
|
|
|
103
284
|
### GitHub Plugin
|
package/dist/client.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { type AuthenticationError } from "./errors.js";
|
|
|
9
9
|
import type { GitHubPluginClient } from "./plugins/github-client.js";
|
|
10
10
|
import type { GmailPluginClient } from "./plugins/gmail-client.js";
|
|
11
11
|
import type { ServerPluginClient } from "./plugins/server-client.js";
|
|
12
|
+
import type { AuthStatus, OAuthCallbackParams } from "./oauth/types.js";
|
|
12
13
|
/**
|
|
13
14
|
* Tool invocation options
|
|
14
15
|
*/
|
|
@@ -54,6 +55,7 @@ export declare class MCPClient<TPlugins extends readonly MCPPlugin[] = readonly
|
|
|
54
55
|
private authState;
|
|
55
56
|
private connectionMode;
|
|
56
57
|
private connecting;
|
|
58
|
+
private oauthManager;
|
|
57
59
|
readonly github: PluginNamespaces<TPlugins> extends {
|
|
58
60
|
github: GitHubPluginClient;
|
|
59
61
|
} ? GitHubPluginClient : never;
|
|
@@ -169,6 +171,97 @@ export declare class MCPClient<TPlugins extends readonly MCPPlugin[] = readonly
|
|
|
169
171
|
* Check if a specific provider is authenticated
|
|
170
172
|
*/
|
|
171
173
|
isProviderAuthenticated(provider: string): boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Check if a provider is authorized via OAuth
|
|
176
|
+
* Queries the MCP server to verify OAuth token validity
|
|
177
|
+
*
|
|
178
|
+
* @param provider - Provider name (github, gmail, etc.)
|
|
179
|
+
* @returns Authorization status
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```typescript
|
|
183
|
+
* const isAuthorized = await client.isAuthorized('github');
|
|
184
|
+
* if (!isAuthorized) {
|
|
185
|
+
* await client.authorize('github');
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
isAuthorized(provider: string): Promise<boolean>;
|
|
190
|
+
/**
|
|
191
|
+
* Get list of all authorized providers
|
|
192
|
+
* Checks all configured OAuth providers and returns names of authorized ones
|
|
193
|
+
*
|
|
194
|
+
* @returns Array of authorized provider names
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const authorized = await client.authorizedProviders();
|
|
199
|
+
* console.log('Authorized services:', authorized); // ['github', 'gmail']
|
|
200
|
+
*
|
|
201
|
+
* // Check if specific service is in the list
|
|
202
|
+
* if (authorized.includes('github')) {
|
|
203
|
+
* const repos = await client.github.listOwnRepos({});
|
|
204
|
+
* }
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
authorizedProviders(): Promise<string[]>;
|
|
208
|
+
/**
|
|
209
|
+
* Get detailed authorization status for a provider
|
|
210
|
+
*
|
|
211
|
+
* @param provider - Provider name
|
|
212
|
+
* @returns Full authorization status including scopes and expiration
|
|
213
|
+
*/
|
|
214
|
+
getAuthorizationStatus(provider: string): Promise<AuthStatus>;
|
|
215
|
+
/**
|
|
216
|
+
* Initiate OAuth authorization flow for a provider
|
|
217
|
+
* Opens authorization URL in popup or redirects based on configuration
|
|
218
|
+
*
|
|
219
|
+
* @param provider - Provider name (github, gmail, etc.)
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* // Popup flow
|
|
224
|
+
* await client.authorize('github');
|
|
225
|
+
*
|
|
226
|
+
* // Redirect flow
|
|
227
|
+
* await client.authorize('github'); // User is redirected away
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
authorize(provider: string): Promise<void>;
|
|
231
|
+
/**
|
|
232
|
+
* Handle OAuth callback after user authorization
|
|
233
|
+
* Call this from your OAuth callback page with code and state from URL
|
|
234
|
+
*
|
|
235
|
+
* @param params - Callback parameters containing code and state
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* // In your callback route (e.g., /oauth/callback)
|
|
240
|
+
* const params = new URLSearchParams(window.location.search);
|
|
241
|
+
* await client.handleOAuthCallback({
|
|
242
|
+
* code: params.get('code')!,
|
|
243
|
+
* state: params.get('state')!
|
|
244
|
+
* });
|
|
245
|
+
*
|
|
246
|
+
* // Now you can use the client
|
|
247
|
+
* const repos = await client.github.listOwnRepos({});
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
handleOAuthCallback(params: OAuthCallbackParams): Promise<void>;
|
|
251
|
+
/**
|
|
252
|
+
* Get the current session token
|
|
253
|
+
* Useful for storing and restoring sessions
|
|
254
|
+
*
|
|
255
|
+
* @returns Session token or undefined if not authorized
|
|
256
|
+
*/
|
|
257
|
+
getSessionToken(): string | undefined;
|
|
258
|
+
/**
|
|
259
|
+
* Set session token manually
|
|
260
|
+
* Use this if you have an existing session token
|
|
261
|
+
*
|
|
262
|
+
* @param token - Session token
|
|
263
|
+
*/
|
|
264
|
+
setSessionToken(token: string): void;
|
|
172
265
|
/**
|
|
173
266
|
* Manually trigger re-authentication for a specific provider
|
|
174
267
|
* Useful if you want to proactively refresh tokens
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EACV,OAAO,EAEP,mBAAmB,EAIpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/config/types.d.ts
CHANGED
|
@@ -88,6 +88,46 @@ export interface MCPClientConfig<TPlugins extends readonly MCPPlugin[]> {
|
|
|
88
88
|
* @default true
|
|
89
89
|
*/
|
|
90
90
|
autoCleanup?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* OAuth flow configuration
|
|
93
|
+
* Controls how OAuth authorization is handled (popup vs redirect)
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const client = createMCPClient({
|
|
98
|
+
* plugins: [githubPlugin({ ... })],
|
|
99
|
+
* oauthFlow: {
|
|
100
|
+
* mode: 'popup',
|
|
101
|
+
* popupOptions: { width: 600, height: 700 }
|
|
102
|
+
* }
|
|
103
|
+
* });
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
oauthFlow?: {
|
|
107
|
+
/** How to display OAuth authorization (default: 'redirect') */
|
|
108
|
+
mode?: 'popup' | 'redirect';
|
|
109
|
+
/** Popup window dimensions (only for popup mode) */
|
|
110
|
+
popupOptions?: {
|
|
111
|
+
width?: number;
|
|
112
|
+
height?: number;
|
|
113
|
+
};
|
|
114
|
+
/** Custom callback handler for receiving auth code */
|
|
115
|
+
onAuthCallback?: (provider: string, code: string, state: string) => Promise<void>;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Session token for authenticated requests
|
|
119
|
+
* Set automatically after OAuth flow completes
|
|
120
|
+
* Can be provided manually if you manage tokens externally
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const client = createMCPClient({
|
|
125
|
+
* plugins: [githubPlugin({ ... })],
|
|
126
|
+
* sessionToken: 'existing-session-token'
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
sessionToken?: string;
|
|
91
131
|
}
|
|
92
132
|
/**
|
|
93
133
|
* 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;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;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
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export { MCPClient, createMCPClient, clearClientCache } from "./client.js";
|
|
6
6
|
export type { ToolInvocationOptions } from "./client.js";
|
|
7
|
+
export { OAuthManager } from "./oauth/manager.js";
|
|
8
|
+
export { OAuthWindowManager, sendCallbackToOpener } from "./oauth/window-manager.js";
|
|
9
|
+
export { generateCodeVerifier, generateCodeChallenge, generateState } from "./oauth/pkce.js";
|
|
10
|
+
export type { OAuthFlowConfig, PopupOptions, AuthStatus, PendingAuth, AuthorizationUrlResponse, OAuthCallbackResponse, OAuthCallbackParams, } from "./oauth/types.js";
|
|
7
11
|
export type { MCPClientConfig, ReauthContext, ReauthHandler } from "./config/types.js";
|
|
8
12
|
export { IntegrateSDKError, AuthenticationError, AuthorizationError, TokenExpiredError, ConnectionError, ToolCallError, isAuthError, isTokenExpiredError, isAuthorizationError, parseServerError, } from "./errors.js";
|
|
9
13
|
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,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,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/index.js
CHANGED
|
@@ -335,6 +335,15 @@ class HttpSessionTransport {
|
|
|
335
335
|
getSessionId() {
|
|
336
336
|
return this.sessionId;
|
|
337
337
|
}
|
|
338
|
+
setHeader(key, value) {
|
|
339
|
+
this.headers[key] = value;
|
|
340
|
+
}
|
|
341
|
+
removeHeader(key) {
|
|
342
|
+
delete this.headers[key];
|
|
343
|
+
}
|
|
344
|
+
getHeaders() {
|
|
345
|
+
return { ...this.headers };
|
|
346
|
+
}
|
|
338
347
|
}
|
|
339
348
|
|
|
340
349
|
// src/protocol/messages.ts
|
|
@@ -361,6 +370,357 @@ function methodToToolName(methodName, pluginId) {
|
|
|
361
370
|
return `${pluginId}_${snakeCaseMethod}`;
|
|
362
371
|
}
|
|
363
372
|
|
|
373
|
+
// src/oauth/pkce.ts
|
|
374
|
+
function generateCodeVerifier() {
|
|
375
|
+
const array = new Uint8Array(32);
|
|
376
|
+
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
|
|
377
|
+
crypto.getRandomValues(array);
|
|
378
|
+
} else if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
379
|
+
globalThis.crypto.getRandomValues(array);
|
|
380
|
+
} else {
|
|
381
|
+
throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
|
|
382
|
+
}
|
|
383
|
+
return base64UrlEncode(array);
|
|
384
|
+
}
|
|
385
|
+
async function generateCodeChallenge(verifier) {
|
|
386
|
+
const encoder = new TextEncoder;
|
|
387
|
+
const data = encoder.encode(verifier);
|
|
388
|
+
let hashBuffer;
|
|
389
|
+
if (typeof crypto !== "undefined" && crypto.subtle) {
|
|
390
|
+
hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
391
|
+
} else if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
|
|
392
|
+
hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", data);
|
|
393
|
+
} else {
|
|
394
|
+
throw new Error("crypto.subtle.digest is not available. Please use Node.js 19+ or a modern browser.");
|
|
395
|
+
}
|
|
396
|
+
return base64UrlEncode(new Uint8Array(hashBuffer));
|
|
397
|
+
}
|
|
398
|
+
function generateState() {
|
|
399
|
+
const array = new Uint8Array(16);
|
|
400
|
+
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
|
|
401
|
+
crypto.getRandomValues(array);
|
|
402
|
+
} else if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
403
|
+
globalThis.crypto.getRandomValues(array);
|
|
404
|
+
} else {
|
|
405
|
+
throw new Error("crypto.getRandomValues is not available. Please use Node.js 19+ or a modern browser.");
|
|
406
|
+
}
|
|
407
|
+
return base64UrlEncode(array);
|
|
408
|
+
}
|
|
409
|
+
function base64UrlEncode(array) {
|
|
410
|
+
let base64 = "";
|
|
411
|
+
if (typeof Buffer !== "undefined") {
|
|
412
|
+
base64 = Buffer.from(array).toString("base64");
|
|
413
|
+
} else {
|
|
414
|
+
const binary = String.fromCharCode(...array);
|
|
415
|
+
base64 = btoa(binary);
|
|
416
|
+
}
|
|
417
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// src/oauth/window-manager.ts
|
|
421
|
+
function isBrowser() {
|
|
422
|
+
return typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
class OAuthWindowManager {
|
|
426
|
+
popupWindow = null;
|
|
427
|
+
popupCheckInterval = null;
|
|
428
|
+
openPopup(url, options) {
|
|
429
|
+
if (!isBrowser()) {
|
|
430
|
+
throw new Error("OAuthWindowManager.openPopup() can only be used in browser environments");
|
|
431
|
+
}
|
|
432
|
+
const width = options?.width || 600;
|
|
433
|
+
const height = options?.height || 700;
|
|
434
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
435
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
436
|
+
const features = [
|
|
437
|
+
`width=${width}`,
|
|
438
|
+
`height=${height}`,
|
|
439
|
+
`left=${left}`,
|
|
440
|
+
`top=${top}`,
|
|
441
|
+
"toolbar=no",
|
|
442
|
+
"location=no",
|
|
443
|
+
"directories=no",
|
|
444
|
+
"status=no",
|
|
445
|
+
"menubar=no",
|
|
446
|
+
"scrollbars=yes",
|
|
447
|
+
"resizable=yes",
|
|
448
|
+
"copyhistory=no"
|
|
449
|
+
].join(",");
|
|
450
|
+
this.popupWindow = window.open(url, "oauth_popup", features);
|
|
451
|
+
if (!this.popupWindow) {
|
|
452
|
+
console.warn("Popup was blocked by the browser. Please allow popups for this site.");
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
this.popupWindow.focus();
|
|
456
|
+
return this.popupWindow;
|
|
457
|
+
}
|
|
458
|
+
openRedirect(url) {
|
|
459
|
+
if (!isBrowser()) {
|
|
460
|
+
throw new Error("OAuthWindowManager.openRedirect() can only be used in browser environments");
|
|
461
|
+
}
|
|
462
|
+
window.location.href = url;
|
|
463
|
+
}
|
|
464
|
+
listenForCallback(mode, timeoutMs = 5 * 60 * 1000) {
|
|
465
|
+
if (mode === "popup") {
|
|
466
|
+
return this.listenForPopupCallback(timeoutMs);
|
|
467
|
+
} else {
|
|
468
|
+
return this.listenForRedirectCallback();
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
listenForPopupCallback(timeoutMs) {
|
|
472
|
+
if (!isBrowser()) {
|
|
473
|
+
return Promise.reject(new Error("OAuth popup callback can only be used in browser environments"));
|
|
474
|
+
}
|
|
475
|
+
return new Promise((resolve, reject) => {
|
|
476
|
+
const timeout = setTimeout(() => {
|
|
477
|
+
this.cleanup();
|
|
478
|
+
reject(new Error("OAuth authorization timed out"));
|
|
479
|
+
}, timeoutMs);
|
|
480
|
+
const messageHandler = (event) => {
|
|
481
|
+
if (event.data && event.data.type === "oauth_callback") {
|
|
482
|
+
clearTimeout(timeout);
|
|
483
|
+
window.removeEventListener("message", messageHandler);
|
|
484
|
+
const { code, state, error } = event.data;
|
|
485
|
+
if (error) {
|
|
486
|
+
this.cleanup();
|
|
487
|
+
reject(new Error(`OAuth error: ${error}`));
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
if (!code || !state) {
|
|
491
|
+
this.cleanup();
|
|
492
|
+
reject(new Error("Invalid OAuth callback: missing code or state"));
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
this.cleanup();
|
|
496
|
+
resolve({ code, state });
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
window.addEventListener("message", messageHandler);
|
|
500
|
+
this.popupCheckInterval = setInterval(() => {
|
|
501
|
+
if (this.popupWindow?.closed) {
|
|
502
|
+
clearTimeout(timeout);
|
|
503
|
+
clearInterval(this.popupCheckInterval);
|
|
504
|
+
window.removeEventListener("message", messageHandler);
|
|
505
|
+
this.cleanup();
|
|
506
|
+
reject(new Error("OAuth popup was closed by user"));
|
|
507
|
+
}
|
|
508
|
+
}, 500);
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
listenForRedirectCallback() {
|
|
512
|
+
if (!isBrowser()) {
|
|
513
|
+
return Promise.reject(new Error("OAuth redirect callback can only be used in browser environments"));
|
|
514
|
+
}
|
|
515
|
+
return new Promise((resolve, reject) => {
|
|
516
|
+
const params = new URLSearchParams(window.location.search);
|
|
517
|
+
const code = params.get("code");
|
|
518
|
+
const state = params.get("state");
|
|
519
|
+
const error = params.get("error");
|
|
520
|
+
const errorDescription = params.get("error_description");
|
|
521
|
+
if (error) {
|
|
522
|
+
const errorMsg = errorDescription || error;
|
|
523
|
+
reject(new Error(`OAuth error: ${errorMsg}`));
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (!code || !state) {
|
|
527
|
+
reject(new Error("Invalid OAuth callback: missing code or state in URL"));
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
resolve({ code, state });
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
cleanup() {
|
|
534
|
+
if (this.popupWindow && !this.popupWindow.closed) {
|
|
535
|
+
this.popupWindow.close();
|
|
536
|
+
}
|
|
537
|
+
this.popupWindow = null;
|
|
538
|
+
if (this.popupCheckInterval) {
|
|
539
|
+
clearInterval(this.popupCheckInterval);
|
|
540
|
+
this.popupCheckInterval = null;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
close() {
|
|
544
|
+
this.cleanup();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function sendCallbackToOpener(params) {
|
|
548
|
+
if (!isBrowser()) {
|
|
549
|
+
console.error("sendCallbackToOpener() can only be used in browser environments");
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
if (!window.opener) {
|
|
553
|
+
console.error("No opener window found. This function should only be called from a popup window.");
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
window.opener.postMessage({
|
|
557
|
+
type: "oauth_callback",
|
|
558
|
+
code: params.code,
|
|
559
|
+
state: params.state,
|
|
560
|
+
error: params.error
|
|
561
|
+
}, "*");
|
|
562
|
+
window.close();
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/oauth/manager.ts
|
|
566
|
+
class OAuthManager {
|
|
567
|
+
pendingAuths = new Map;
|
|
568
|
+
sessionToken;
|
|
569
|
+
windowManager;
|
|
570
|
+
flowConfig;
|
|
571
|
+
serverUrl;
|
|
572
|
+
constructor(serverUrl, flowConfig) {
|
|
573
|
+
this.serverUrl = serverUrl;
|
|
574
|
+
this.windowManager = new OAuthWindowManager;
|
|
575
|
+
this.flowConfig = {
|
|
576
|
+
mode: flowConfig?.mode || "redirect",
|
|
577
|
+
popupOptions: flowConfig?.popupOptions,
|
|
578
|
+
onAuthCallback: flowConfig?.onAuthCallback
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
async initiateFlow(provider, config) {
|
|
582
|
+
const codeVerifier = generateCodeVerifier();
|
|
583
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
584
|
+
const state = generateState();
|
|
585
|
+
const pendingAuth = {
|
|
586
|
+
provider,
|
|
587
|
+
state,
|
|
588
|
+
codeVerifier,
|
|
589
|
+
codeChallenge,
|
|
590
|
+
scopes: config.scopes,
|
|
591
|
+
redirectUri: config.redirectUri,
|
|
592
|
+
initiatedAt: Date.now()
|
|
593
|
+
};
|
|
594
|
+
this.pendingAuths.set(state, pendingAuth);
|
|
595
|
+
const authUrl = await this.getAuthorizationUrl(provider, config, state, codeChallenge);
|
|
596
|
+
if (this.flowConfig.mode === "popup") {
|
|
597
|
+
this.windowManager.openPopup(authUrl, this.flowConfig.popupOptions);
|
|
598
|
+
try {
|
|
599
|
+
const callbackParams = await this.windowManager.listenForCallback("popup");
|
|
600
|
+
await this.handleCallback(callbackParams.code, callbackParams.state);
|
|
601
|
+
} catch (error) {
|
|
602
|
+
this.pendingAuths.delete(state);
|
|
603
|
+
throw error;
|
|
604
|
+
}
|
|
605
|
+
} else {
|
|
606
|
+
this.windowManager.openRedirect(authUrl);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
async handleCallback(code, state) {
|
|
610
|
+
const pendingAuth = this.pendingAuths.get(state);
|
|
611
|
+
if (!pendingAuth) {
|
|
612
|
+
throw new Error("Invalid state parameter: no matching OAuth flow found");
|
|
613
|
+
}
|
|
614
|
+
const fiveMinutes = 5 * 60 * 1000;
|
|
615
|
+
if (Date.now() - pendingAuth.initiatedAt > fiveMinutes) {
|
|
616
|
+
this.pendingAuths.delete(state);
|
|
617
|
+
throw new Error("OAuth flow expired: please try again");
|
|
618
|
+
}
|
|
619
|
+
if (this.flowConfig.onAuthCallback) {
|
|
620
|
+
try {
|
|
621
|
+
await this.flowConfig.onAuthCallback(pendingAuth.provider, code, state);
|
|
622
|
+
} catch (error) {
|
|
623
|
+
console.error("Custom OAuth callback handler failed:", error);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
try {
|
|
627
|
+
const response = await this.exchangeCodeForToken(pendingAuth.provider, code, pendingAuth.codeVerifier, state);
|
|
628
|
+
this.sessionToken = response.sessionToken;
|
|
629
|
+
this.pendingAuths.delete(state);
|
|
630
|
+
return response.sessionToken;
|
|
631
|
+
} catch (error) {
|
|
632
|
+
this.pendingAuths.delete(state);
|
|
633
|
+
throw error;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
async checkAuthStatus(provider) {
|
|
637
|
+
if (!this.sessionToken) {
|
|
638
|
+
return {
|
|
639
|
+
authorized: false,
|
|
640
|
+
provider
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
try {
|
|
644
|
+
const url = new URL("/oauth/status", this.serverUrl);
|
|
645
|
+
url.searchParams.set("provider", provider);
|
|
646
|
+
const response = await fetch(url.toString(), {
|
|
647
|
+
method: "GET",
|
|
648
|
+
headers: {
|
|
649
|
+
"X-Session-Token": this.sessionToken
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
if (!response.ok) {
|
|
653
|
+
return {
|
|
654
|
+
authorized: false,
|
|
655
|
+
provider
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
const status = await response.json();
|
|
659
|
+
return status;
|
|
660
|
+
} catch (error) {
|
|
661
|
+
console.error("Failed to check auth status:", error);
|
|
662
|
+
return {
|
|
663
|
+
authorized: false,
|
|
664
|
+
provider
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
getSessionToken() {
|
|
669
|
+
return this.sessionToken;
|
|
670
|
+
}
|
|
671
|
+
setSessionToken(token) {
|
|
672
|
+
this.sessionToken = token;
|
|
673
|
+
}
|
|
674
|
+
clearSessionToken() {
|
|
675
|
+
this.sessionToken = undefined;
|
|
676
|
+
}
|
|
677
|
+
async getAuthorizationUrl(provider, config, state, codeChallenge) {
|
|
678
|
+
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
679
|
+
url.searchParams.set("provider", provider);
|
|
680
|
+
url.searchParams.set("client_id", config.clientId || "");
|
|
681
|
+
url.searchParams.set("scope", config.scopes.join(","));
|
|
682
|
+
url.searchParams.set("state", state);
|
|
683
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
684
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
685
|
+
if (config.redirectUri) {
|
|
686
|
+
url.searchParams.set("redirect_uri", config.redirectUri);
|
|
687
|
+
}
|
|
688
|
+
const response = await fetch(url.toString(), {
|
|
689
|
+
method: "GET"
|
|
690
|
+
});
|
|
691
|
+
if (!response.ok) {
|
|
692
|
+
const error = await response.text();
|
|
693
|
+
throw new Error(`Failed to get authorization URL: ${error}`);
|
|
694
|
+
}
|
|
695
|
+
const data = await response.json();
|
|
696
|
+
return data.authorizationUrl;
|
|
697
|
+
}
|
|
698
|
+
async exchangeCodeForToken(provider, code, codeVerifier, state) {
|
|
699
|
+
const url = new URL("/oauth/callback", this.serverUrl);
|
|
700
|
+
const response = await fetch(url.toString(), {
|
|
701
|
+
method: "POST",
|
|
702
|
+
headers: {
|
|
703
|
+
"Content-Type": "application/json"
|
|
704
|
+
},
|
|
705
|
+
body: JSON.stringify({
|
|
706
|
+
provider,
|
|
707
|
+
code,
|
|
708
|
+
code_verifier: codeVerifier,
|
|
709
|
+
state
|
|
710
|
+
})
|
|
711
|
+
});
|
|
712
|
+
if (!response.ok) {
|
|
713
|
+
const error = await response.text();
|
|
714
|
+
throw new Error(`Failed to exchange code for token: ${error}`);
|
|
715
|
+
}
|
|
716
|
+
const data = await response.json();
|
|
717
|
+
return data;
|
|
718
|
+
}
|
|
719
|
+
close() {
|
|
720
|
+
this.windowManager.close();
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
|
|
364
724
|
// src/client.ts
|
|
365
725
|
var MCP_SERVER_URL = "https://mcp.integrate.dev/api/v1/mcp";
|
|
366
726
|
var clientCache = new Map;
|
|
@@ -379,6 +739,7 @@ class MCPClient {
|
|
|
379
739
|
authState = new Map;
|
|
380
740
|
connectionMode;
|
|
381
741
|
connecting = null;
|
|
742
|
+
oauthManager;
|
|
382
743
|
github;
|
|
383
744
|
gmail;
|
|
384
745
|
server;
|
|
@@ -396,6 +757,11 @@ class MCPClient {
|
|
|
396
757
|
this.onReauthRequired = config.onReauthRequired;
|
|
397
758
|
this.maxReauthRetries = config.maxReauthRetries ?? 1;
|
|
398
759
|
this.connectionMode = config.connectionMode ?? "lazy";
|
|
760
|
+
this.oauthManager = new OAuthManager(MCP_SERVER_URL, config.oauthFlow);
|
|
761
|
+
if (config.sessionToken) {
|
|
762
|
+
this.oauthManager.setSessionToken(config.sessionToken);
|
|
763
|
+
this.transport.setHeader("X-Session-Token", config.sessionToken);
|
|
764
|
+
}
|
|
399
765
|
for (const plugin of this.plugins) {
|
|
400
766
|
for (const toolName of plugin.tools) {
|
|
401
767
|
this.enabledToolNames.add(toolName);
|
|
@@ -631,6 +997,49 @@ class MCPClient {
|
|
|
631
997
|
isProviderAuthenticated(provider) {
|
|
632
998
|
return this.authState.get(provider)?.authenticated ?? false;
|
|
633
999
|
}
|
|
1000
|
+
async isAuthorized(provider) {
|
|
1001
|
+
const status = await this.oauthManager.checkAuthStatus(provider);
|
|
1002
|
+
return status.authorized;
|
|
1003
|
+
}
|
|
1004
|
+
async authorizedProviders() {
|
|
1005
|
+
const authorized = [];
|
|
1006
|
+
for (const plugin of this.plugins) {
|
|
1007
|
+
if (plugin.oauth) {
|
|
1008
|
+
const status = await this.oauthManager.checkAuthStatus(plugin.oauth.provider);
|
|
1009
|
+
if (status.authorized) {
|
|
1010
|
+
authorized.push(plugin.oauth.provider);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return authorized;
|
|
1015
|
+
}
|
|
1016
|
+
async getAuthorizationStatus(provider) {
|
|
1017
|
+
return await this.oauthManager.checkAuthStatus(provider);
|
|
1018
|
+
}
|
|
1019
|
+
async authorize(provider) {
|
|
1020
|
+
const plugin = this.plugins.find((p) => p.oauth?.provider === provider);
|
|
1021
|
+
if (!plugin?.oauth) {
|
|
1022
|
+
throw new Error(`No OAuth configuration found for provider: ${provider}`);
|
|
1023
|
+
}
|
|
1024
|
+
await this.oauthManager.initiateFlow(provider, plugin.oauth);
|
|
1025
|
+
this.authState.set(provider, { authenticated: true });
|
|
1026
|
+
}
|
|
1027
|
+
async handleOAuthCallback(params) {
|
|
1028
|
+
const sessionToken = await this.oauthManager.handleCallback(params.code, params.state);
|
|
1029
|
+
this.transport.setHeader("X-Session-Token", sessionToken);
|
|
1030
|
+
for (const plugin of this.plugins) {
|
|
1031
|
+
if (plugin.oauth) {
|
|
1032
|
+
this.authState.set(plugin.oauth.provider, { authenticated: true });
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
getSessionToken() {
|
|
1037
|
+
return this.oauthManager.getSessionToken();
|
|
1038
|
+
}
|
|
1039
|
+
setSessionToken(token) {
|
|
1040
|
+
this.oauthManager.setSessionToken(token);
|
|
1041
|
+
this.transport.setHeader("X-Session-Token", token);
|
|
1042
|
+
}
|
|
634
1043
|
async reauthenticate(provider) {
|
|
635
1044
|
const state = this.authState.get(provider);
|
|
636
1045
|
if (!state) {
|
|
@@ -880,6 +1289,7 @@ function getVercelAITools(client) {
|
|
|
880
1289
|
return convertMCPToolsToVercelAI(client);
|
|
881
1290
|
}
|
|
882
1291
|
export {
|
|
1292
|
+
sendCallbackToOpener,
|
|
883
1293
|
parseServerError,
|
|
884
1294
|
isTokenExpiredError,
|
|
885
1295
|
isAuthorizationError,
|
|
@@ -888,6 +1298,9 @@ export {
|
|
|
888
1298
|
githubPlugin,
|
|
889
1299
|
getVercelAITools,
|
|
890
1300
|
genericOAuthPlugin,
|
|
1301
|
+
generateState,
|
|
1302
|
+
generateCodeVerifier,
|
|
1303
|
+
generateCodeChallenge,
|
|
891
1304
|
createSimplePlugin,
|
|
892
1305
|
createMCPClient,
|
|
893
1306
|
convertMCPToolsToVercelAI,
|
|
@@ -895,6 +1308,8 @@ export {
|
|
|
895
1308
|
clearClientCache,
|
|
896
1309
|
ToolCallError,
|
|
897
1310
|
TokenExpiredError,
|
|
1311
|
+
OAuthWindowManager,
|
|
1312
|
+
OAuthManager,
|
|
898
1313
|
MCPMethod,
|
|
899
1314
|
MCPClient,
|
|
900
1315
|
IntegrateSDKError,
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Manager
|
|
3
|
+
* Orchestrates OAuth 2.0 Authorization Code Flow with PKCE
|
|
4
|
+
*/
|
|
5
|
+
import type { OAuthConfig } from "../plugins/types.js";
|
|
6
|
+
import type { OAuthFlowConfig, AuthStatus } from "./types.js";
|
|
7
|
+
/**
|
|
8
|
+
* OAuth Manager
|
|
9
|
+
* Handles OAuth authorization flows and token management
|
|
10
|
+
*/
|
|
11
|
+
export declare class OAuthManager {
|
|
12
|
+
private pendingAuths;
|
|
13
|
+
private sessionToken?;
|
|
14
|
+
private windowManager;
|
|
15
|
+
private flowConfig;
|
|
16
|
+
private serverUrl;
|
|
17
|
+
constructor(serverUrl: string, flowConfig?: Partial<OAuthFlowConfig>);
|
|
18
|
+
/**
|
|
19
|
+
* Initiate OAuth authorization flow
|
|
20
|
+
*
|
|
21
|
+
* @param provider - OAuth provider (github, gmail, etc.)
|
|
22
|
+
* @param config - OAuth configuration
|
|
23
|
+
* @returns Promise that resolves when authorization is complete
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* await oauthManager.initiateFlow('github', {
|
|
28
|
+
* provider: 'github',
|
|
29
|
+
* clientId: 'abc123',
|
|
30
|
+
* clientSecret: 'secret',
|
|
31
|
+
* scopes: ['repo', 'user']
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
initiateFlow(provider: string, config: OAuthConfig): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Handle OAuth callback
|
|
38
|
+
* Call this after user authorizes (from your callback page)
|
|
39
|
+
*
|
|
40
|
+
* @param code - Authorization code from OAuth provider
|
|
41
|
+
* @param state - State parameter for verification
|
|
42
|
+
* @returns Session token for authenticated requests
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* // In your callback route
|
|
47
|
+
* const sessionToken = await oauthManager.handleCallback(code, state);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
handleCallback(code: string, state: string): Promise<string>;
|
|
51
|
+
/**
|
|
52
|
+
* Check authorization status for a provider
|
|
53
|
+
*
|
|
54
|
+
* @param provider - OAuth provider to check
|
|
55
|
+
* @returns Authorization status
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const status = await oauthManager.checkAuthStatus('github');
|
|
60
|
+
* if (status.authorized) {
|
|
61
|
+
* console.log('GitHub is authorized');
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
checkAuthStatus(provider: string): Promise<AuthStatus>;
|
|
66
|
+
/**
|
|
67
|
+
* Get session token
|
|
68
|
+
*/
|
|
69
|
+
getSessionToken(): string | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Set session token (for manual token management)
|
|
72
|
+
*/
|
|
73
|
+
setSessionToken(token: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Clear session token
|
|
76
|
+
*/
|
|
77
|
+
clearSessionToken(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Request authorization URL from MCP server
|
|
80
|
+
*/
|
|
81
|
+
private getAuthorizationUrl;
|
|
82
|
+
/**
|
|
83
|
+
* Exchange authorization code for session token
|
|
84
|
+
*/
|
|
85
|
+
private exchangeCodeForToken;
|
|
86
|
+
/**
|
|
87
|
+
* Close any open OAuth windows
|
|
88
|
+
*/
|
|
89
|
+
close(): void;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +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,SAAS,CAAS;gBAGxB,SAAS,EAAE,MAAM,EACjB,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;IAqC5D;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,SAAS;IAIrC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAIzB;;OAEG;YACW,mBAAmB;IA+BjC;;OAEG;YACW,oBAAoB;IA8BlC;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PKCE Utilities
|
|
3
|
+
* Proof Key for Code Exchange (RFC 7636) implementation
|
|
4
|
+
*
|
|
5
|
+
* PKCE enhances OAuth 2.0 security by preventing authorization code interception attacks.
|
|
6
|
+
* It's especially important for public clients (browser/mobile apps).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Generate a cryptographically secure random code verifier
|
|
10
|
+
* Must be 43-128 characters long, using [A-Z] [a-z] [0-9] - . _ ~
|
|
11
|
+
*
|
|
12
|
+
* @returns A random code verifier string
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const verifier = generateCodeVerifier();
|
|
17
|
+
* // Returns: "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateCodeVerifier(): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate code challenge from verifier using SHA-256
|
|
23
|
+
*
|
|
24
|
+
* @param verifier - The code verifier to hash
|
|
25
|
+
* @returns A Promise resolving to the base64url-encoded SHA-256 hash
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const verifier = generateCodeVerifier();
|
|
30
|
+
* const challenge = await generateCodeChallenge(verifier);
|
|
31
|
+
* // Returns: "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function generateCodeChallenge(verifier: string): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Generate a random state parameter for CSRF protection
|
|
37
|
+
*
|
|
38
|
+
* @returns A random state string
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```typescript
|
|
42
|
+
* const state = generateState();
|
|
43
|
+
* // Returns: "xyzABC123"
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export declare function generateState(): string;
|
|
47
|
+
//# sourceMappingURL=pkce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/oauth/pkce.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAgB7C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB7E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAatC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Flow Types
|
|
3
|
+
* Type definitions for OAuth 2.0 Authorization Code Flow with PKCE
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Popup window options for OAuth flow
|
|
7
|
+
*/
|
|
8
|
+
export interface PopupOptions {
|
|
9
|
+
/** Window width in pixels (default: 600) */
|
|
10
|
+
width?: number;
|
|
11
|
+
/** Window height in pixels (default: 700) */
|
|
12
|
+
height?: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* OAuth flow configuration
|
|
16
|
+
*/
|
|
17
|
+
export interface OAuthFlowConfig {
|
|
18
|
+
/** How to display OAuth authorization */
|
|
19
|
+
mode: 'popup' | 'redirect';
|
|
20
|
+
/** Popup window dimensions (only for popup mode) */
|
|
21
|
+
popupOptions?: PopupOptions;
|
|
22
|
+
/** Custom callback handler for receiving auth code */
|
|
23
|
+
onAuthCallback?: (provider: string, code: string, state: string) => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Authorization status for a provider
|
|
27
|
+
*/
|
|
28
|
+
export interface AuthStatus {
|
|
29
|
+
/** Whether the provider is authorized */
|
|
30
|
+
authorized: boolean;
|
|
31
|
+
/** The provider name */
|
|
32
|
+
provider: string;
|
|
33
|
+
/** Authorized scopes */
|
|
34
|
+
scopes?: string[];
|
|
35
|
+
/** Token expiration time */
|
|
36
|
+
expiresAt?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Pending OAuth authorization
|
|
40
|
+
* Tracks in-progress OAuth flows
|
|
41
|
+
*/
|
|
42
|
+
export interface PendingAuth {
|
|
43
|
+
/** OAuth provider (github, gmail, etc.) */
|
|
44
|
+
provider: string;
|
|
45
|
+
/** CSRF protection state */
|
|
46
|
+
state: string;
|
|
47
|
+
/** PKCE code verifier */
|
|
48
|
+
codeVerifier: string;
|
|
49
|
+
/** PKCE code challenge */
|
|
50
|
+
codeChallenge: string;
|
|
51
|
+
/** OAuth scopes being requested */
|
|
52
|
+
scopes: string[];
|
|
53
|
+
/** Redirect URI */
|
|
54
|
+
redirectUri?: string;
|
|
55
|
+
/** Timestamp when auth was initiated */
|
|
56
|
+
initiatedAt: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* OAuth authorization URL response from server
|
|
60
|
+
*/
|
|
61
|
+
export interface AuthorizationUrlResponse {
|
|
62
|
+
/** The full authorization URL to redirect user to */
|
|
63
|
+
authorizationUrl: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* OAuth callback response from server
|
|
67
|
+
* Contains session token after successful authorization
|
|
68
|
+
*/
|
|
69
|
+
export interface OAuthCallbackResponse {
|
|
70
|
+
/** Session token for authenticated requests */
|
|
71
|
+
sessionToken: string;
|
|
72
|
+
/** Token expiration time */
|
|
73
|
+
expiresAt?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parameters for OAuth callback
|
|
77
|
+
*/
|
|
78
|
+
export interface OAuthCallbackParams {
|
|
79
|
+
/** Authorization code from OAuth provider */
|
|
80
|
+
code: string;
|
|
81
|
+
/** State parameter for CSRF protection */
|
|
82
|
+
state: string;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/oauth/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yCAAyC;IACzC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,oDAAoD;IACpD,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,sDAAsD;IACtD,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,mBAAmB;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Window Manager
|
|
3
|
+
* Handles OAuth authorization UI (popup windows and redirects)
|
|
4
|
+
*/
|
|
5
|
+
import type { PopupOptions, OAuthCallbackParams } from "./types.js";
|
|
6
|
+
/**
|
|
7
|
+
* OAuth Window Manager
|
|
8
|
+
* Manages popup windows and redirect flows for OAuth authorization
|
|
9
|
+
*
|
|
10
|
+
* Note: This class should only be used in browser environments.
|
|
11
|
+
* Server-side usage will throw errors.
|
|
12
|
+
*/
|
|
13
|
+
export declare class OAuthWindowManager {
|
|
14
|
+
private popupWindow;
|
|
15
|
+
private popupCheckInterval;
|
|
16
|
+
/**
|
|
17
|
+
* Open OAuth authorization in a popup window
|
|
18
|
+
*
|
|
19
|
+
* @param url - The authorization URL to open
|
|
20
|
+
* @param options - Popup window dimensions
|
|
21
|
+
* @returns The opened popup window or null if blocked
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const manager = new OAuthWindowManager();
|
|
26
|
+
* const popup = manager.openPopup(authUrl, { width: 600, height: 700 });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
openPopup(url: string, options?: PopupOptions): Window | null;
|
|
30
|
+
/**
|
|
31
|
+
* Redirect current window to OAuth authorization URL
|
|
32
|
+
*
|
|
33
|
+
* @param url - The authorization URL to redirect to
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const manager = new OAuthWindowManager();
|
|
38
|
+
* manager.openRedirect(authUrl);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
openRedirect(url: string): void;
|
|
42
|
+
/**
|
|
43
|
+
* Listen for OAuth callback
|
|
44
|
+
* For popup: listens for postMessage from callback page
|
|
45
|
+
* For redirect: parses URL parameters after redirect back
|
|
46
|
+
*
|
|
47
|
+
* @param mode - The OAuth flow mode ('popup' or 'redirect')
|
|
48
|
+
* @param timeoutMs - Timeout in milliseconds (default: 5 minutes)
|
|
49
|
+
* @returns Promise resolving to callback parameters (code and state)
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* // For popup flow
|
|
54
|
+
* const params = await manager.listenForCallback('popup');
|
|
55
|
+
*
|
|
56
|
+
* // For redirect flow (after redirect back)
|
|
57
|
+
* const params = await manager.listenForCallback('redirect');
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
listenForCallback(mode: 'popup' | 'redirect', timeoutMs?: number): Promise<OAuthCallbackParams>;
|
|
61
|
+
/**
|
|
62
|
+
* Listen for callback from popup window via postMessage
|
|
63
|
+
*/
|
|
64
|
+
private listenForPopupCallback;
|
|
65
|
+
/**
|
|
66
|
+
* Parse callback parameters from current URL (for redirect flow)
|
|
67
|
+
*/
|
|
68
|
+
private listenForRedirectCallback;
|
|
69
|
+
/**
|
|
70
|
+
* Clean up popup window and intervals
|
|
71
|
+
*/
|
|
72
|
+
private cleanup;
|
|
73
|
+
/**
|
|
74
|
+
* Close any open popup windows
|
|
75
|
+
* Call this when aborting the OAuth flow
|
|
76
|
+
*/
|
|
77
|
+
close(): void;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Helper function to send callback data from callback page to opener window
|
|
81
|
+
* Call this in your OAuth callback page
|
|
82
|
+
*
|
|
83
|
+
* @param params - The callback parameters from URL
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // In your callback page (e.g., /oauth/callback.html)
|
|
88
|
+
* import { sendCallbackToOpener } from '@integrate/sdk';
|
|
89
|
+
*
|
|
90
|
+
* const params = new URLSearchParams(window.location.search);
|
|
91
|
+
* sendCallbackToOpener({
|
|
92
|
+
* code: params.get('code'),
|
|
93
|
+
* state: params.get('state'),
|
|
94
|
+
* error: params.get('error')
|
|
95
|
+
* });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
export declare function sendCallbackToOpener(params: {
|
|
99
|
+
code: string | null;
|
|
100
|
+
state: string | null;
|
|
101
|
+
error?: string | null;
|
|
102
|
+
}): void;
|
|
103
|
+
//# sourceMappingURL=window-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"window-manager.d.ts","sourceRoot":"","sources":["../../src/oauth/window-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AASpE;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,kBAAkB,CAA+C;IAEzE;;;;;;;;;;;;OAYG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAwC7D;;;;;;;;;;OAUG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQ/B;;;;;;;;;;;;;;;;;OAiBG;IACH,iBAAiB,CACf,IAAI,EAAE,OAAO,GAAG,UAAU,EAC1B,SAAS,GAAE,MAAsB,GAChC,OAAO,CAAC,mBAAmB,CAAC;IAQ/B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAuD9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA4BjC;;OAEG;IACH,OAAO,CAAC,OAAO;IAYf;;;OAGG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GAAG,IAAI,CAwBP"}
|
|
@@ -63,5 +63,28 @@ export declare class HttpSessionTransport {
|
|
|
63
63
|
* Get current session ID
|
|
64
64
|
*/
|
|
65
65
|
getSessionId(): string | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* Set a custom header for all requests
|
|
68
|
+
* Used for session tokens and other auth headers
|
|
69
|
+
*
|
|
70
|
+
* @param key - Header name
|
|
71
|
+
* @param value - Header value
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* transport.setHeader('X-Session-Token', 'abc123');
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
setHeader(key: string, value: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Remove a custom header
|
|
81
|
+
*
|
|
82
|
+
* @param key - Header name to remove
|
|
83
|
+
*/
|
|
84
|
+
removeHeader(key: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* Get all current headers
|
|
87
|
+
*/
|
|
88
|
+
getHeaders(): Record<string, string>;
|
|
66
89
|
}
|
|
67
90
|
//# sourceMappingURL=http-session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-session.d.ts","sourceRoot":"","sources":["../../src/transport/http-session.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,eAAe,GAAG,mBAAmB,KAC3C,IAAI,CAAC;AAEV,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAkB;IACxC,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,2BAA2B;IAMhD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B;;OAEG;IACG,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,GACf,OAAO,CAAC,CAAC,CAAC;IAsFb;;OAEG;YACW,gBAAgB;IAiC9B;;OAEG;YACW,gBAAgB;IAiC9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI;IAS9C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBjC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"http-session.d.ts","sourceRoot":"","sources":["../../src/transport/http-session.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAEV,eAAe,EACf,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,cAAc,GAAG,CAC3B,OAAO,EAAE,eAAe,GAAG,mBAAmB,KAC3C,IAAI,CAAC;AAEV,MAAM,WAAW,2BAA2B;IAC1C,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAkC;IACzD,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAC,CAAkB;IACxC,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,EAAE,2BAA2B;IAMhD;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAS9B;;OAEG;IACG,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,GACf,OAAO,CAAC,CAAC,CAAC;IAsFb;;OAEG;YACW,gBAAgB;IAiC9B;;OAEG;YACW,gBAAgB;IAiC9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAiB1B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,IAAI;IAS9C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBjC;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,SAAS;IAIlC;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3C;;;;OAIG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAGrC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "integrate-sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Type-safe TypeScript SDK for MCP Client with plugin-based OAuth provider configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"build:types": "tsc --emitDeclarationOnly --declaration --declarationMap",
|
|
29
29
|
"dev": "bun --watch src/index.ts",
|
|
30
30
|
"type-check": "tsc --noEmit",
|
|
31
|
-
"test": "bun test tests/
|
|
32
|
-
"test:watch": "bun test --watch tests/
|
|
33
|
-
"test:unit": "bun test tests/protocol tests/plugins tests/client tests/integrations",
|
|
31
|
+
"test": "bun test tests/",
|
|
32
|
+
"test:watch": "bun test --watch tests/",
|
|
33
|
+
"test:unit": "bun test tests/protocol tests/plugins tests/client tests/integrations tests/oauth tests/transport tests/utils tests/errors",
|
|
34
34
|
"test:integration": "bun test tests/integration/simple-integration.test.ts",
|
|
35
|
-
"test:coverage": "bun test --coverage tests/
|
|
35
|
+
"test:coverage": "bun test --coverage tests/",
|
|
36
36
|
"prepare": "simple-git-hooks"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [
|