@olane/o-mcp 0.7.1 → 0.7.2

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.
Files changed (37) hide show
  1. package/dist/src/mcp.tool.d.ts +1 -1
  2. package/dist/src/mcp.tool.d.ts.map +1 -1
  3. package/dist/src/methods/mcp-bridge.methods.js +1 -1
  4. package/dist/src/oauth/index.d.ts +8 -0
  5. package/dist/src/oauth/index.d.ts.map +1 -0
  6. package/dist/src/oauth/index.js +7 -0
  7. package/dist/src/oauth/interfaces/client-metadata.interface.d.ts +17 -0
  8. package/dist/src/oauth/interfaces/client-metadata.interface.d.ts.map +1 -0
  9. package/dist/src/oauth/interfaces/client-metadata.interface.js +1 -0
  10. package/dist/src/oauth/interfaces/index.d.ts +4 -0
  11. package/dist/src/oauth/interfaces/index.d.ts.map +1 -0
  12. package/dist/src/oauth/interfaces/index.js +3 -0
  13. package/dist/src/oauth/interfaces/oauth-client-info.interface.d.ts +12 -0
  14. package/dist/src/oauth/interfaces/oauth-client-info.interface.d.ts.map +1 -0
  15. package/dist/src/oauth/interfaces/oauth-client-info.interface.js +1 -0
  16. package/dist/src/oauth/interfaces/oauth-tokens.interface.d.ts +10 -0
  17. package/dist/src/oauth/interfaces/oauth-tokens.interface.d.ts.map +1 -0
  18. package/dist/src/oauth/interfaces/oauth-tokens.interface.js +1 -0
  19. package/dist/src/oauth/mcp-dynamic-registration.d.ts +33 -0
  20. package/dist/src/oauth/mcp-dynamic-registration.d.ts.map +1 -0
  21. package/dist/src/oauth/mcp-dynamic-registration.js +107 -0
  22. package/dist/src/oauth/mcp-oauth-callback-server.d.ts +51 -0
  23. package/dist/src/oauth/mcp-oauth-callback-server.d.ts.map +1 -0
  24. package/dist/src/oauth/mcp-oauth-callback-server.js +179 -0
  25. package/dist/src/oauth/mcp-oauth-manager.d.ts +61 -0
  26. package/dist/src/oauth/mcp-oauth-manager.d.ts.map +1 -0
  27. package/dist/src/oauth/mcp-oauth-manager.js +289 -0
  28. package/dist/src/oauth/mcp-oauth-storage.d.ts +60 -0
  29. package/dist/src/oauth/mcp-oauth-storage.d.ts.map +1 -0
  30. package/dist/src/oauth/mcp-oauth-storage.js +146 -0
  31. package/dist/src/oauth/methods/mcp-oauth.methods.d.ts +5 -0
  32. package/dist/src/oauth/methods/mcp-oauth.methods.d.ts.map +1 -0
  33. package/dist/src/oauth/methods/mcp-oauth.methods.js +99 -0
  34. package/dist/src/oauth/oauth-aware-transport.d.ts +50 -0
  35. package/dist/src/oauth/oauth-aware-transport.d.ts.map +1 -0
  36. package/dist/src/oauth/oauth-aware-transport.js +120 -0
  37. package/package.json +20 -15
@@ -3,7 +3,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
3
  import { oLaneTool } from '@olane/o-lane';
4
4
  import { oNodeToolConfig } from '@olane/o-node';
5
5
  export declare class McpTool extends oLaneTool {
6
- private mcpClient;
6
+ protected mcpClient: Client;
7
7
  constructor(config: oNodeToolConfig & {
8
8
  address: oAddress;
9
9
  mcpClient: Client;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.tool.d.ts","sourceRoot":"","sources":["../../src/mcp.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiC,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,qBAAa,OAAQ,SAAQ,SAAS;IACpC,OAAO,CAAC,SAAS,CAAS;gBAGxB,MAAM,EAAE,eAAe,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAa9D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC3B,OAAO;IAQP,KAAK;;;;;;;IAuBL,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;CAoB7B"}
1
+ {"version":3,"file":"mcp.tool.d.ts","sourceRoot":"","sources":["../../src/mcp.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiC,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,qBAAa,OAAQ,SAAQ,SAAS;IACpC,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;gBAG1B,MAAM,EAAE,eAAe,GAAG;QAAE,OAAO,EAAE,QAAQ,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAa9D,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC3B,OAAO;IAQP,KAAK;;;;;;;IAuBL,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC;CAoB7B"}
@@ -78,7 +78,7 @@ export const MCP_BRIDGE_METHODS = {
78
78
  },
79
79
  add_local_server: {
80
80
  name: 'add_local_server',
81
- description: 'Add a local MCP server to the bridge using command and arguments',
81
+ description: 'Add a local MCP server to the bridge using command and arguments. If a command line argument is provided, use this method.',
82
82
  dependencies: [],
83
83
  parameters: [
84
84
  {
@@ -0,0 +1,8 @@
1
+ export * from './interfaces/index.js';
2
+ export * from './mcp-oauth-storage.js';
3
+ export * from './mcp-oauth-callback-server.js';
4
+ export * from './mcp-dynamic-registration.js';
5
+ export * from './oauth-aware-transport.js';
6
+ export * from './mcp-oauth-manager.js';
7
+ export * from './methods/mcp-oauth.methods.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/oauth/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export * from './interfaces/index.js';
2
+ export * from './mcp-oauth-storage.js';
3
+ export * from './mcp-oauth-callback-server.js';
4
+ export * from './mcp-dynamic-registration.js';
5
+ export * from './oauth-aware-transport.js';
6
+ export * from './mcp-oauth-manager.js';
7
+ export * from './methods/mcp-oauth.methods.js';
@@ -0,0 +1,17 @@
1
+ export interface ClientMetadata {
2
+ client_name: string;
3
+ redirect_uris: string[];
4
+ grant_types?: string[];
5
+ response_types?: string[];
6
+ scope?: string;
7
+ token_endpoint_auth_method?: string;
8
+ application_type?: string;
9
+ }
10
+ export interface StaticOAuthClientInfo {
11
+ client_id: string;
12
+ client_secret?: string;
13
+ authorization_endpoint?: string;
14
+ token_endpoint?: string;
15
+ scope?: string;
16
+ }
17
+ //# sourceMappingURL=client-metadata.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-metadata.interface.d.ts","sourceRoot":"","sources":["../../../../src/oauth/interfaces/client-metadata.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,4 @@
1
+ export * from './oauth-tokens.interface.js';
2
+ export * from './oauth-client-info.interface.js';
3
+ export * from './client-metadata.interface.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/interfaces/index.ts"],"names":[],"mappings":"AAAA,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from './oauth-tokens.interface.js';
2
+ export * from './oauth-client-info.interface.js';
3
+ export * from './client-metadata.interface.js';
@@ -0,0 +1,12 @@
1
+ export interface OAuthClientInfo {
2
+ client_id: string;
3
+ client_secret?: string;
4
+ authorization_endpoint: string;
5
+ token_endpoint: string;
6
+ registration_endpoint?: string;
7
+ scope?: string;
8
+ redirect_uris?: string[];
9
+ grant_types?: string[];
10
+ response_types?: string[];
11
+ }
12
+ //# sourceMappingURL=oauth-client-info.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-client-info.interface.d.ts","sourceRoot":"","sources":["../../../../src/oauth/interfaces/oauth-client-info.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B"}
@@ -0,0 +1,10 @@
1
+ export interface OAuthTokens {
2
+ access_token: string;
3
+ refresh_token?: string;
4
+ token_type: string;
5
+ expires_in?: number;
6
+ expires_at?: number;
7
+ scope?: string;
8
+ code_verifier?: string;
9
+ }
10
+ //# sourceMappingURL=oauth-tokens.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-tokens.interface.d.ts","sourceRoot":"","sources":["../../../../src/oauth/interfaces/oauth-tokens.interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB"}
@@ -0,0 +1,33 @@
1
+ import { OAuthClientInfo } from './interfaces/oauth-client-info.interface.js';
2
+ import { ClientMetadata } from './interfaces/client-metadata.interface.js';
3
+ /**
4
+ * Implements RFC 7591 Dynamic Client Registration for OAuth 2.0
5
+ *
6
+ * This class handles automatic registration of OAuth clients with remote servers
7
+ * that support dynamic client registration.
8
+ */
9
+ export declare class McpDynamicRegistration {
10
+ /**
11
+ * Register a new OAuth client dynamically
12
+ */
13
+ registerClient(registrationEndpoint: string, clientMetadata: ClientMetadata): Promise<OAuthClientInfo>;
14
+ /**
15
+ * Discover OAuth endpoints from a server URL
16
+ * Tries to find .well-known/oauth-authorization-server or OpenID Connect discovery
17
+ */
18
+ discoverEndpoints(serverUrl: string): Promise<{
19
+ authorization_endpoint?: string;
20
+ token_endpoint?: string;
21
+ registration_endpoint?: string;
22
+ }>;
23
+ /**
24
+ * Create client metadata for registration
25
+ */
26
+ createClientMetadata(clientName: string, redirectUri: string, scope?: string): ClientMetadata;
27
+ /**
28
+ * Get or register an OAuth client
29
+ * Returns cached client info if available, otherwise performs registration
30
+ */
31
+ getOrRegisterClient(serverUrl: string, clientName: string, redirectUri: string, existingClientInfo?: OAuthClientInfo | null, scope?: string): Promise<OAuthClientInfo>;
32
+ }
33
+ //# sourceMappingURL=mcp-dynamic-registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-dynamic-registration.d.ts","sourceRoot":"","sources":["../../../src/oauth/mcp-dynamic-registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAE3E;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC;;OAEG;IACG,cAAc,CAClB,oBAAoB,EAAE,MAAM,EAC5B,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,eAAe,CAAC;IAmC3B;;;OAGG;IACG,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QAClD,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;KAChC,CAAC;IA0BF;;OAEG;IACH,oBAAoB,CAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,MAAM,GACb,cAAc;IAYjB;;;OAGG;IACG,mBAAmB,CACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,kBAAkB,CAAC,EAAE,eAAe,GAAG,IAAI,EAC3C,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,CAAC;CAyC5B"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Implements RFC 7591 Dynamic Client Registration for OAuth 2.0
3
+ *
4
+ * This class handles automatic registration of OAuth clients with remote servers
5
+ * that support dynamic client registration.
6
+ */
7
+ export class McpDynamicRegistration {
8
+ /**
9
+ * Register a new OAuth client dynamically
10
+ */
11
+ async registerClient(registrationEndpoint, clientMetadata) {
12
+ const response = await fetch(registrationEndpoint, {
13
+ method: 'POST',
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ Accept: 'application/json',
17
+ },
18
+ body: JSON.stringify(clientMetadata),
19
+ });
20
+ if (!response.ok) {
21
+ const errorText = await response.text();
22
+ throw new Error(`Dynamic client registration failed: ${response.status} ${errorText}`);
23
+ }
24
+ const registrationResponse = await response.json();
25
+ return {
26
+ client_id: registrationResponse.client_id,
27
+ client_secret: registrationResponse.client_secret,
28
+ authorization_endpoint: registrationResponse.authorization_endpoint ||
29
+ registrationResponse.authorization_url,
30
+ token_endpoint: registrationResponse.token_endpoint || registrationResponse.token_url,
31
+ registration_endpoint: registrationEndpoint,
32
+ scope: clientMetadata.scope,
33
+ redirect_uris: registrationResponse.redirect_uris,
34
+ grant_types: registrationResponse.grant_types,
35
+ response_types: registrationResponse.response_types,
36
+ };
37
+ }
38
+ /**
39
+ * Discover OAuth endpoints from a server URL
40
+ * Tries to find .well-known/oauth-authorization-server or OpenID Connect discovery
41
+ */
42
+ async discoverEndpoints(serverUrl) {
43
+ const wellKnownUrls = [
44
+ `${serverUrl}/.well-known/oauth-authorization-server`,
45
+ `${serverUrl}/.well-known/openid-configuration`,
46
+ ];
47
+ for (const wellKnownUrl of wellKnownUrls) {
48
+ try {
49
+ const response = await fetch(wellKnownUrl);
50
+ if (response.ok) {
51
+ const discovery = await response.json();
52
+ return {
53
+ authorization_endpoint: discovery.authorization_endpoint,
54
+ token_endpoint: discovery.token_endpoint,
55
+ registration_endpoint: discovery.registration_endpoint,
56
+ };
57
+ }
58
+ }
59
+ catch (error) {
60
+ // Try next well-known URL
61
+ continue;
62
+ }
63
+ }
64
+ return {};
65
+ }
66
+ /**
67
+ * Create client metadata for registration
68
+ */
69
+ createClientMetadata(clientName, redirectUri, scope) {
70
+ return {
71
+ client_name: clientName,
72
+ redirect_uris: [redirectUri],
73
+ grant_types: ['authorization_code', 'refresh_token'],
74
+ response_types: ['code'],
75
+ token_endpoint_auth_method: 'client_secret_basic',
76
+ application_type: 'native',
77
+ scope: scope || 'openid profile email',
78
+ };
79
+ }
80
+ /**
81
+ * Get or register an OAuth client
82
+ * Returns cached client info if available, otherwise performs registration
83
+ */
84
+ async getOrRegisterClient(serverUrl, clientName, redirectUri, existingClientInfo, scope) {
85
+ // Return existing client info if valid
86
+ if (existingClientInfo?.client_id) {
87
+ return existingClientInfo;
88
+ }
89
+ // Discover endpoints
90
+ const endpoints = await this.discoverEndpoints(serverUrl);
91
+ if (!endpoints.registration_endpoint) {
92
+ throw new Error(`No registration endpoint found for server: ${serverUrl}. ` +
93
+ `Please provide static OAuth client credentials instead.`);
94
+ }
95
+ if (!endpoints.authorization_endpoint || !endpoints.token_endpoint) {
96
+ throw new Error(`Could not discover OAuth endpoints for server: ${serverUrl}`);
97
+ }
98
+ // Create client metadata
99
+ const clientMetadata = this.createClientMetadata(clientName, redirectUri, scope);
100
+ // Register the client
101
+ const clientInfo = await this.registerClient(endpoints.registration_endpoint, clientMetadata);
102
+ // Add discovered endpoints
103
+ clientInfo.authorization_endpoint = endpoints.authorization_endpoint;
104
+ clientInfo.token_endpoint = endpoints.token_endpoint;
105
+ return clientInfo;
106
+ }
107
+ }
@@ -0,0 +1,51 @@
1
+ interface CallbackResult {
2
+ code: string;
3
+ state?: string;
4
+ error?: string;
5
+ error_description?: string;
6
+ }
7
+ /**
8
+ * HTTP server for handling OAuth callbacks
9
+ *
10
+ * This server runs locally to receive the OAuth redirect after user authorization.
11
+ * It automatically shuts down after receiving the callback.
12
+ */
13
+ export declare class McpOAuthCallbackServer {
14
+ private app;
15
+ private server;
16
+ private port;
17
+ private events;
18
+ private callbackResult;
19
+ constructor(port?: number);
20
+ /**
21
+ * Setup Express routes
22
+ */
23
+ private setupRoutes;
24
+ /**
25
+ * Start the callback server
26
+ */
27
+ start(port?: number): Promise<void>;
28
+ /**
29
+ * Stop the callback server
30
+ */
31
+ stop(): Promise<void>;
32
+ /**
33
+ * Wait for OAuth callback
34
+ * @param timeout Timeout in milliseconds (default: 5 minutes)
35
+ */
36
+ waitForCallback(timeout?: number): Promise<CallbackResult>;
37
+ /**
38
+ * Get the callback URL
39
+ */
40
+ getCallbackUrl(): string;
41
+ /**
42
+ * Get the current port
43
+ */
44
+ getPort(): number;
45
+ /**
46
+ * Check if server is running
47
+ */
48
+ isRunning(): boolean;
49
+ }
50
+ export {};
51
+ //# sourceMappingURL=mcp-oauth-callback-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-oauth-callback-server.d.ts","sourceRoot":"","sources":["../../../src/oauth/mcp-oauth-callback-server.ts"],"names":[],"mappings":"AAIA,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,cAAc,CAA+B;gBAEzC,IAAI,CAAC,EAAE,MAAM;IASzB;;OAEG;IACH,OAAO,CAAC,WAAW;IAoEnB;;OAEG;IACG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCzC;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B;;;OAGG;IACG,eAAe,CAAC,OAAO,GAAE,MAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA2BxE;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACH,SAAS,IAAI,OAAO;CAGrB"}
@@ -0,0 +1,179 @@
1
+ import express from 'express';
2
+ import { EventEmitter } from 'events';
3
+ /**
4
+ * HTTP server for handling OAuth callbacks
5
+ *
6
+ * This server runs locally to receive the OAuth redirect after user authorization.
7
+ * It automatically shuts down after receiving the callback.
8
+ */
9
+ export class McpOAuthCallbackServer {
10
+ constructor(port) {
11
+ this.server = null;
12
+ this.port = 3334;
13
+ this.callbackResult = null;
14
+ if (port) {
15
+ this.port = port;
16
+ }
17
+ this.app = express();
18
+ this.events = new EventEmitter();
19
+ this.setupRoutes();
20
+ }
21
+ /**
22
+ * Setup Express routes
23
+ */
24
+ setupRoutes() {
25
+ // OAuth callback endpoint
26
+ this.app.get('/oauth/callback', (req, res) => {
27
+ const { code, state, error, error_description } = req.query;
28
+ if (error) {
29
+ this.callbackResult = {
30
+ code: '',
31
+ error: error,
32
+ error_description: error_description,
33
+ };
34
+ res.send(`
35
+ <html>
36
+ <head><title>OAuth Error</title></head>
37
+ <body style="font-family: Arial, sans-serif; padding: 40px; text-align: center;">
38
+ <h1 style="color: #d32f2f;">Authentication Failed</h1>
39
+ <p style="color: #666;">Error: ${error}</p>
40
+ <p style="color: #666;">${error_description || ''}</p>
41
+ <p style="margin-top: 40px; color: #999;">You can close this window.</p>
42
+ </body>
43
+ </html>
44
+ `);
45
+ }
46
+ else if (code) {
47
+ this.callbackResult = {
48
+ code: code,
49
+ state: state,
50
+ };
51
+ res.send(`
52
+ <html>
53
+ <head><title>OAuth Success</title></head>
54
+ <body style="font-family: Arial, sans-serif; padding: 40px; text-align: center;">
55
+ <h1 style="color: #4caf50;">✓ Authentication Successful</h1>
56
+ <p style="color: #666;">You have successfully authenticated with the MCP server.</p>
57
+ <p style="margin-top: 40px; color: #999;">You can close this window.</p>
58
+ <script>
59
+ setTimeout(() => window.close(), 3000);
60
+ </script>
61
+ </body>
62
+ </html>
63
+ `);
64
+ }
65
+ else {
66
+ this.callbackResult = {
67
+ code: '',
68
+ error: 'invalid_request',
69
+ error_description: 'No code or error in callback',
70
+ };
71
+ res.status(400).send(`
72
+ <html>
73
+ <head><title>OAuth Error</title></head>
74
+ <body style="font-family: Arial, sans-serif; padding: 40px; text-align: center;">
75
+ <h1 style="color: #d32f2f;">Invalid Callback</h1>
76
+ <p style="color: #666;">The OAuth callback was missing required parameters.</p>
77
+ <p style="margin-top: 40px; color: #999;">You can close this window.</p>
78
+ </body>
79
+ </html>
80
+ `);
81
+ }
82
+ // Emit callback event
83
+ this.events.emit('callback', this.callbackResult);
84
+ });
85
+ // Health check endpoint
86
+ this.app.get('/health', (req, res) => {
87
+ res.json({ status: 'ok', port: this.port });
88
+ });
89
+ }
90
+ /**
91
+ * Start the callback server
92
+ */
93
+ async start(port) {
94
+ if (port) {
95
+ this.port = port;
96
+ }
97
+ if (this.server) {
98
+ throw new Error('Callback server is already running');
99
+ }
100
+ return new Promise((resolve, reject) => {
101
+ try {
102
+ this.server = this.app.listen(this.port, () => {
103
+ console.log(`OAuth callback server listening on http://localhost:${this.port}`);
104
+ resolve();
105
+ });
106
+ this.server.on('error', (error) => {
107
+ if (error.code === 'EADDRINUSE') {
108
+ reject(new Error(`Port ${this.port} is already in use. Please close other OAuth flows or choose a different port.`));
109
+ }
110
+ else {
111
+ reject(error);
112
+ }
113
+ });
114
+ }
115
+ catch (error) {
116
+ reject(error);
117
+ }
118
+ });
119
+ }
120
+ /**
121
+ * Stop the callback server
122
+ */
123
+ async stop() {
124
+ if (!this.server) {
125
+ return;
126
+ }
127
+ return new Promise((resolve, reject) => {
128
+ this.server.close((error) => {
129
+ if (error) {
130
+ reject(error);
131
+ }
132
+ else {
133
+ this.server = null;
134
+ this.callbackResult = null;
135
+ resolve();
136
+ }
137
+ });
138
+ });
139
+ }
140
+ /**
141
+ * Wait for OAuth callback
142
+ * @param timeout Timeout in milliseconds (default: 5 minutes)
143
+ */
144
+ async waitForCallback(timeout = 300000) {
145
+ return new Promise((resolve, reject) => {
146
+ const timeoutId = setTimeout(() => {
147
+ this.events.removeAllListeners('callback');
148
+ reject(new Error('OAuth callback timeout. User did not complete authentication.'));
149
+ }, timeout);
150
+ this.events.once('callback', (result) => {
151
+ clearTimeout(timeoutId);
152
+ if (result.error) {
153
+ reject(new Error(`OAuth error: ${result.error}. ${result.error_description || ''}`));
154
+ }
155
+ else {
156
+ resolve(result);
157
+ }
158
+ });
159
+ });
160
+ }
161
+ /**
162
+ * Get the callback URL
163
+ */
164
+ getCallbackUrl() {
165
+ return `http://localhost:${this.port}/oauth/callback`;
166
+ }
167
+ /**
168
+ * Get the current port
169
+ */
170
+ getPort() {
171
+ return this.port;
172
+ }
173
+ /**
174
+ * Check if server is running
175
+ */
176
+ isRunning() {
177
+ return this.server !== null;
178
+ }
179
+ }
@@ -0,0 +1,61 @@
1
+ import { oRequest } from '@olane/o-core';
2
+ import { oLaneTool } from '@olane/o-lane';
3
+ import { oNodeToolConfig } from '@olane/o-node';
4
+ import { ToolResult } from '@olane/o-tool';
5
+ /**
6
+ * MCP OAuth Manager Tool
7
+ *
8
+ * Coordinates OAuth authentication flows for MCP servers:
9
+ * - Dynamic client registration (RFC 7591)
10
+ * - PKCE authorization flow
11
+ * - Token storage and refresh
12
+ * - Callback server management
13
+ */
14
+ export declare class McpOAuthManager extends oLaneTool {
15
+ private storage;
16
+ private callbackServer;
17
+ private dynamicRegistration;
18
+ private oauthToolAddress;
19
+ constructor(config: oNodeToolConfig);
20
+ /**
21
+ * Authenticate with an OAuth-protected MCP server
22
+ */
23
+ _tool_authenticate_server(request: oRequest): Promise<ToolResult>;
24
+ /**
25
+ * Refresh OAuth tokens for an MCP server
26
+ */
27
+ _tool_refresh_tokens(request: oRequest): Promise<ToolResult>;
28
+ /**
29
+ * Check OAuth token status for an MCP server
30
+ */
31
+ _tool_check_tokens(request: oRequest): Promise<ToolResult>;
32
+ /**
33
+ * Clear OAuth tokens and client info for an MCP server
34
+ */
35
+ _tool_clear_tokens(request: oRequest): Promise<ToolResult>;
36
+ /**
37
+ * List all authenticated MCP servers
38
+ */
39
+ _tool_list_authenticated_servers(request: oRequest): Promise<ToolResult>;
40
+ /**
41
+ * Public method for refreshing tokens (used by transport)
42
+ */
43
+ refreshTokens(serverUrl: string): Promise<void>;
44
+ /**
45
+ * Get service name for OAuth tool
46
+ */
47
+ private getServiceName;
48
+ /**
49
+ * Hash server URL for service name
50
+ */
51
+ private hashServerUrl;
52
+ /**
53
+ * Launch browser for OAuth authorization
54
+ */
55
+ private launchBrowser;
56
+ /**
57
+ * Cleanup on shutdown
58
+ */
59
+ stop(): Promise<void>;
60
+ }
61
+ //# sourceMappingURL=mcp-oauth-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-oauth-manager.d.ts","sourceRoot":"","sources":["../../../src/oauth/mcp-oauth-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C;;;;;;;;GAQG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,cAAc,CAAuC;IAC7D,OAAO,CAAC,mBAAmB,CAAyB;IACpD,OAAO,CAAC,gBAAgB,CAAW;gBAEvB,MAAM,EAAE,eAAe;IAkBnC;;OAEG;IACG,yBAAyB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAyLvE;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAwClE;;OAEG;IACG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAehE;;OAEG;IACG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAahE;;OAEG;IACG,gCAAgC,CACpC,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,UAAU,CAAC;IAWtB;;OAEG;IACG,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAarD;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;YACW,aAAa;IAY3B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}